|
|
@ -25,6 +25,9 @@ |
|
|
#include "video_core/host_shaders/vulkan_quad_indexed_comp_spv.h"
|
|
|
#include "video_core/host_shaders/vulkan_quad_indexed_comp_spv.h"
|
|
|
#include "video_core/host_shaders/vulkan_uint8_comp_spv.h"
|
|
|
#include "video_core/host_shaders/vulkan_uint8_comp_spv.h"
|
|
|
#include "video_core/host_shaders/block_linear_unswizzle_3d_bcn_comp_spv.h"
|
|
|
#include "video_core/host_shaders/block_linear_unswizzle_3d_bcn_comp_spv.h"
|
|
|
|
|
|
#include "video_core/host_shaders/block_linear_unswizzle_2d_comp_spv.h"
|
|
|
|
|
|
#include "video_core/host_shaders/block_linear_unswizzle_3d_comp_spv.h"
|
|
|
|
|
|
#include "video_core/host_shaders/pitch_unswizzle_comp_spv.h"
|
|
|
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
|
|
#include "video_core/renderer_vulkan/vk_compute_pass.h"
|
|
|
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
|
|
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
|
|
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
|
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
|
|
@ -232,6 +235,26 @@ struct QueriesPrefixScanPushConstants { |
|
|
struct ConditionalRenderingResolvePushConstants { |
|
|
struct ConditionalRenderingResolvePushConstants { |
|
|
u32 compare_to_zero; |
|
|
u32 compare_to_zero; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct BlockLinear3DImagePushConstants { |
|
|
|
|
|
alignas(16) std::array<u32, 3> origin; |
|
|
|
|
|
alignas(16) std::array<s32, 3> destination; |
|
|
|
|
|
u32 bytes_per_block_log2; |
|
|
|
|
|
u32 slice_size; |
|
|
|
|
|
u32 block_size; |
|
|
|
|
|
u32 x_shift; |
|
|
|
|
|
u32 block_height; |
|
|
|
|
|
u32 block_height_mask; |
|
|
|
|
|
u32 block_depth; |
|
|
|
|
|
u32 block_depth_mask; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
struct PitchUnswizzlePushConstants { |
|
|
|
|
|
std::array<u32, 2> origin; |
|
|
|
|
|
std::array<s32, 2> destination; |
|
|
|
|
|
u32 bytes_per_block; |
|
|
|
|
|
u32 pitch; |
|
|
|
|
|
}; |
|
|
} // Anonymous namespace
|
|
|
} // Anonymous namespace
|
|
|
|
|
|
|
|
|
ComputePass::ComputePass(const Device& device_, Scheduler& scheduler, DescriptorPool& descriptor_pool, |
|
|
ComputePass::ComputePass(const Device& device_, Scheduler& scheduler, DescriptorPool& descriptor_pool, |
|
|
@ -653,6 +676,306 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, |
|
|
scheduler.Finish(); |
|
|
scheduler.Finish(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
BlockLinearUnswizzleImage2DPass::BlockLinearUnswizzleImage2DPass( |
|
|
|
|
|
const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool_, |
|
|
|
|
|
StagingBufferPool& staging_buffer_pool_, |
|
|
|
|
|
ComputePassDescriptorQueue& compute_pass_descriptor_queue_) |
|
|
|
|
|
: ComputePass(device_, scheduler_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, |
|
|
|
|
|
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, |
|
|
|
|
|
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(BlockLinearSwizzle2DParams)>, |
|
|
|
|
|
BLOCK_LINEAR_UNSWIZZLE_2D_COMP_SPV), |
|
|
|
|
|
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, |
|
|
|
|
|
compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {} |
|
|
|
|
|
|
|
|
|
|
|
BlockLinearUnswizzleImage2DPass::~BlockLinearUnswizzleImage2DPass() = default; |
|
|
|
|
|
|
|
|
|
|
|
void BlockLinearUnswizzleImage2DPass::Unswizzle( |
|
|
|
|
|
Image& image, const StagingBufferRef& map, |
|
|
|
|
|
std::span<const VideoCommon::SwizzleParameters> swizzles) { |
|
|
|
|
|
using namespace VideoCommon::Accelerated; |
|
|
|
|
|
scheduler.RequestOutsideRenderPassOperationContext(); |
|
|
|
|
|
const VkPipeline vk_pipeline = *pipeline; |
|
|
|
|
|
const VkImageAspectFlags aspect_mask = image.AspectMask(); |
|
|
|
|
|
const VkImage vk_image = image.Handle(); |
|
|
|
|
|
const bool is_initialized = image.ExchangeInitialization(); |
|
|
|
|
|
scheduler.Record([vk_pipeline, vk_image, aspect_mask, |
|
|
|
|
|
is_initialized](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkImageMemoryBarrier image_barrier{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcAccessMask = static_cast<VkAccessFlags>(is_initialized ? VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
: VK_ACCESS_NONE), |
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, |
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.image = vk_image, |
|
|
|
|
|
.subresourceRange{ |
|
|
|
|
|
.aspectMask = aspect_mask, |
|
|
|
|
|
.baseMipLevel = 0, |
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS, |
|
|
|
|
|
.baseArrayLayer = 0, |
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
|
|
|
cmdbuf.PipelineBarrier(is_initialized ? vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER |
|
|
|
|
|
: VkPipelineStageFlags(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT), |
|
|
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); |
|
|
|
|
|
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); |
|
|
|
|
|
}); |
|
|
|
|
|
for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { |
|
|
|
|
|
const size_t input_offset = swizzle.buffer_offset + map.offset; |
|
|
|
|
|
const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 32U); |
|
|
|
|
|
const u32 num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 32U); |
|
|
|
|
|
const u32 num_dispatches_z = image.info.resources.layers; |
|
|
|
|
|
|
|
|
|
|
|
compute_pass_descriptor_queue.Acquire(scheduler, 2); |
|
|
|
|
|
compute_pass_descriptor_queue.AddBuffer(map.buffer, input_offset, |
|
|
|
|
|
image.guest_size_bytes - swizzle.buffer_offset); |
|
|
|
|
|
compute_pass_descriptor_queue.AddImage(image.StorageImageView(swizzle.level)); |
|
|
|
|
|
const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; |
|
|
|
|
|
|
|
|
|
|
|
const auto params = MakeBlockLinearSwizzle2DParams(swizzle, image.info); |
|
|
|
|
|
scheduler.Record([this, num_dispatches_x, num_dispatches_y, num_dispatches_z, params, |
|
|
|
|
|
descriptor_data](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkDescriptorSet set = descriptor_allocator.Commit(); |
|
|
|
|
|
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); |
|
|
|
|
|
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {}); |
|
|
|
|
|
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, params); |
|
|
|
|
|
cmdbuf.Dispatch(num_dispatches_x, num_dispatches_y, num_dispatches_z); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
scheduler.Record([vk_image, aspect_mask](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkImageMemoryBarrier image_barrier{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.image = vk_image, |
|
|
|
|
|
.subresourceRange{ |
|
|
|
|
|
.aspectMask = aspect_mask, |
|
|
|
|
|
.baseMipLevel = 0, |
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS, |
|
|
|
|
|
.baseArrayLayer = 0, |
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, |
|
|
|
|
|
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, image_barrier); |
|
|
|
|
|
}); |
|
|
|
|
|
scheduler.Finish(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
BlockLinearUnswizzleImage3DPass::BlockLinearUnswizzleImage3DPass( |
|
|
|
|
|
const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool_, |
|
|
|
|
|
StagingBufferPool& staging_buffer_pool_, |
|
|
|
|
|
ComputePassDescriptorQueue& compute_pass_descriptor_queue_) |
|
|
|
|
|
: ComputePass(device_, scheduler_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, |
|
|
|
|
|
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, |
|
|
|
|
|
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(BlockLinear3DImagePushConstants)>, |
|
|
|
|
|
BLOCK_LINEAR_UNSWIZZLE_3D_COMP_SPV), |
|
|
|
|
|
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, |
|
|
|
|
|
compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {} |
|
|
|
|
|
|
|
|
|
|
|
BlockLinearUnswizzleImage3DPass::~BlockLinearUnswizzleImage3DPass() = default; |
|
|
|
|
|
|
|
|
|
|
|
void BlockLinearUnswizzleImage3DPass::Unswizzle( |
|
|
|
|
|
Image& image, const StagingBufferRef& map, |
|
|
|
|
|
std::span<const VideoCommon::SwizzleParameters> swizzles) { |
|
|
|
|
|
using namespace VideoCommon::Accelerated; |
|
|
|
|
|
scheduler.RequestOutsideRenderPassOperationContext(); |
|
|
|
|
|
const VkPipeline vk_pipeline = *pipeline; |
|
|
|
|
|
const VkImageAspectFlags aspect_mask = image.AspectMask(); |
|
|
|
|
|
const VkImage vk_image = image.Handle(); |
|
|
|
|
|
const bool is_initialized = image.ExchangeInitialization(); |
|
|
|
|
|
scheduler.Record([vk_pipeline, vk_image, aspect_mask, |
|
|
|
|
|
is_initialized](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkImageMemoryBarrier image_barrier{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcAccessMask = static_cast<VkAccessFlags>(is_initialized ? VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
: VK_ACCESS_NONE), |
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, |
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.image = vk_image, |
|
|
|
|
|
.subresourceRange{ |
|
|
|
|
|
.aspectMask = aspect_mask, |
|
|
|
|
|
.baseMipLevel = 0, |
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS, |
|
|
|
|
|
.baseArrayLayer = 0, |
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
|
|
|
cmdbuf.PipelineBarrier(is_initialized ? vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER |
|
|
|
|
|
: VkPipelineStageFlags(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT), |
|
|
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); |
|
|
|
|
|
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); |
|
|
|
|
|
}); |
|
|
|
|
|
for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { |
|
|
|
|
|
const size_t input_offset = swizzle.buffer_offset + map.offset; |
|
|
|
|
|
const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 16U); |
|
|
|
|
|
const u32 num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 8U); |
|
|
|
|
|
const u32 num_dispatches_z = Common::DivCeil(swizzle.num_tiles.depth, 8U); |
|
|
|
|
|
|
|
|
|
|
|
compute_pass_descriptor_queue.Acquire(scheduler, 2); |
|
|
|
|
|
compute_pass_descriptor_queue.AddBuffer(map.buffer, input_offset, |
|
|
|
|
|
image.guest_size_bytes - swizzle.buffer_offset); |
|
|
|
|
|
compute_pass_descriptor_queue.AddImage(image.StorageImageView(swizzle.level)); |
|
|
|
|
|
const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; |
|
|
|
|
|
|
|
|
|
|
|
const auto p = MakeBlockLinearSwizzle3DParams(swizzle, image.info); |
|
|
|
|
|
const BlockLinear3DImagePushConstants params{ |
|
|
|
|
|
.origin = p.origin, |
|
|
|
|
|
.destination = p.destination, |
|
|
|
|
|
.bytes_per_block_log2 = p.bytes_per_block_log2, |
|
|
|
|
|
.slice_size = p.slice_size, |
|
|
|
|
|
.block_size = p.block_size, |
|
|
|
|
|
.x_shift = p.x_shift, |
|
|
|
|
|
.block_height = p.block_height, |
|
|
|
|
|
.block_height_mask = p.block_height_mask, |
|
|
|
|
|
.block_depth = p.block_depth, |
|
|
|
|
|
.block_depth_mask = p.block_depth_mask, |
|
|
|
|
|
}; |
|
|
|
|
|
scheduler.Record([this, num_dispatches_x, num_dispatches_y, num_dispatches_z, params, |
|
|
|
|
|
descriptor_data](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkDescriptorSet set = descriptor_allocator.Commit(); |
|
|
|
|
|
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); |
|
|
|
|
|
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {}); |
|
|
|
|
|
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, params); |
|
|
|
|
|
cmdbuf.Dispatch(num_dispatches_x, num_dispatches_y, num_dispatches_z); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
scheduler.Record([vk_image, aspect_mask](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkImageMemoryBarrier image_barrier{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.image = vk_image, |
|
|
|
|
|
.subresourceRange{ |
|
|
|
|
|
.aspectMask = aspect_mask, |
|
|
|
|
|
.baseMipLevel = 0, |
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS, |
|
|
|
|
|
.baseArrayLayer = 0, |
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, |
|
|
|
|
|
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, image_barrier); |
|
|
|
|
|
}); |
|
|
|
|
|
scheduler.Finish(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
PitchUnswizzlePass::PitchUnswizzlePass(const Device& device_, Scheduler& scheduler_, |
|
|
|
|
|
DescriptorPool& descriptor_pool_, |
|
|
|
|
|
StagingBufferPool& staging_buffer_pool_, |
|
|
|
|
|
ComputePassDescriptorQueue& compute_pass_descriptor_queue_) |
|
|
|
|
|
: ComputePass(device_, scheduler_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, |
|
|
|
|
|
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, |
|
|
|
|
|
COMPUTE_PUSH_CONSTANT_RANGE<sizeof(PitchUnswizzlePushConstants)>, |
|
|
|
|
|
PITCH_UNSWIZZLE_COMP_SPV), |
|
|
|
|
|
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, |
|
|
|
|
|
compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {} |
|
|
|
|
|
|
|
|
|
|
|
PitchUnswizzlePass::~PitchUnswizzlePass() = default; |
|
|
|
|
|
|
|
|
|
|
|
void PitchUnswizzlePass::Unswizzle(Image& image, const StagingBufferRef& map, |
|
|
|
|
|
std::span<const VideoCommon::SwizzleParameters> swizzles) { |
|
|
|
|
|
scheduler.RequestOutsideRenderPassOperationContext(); |
|
|
|
|
|
const VkPipeline vk_pipeline = *pipeline; |
|
|
|
|
|
const VkImageAspectFlags aspect_mask = image.AspectMask(); |
|
|
|
|
|
const VkImage vk_image = image.Handle(); |
|
|
|
|
|
const bool is_initialized = image.ExchangeInitialization(); |
|
|
|
|
|
scheduler.Record([vk_pipeline, vk_image, aspect_mask, |
|
|
|
|
|
is_initialized](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkImageMemoryBarrier image_barrier{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcAccessMask = static_cast<VkAccessFlags>(is_initialized ? VK_ACCESS_SHADER_WRITE_BIT |
|
|
|
|
|
: VK_ACCESS_NONE), |
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, |
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.image = vk_image, |
|
|
|
|
|
.subresourceRange{ |
|
|
|
|
|
.aspectMask = aspect_mask, |
|
|
|
|
|
.baseMipLevel = 0, |
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS, |
|
|
|
|
|
.baseArrayLayer = 0, |
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
|
|
|
cmdbuf.PipelineBarrier(is_initialized ? vk::PIPELINE_STAGE_GRAPHICS_COMPUTE_TRANSFER |
|
|
|
|
|
: VkPipelineStageFlags(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT), |
|
|
|
|
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); |
|
|
|
|
|
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); |
|
|
|
|
|
}); |
|
|
|
|
|
const u32 bytes_per_block = VideoCore::Surface::BytesPerBlock(image.info.format); |
|
|
|
|
|
for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { |
|
|
|
|
|
const size_t input_offset = swizzle.buffer_offset + map.offset; |
|
|
|
|
|
const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 32U); |
|
|
|
|
|
const u32 num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 32U); |
|
|
|
|
|
|
|
|
|
|
|
compute_pass_descriptor_queue.Acquire(scheduler, 2); |
|
|
|
|
|
compute_pass_descriptor_queue.AddBuffer(map.buffer, input_offset, |
|
|
|
|
|
image.guest_size_bytes - swizzle.buffer_offset); |
|
|
|
|
|
compute_pass_descriptor_queue.AddImage(image.StorageImageView(swizzle.level)); |
|
|
|
|
|
const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; |
|
|
|
|
|
|
|
|
|
|
|
const PitchUnswizzlePushConstants params{ |
|
|
|
|
|
.origin = {0, 0}, |
|
|
|
|
|
.destination = {0, 0}, |
|
|
|
|
|
.bytes_per_block = bytes_per_block, |
|
|
|
|
|
.pitch = image.info.pitch, |
|
|
|
|
|
}; |
|
|
|
|
|
scheduler.Record([this, num_dispatches_x, num_dispatches_y, params, |
|
|
|
|
|
descriptor_data](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkDescriptorSet set = descriptor_allocator.Commit(); |
|
|
|
|
|
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); |
|
|
|
|
|
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {}); |
|
|
|
|
|
cmdbuf.PushConstants(*layout, VK_SHADER_STAGE_COMPUTE_BIT, params); |
|
|
|
|
|
cmdbuf.Dispatch(num_dispatches_x, num_dispatches_y, 1); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
scheduler.Record([vk_image, aspect_mask](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkImageMemoryBarrier image_barrier{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.image = vk_image, |
|
|
|
|
|
.subresourceRange{ |
|
|
|
|
|
.aspectMask = aspect_mask, |
|
|
|
|
|
.baseMipLevel = 0, |
|
|
|
|
|
.levelCount = VK_REMAINING_MIP_LEVELS, |
|
|
|
|
|
.baseArrayLayer = 0, |
|
|
|
|
|
.layerCount = VK_REMAINING_ARRAY_LAYERS, |
|
|
|
|
|
}, |
|
|
|
|
|
}; |
|
|
|
|
|
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, |
|
|
|
|
|
vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, 0, image_barrier); |
|
|
|
|
|
}); |
|
|
|
|
|
scheduler.Finish(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
constexpr u32 BL3D_BINDING_INPUT_BUFFER = 0; |
|
|
constexpr u32 BL3D_BINDING_INPUT_BUFFER = 0; |
|
|
constexpr u32 BL3D_BINDING_OUTPUT_BUFFER = 1; |
|
|
constexpr u32 BL3D_BINDING_OUTPUT_BUFFER = 1; |
|
|
|
|
|
|
|
|
|