summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/host_shaders/fxaa.vert2
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp390
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.h17
3 files changed, 387 insertions, 22 deletions
diff --git a/src/video_core/host_shaders/fxaa.vert b/src/video_core/host_shaders/fxaa.vert
index 715fce462..01d5ff4df 100644
--- a/src/video_core/host_shaders/fxaa.vert
+++ b/src/video_core/host_shaders/fxaa.vert
@@ -15,7 +15,7 @@ layout (location = 0) out vec4 posPos;
15 15
16#ifdef VULKAN 16#ifdef VULKAN
17 17
18#define BINDING_COLOR_TEXTURE 1 18#define BINDING_COLOR_TEXTURE 0
19 19
20#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv 20#else // ^^^ Vulkan ^^^ // vvv OpenGL vvv
21 21
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 0d6bce214..c0abcc17a 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -17,6 +17,8 @@
17#include "core/frontend/emu_window.h" 17#include "core/frontend/emu_window.h"
18#include "core/memory.h" 18#include "core/memory.h"
19#include "video_core/gpu.h" 19#include "video_core/gpu.h"
20#include "video_core/host_shaders/fxaa_frag_spv.h"
21#include "video_core/host_shaders/fxaa_vert_spv.h"
20#include "video_core/host_shaders/present_bicubic_frag_spv.h" 22#include "video_core/host_shaders/present_bicubic_frag_spv.h"
21#include "video_core/host_shaders/present_gaussian_frag_spv.h" 23#include "video_core/host_shaders/present_gaussian_frag_spv.h"
22#include "video_core/host_shaders/present_scaleforce_frag_spv.h" 24#include "video_core/host_shaders/present_scaleforce_frag_spv.h"
@@ -149,15 +151,9 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
149 scheduler.Wait(resource_ticks[image_index]); 151 scheduler.Wait(resource_ticks[image_index]);
150 resource_ticks[image_index] = scheduler.CurrentTick(); 152 resource_ticks[image_index] = scheduler.CurrentTick();
151 153
152 const VkImageView source_image_view = 154 VkImageView source_image_view =
153 use_accelerated ? screen_info.image_view : *raw_image_views[image_index]; 155 use_accelerated ? screen_info.image_view : *raw_image_views[image_index];
154 156
155 if (!fsr) {
156 const bool is_nn =
157 Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::NearestNeighbor;
158 UpdateDescriptorSet(image_index, source_image_view, is_nn);
159 }
160
161 BufferData data; 157 BufferData data;
162 SetUniformData(data, layout); 158 SetUniformData(data, layout);
163 SetVertexData(data, framebuffer, layout); 159 SetVertexData(data, framebuffer, layout);
@@ -239,6 +235,68 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
239 }); 235 });
240 } 236 }
241 237
238 const auto anti_alias_pass = Settings::values.anti_aliasing.GetValue();
239 if (use_accelerated && anti_alias_pass != Settings::AntiAliasing::None) {
240 UpdateAADescriptorSet(image_index, source_image_view, false);
241 const u32 up_scale = Settings::values.resolution_info.up_scale;
242 const u32 down_shift = Settings::values.resolution_info.down_shift;
243 VkExtent2D size{
244 .width = (up_scale * framebuffer.width) >> down_shift,
245 .height = (up_scale * framebuffer.height) >> down_shift,
246 };
247 source_image_view = *aa_image_view;
248 scheduler.Record([this, image_index, size, anti_alias_pass](vk::CommandBuffer cmdbuf) {
249 const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f;
250 const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f;
251 const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f;
252 const VkClearValue clear_color{
253 .color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}},
254 };
255 const VkRenderPassBeginInfo renderpass_bi{
256 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
257 .pNext = nullptr,
258 .renderPass = *aa_renderpass,
259 .framebuffer = *aa_framebuffer,
260 .renderArea =
261 {
262 .offset = {0, 0},
263 .extent = size,
264 },
265 .clearValueCount = 1,
266 .pClearValues = &clear_color,
267 };
268 const VkViewport viewport{
269 .x = 0.0f,
270 .y = 0.0f,
271 .width = static_cast<float>(size.width),
272 .height = static_cast<float>(size.height),
273 .minDepth = 0.0f,
274 .maxDepth = 1.0f,
275 };
276 const VkRect2D scissor{
277 .offset = {0, 0},
278 .extent = size,
279 };
280 cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE);
281 switch (anti_alias_pass) {
282 case Settings::AntiAliasing::Fxaa:
283 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *aa_pipeline);
284 break;
285 default:
286 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *aa_pipeline);
287 break;
288 }
289 cmdbuf.SetViewport(0, viewport);
290 cmdbuf.SetScissor(0, scissor);
291
292 cmdbuf.BindVertexBuffer(0, *buffer, offsetof(BufferData, vertices));
293 cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *aa_pipeline_layout, 0,
294 aa_descriptor_sets[image_index], {});
295 cmdbuf.Draw(4, 1, 0, 0);
296 cmdbuf.EndRenderPass();
297 });
298 }
299
242 if (fsr) { 300 if (fsr) {
243 auto crop_rect = framebuffer.crop_rect; 301 auto crop_rect = framebuffer.crop_rect;
244 if (crop_rect.GetWidth() == 0) { 302 if (crop_rect.GetWidth() == 0) {
@@ -251,6 +309,10 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
251 VkImageView fsr_image_view = 309 VkImageView fsr_image_view =
252 fsr->Draw(scheduler, image_index, source_image_view, crop_rect); 310 fsr->Draw(scheduler, image_index, source_image_view, crop_rect);
253 UpdateDescriptorSet(image_index, fsr_image_view, true); 311 UpdateDescriptorSet(image_index, fsr_image_view, true);
312 } else {
313 const bool is_nn =
314 Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::NearestNeighbor;
315 UpdateDescriptorSet(image_index, source_image_view, is_nn);
254 } 316 }
255 317
256 scheduler.Record( 318 scheduler.Record(
@@ -329,11 +391,16 @@ VkSemaphore VKBlitScreen::DrawToSwapchain(const Tegra::FramebufferConfig& frameb
329} 391}
330 392
331vk::Framebuffer VKBlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent) { 393vk::Framebuffer VKBlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent) {
394 return CreateFramebuffer(image_view, extent, renderpass);
395}
396
397vk::Framebuffer VKBlitScreen::CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent,
398 vk::RenderPass& rd) {
332 return device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{ 399 return device.GetLogical().CreateFramebuffer(VkFramebufferCreateInfo{
333 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 400 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
334 .pNext = nullptr, 401 .pNext = nullptr,
335 .flags = 0, 402 .flags = 0,
336 .renderPass = *renderpass, 403 .renderPass = *rd,
337 .attachmentCount = 1, 404 .attachmentCount = 1,
338 .pAttachments = &image_view, 405 .pAttachments = &image_view,
339 .width = extent.width, 406 .width = extent.width,
@@ -390,6 +457,8 @@ void VKBlitScreen::RefreshResources(const Tegra::FramebufferConfig& framebuffer)
390 457
391void VKBlitScreen::CreateShaders() { 458void VKBlitScreen::CreateShaders() {
392 vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV); 459 vertex_shader = BuildShader(device, VULKAN_PRESENT_VERT_SPV);
460 fxaa_vertex_shader = BuildShader(device, FXAA_VERT_SPV);
461 fxaa_fragment_shader = BuildShader(device, FXAA_FRAG_SPV);
393 bilinear_fragment_shader = BuildShader(device, VULKAN_PRESENT_FRAG_SPV); 462 bilinear_fragment_shader = BuildShader(device, VULKAN_PRESENT_FRAG_SPV);
394 bicubic_fragment_shader = BuildShader(device, PRESENT_BICUBIC_FRAG_SPV); 463 bicubic_fragment_shader = BuildShader(device, PRESENT_BICUBIC_FRAG_SPV);
395 gaussian_fragment_shader = BuildShader(device, PRESENT_GAUSSIAN_FRAG_SPV); 464 gaussian_fragment_shader = BuildShader(device, PRESENT_GAUSSIAN_FRAG_SPV);
@@ -413,6 +482,13 @@ void VKBlitScreen::CreateDescriptorPool() {
413 }, 482 },
414 }}; 483 }};
415 484
485 const std::array<VkDescriptorPoolSize, 1> pool_sizes_aa{{
486 {
487 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
488 .descriptorCount = static_cast<u32>(2 * image_count),
489 },
490 }};
491
416 const VkDescriptorPoolCreateInfo ci{ 492 const VkDescriptorPoolCreateInfo ci{
417 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 493 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
418 .pNext = nullptr, 494 .pNext = nullptr,
@@ -422,19 +498,33 @@ void VKBlitScreen::CreateDescriptorPool() {
422 .pPoolSizes = pool_sizes.data(), 498 .pPoolSizes = pool_sizes.data(),
423 }; 499 };
424 descriptor_pool = device.GetLogical().CreateDescriptorPool(ci); 500 descriptor_pool = device.GetLogical().CreateDescriptorPool(ci);
501
502 const VkDescriptorPoolCreateInfo ci_aa{
503 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
504 .pNext = nullptr,
505 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
506 .maxSets = static_cast<u32>(image_count),
507 .poolSizeCount = static_cast<u32>(pool_sizes_aa.size()),
508 .pPoolSizes = pool_sizes_aa.data(),
509 };
510 aa_descriptor_pool = device.GetLogical().CreateDescriptorPool(ci_aa);
425} 511}
426 512
427void VKBlitScreen::CreateRenderPass() { 513void VKBlitScreen::CreateRenderPass() {
514 renderpass = CreateRenderPassImpl(swapchain.GetImageViewFormat());
515}
516
517vk::RenderPass VKBlitScreen::CreateRenderPassImpl(VkFormat format, bool is_present) {
428 const VkAttachmentDescription color_attachment{ 518 const VkAttachmentDescription color_attachment{
429 .flags = 0, 519 .flags = 0,
430 .format = swapchain.GetImageViewFormat(), 520 .format = format,
431 .samples = VK_SAMPLE_COUNT_1_BIT, 521 .samples = VK_SAMPLE_COUNT_1_BIT,
432 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, 522 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
433 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 523 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
434 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, 524 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
435 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, 525 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
436 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, 526 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
437 .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 527 .finalLayout = is_present ? VK_IMAGE_LAYOUT_PRESENT_SRC_KHR : VK_IMAGE_LAYOUT_GENERAL,
438 }; 528 };
439 529
440 const VkAttachmentReference color_attachment_ref{ 530 const VkAttachmentReference color_attachment_ref{
@@ -477,7 +567,7 @@ void VKBlitScreen::CreateRenderPass() {
477 .pDependencies = &dependency, 567 .pDependencies = &dependency,
478 }; 568 };
479 569
480 renderpass = device.GetLogical().CreateRenderPass(renderpass_ci); 570 return device.GetLogical().CreateRenderPass(renderpass_ci);
481} 571}
482 572
483void VKBlitScreen::CreateDescriptorSetLayout() { 573void VKBlitScreen::CreateDescriptorSetLayout() {
@@ -498,6 +588,23 @@ void VKBlitScreen::CreateDescriptorSetLayout() {
498 }, 588 },
499 }}; 589 }};
500 590
591 const std::array<VkDescriptorSetLayoutBinding, 2> layout_bindings_aa{{
592 {
593 .binding = 0,
594 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
595 .descriptorCount = 1,
596 .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
597 .pImmutableSamplers = nullptr,
598 },
599 {
600 .binding = 1,
601 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
602 .descriptorCount = 1,
603 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
604 .pImmutableSamplers = nullptr,
605 },
606 }};
607
501 const VkDescriptorSetLayoutCreateInfo ci{ 608 const VkDescriptorSetLayoutCreateInfo ci{
502 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 609 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
503 .pNext = nullptr, 610 .pNext = nullptr,
@@ -506,11 +613,21 @@ void VKBlitScreen::CreateDescriptorSetLayout() {
506 .pBindings = layout_bindings.data(), 613 .pBindings = layout_bindings.data(),
507 }; 614 };
508 615
616 const VkDescriptorSetLayoutCreateInfo ci_aa{
617 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
618 .pNext = nullptr,
619 .flags = 0,
620 .bindingCount = static_cast<u32>(layout_bindings_aa.size()),
621 .pBindings = layout_bindings_aa.data(),
622 };
623
509 descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci); 624 descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci);
625 aa_descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci_aa);
510} 626}
511 627
512void VKBlitScreen::CreateDescriptorSets() { 628void VKBlitScreen::CreateDescriptorSets() {
513 const std::vector layouts(image_count, *descriptor_set_layout); 629 const std::vector layouts(image_count, *descriptor_set_layout);
630 const std::vector layouts_aa(image_count, *aa_descriptor_set_layout);
514 631
515 const VkDescriptorSetAllocateInfo ai{ 632 const VkDescriptorSetAllocateInfo ai{
516 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 633 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
@@ -520,7 +637,16 @@ void VKBlitScreen::CreateDescriptorSets() {
520 .pSetLayouts = layouts.data(), 637 .pSetLayouts = layouts.data(),
521 }; 638 };
522 639
640 const VkDescriptorSetAllocateInfo ai_aa{
641 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
642 .pNext = nullptr,
643 .descriptorPool = *aa_descriptor_pool,
644 .descriptorSetCount = static_cast<u32>(image_count),
645 .pSetLayouts = layouts_aa.data(),
646 };
647
523 descriptor_sets = descriptor_pool.Allocate(ai); 648 descriptor_sets = descriptor_pool.Allocate(ai);
649 aa_descriptor_sets = aa_descriptor_pool.Allocate(ai_aa);
524} 650}
525 651
526void VKBlitScreen::CreatePipelineLayout() { 652void VKBlitScreen::CreatePipelineLayout() {
@@ -533,7 +659,17 @@ void VKBlitScreen::CreatePipelineLayout() {
533 .pushConstantRangeCount = 0, 659 .pushConstantRangeCount = 0,
534 .pPushConstantRanges = nullptr, 660 .pPushConstantRanges = nullptr,
535 }; 661 };
662 const VkPipelineLayoutCreateInfo ci_aa{
663 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
664 .pNext = nullptr,
665 .flags = 0,
666 .setLayoutCount = 1,
667 .pSetLayouts = aa_descriptor_set_layout.address(),
668 .pushConstantRangeCount = 0,
669 .pPushConstantRanges = nullptr,
670 };
536 pipeline_layout = device.GetLogical().CreatePipelineLayout(ci); 671 pipeline_layout = device.GetLogical().CreatePipelineLayout(ci);
672 aa_pipeline_layout = device.GetLogical().CreatePipelineLayout(ci_aa);
537} 673}
538 674
539void VKBlitScreen::CreateGraphicsPipeline() { 675void VKBlitScreen::CreateGraphicsPipeline() {
@@ -862,7 +998,7 @@ void VKBlitScreen::CreateFramebuffers() {
862 998
863 for (std::size_t i = 0; i < image_count; ++i) { 999 for (std::size_t i = 0; i < image_count; ++i) {
864 const VkImageView image_view{swapchain.GetImageViewIndex(i)}; 1000 const VkImageView image_view{swapchain.GetImageViewIndex(i)};
865 framebuffers[i] = CreateFramebuffer(image_view, size); 1001 framebuffers[i] = CreateFramebuffer(image_view, size, renderpass);
866 } 1002 }
867} 1003}
868 1004
@@ -872,6 +1008,11 @@ void VKBlitScreen::ReleaseRawImages() {
872 } 1008 }
873 raw_images.clear(); 1009 raw_images.clear();
874 raw_buffer_commits.clear(); 1010 raw_buffer_commits.clear();
1011
1012 aa_image_view.reset();
1013 aa_image.reset();
1014 aa_commit = MemoryCommit{};
1015
875 buffer.reset(); 1016 buffer.reset();
876 buffer_commit = MemoryCommit{}; 1017 buffer_commit = MemoryCommit{};
877} 1018}
@@ -898,8 +1039,11 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
898 raw_image_views.resize(image_count); 1039 raw_image_views.resize(image_count);
899 raw_buffer_commits.resize(image_count); 1040 raw_buffer_commits.resize(image_count);
900 1041
901 for (size_t i = 0; i < image_count; ++i) { 1042 const auto create_image = [&](bool used_on_framebuffer = false, u32 up_scale = 1,
902 raw_images[i] = device.GetLogical().CreateImage(VkImageCreateInfo{ 1043 u32 down_shift = 0) {
1044 u32 extra_usages = used_on_framebuffer ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
1045 : VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1046 return device.GetLogical().CreateImage(VkImageCreateInfo{
903 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 1047 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
904 .pNext = nullptr, 1048 .pNext = nullptr,
905 .flags = 0, 1049 .flags = 0,
@@ -907,26 +1051,30 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
907 .format = GetFormat(framebuffer), 1051 .format = GetFormat(framebuffer),
908 .extent = 1052 .extent =
909 { 1053 {
910 .width = framebuffer.width, 1054 .width = (up_scale * framebuffer.width) >> down_shift,
911 .height = framebuffer.height, 1055 .height = (up_scale * framebuffer.height) >> down_shift,
912 .depth = 1, 1056 .depth = 1,
913 }, 1057 },
914 .mipLevels = 1, 1058 .mipLevels = 1,
915 .arrayLayers = 1, 1059 .arrayLayers = 1,
916 .samples = VK_SAMPLE_COUNT_1_BIT, 1060 .samples = VK_SAMPLE_COUNT_1_BIT,
917 .tiling = VK_IMAGE_TILING_LINEAR, 1061 .tiling = used_on_framebuffer ? VK_IMAGE_TILING_OPTIMAL : VK_IMAGE_TILING_LINEAR,
918 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 1062 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | extra_usages,
919 .sharingMode = VK_SHARING_MODE_EXCLUSIVE, 1063 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
920 .queueFamilyIndexCount = 0, 1064 .queueFamilyIndexCount = 0,
921 .pQueueFamilyIndices = nullptr, 1065 .pQueueFamilyIndices = nullptr,
922 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, 1066 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
923 }); 1067 });
924 raw_buffer_commits[i] = memory_allocator.Commit(raw_images[i], MemoryUsage::DeviceLocal); 1068 };
925 raw_image_views[i] = device.GetLogical().CreateImageView(VkImageViewCreateInfo{ 1069 const auto create_commit = [&](vk::Image& image) {
1070 return memory_allocator.Commit(image, MemoryUsage::DeviceLocal);
1071 };
1072 const auto create_image_view = [&](vk::Image& image) {
1073 return device.GetLogical().CreateImageView(VkImageViewCreateInfo{
926 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 1074 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
927 .pNext = nullptr, 1075 .pNext = nullptr,
928 .flags = 0, 1076 .flags = 0,
929 .image = *raw_images[i], 1077 .image = *image,
930 .viewType = VK_IMAGE_VIEW_TYPE_2D, 1078 .viewType = VK_IMAGE_VIEW_TYPE_2D,
931 .format = GetFormat(framebuffer), 1079 .format = GetFormat(framebuffer),
932 .components = 1080 .components =
@@ -945,7 +1093,207 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
945 .layerCount = 1, 1093 .layerCount = 1,
946 }, 1094 },
947 }); 1095 });
1096 };
1097
1098 for (size_t i = 0; i < image_count; ++i) {
1099 raw_images[i] = create_image();
1100 raw_buffer_commits[i] = create_commit(raw_images[i]);
1101 raw_image_views[i] = create_image_view(raw_images[i]);
948 } 1102 }
1103
1104 // AA Resources
1105 const u32 up_scale = Settings::values.resolution_info.up_scale;
1106 const u32 down_shift = Settings::values.resolution_info.down_shift;
1107 aa_image = create_image(true, up_scale, down_shift);
1108 aa_commit = create_commit(aa_image);
1109 aa_image_view = create_image_view(aa_image);
1110 VkExtent2D size{
1111 .width = (up_scale * framebuffer.width) >> down_shift,
1112 .height = (up_scale * framebuffer.height) >> down_shift,
1113 };
1114 if (aa_renderpass) {
1115 aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass);
1116 return;
1117 }
1118 aa_renderpass = CreateRenderPassImpl(GetFormat(framebuffer), false);
1119 aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass);
1120
1121 const std::array<VkPipelineShaderStageCreateInfo, 2> fxaa_shader_stages{{
1122 {
1123 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1124 .pNext = nullptr,
1125 .flags = 0,
1126 .stage = VK_SHADER_STAGE_VERTEX_BIT,
1127 .module = *fxaa_vertex_shader,
1128 .pName = "main",
1129 .pSpecializationInfo = nullptr,
1130 },
1131 {
1132 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1133 .pNext = nullptr,
1134 .flags = 0,
1135 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
1136 .module = *fxaa_fragment_shader,
1137 .pName = "main",
1138 .pSpecializationInfo = nullptr,
1139 },
1140 }};
1141
1142 const auto vertex_binding_description = ScreenRectVertex::GetDescription();
1143 const auto vertex_attrs_description = ScreenRectVertex::GetAttributes();
1144
1145 const VkPipelineVertexInputStateCreateInfo vertex_input_ci{
1146 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1147 .pNext = nullptr,
1148 .flags = 0,
1149 .vertexBindingDescriptionCount = 1,
1150 .pVertexBindingDescriptions = &vertex_binding_description,
1151 .vertexAttributeDescriptionCount = u32{vertex_attrs_description.size()},
1152 .pVertexAttributeDescriptions = vertex_attrs_description.data(),
1153 };
1154
1155 const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci{
1156 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1157 .pNext = nullptr,
1158 .flags = 0,
1159 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
1160 .primitiveRestartEnable = VK_FALSE,
1161 };
1162
1163 const VkPipelineViewportStateCreateInfo viewport_state_ci{
1164 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1165 .pNext = nullptr,
1166 .flags = 0,
1167 .viewportCount = 1,
1168 .pViewports = nullptr,
1169 .scissorCount = 1,
1170 .pScissors = nullptr,
1171 };
1172
1173 const VkPipelineRasterizationStateCreateInfo rasterization_ci{
1174 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1175 .pNext = nullptr,
1176 .flags = 0,
1177 .depthClampEnable = VK_FALSE,
1178 .rasterizerDiscardEnable = VK_FALSE,
1179 .polygonMode = VK_POLYGON_MODE_FILL,
1180 .cullMode = VK_CULL_MODE_NONE,
1181 .frontFace = VK_FRONT_FACE_CLOCKWISE,
1182 .depthBiasEnable = VK_FALSE,
1183 .depthBiasConstantFactor = 0.0f,
1184 .depthBiasClamp = 0.0f,
1185 .depthBiasSlopeFactor = 0.0f,
1186 .lineWidth = 1.0f,
1187 };
1188
1189 const VkPipelineMultisampleStateCreateInfo multisampling_ci{
1190 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1191 .pNext = nullptr,
1192 .flags = 0,
1193 .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
1194 .sampleShadingEnable = VK_FALSE,
1195 .minSampleShading = 0.0f,
1196 .pSampleMask = nullptr,
1197 .alphaToCoverageEnable = VK_FALSE,
1198 .alphaToOneEnable = VK_FALSE,
1199 };
1200
1201 const VkPipelineColorBlendAttachmentState color_blend_attachment{
1202 .blendEnable = VK_FALSE,
1203 .srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
1204 .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
1205 .colorBlendOp = VK_BLEND_OP_ADD,
1206 .srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
1207 .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
1208 .alphaBlendOp = VK_BLEND_OP_ADD,
1209 .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
1210 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
1211 };
1212
1213 const VkPipelineColorBlendStateCreateInfo color_blend_ci{
1214 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1215 .pNext = nullptr,
1216 .flags = 0,
1217 .logicOpEnable = VK_FALSE,
1218 .logicOp = VK_LOGIC_OP_COPY,
1219 .attachmentCount = 1,
1220 .pAttachments = &color_blend_attachment,
1221 .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
1222 };
1223
1224 static constexpr std::array dynamic_states{
1225 VK_DYNAMIC_STATE_VIEWPORT,
1226 VK_DYNAMIC_STATE_SCISSOR,
1227 };
1228 const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
1229 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1230 .pNext = nullptr,
1231 .flags = 0,
1232 .dynamicStateCount = static_cast<u32>(dynamic_states.size()),
1233 .pDynamicStates = dynamic_states.data(),
1234 };
1235
1236 const VkGraphicsPipelineCreateInfo fxaa_pipeline_ci{
1237 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1238 .pNext = nullptr,
1239 .flags = 0,
1240 .stageCount = static_cast<u32>(fxaa_shader_stages.size()),
1241 .pStages = fxaa_shader_stages.data(),
1242 .pVertexInputState = &vertex_input_ci,
1243 .pInputAssemblyState = &input_assembly_ci,
1244 .pTessellationState = nullptr,
1245 .pViewportState = &viewport_state_ci,
1246 .pRasterizationState = &rasterization_ci,
1247 .pMultisampleState = &multisampling_ci,
1248 .pDepthStencilState = nullptr,
1249 .pColorBlendState = &color_blend_ci,
1250 .pDynamicState = &dynamic_state_ci,
1251 .layout = *aa_pipeline_layout,
1252 .renderPass = *aa_renderpass,
1253 .subpass = 0,
1254 .basePipelineHandle = 0,
1255 .basePipelineIndex = 0,
1256 };
1257
1258 // AA
1259 aa_pipeline = device.GetLogical().CreateGraphicsPipeline(fxaa_pipeline_ci);
1260}
1261
1262void VKBlitScreen::UpdateAADescriptorSet(std::size_t image_index, VkImageView image_view,
1263 bool nn) const {
1264 const VkDescriptorImageInfo image_info{
1265 .sampler = nn ? *nn_sampler : *sampler,
1266 .imageView = image_view,
1267 .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
1268 };
1269
1270 const VkWriteDescriptorSet sampler_write{
1271 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1272 .pNext = nullptr,
1273 .dstSet = aa_descriptor_sets[image_index],
1274 .dstBinding = 0,
1275 .dstArrayElement = 0,
1276 .descriptorCount = 1,
1277 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1278 .pImageInfo = &image_info,
1279 .pBufferInfo = nullptr,
1280 .pTexelBufferView = nullptr,
1281 };
1282
1283 const VkWriteDescriptorSet sampler_write_2{
1284 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1285 .pNext = nullptr,
1286 .dstSet = aa_descriptor_sets[image_index],
1287 .dstBinding = 1,
1288 .dstArrayElement = 0,
1289 .descriptorCount = 1,
1290 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1291 .pImageInfo = &image_info,
1292 .pBufferInfo = nullptr,
1293 .pTexelBufferView = nullptr,
1294 };
1295
1296 device.GetLogical().UpdateDescriptorSets(std::array{sampler_write, sampler_write_2}, {});
949} 1297}
950 1298
951void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, 1299void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view,
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h
index 96a5598ad..e8737537e 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.h
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.h
@@ -68,6 +68,9 @@ public:
68 [[nodiscard]] vk::Framebuffer CreateFramebuffer(const VkImageView& image_view, 68 [[nodiscard]] vk::Framebuffer CreateFramebuffer(const VkImageView& image_view,
69 VkExtent2D extent); 69 VkExtent2D extent);
70 70
71 [[nodiscard]] vk::Framebuffer CreateFramebuffer(const VkImageView& image_view,
72 VkExtent2D extent, vk::RenderPass& rd);
73
71private: 74private:
72 struct BufferData; 75 struct BufferData;
73 76
@@ -76,6 +79,7 @@ private:
76 void CreateSemaphores(); 79 void CreateSemaphores();
77 void CreateDescriptorPool(); 80 void CreateDescriptorPool();
78 void CreateRenderPass(); 81 void CreateRenderPass();
82 vk::RenderPass CreateRenderPassImpl(VkFormat, bool is_present = true);
79 void CreateDescriptorSetLayout(); 83 void CreateDescriptorSetLayout();
80 void CreateDescriptorSets(); 84 void CreateDescriptorSets();
81 void CreatePipelineLayout(); 85 void CreatePipelineLayout();
@@ -91,6 +95,7 @@ private:
91 void CreateRawImages(const Tegra::FramebufferConfig& framebuffer); 95 void CreateRawImages(const Tegra::FramebufferConfig& framebuffer);
92 96
93 void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, bool nn) const; 97 void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view, bool nn) const;
98 void UpdateAADescriptorSet(std::size_t image_index, VkImageView image_view, bool nn) const;
94 void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const; 99 void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const;
95 void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, 100 void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer,
96 const Layout::FramebufferLayout layout) const; 101 const Layout::FramebufferLayout layout) const;
@@ -109,6 +114,8 @@ private:
109 const VKScreenInfo& screen_info; 114 const VKScreenInfo& screen_info;
110 115
111 vk::ShaderModule vertex_shader; 116 vk::ShaderModule vertex_shader;
117 vk::ShaderModule fxaa_vertex_shader;
118 vk::ShaderModule fxaa_fragment_shader;
112 vk::ShaderModule bilinear_fragment_shader; 119 vk::ShaderModule bilinear_fragment_shader;
113 vk::ShaderModule bicubic_fragment_shader; 120 vk::ShaderModule bicubic_fragment_shader;
114 vk::ShaderModule gaussian_fragment_shader; 121 vk::ShaderModule gaussian_fragment_shader;
@@ -116,6 +123,7 @@ private:
116 vk::DescriptorPool descriptor_pool; 123 vk::DescriptorPool descriptor_pool;
117 vk::DescriptorSetLayout descriptor_set_layout; 124 vk::DescriptorSetLayout descriptor_set_layout;
118 vk::PipelineLayout pipeline_layout; 125 vk::PipelineLayout pipeline_layout;
126 vk::Pipeline aa_pipeline;
119 vk::Pipeline nearest_neightbor_pipeline; 127 vk::Pipeline nearest_neightbor_pipeline;
120 vk::Pipeline bilinear_pipeline; 128 vk::Pipeline bilinear_pipeline;
121 vk::Pipeline bicubic_pipeline; 129 vk::Pipeline bicubic_pipeline;
@@ -136,6 +144,15 @@ private:
136 std::vector<vk::Image> raw_images; 144 std::vector<vk::Image> raw_images;
137 std::vector<vk::ImageView> raw_image_views; 145 std::vector<vk::ImageView> raw_image_views;
138 std::vector<MemoryCommit> raw_buffer_commits; 146 std::vector<MemoryCommit> raw_buffer_commits;
147 vk::Image aa_image;
148 vk::ImageView aa_image_view;
149 MemoryCommit aa_commit;
150 vk::Framebuffer aa_framebuffer;
151 vk::RenderPass aa_renderpass;
152 vk::DescriptorSets aa_descriptor_sets;
153 vk::DescriptorPool aa_descriptor_pool;
154 vk::DescriptorSetLayout aa_descriptor_set_layout;
155 vk::PipelineLayout aa_pipeline_layout;
139 u32 raw_width = 0; 156 u32 raw_width = 0;
140 u32 raw_height = 0; 157 u32 raw_height = 0;
141 158