|
|
@ -3,6 +3,7 @@ |
|
|
|
|
|
|
|
|
#include <array>
|
|
|
#include <array>
|
|
|
#include <memory>
|
|
|
#include <memory>
|
|
|
|
|
|
#include <numeric>
|
|
|
#include <optional>
|
|
|
#include <optional>
|
|
|
#include <utility>
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
@ -11,7 +12,10 @@ |
|
|
#include "common/assert.h"
|
|
|
#include "common/assert.h"
|
|
|
#include "common/common_types.h"
|
|
|
#include "common/common_types.h"
|
|
|
#include "common/div_ceil.h"
|
|
|
#include "common/div_ceil.h"
|
|
|
|
|
|
#include "common/vector_math.h"
|
|
|
#include "video_core/host_shaders/astc_decoder_comp_spv.h"
|
|
|
#include "video_core/host_shaders/astc_decoder_comp_spv.h"
|
|
|
|
|
|
#include "video_core/host_shaders/convert_msaa_to_non_msaa_comp_spv.h"
|
|
|
|
|
|
#include "video_core/host_shaders/convert_non_msaa_to_msaa_comp_spv.h"
|
|
|
#include "video_core/host_shaders/queries_prefix_scan_sum_comp_spv.h"
|
|
|
#include "video_core/host_shaders/queries_prefix_scan_sum_comp_spv.h"
|
|
|
#include "video_core/host_shaders/queries_prefix_scan_sum_nosubgroups_comp_spv.h"
|
|
|
#include "video_core/host_shaders/queries_prefix_scan_sum_nosubgroups_comp_spv.h"
|
|
|
#include "video_core/host_shaders/resolve_conditional_render_comp_spv.h"
|
|
|
#include "video_core/host_shaders/resolve_conditional_render_comp_spv.h"
|
|
|
@ -131,6 +135,33 @@ constexpr DescriptorBankInfo ASTC_BANK_INFO{ |
|
|
.score = 2, |
|
|
.score = 2, |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
constexpr std::array<VkDescriptorSetLayoutBinding, ASTC_NUM_BINDINGS> MSAA_DESCRIPTOR_SET_BINDINGS{{ |
|
|
|
|
|
{ |
|
|
|
|
|
.binding = 0, |
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, |
|
|
|
|
|
.descriptorCount = 1, |
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, |
|
|
|
|
|
.pImmutableSamplers = nullptr, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
.binding = 1, |
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, |
|
|
|
|
|
.descriptorCount = 1, |
|
|
|
|
|
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, |
|
|
|
|
|
.pImmutableSamplers = nullptr, |
|
|
|
|
|
}, |
|
|
|
|
|
}}; |
|
|
|
|
|
|
|
|
|
|
|
constexpr DescriptorBankInfo MSAA_BANK_INFO{ |
|
|
|
|
|
.uniform_buffers = 0, |
|
|
|
|
|
.storage_buffers = 0, |
|
|
|
|
|
.texture_buffers = 0, |
|
|
|
|
|
.image_buffers = 0, |
|
|
|
|
|
.textures = 0, |
|
|
|
|
|
.images = 2, |
|
|
|
|
|
.score = 2, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
constexpr VkDescriptorUpdateTemplateEntry INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE{ |
|
|
constexpr VkDescriptorUpdateTemplateEntry INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE{ |
|
|
.dstBinding = 0, |
|
|
.dstBinding = 0, |
|
|
.dstArrayElement = 0, |
|
|
.dstArrayElement = 0, |
|
|
@ -149,6 +180,15 @@ constexpr VkDescriptorUpdateTemplateEntry QUERIES_SCAN_DESCRIPTOR_UPDATE_TEMPLAT |
|
|
.stride = sizeof(DescriptorUpdateEntry), |
|
|
.stride = sizeof(DescriptorUpdateEntry), |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
constexpr VkDescriptorUpdateTemplateEntry MSAA_DESCRIPTOR_UPDATE_TEMPLATE{ |
|
|
|
|
|
.dstBinding = 0, |
|
|
|
|
|
.dstArrayElement = 0, |
|
|
|
|
|
.descriptorCount = 2, |
|
|
|
|
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, |
|
|
|
|
|
.offset = 0, |
|
|
|
|
|
.stride = sizeof(DescriptorUpdateEntry), |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
constexpr std::array<VkDescriptorUpdateTemplateEntry, ASTC_NUM_BINDINGS> |
|
|
constexpr std::array<VkDescriptorUpdateTemplateEntry, ASTC_NUM_BINDINGS> |
|
|
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{ |
|
|
ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{ |
|
|
{ |
|
|
{ |
|
|
@ -224,6 +264,9 @@ ComputePass::ComputePass(const Device& device_, DescriptorPool& descriptor_pool, |
|
|
}); |
|
|
}); |
|
|
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, bank_info); |
|
|
descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, bank_info); |
|
|
} |
|
|
} |
|
|
|
|
|
if (code.empty()) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
module = device.GetLogical().CreateShaderModule({ |
|
|
module = device.GetLogical().CreateShaderModule({ |
|
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, |
|
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, |
|
|
.pNext = nullptr, |
|
|
.pNext = nullptr, |
|
|
@ -590,4 +633,100 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, |
|
|
scheduler.Finish(); |
|
|
scheduler.Finish(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MSAACopyPass::MSAACopyPass(const Device& device_, Scheduler& scheduler_, |
|
|
|
|
|
DescriptorPool& descriptor_pool_, |
|
|
|
|
|
StagingBufferPool& staging_buffer_pool_, |
|
|
|
|
|
ComputePassDescriptorQueue& compute_pass_descriptor_queue_) |
|
|
|
|
|
: ComputePass(device_, descriptor_pool_, MSAA_DESCRIPTOR_SET_BINDINGS, |
|
|
|
|
|
MSAA_DESCRIPTOR_UPDATE_TEMPLATE, MSAA_BANK_INFO, {}, |
|
|
|
|
|
CONVERT_NON_MSAA_TO_MSAA_COMP_SPV), |
|
|
|
|
|
scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, |
|
|
|
|
|
compute_pass_descriptor_queue{compute_pass_descriptor_queue_} { |
|
|
|
|
|
const auto make_msaa_pipeline = [this](size_t i, std::span<const u32> code) { |
|
|
|
|
|
modules[i] = device.GetLogical().CreateShaderModule({ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.flags = 0, |
|
|
|
|
|
.codeSize = static_cast<u32>(code.size_bytes()), |
|
|
|
|
|
.pCode = code.data(), |
|
|
|
|
|
}); |
|
|
|
|
|
pipelines[i] = device.GetLogical().CreateComputePipeline({ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.flags = 0, |
|
|
|
|
|
.stage{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.flags = 0, |
|
|
|
|
|
.stage = VK_SHADER_STAGE_COMPUTE_BIT, |
|
|
|
|
|
.module = *modules[i], |
|
|
|
|
|
.pName = "main", |
|
|
|
|
|
.pSpecializationInfo = nullptr, |
|
|
|
|
|
}, |
|
|
|
|
|
.layout = *layout, |
|
|
|
|
|
.basePipelineHandle = nullptr, |
|
|
|
|
|
.basePipelineIndex = 0, |
|
|
|
|
|
}); |
|
|
|
|
|
}; |
|
|
|
|
|
make_msaa_pipeline(0, CONVERT_NON_MSAA_TO_MSAA_COMP_SPV); |
|
|
|
|
|
make_msaa_pipeline(1, CONVERT_MSAA_TO_NON_MSAA_COMP_SPV); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MSAACopyPass::~MSAACopyPass() = default; |
|
|
|
|
|
|
|
|
|
|
|
void MSAACopyPass::CopyImage(Image& dst_image, Image& src_image, |
|
|
|
|
|
std::span<const VideoCommon::ImageCopy> copies, |
|
|
|
|
|
bool msaa_to_non_msaa) { |
|
|
|
|
|
const VkPipeline msaa_pipeline = *pipelines[msaa_to_non_msaa ? 1 : 0]; |
|
|
|
|
|
scheduler.RequestOutsideRenderPassOperationContext(); |
|
|
|
|
|
for (const VideoCommon::ImageCopy& copy : copies) { |
|
|
|
|
|
ASSERT(copy.src_subresource.base_layer == 0); |
|
|
|
|
|
ASSERT(copy.src_subresource.num_layers == 1); |
|
|
|
|
|
ASSERT(copy.dst_subresource.base_layer == 0); |
|
|
|
|
|
ASSERT(copy.dst_subresource.num_layers == 1); |
|
|
|
|
|
|
|
|
|
|
|
compute_pass_descriptor_queue.Acquire(); |
|
|
|
|
|
compute_pass_descriptor_queue.AddImage( |
|
|
|
|
|
src_image.StorageImageView(copy.src_subresource.base_level)); |
|
|
|
|
|
compute_pass_descriptor_queue.AddImage( |
|
|
|
|
|
dst_image.StorageImageView(copy.dst_subresource.base_level)); |
|
|
|
|
|
const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; |
|
|
|
|
|
|
|
|
|
|
|
const Common::Vec3<u32> num_dispatches = { |
|
|
|
|
|
Common::DivCeil(copy.extent.width, 8U), |
|
|
|
|
|
Common::DivCeil(copy.extent.height, 8U), |
|
|
|
|
|
copy.extent.depth, |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
scheduler.Record([this, dst = dst_image.Handle(), msaa_pipeline, num_dispatches, |
|
|
|
|
|
descriptor_data](vk::CommandBuffer cmdbuf) { |
|
|
|
|
|
const VkDescriptorSet set = descriptor_allocator.Commit(); |
|
|
|
|
|
device.GetLogical().UpdateDescriptorSet(set, *descriptor_template, descriptor_data); |
|
|
|
|
|
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, msaa_pipeline); |
|
|
|
|
|
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_COMPUTE, *layout, 0, set, {}); |
|
|
|
|
|
cmdbuf.Dispatch(num_dispatches.x, num_dispatches.y, num_dispatches.z); |
|
|
|
|
|
const VkImageMemoryBarrier write_barrier{ |
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
|
|
|
|
|
.pNext = nullptr, |
|
|
|
|
|
.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, |
|
|
|
|
|
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT, |
|
|
|
|
|
.oldLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.newLayout = VK_IMAGE_LAYOUT_GENERAL, |
|
|
|
|
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, |
|
|
|
|
|
.image = dst, |
|
|
|
|
|
.subresourceRange{ |
|
|
|
|
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, |
|
|
|
|
|
.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_FRAGMENT_SHADER_BIT, 0, write_barrier); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} // namespace Vulkan
|
|
|
} // namespace Vulkan
|