[TEST] Add Exchange initialization on 3D pass for linear unswizzling

This commit is contained in:
CamilleLaVey
2026-08-21 22:30:07 -04:00
parent 1cd118eccc
commit 33ae95f4ae
2 changed files with 16 additions and 10 deletions
@@ -720,13 +720,15 @@ void BlockLinearUnswizzle3DPass::Unswizzle(
const u32 blocks_x = (image.info.size.width + 3) / 4; const u32 blocks_x = (image.info.size.width + 3) / 4;
const u32 blocks_y = (image.info.size.height + 3) / 4; const u32 blocks_y = (image.info.size.height + 3) / 4;
const bool is_initialized = image.ExchangeInitialization();
scheduler.RequestOutsideRenderPassOperationContext(); scheduler.RequestOutsideRenderPassOperationContext();
for (u32 z_offset = 0; z_offset < z_count; z_offset += MAX_BATCH_SLICES) { for (u32 z_offset = 0; z_offset < z_count; z_offset += MAX_BATCH_SLICES) {
const u32 current_chunk_slices = (std::min)(MAX_BATCH_SLICES, z_count - z_offset); const u32 current_chunk_slices = (std::min)(MAX_BATCH_SLICES, z_count - z_offset);
const u32 current_z_start = z_start + z_offset; const u32 current_z_start = z_start + z_offset;
UnswizzleChunk(image, swizzled, sw, params, blocks_x, blocks_y, UnswizzleChunk(image, swizzled, sw, params, blocks_x, blocks_y,
current_z_start, current_chunk_slices); current_z_start, current_chunk_slices, is_initialized);
} }
} }
@@ -736,7 +738,7 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk(
const VideoCommon::SwizzleParameters& sw, const VideoCommon::SwizzleParameters& sw,
const BlockLinearSwizzle3DParams& params, const BlockLinearSwizzle3DParams& params,
u32 blocks_x, u32 blocks_y, u32 blocks_x, u32 blocks_y,
u32 z_start, u32 z_count) u32 z_start, u32 z_count, bool is_initialized)
{ {
BlockLinearUnswizzle3DPushConstants pc{}; BlockLinearUnswizzle3DPushConstants pc{};
pc.origin[0] = params.origin[0]; pc.origin[0] = params.origin[0];
@@ -780,6 +782,7 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk(
const VkDeviceSize barrier_size = output_slice_size * z_count; const VkDeviceSize barrier_size = output_slice_size * z_count;
const bool is_first_chunk = (z_start == 0); const bool is_first_chunk = (z_start == 0);
const bool use_undefined_layout = !is_initialized && is_first_chunk;
const VkBuffer out_buffer = *image.compute_unswizzle_buffer; const VkBuffer out_buffer = *image.compute_unswizzle_buffer;
const VkImage dst_image = image.Handle(); const VkImage dst_image = image.Handle();
@@ -788,7 +791,7 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk(
const u32 image_height = image.info.size.height; const u32 image_height = image.info.size.height;
scheduler.Record([this, set, descriptor_data, pc, gx, gy, gz, z_start, z_count, scheduler.Record([this, set, descriptor_data, pc, gx, gy, gz, z_start, z_count,
barrier_size, is_first_chunk, out_buffer, dst_image, aspect, barrier_size, use_undefined_layout, out_buffer, dst_image, aspect,
image_width, image_height image_width, image_height
](vk::CommandBuffer cmdbuf) { ](vk::CommandBuffer cmdbuf) {
@@ -815,15 +818,14 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk(
.size = barrier_size, .size = barrier_size,
}; };
// Image layout transition
const VkImageMemoryBarrier pre_barrier{ const VkImageMemoryBarrier pre_barrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = is_first_chunk ? VkAccessFlags{} : .srcAccessMask = use_undefined_layout ? VkAccessFlags{} :
static_cast<VkAccessFlags>(VK_ACCESS_TRANSFER_WRITE_BIT), static_cast<VkAccessFlags>(VK_ACCESS_SHADER_READ_BIT),
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.oldLayout = is_first_chunk ? VK_IMAGE_LAYOUT_UNDEFINED : .oldLayout = use_undefined_layout ? VK_IMAGE_LAYOUT_UNDEFINED :
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -831,9 +833,13 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk(
.subresourceRange = {aspect, 0, 1, 0, 1}, .subresourceRange = {aspect, 0, 1, 0, 1},
}; };
VkPipelineStageFlags pre_barrier_src_stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
pre_barrier_src_stages |= use_undefined_layout ? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
: vk::PIPELINE_STAGE_GRAPHICS_COMPUTE;
// Single barrier handles both buffer and image // Single barrier handles both buffer and image
cmdbuf.PipelineBarrier( cmdbuf.PipelineBarrier(
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, pre_barrier_src_stages,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0,
nullptr, buffer_barrier, pre_barrier nullptr, buffer_barrier, pre_barrier
@@ -156,7 +156,7 @@ public:
const VideoCommon::SwizzleParameters& sw, const VideoCommon::SwizzleParameters& sw,
const BlockLinearSwizzle3DParams& params, const BlockLinearSwizzle3DParams& params,
u32 blocks_x, u32 blocks_y, u32 blocks_x, u32 blocks_y,
u32 z_start, u32 z_count); u32 z_start, u32 z_count, bool is_initialized);
private: private:
Scheduler& scheduler; Scheduler& scheduler;