| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779 |
- // Copyright 2020 yuzu Emulator Project
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #include <algorithm>
- #include "common/settings.h"
- #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h"
- #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h"
- #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h"
- #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h"
- #include "video_core/host_shaders/full_screen_triangle_vert_spv.h"
- #include "video_core/host_shaders/vulkan_blit_color_float_frag_spv.h"
- #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h"
- #include "video_core/renderer_vulkan/blit_image.h"
- #include "video_core/renderer_vulkan/maxwell_to_vk.h"
- #include "video_core/renderer_vulkan/vk_scheduler.h"
- #include "video_core/renderer_vulkan/vk_shader_util.h"
- #include "video_core/renderer_vulkan/vk_state_tracker.h"
- #include "video_core/renderer_vulkan/vk_texture_cache.h"
- #include "video_core/renderer_vulkan/vk_update_descriptor.h"
- #include "video_core/surface.h"
- #include "video_core/vulkan_common/vulkan_device.h"
- #include "video_core/vulkan_common/vulkan_wrapper.h"
- namespace Vulkan {
- using VideoCommon::ImageViewType;
- namespace {
- struct PushConstants {
- std::array<float, 2> tex_scale;
- std::array<float, 2> tex_offset;
- };
- template <u32 binding>
- inline constexpr VkDescriptorSetLayoutBinding TEXTURE_DESCRIPTOR_SET_LAYOUT_BINDING{
- .binding = binding,
- .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
- .descriptorCount = 1,
- .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
- .pImmutableSamplers = nullptr,
- };
- constexpr std::array TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_BINDINGS{
- TEXTURE_DESCRIPTOR_SET_LAYOUT_BINDING<0>,
- TEXTURE_DESCRIPTOR_SET_LAYOUT_BINDING<1>,
- };
- constexpr VkDescriptorSetLayoutCreateInfo ONE_TEXTURE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .bindingCount = 1,
- .pBindings = &TEXTURE_DESCRIPTOR_SET_LAYOUT_BINDING<0>,
- };
- template <u32 num_textures>
- inline constexpr DescriptorBankInfo TEXTURE_DESCRIPTOR_BANK_INFO{
- .uniform_buffers = 0,
- .storage_buffers = 0,
- .texture_buffers = 0,
- .image_buffers = 0,
- .textures = num_textures,
- .images = 0,
- .score = 2,
- };
- constexpr VkDescriptorSetLayoutCreateInfo TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .bindingCount = static_cast<u32>(TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_BINDINGS.size()),
- .pBindings = TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_BINDINGS.data(),
- };
- constexpr VkPushConstantRange PUSH_CONSTANT_RANGE{
- .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
- .offset = 0,
- .size = sizeof(PushConstants),
- };
- constexpr VkPipelineVertexInputStateCreateInfo PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .vertexBindingDescriptionCount = 0,
- .pVertexBindingDescriptions = nullptr,
- .vertexAttributeDescriptionCount = 0,
- .pVertexAttributeDescriptions = nullptr,
- };
- constexpr VkPipelineInputAssemblyStateCreateInfo PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
- .primitiveRestartEnable = VK_FALSE,
- };
- constexpr VkPipelineViewportStateCreateInfo PIPELINE_VIEWPORT_STATE_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .viewportCount = 1,
- .pViewports = nullptr,
- .scissorCount = 1,
- .pScissors = nullptr,
- };
- constexpr VkPipelineRasterizationStateCreateInfo PIPELINE_RASTERIZATION_STATE_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .depthClampEnable = VK_FALSE,
- .rasterizerDiscardEnable = VK_FALSE,
- .polygonMode = VK_POLYGON_MODE_FILL,
- .cullMode = VK_CULL_MODE_BACK_BIT,
- .frontFace = VK_FRONT_FACE_CLOCKWISE,
- .depthBiasEnable = VK_FALSE,
- .depthBiasConstantFactor = 0.0f,
- .depthBiasClamp = 0.0f,
- .depthBiasSlopeFactor = 0.0f,
- .lineWidth = 1.0f,
- };
- constexpr VkPipelineMultisampleStateCreateInfo PIPELINE_MULTISAMPLE_STATE_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
- .sampleShadingEnable = VK_FALSE,
- .minSampleShading = 0.0f,
- .pSampleMask = nullptr,
- .alphaToCoverageEnable = VK_FALSE,
- .alphaToOneEnable = VK_FALSE,
- };
- constexpr std::array DYNAMIC_STATES{
- VK_DYNAMIC_STATE_VIEWPORT,
- VK_DYNAMIC_STATE_SCISSOR,
- };
- constexpr VkPipelineDynamicStateCreateInfo PIPELINE_DYNAMIC_STATE_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .dynamicStateCount = static_cast<u32>(DYNAMIC_STATES.size()),
- .pDynamicStates = DYNAMIC_STATES.data(),
- };
- constexpr VkPipelineColorBlendStateCreateInfo PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .logicOpEnable = VK_FALSE,
- .logicOp = VK_LOGIC_OP_CLEAR,
- .attachmentCount = 0,
- .pAttachments = nullptr,
- .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
- };
- constexpr VkPipelineColorBlendAttachmentState PIPELINE_COLOR_BLEND_ATTACHMENT_STATE{
- .blendEnable = VK_FALSE,
- .srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
- .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
- .colorBlendOp = VK_BLEND_OP_ADD,
- .srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
- .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
- .alphaBlendOp = VK_BLEND_OP_ADD,
- .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
- VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
- };
- constexpr VkPipelineColorBlendStateCreateInfo PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .logicOpEnable = VK_FALSE,
- .logicOp = VK_LOGIC_OP_CLEAR,
- .attachmentCount = 1,
- .pAttachments = &PIPELINE_COLOR_BLEND_ATTACHMENT_STATE,
- .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
- };
- constexpr VkPipelineDepthStencilStateCreateInfo PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .depthTestEnable = VK_TRUE,
- .depthWriteEnable = VK_TRUE,
- .depthCompareOp = VK_COMPARE_OP_ALWAYS,
- .depthBoundsTestEnable = VK_FALSE,
- .stencilTestEnable = VK_FALSE,
- .front = VkStencilOpState{},
- .back = VkStencilOpState{},
- .minDepthBounds = 0.0f,
- .maxDepthBounds = 0.0f,
- };
- template <VkFilter filter>
- inline constexpr VkSamplerCreateInfo SAMPLER_CREATE_INFO{
- .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .magFilter = filter,
- .minFilter = filter,
- .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
- .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
- .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
- .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
- .mipLodBias = 0.0f,
- .anisotropyEnable = VK_FALSE,
- .maxAnisotropy = 0.0f,
- .compareEnable = VK_FALSE,
- .compareOp = VK_COMPARE_OP_NEVER,
- .minLod = 0.0f,
- .maxLod = 0.0f,
- .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
- .unnormalizedCoordinates = VK_TRUE,
- };
- constexpr VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo(
- const VkDescriptorSetLayout* set_layout) {
- return VkPipelineLayoutCreateInfo{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .setLayoutCount = 1,
- .pSetLayouts = set_layout,
- .pushConstantRangeCount = 1,
- .pPushConstantRanges = &PUSH_CONSTANT_RANGE,
- };
- }
- constexpr VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(VkShaderStageFlagBits stage,
- VkShaderModule shader) {
- return VkPipelineShaderStageCreateInfo{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .stage = stage,
- .module = shader,
- .pName = "main",
- .pSpecializationInfo = nullptr,
- };
- }
- constexpr std::array<VkPipelineShaderStageCreateInfo, 2> MakeStages(
- VkShaderModule vertex_shader, VkShaderModule fragment_shader) {
- return std::array{
- PipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, vertex_shader),
- PipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, fragment_shader),
- };
- }
- void UpdateOneTextureDescriptorSet(const Device& device, VkDescriptorSet descriptor_set,
- VkSampler sampler, VkImageView image_view) {
- const VkDescriptorImageInfo image_info{
- .sampler = sampler,
- .imageView = image_view,
- .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
- };
- const VkWriteDescriptorSet write_descriptor_set{
- .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- .pNext = nullptr,
- .dstSet = descriptor_set,
- .dstBinding = 0,
- .dstArrayElement = 0,
- .descriptorCount = 1,
- .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
- .pImageInfo = &image_info,
- .pBufferInfo = nullptr,
- .pTexelBufferView = nullptr,
- };
- device.GetLogical().UpdateDescriptorSets(write_descriptor_set, nullptr);
- }
- void UpdateTwoTexturesDescriptorSet(const Device& device, VkDescriptorSet descriptor_set,
- VkSampler sampler, VkImageView image_view_0,
- VkImageView image_view_1) {
- const VkDescriptorImageInfo image_info_0{
- .sampler = sampler,
- .imageView = image_view_0,
- .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
- };
- const VkDescriptorImageInfo image_info_1{
- .sampler = sampler,
- .imageView = image_view_1,
- .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
- };
- const std::array write_descriptor_sets{
- VkWriteDescriptorSet{
- .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- .pNext = nullptr,
- .dstSet = descriptor_set,
- .dstBinding = 0,
- .dstArrayElement = 0,
- .descriptorCount = 1,
- .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
- .pImageInfo = &image_info_0,
- .pBufferInfo = nullptr,
- .pTexelBufferView = nullptr,
- },
- VkWriteDescriptorSet{
- .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- .pNext = nullptr,
- .dstSet = descriptor_set,
- .dstBinding = 1,
- .dstArrayElement = 0,
- .descriptorCount = 1,
- .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
- .pImageInfo = &image_info_1,
- .pBufferInfo = nullptr,
- .pTexelBufferView = nullptr,
- },
- };
- device.GetLogical().UpdateDescriptorSets(write_descriptor_sets, nullptr);
- }
- void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Region2D& dst_region,
- const Region2D& src_region) {
- const VkOffset2D offset{
- .x = std::min(dst_region.start.x, dst_region.end.x),
- .y = std::min(dst_region.start.y, dst_region.end.y),
- };
- const VkExtent2D extent{
- .width = static_cast<u32>(std::abs(dst_region.end.x - dst_region.start.x)),
- .height = static_cast<u32>(std::abs(dst_region.end.y - dst_region.start.y)),
- };
- const VkViewport viewport{
- .x = static_cast<float>(offset.x),
- .y = static_cast<float>(offset.y),
- .width = static_cast<float>(extent.width),
- .height = static_cast<float>(extent.height),
- .minDepth = 0.0f,
- .maxDepth = 1.0f,
- };
- // TODO: Support scissored blits
- const VkRect2D scissor{
- .offset = offset,
- .extent = extent,
- };
- const float scale_x = static_cast<float>(src_region.end.x - src_region.start.x);
- const float scale_y = static_cast<float>(src_region.end.y - src_region.start.y);
- const PushConstants push_constants{
- .tex_scale = {scale_x, scale_y},
- .tex_offset = {static_cast<float>(src_region.start.x),
- static_cast<float>(src_region.start.y)},
- };
- cmdbuf.SetViewport(0, viewport);
- cmdbuf.SetScissor(0, scissor);
- cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants);
- }
- VkExtent2D GetConversionExtent(const ImageView& src_image_view) {
- const auto& resolution = Settings::values.resolution_info;
- const bool is_rescaled = src_image_view.IsRescaled();
- u32 width = src_image_view.size.width;
- u32 height = src_image_view.size.height;
- return VkExtent2D{
- .width = is_rescaled ? resolution.ScaleUp(width) : width,
- .height = is_rescaled ? resolution.ScaleUp(height) : height,
- };
- }
- } // Anonymous namespace
- BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_,
- StateTracker& state_tracker_, DescriptorPool& descriptor_pool)
- : device{device_}, scheduler{scheduler_}, state_tracker{state_tracker_},
- one_texture_set_layout(device.GetLogical().CreateDescriptorSetLayout(
- ONE_TEXTURE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)),
- two_textures_set_layout(device.GetLogical().CreateDescriptorSetLayout(
- TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)),
- one_texture_descriptor_allocator{
- descriptor_pool.Allocator(*one_texture_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<1>)},
- two_textures_descriptor_allocator{
- descriptor_pool.Allocator(*two_textures_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<2>)},
- one_texture_pipeline_layout(device.GetLogical().CreatePipelineLayout(
- PipelineLayoutCreateInfo(one_texture_set_layout.address()))),
- two_textures_pipeline_layout(device.GetLogical().CreatePipelineLayout(
- PipelineLayoutCreateInfo(two_textures_set_layout.address()))),
- full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)),
- blit_color_to_color_frag(BuildShader(device, VULKAN_BLIT_COLOR_FLOAT_FRAG_SPV)),
- convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)),
- convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)),
- convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)),
- convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)),
- linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)),
- nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) {
- if (device.IsExtShaderStencilExportSupported()) {
- blit_depth_stencil_frag = BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV);
- }
- }
- BlitImageHelper::~BlitImageHelper() = default;
- void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_view,
- const Region2D& dst_region, const Region2D& src_region,
- Tegra::Engines::Fermi2D::Filter filter,
- Tegra::Engines::Fermi2D::Operation operation) {
- const bool is_linear = filter == Tegra::Engines::Fermi2D::Filter::Bilinear;
- const BlitImagePipelineKey key{
- .renderpass = dst_framebuffer->RenderPass(),
- .operation = operation,
- };
- const VkPipelineLayout layout = *one_texture_pipeline_layout;
- const VkSampler sampler = is_linear ? *linear_sampler : *nearest_sampler;
- const VkPipeline pipeline = FindOrEmplaceColorPipeline(key);
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([this, dst_region, src_region, pipeline, layout, sampler,
- src_view](vk::CommandBuffer cmdbuf) {
- // TODO: Barriers
- const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
- UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- BindBlitState(cmdbuf, layout, dst_region, src_region);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
- }
- void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer,
- VkImageView src_depth_view, VkImageView src_stencil_view,
- const Region2D& dst_region, const Region2D& src_region,
- Tegra::Engines::Fermi2D::Filter filter,
- Tegra::Engines::Fermi2D::Operation operation) {
- ASSERT(filter == Tegra::Engines::Fermi2D::Filter::Point);
- ASSERT(operation == Tegra::Engines::Fermi2D::Operation::SrcCopy);
- const BlitImagePipelineKey key{
- .renderpass = dst_framebuffer->RenderPass(),
- .operation = operation,
- };
- const VkPipelineLayout layout = *two_textures_pipeline_layout;
- const VkSampler sampler = *nearest_sampler;
- const VkPipeline pipeline = FindOrEmplaceDepthStencilPipeline(key);
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([dst_region, src_region, pipeline, layout, sampler, src_depth_view,
- src_stencil_view, this](vk::CommandBuffer cmdbuf) {
- // TODO: Barriers
- const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
- UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
- src_stencil_view);
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- BindBlitState(cmdbuf, layout, dst_region, src_region);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
- }
- void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view) {
- ConvertDepthToColorPipeline(convert_d32_to_r32_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_d32_to_r32_pipeline, dst_framebuffer, src_image_view);
- }
- void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view) {
- ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view);
- }
- void BlitImageHelper::ConvertD16ToR16(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view) {
- ConvertDepthToColorPipeline(convert_d16_to_r16_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_d16_to_r16_pipeline, dst_framebuffer, src_image_view);
- }
- void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view) {
- ConvertColorToDepthPipeline(convert_r16_to_d16_pipeline, dst_framebuffer->RenderPass());
- Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view);
- }
- void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view) {
- ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
- convert_abgr8_to_d24s8_frag);
- Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view);
- }
- void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
- ImageView& src_image_view) {
- ConvertPipelineColorTargetEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(),
- convert_d24s8_to_abgr8_frag);
- ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view);
- }
- void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
- const ImageView& src_image_view) {
- const VkPipelineLayout layout = *one_texture_pipeline_layout;
- const VkImageView src_view = src_image_view.Handle(Shader::TextureType::Color2D);
- const VkSampler sampler = *nearest_sampler;
- const VkExtent2D extent = GetConversionExtent(src_image_view);
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([pipeline, layout, sampler, src_view, extent, this](vk::CommandBuffer cmdbuf) {
- const VkOffset2D offset{
- .x = 0,
- .y = 0,
- };
- const VkViewport viewport{
- .x = 0.0f,
- .y = 0.0f,
- .width = static_cast<float>(extent.width),
- .height = static_cast<float>(extent.height),
- .minDepth = 0.0f,
- .maxDepth = 0.0f,
- };
- const VkRect2D scissor{
- .offset = offset,
- .extent = extent,
- };
- const PushConstants push_constants{
- .tex_scale = {viewport.width, viewport.height},
- .tex_offset = {0.0f, 0.0f},
- };
- const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
- UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
- // TODO: Barriers
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- cmdbuf.SetViewport(0, viewport);
- cmdbuf.SetScissor(0, scissor);
- cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
- }
- void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
- ImageView& src_image_view, u32 up_scale, u32 down_shift) {
- const VkPipelineLayout layout = *one_texture_pipeline_layout;
- const VkImageView src_view = src_image_view.ColorView();
- const VkSampler sampler = *nearest_sampler;
- const VkExtent2D extent{
- .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U),
- .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U),
- };
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift,
- this](vk::CommandBuffer cmdbuf) {
- const VkOffset2D offset{
- .x = 0,
- .y = 0,
- };
- const VkViewport viewport{
- .x = 0.0f,
- .y = 0.0f,
- .width = static_cast<float>(extent.width),
- .height = static_cast<float>(extent.height),
- .minDepth = 0.0f,
- .maxDepth = 0.0f,
- };
- const VkRect2D scissor{
- .offset = offset,
- .extent = extent,
- };
- const PushConstants push_constants{
- .tex_scale = {viewport.width, viewport.height},
- .tex_offset = {0.0f, 0.0f},
- };
- const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
- UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
- // TODO: Barriers
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- cmdbuf.SetViewport(0, viewport);
- cmdbuf.SetScissor(0, scissor);
- cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
- }
- void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
- ImageView& src_image_view) {
- const VkPipelineLayout layout = *two_textures_pipeline_layout;
- const VkImageView src_depth_view = src_image_view.DepthView();
- const VkImageView src_stencil_view = src_image_view.StencilView();
- const VkSampler sampler = *nearest_sampler;
- const VkExtent2D extent = GetConversionExtent(src_image_view);
- scheduler.RequestRenderpass(dst_framebuffer);
- scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent,
- this](vk::CommandBuffer cmdbuf) {
- const VkOffset2D offset{
- .x = 0,
- .y = 0,
- };
- const VkViewport viewport{
- .x = 0.0f,
- .y = 0.0f,
- .width = static_cast<float>(extent.width),
- .height = static_cast<float>(extent.height),
- .minDepth = 0.0f,
- .maxDepth = 0.0f,
- };
- const VkRect2D scissor{
- .offset = offset,
- .extent = extent,
- };
- const PushConstants push_constants{
- .tex_scale = {viewport.width, viewport.height},
- .tex_offset = {0.0f, 0.0f},
- };
- const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit();
- UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view,
- src_stencil_view);
- // TODO: Barriers
- cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
- cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
- nullptr);
- cmdbuf.SetViewport(0, viewport);
- cmdbuf.SetScissor(0, scissor);
- cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants);
- cmdbuf.Draw(3, 1, 0, 0);
- });
- scheduler.InvalidateState();
- }
- VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key) {
- const auto it = std::ranges::find(blit_color_keys, key);
- if (it != blit_color_keys.end()) {
- return *blit_color_pipelines[std::distance(blit_color_keys.begin(), it)];
- }
- blit_color_keys.push_back(key);
- const std::array stages = MakeStages(*full_screen_vert, *blit_color_to_color_frag);
- const VkPipelineColorBlendAttachmentState blend_attachment{
- .blendEnable = VK_FALSE,
- .srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
- .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
- .colorBlendOp = VK_BLEND_OP_ADD,
- .srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
- .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
- .alphaBlendOp = VK_BLEND_OP_ADD,
- .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
- VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
- };
- // TODO: programmable blending
- const VkPipelineColorBlendStateCreateInfo color_blend_create_info{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .logicOpEnable = VK_FALSE,
- .logicOp = VK_LOGIC_OP_CLEAR,
- .attachmentCount = 1,
- .pAttachments = &blend_attachment,
- .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
- };
- blit_color_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .stageCount = static_cast<u32>(stages.size()),
- .pStages = stages.data(),
- .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pTessellationState = nullptr,
- .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pDepthStencilState = nullptr,
- .pColorBlendState = &color_blend_create_info,
- .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .layout = *one_texture_pipeline_layout,
- .renderPass = key.renderpass,
- .subpass = 0,
- .basePipelineHandle = VK_NULL_HANDLE,
- .basePipelineIndex = 0,
- }));
- return *blit_color_pipelines.back();
- }
- VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key) {
- const auto it = std::ranges::find(blit_depth_stencil_keys, key);
- if (it != blit_depth_stencil_keys.end()) {
- return *blit_depth_stencil_pipelines[std::distance(blit_depth_stencil_keys.begin(), it)];
- }
- blit_depth_stencil_keys.push_back(key);
- const std::array stages = MakeStages(*full_screen_vert, *blit_depth_stencil_frag);
- blit_depth_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .stageCount = static_cast<u32>(stages.size()),
- .pStages = stages.data(),
- .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pTessellationState = nullptr,
- .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
- .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
- .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .layout = *two_textures_pipeline_layout,
- .renderPass = key.renderpass,
- .subpass = 0,
- .basePipelineHandle = VK_NULL_HANDLE,
- .basePipelineIndex = 0,
- }));
- return *blit_depth_stencil_pipelines.back();
- }
- void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass,
- bool is_target_depth) {
- if (pipeline) {
- return;
- }
- VkShaderModule frag_shader =
- is_target_depth ? *convert_float_to_depth_frag : *convert_depth_to_float_frag;
- const std::array stages = MakeStages(*full_screen_vert, frag_shader);
- pipeline = device.GetLogical().CreateGraphicsPipeline({
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .stageCount = static_cast<u32>(stages.size()),
- .pStages = stages.data(),
- .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pTessellationState = nullptr,
- .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr,
- .pColorBlendState = is_target_depth ? &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO
- : &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
- .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .layout = *one_texture_pipeline_layout,
- .renderPass = renderpass,
- .subpass = 0,
- .basePipelineHandle = VK_NULL_HANDLE,
- .basePipelineIndex = 0,
- });
- }
- void BlitImageHelper::ConvertDepthToColorPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
- ConvertPipeline(pipeline, renderpass, false);
- }
- void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass) {
- ConvertPipeline(pipeline, renderpass, true);
- }
- void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module, bool single_texture,
- bool is_target_depth) {
- if (pipeline) {
- return;
- }
- const std::array stages = MakeStages(*full_screen_vert, *module);
- pipeline = device.GetLogical().CreateGraphicsPipeline({
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0,
- .stageCount = static_cast<u32>(stages.size()),
- .pStages = stages.data(),
- .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pTessellationState = nullptr,
- .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pDepthStencilState = is_target_depth ? &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr,
- .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
- .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .layout = single_texture ? *one_texture_pipeline_layout : *two_textures_pipeline_layout,
- .renderPass = renderpass,
- .subpass = 0,
- .basePipelineHandle = VK_NULL_HANDLE,
- .basePipelineIndex = 0,
- });
- }
- void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module) {
- ConvertPipelineEx(pipeline, renderpass, module, false, false);
- }
- void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRenderPass renderpass,
- vk::ShaderModule& module) {
- ConvertPipelineEx(pipeline, renderpass, module, true, true);
- }
- } // namespace Vulkan
|