|
|
@ -180,19 +180,19 @@ VkImageCreateInfo GenerateImageCreateInfo(const VKDevice& device, const SurfaceP
|
|
|
|
return ci;
|
|
|
|
return ci;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u32 EncodeSwizzle(Tegra::Texture::SwizzleSource x_source, Tegra::Texture::SwizzleSource y_source,
|
|
|
|
u32 EncodeSwizzle(SwizzleSource x_source, SwizzleSource y_source, SwizzleSource z_source,
|
|
|
|
Tegra::Texture::SwizzleSource z_source, Tegra::Texture::SwizzleSource w_source) {
|
|
|
|
SwizzleSource w_source) {
|
|
|
|
return (static_cast<u32>(x_source) << 24) | (static_cast<u32>(y_source) << 16) |
|
|
|
|
return (static_cast<u32>(x_source) << 24) | (static_cast<u32>(y_source) << 16) |
|
|
|
|
(static_cast<u32>(z_source) << 8) | static_cast<u32>(w_source);
|
|
|
|
(static_cast<u32>(z_source) << 8) | static_cast<u32>(w_source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // Anonymous namespace
|
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
|
|
|
|
CachedSurface::CachedSurface(const VKDevice& device, VKMemoryManager& memory_manager,
|
|
|
|
CachedSurface::CachedSurface(const VKDevice& device_, VKMemoryManager& memory_manager_,
|
|
|
|
VKScheduler& scheduler, VKStagingBufferPool& staging_pool,
|
|
|
|
VKScheduler& scheduler_, VKStagingBufferPool& staging_pool_,
|
|
|
|
GPUVAddr gpu_addr, const SurfaceParams& params)
|
|
|
|
GPUVAddr gpu_addr_, const SurfaceParams& params_)
|
|
|
|
: SurfaceBase<View>{gpu_addr, params, device.IsOptimalAstcSupported()}, device{device},
|
|
|
|
: SurfaceBase<View>{gpu_addr_, params_, device_.IsOptimalAstcSupported()}, device{device_},
|
|
|
|
memory_manager{memory_manager}, scheduler{scheduler}, staging_pool{staging_pool} {
|
|
|
|
memory_manager{memory_manager_}, scheduler{scheduler_}, staging_pool{staging_pool_} {
|
|
|
|
if (params.IsBuffer()) {
|
|
|
|
if (params.IsBuffer()) {
|
|
|
|
buffer = CreateBuffer(device, params, host_memory_size);
|
|
|
|
buffer = CreateBuffer(device, params, host_memory_size);
|
|
|
|
commit = memory_manager.Commit(buffer, false);
|
|
|
|
commit = memory_manager.Commit(buffer, false);
|
|
|
@ -234,7 +234,7 @@ void CachedSurface::UploadTexture(const std::vector<u8>& staging_buffer) {
|
|
|
|
void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
|
|
|
|
void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
|
|
|
|
UNIMPLEMENTED_IF(params.IsBuffer());
|
|
|
|
UNIMPLEMENTED_IF(params.IsBuffer());
|
|
|
|
|
|
|
|
|
|
|
|
if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM) {
|
|
|
|
if (params.pixel_format == PixelFormat::A1B5G5R5_UNORM) {
|
|
|
|
LOG_WARNING(Render_Vulkan, "A1B5G5R5 flushing is stubbed");
|
|
|
|
LOG_WARNING(Render_Vulkan, "A1B5G5R5 flushing is stubbed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -244,10 +244,10 @@ void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
|
|
|
|
FullTransition(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT,
|
|
|
|
FullTransition(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT,
|
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
|
|
|
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
|
|
|
|
|
|
|
|
|
|
|
const auto& buffer = staging_pool.GetUnusedBuffer(host_memory_size, true);
|
|
|
|
const auto& unused_buffer = staging_pool.GetUnusedBuffer(host_memory_size, true);
|
|
|
|
// TODO(Rodrigo): Do this in a single copy
|
|
|
|
// TODO(Rodrigo): Do this in a single copy
|
|
|
|
for (u32 level = 0; level < params.num_levels; ++level) {
|
|
|
|
for (u32 level = 0; level < params.num_levels; ++level) {
|
|
|
|
scheduler.Record([image = *image->GetHandle(), buffer = *buffer.handle,
|
|
|
|
scheduler.Record([image = *image->GetHandle(), buffer = *unused_buffer.handle,
|
|
|
|
copy = GetBufferImageCopy(level)](vk::CommandBuffer cmdbuf) {
|
|
|
|
copy = GetBufferImageCopy(level)](vk::CommandBuffer cmdbuf) {
|
|
|
|
cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, copy);
|
|
|
|
cmdbuf.CopyImageToBuffer(image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer, copy);
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -255,16 +255,17 @@ void CachedSurface::DownloadTexture(std::vector<u8>& staging_buffer) {
|
|
|
|
scheduler.Finish();
|
|
|
|
scheduler.Finish();
|
|
|
|
|
|
|
|
|
|
|
|
// TODO(Rodrigo): Use an intern buffer for staging buffers and avoid this unnecessary memcpy.
|
|
|
|
// TODO(Rodrigo): Use an intern buffer for staging buffers and avoid this unnecessary memcpy.
|
|
|
|
std::memcpy(staging_buffer.data(), buffer.commit->Map(host_memory_size), host_memory_size);
|
|
|
|
std::memcpy(staging_buffer.data(), unused_buffer.commit->Map(host_memory_size),
|
|
|
|
|
|
|
|
host_memory_size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CachedSurface::DecorateSurfaceName() {
|
|
|
|
void CachedSurface::DecorateSurfaceName() {
|
|
|
|
// TODO(Rodrigo): Add name decorations
|
|
|
|
// TODO(Rodrigo): Add name decorations
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
View CachedSurface::CreateView(const ViewParams& params) {
|
|
|
|
View CachedSurface::CreateView(const ViewParams& view_params) {
|
|
|
|
// TODO(Rodrigo): Add name decorations
|
|
|
|
// TODO(Rodrigo): Add name decorations
|
|
|
|
return views[params] = std::make_shared<CachedSurfaceView>(device, *this, params);
|
|
|
|
return views[view_params] = std::make_shared<CachedSurfaceView>(device, *this, view_params);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CachedSurface::UploadBuffer(const std::vector<u8>& staging_buffer) {
|
|
|
|
void CachedSurface::UploadBuffer(const std::vector<u8>& staging_buffer) {
|
|
|
@ -348,21 +349,21 @@ VkImageSubresourceRange CachedSurface::GetImageSubresourceRange() const {
|
|
|
|
static_cast<u32>(params.GetNumLayers())};
|
|
|
|
static_cast<u32>(params.GetNumLayers())};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CachedSurfaceView::CachedSurfaceView(const VKDevice& device, CachedSurface& surface,
|
|
|
|
CachedSurfaceView::CachedSurfaceView(const VKDevice& device_, CachedSurface& surface_,
|
|
|
|
const ViewParams& params)
|
|
|
|
const ViewParams& view_params_)
|
|
|
|
: VideoCommon::ViewBase{params}, params{surface.GetSurfaceParams()},
|
|
|
|
: ViewBase{view_params_}, surface_params{surface_.GetSurfaceParams()},
|
|
|
|
image{surface.GetImageHandle()}, buffer_view{surface.GetBufferViewHandle()},
|
|
|
|
image{surface_.GetImageHandle()}, buffer_view{surface_.GetBufferViewHandle()},
|
|
|
|
aspect_mask{surface.GetAspectMask()}, device{device}, surface{surface},
|
|
|
|
aspect_mask{surface_.GetAspectMask()}, device{device_}, surface{surface_},
|
|
|
|
base_level{params.base_level}, num_levels{params.num_levels},
|
|
|
|
base_level{view_params_.base_level}, num_levels{view_params_.num_levels},
|
|
|
|
image_view_type{image ? GetImageViewType(params.target) : VK_IMAGE_VIEW_TYPE_1D} {
|
|
|
|
image_view_type{image ? GetImageViewType(view_params_.target) : VK_IMAGE_VIEW_TYPE_1D} {
|
|
|
|
if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) {
|
|
|
|
if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) {
|
|
|
|
base_layer = 0;
|
|
|
|
base_layer = 0;
|
|
|
|
num_layers = 1;
|
|
|
|
num_layers = 1;
|
|
|
|
base_slice = params.base_layer;
|
|
|
|
base_slice = view_params_.base_layer;
|
|
|
|
num_slices = params.num_layers;
|
|
|
|
num_slices = view_params_.num_layers;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
base_layer = params.base_layer;
|
|
|
|
base_layer = view_params_.base_layer;
|
|
|
|
num_layers = params.num_layers;
|
|
|
|
num_layers = view_params_.num_layers;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -384,7 +385,7 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc
|
|
|
|
|
|
|
|
|
|
|
|
std::array swizzle{MaxwellToVK::SwizzleSource(x_source), MaxwellToVK::SwizzleSource(y_source),
|
|
|
|
std::array swizzle{MaxwellToVK::SwizzleSource(x_source), MaxwellToVK::SwizzleSource(y_source),
|
|
|
|
MaxwellToVK::SwizzleSource(z_source), MaxwellToVK::SwizzleSource(w_source)};
|
|
|
|
MaxwellToVK::SwizzleSource(z_source), MaxwellToVK::SwizzleSource(w_source)};
|
|
|
|
if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM) {
|
|
|
|
if (surface_params.pixel_format == PixelFormat::A1B5G5R5_UNORM) {
|
|
|
|
// A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here.
|
|
|
|
// A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here.
|
|
|
|
std::swap(swizzle[0], swizzle[2]);
|
|
|
|
std::swap(swizzle[0], swizzle[2]);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -395,12 +396,12 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc
|
|
|
|
if (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
|
|
|
if (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
|
|
|
UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G);
|
|
|
|
UNIMPLEMENTED_IF(x_source != SwizzleSource::R && x_source != SwizzleSource::G);
|
|
|
|
const bool is_first = x_source == SwizzleSource::R;
|
|
|
|
const bool is_first = x_source == SwizzleSource::R;
|
|
|
|
switch (params.pixel_format) {
|
|
|
|
switch (surface_params.pixel_format) {
|
|
|
|
case VideoCore::Surface::PixelFormat::D24_UNORM_S8_UINT:
|
|
|
|
case PixelFormat::D24_UNORM_S8_UINT:
|
|
|
|
case VideoCore::Surface::PixelFormat::D32_FLOAT_S8_UINT:
|
|
|
|
case PixelFormat::D32_FLOAT_S8_UINT:
|
|
|
|
aspect = is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
|
|
aspect = is_first ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM:
|
|
|
|
case PixelFormat::S8_UINT_D24_UNORM:
|
|
|
|
aspect = is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
|
|
aspect = is_first ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
@ -417,7 +418,7 @@ VkImageView CachedSurfaceView::GetImageView(SwizzleSource x_source, SwizzleSourc
|
|
|
|
|
|
|
|
|
|
|
|
if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) {
|
|
|
|
if (image_view_type == VK_IMAGE_VIEW_TYPE_3D) {
|
|
|
|
ASSERT(base_slice == 0);
|
|
|
|
ASSERT(base_slice == 0);
|
|
|
|
ASSERT(num_slices == params.depth);
|
|
|
|
ASSERT(num_slices == surface_params.depth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
image_view = device.GetLogical().CreateImageView({
|
|
|
|
image_view = device.GetLogical().CreateImageView({
|
|
|
|