diff options
| author | 2023-01-19 14:58:53 -0500 | |
|---|---|---|
| committer | 2023-01-19 14:58:53 -0500 | |
| commit | 475370c8f89002e3b508eb152b981a5b89049d68 (patch) | |
| tree | 79a145e24f2bf5ab5baca6824cae6cd525a8d170 /src/video_core/renderer_vulkan | |
| parent | Merge pull request #9623 from liamwhite/wp-oops (diff) | |
| parent | Address feedback (diff) | |
| download | yuzu-475370c8f89002e3b508eb152b981a5b89049d68.tar.gz yuzu-475370c8f89002e3b508eb152b981a5b89049d68.tar.xz yuzu-475370c8f89002e3b508eb152b981a5b89049d68.zip | |
Merge pull request #9556 from vonchenplus/draw_texture
video_core: Implement maxwell3d draw texture method
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.cpp | 88 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 1 |
4 files changed, 117 insertions, 7 deletions
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index 3f2b139e0..dd00d3edf 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp | |||
| @@ -4,13 +4,13 @@ | |||
| 4 | #include <algorithm> | 4 | #include <algorithm> |
| 5 | 5 | ||
| 6 | #include "common/settings.h" | 6 | #include "common/settings.h" |
| 7 | #include "video_core/host_shaders/blit_color_float_frag_spv.h" | ||
| 7 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" | 8 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" |
| 8 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" | 9 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" |
| 9 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" | 10 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" |
| 10 | #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" | 11 | #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" |
| 11 | #include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h" | 12 | #include "video_core/host_shaders/convert_s8d24_to_abgr8_frag_spv.h" |
| 12 | #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" | 13 | #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" |
| 13 | #include "video_core/host_shaders/vulkan_blit_color_float_frag_spv.h" | ||
| 14 | #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" | 14 | #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" |
| 15 | #include "video_core/renderer_vulkan/blit_image.h" | 15 | #include "video_core/renderer_vulkan/blit_image.h" |
| 16 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" | 16 | #include "video_core/renderer_vulkan/maxwell_to_vk.h" |
| @@ -303,7 +303,7 @@ void UpdateTwoTexturesDescriptorSet(const Device& device, VkDescriptorSet descri | |||
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Region2D& dst_region, | 305 | void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Region2D& dst_region, |
| 306 | const Region2D& src_region) { | 306 | const Region2D& src_region, const Extent3D& src_size = {1, 1, 1}) { |
| 307 | const VkOffset2D offset{ | 307 | const VkOffset2D offset{ |
| 308 | .x = std::min(dst_region.start.x, dst_region.end.x), | 308 | .x = std::min(dst_region.start.x, dst_region.end.x), |
| 309 | .y = std::min(dst_region.start.y, dst_region.end.y), | 309 | .y = std::min(dst_region.start.y, dst_region.end.y), |
| @@ -325,12 +325,15 @@ void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Regi | |||
| 325 | .offset = offset, | 325 | .offset = offset, |
| 326 | .extent = extent, | 326 | .extent = extent, |
| 327 | }; | 327 | }; |
| 328 | const float scale_x = static_cast<float>(src_region.end.x - src_region.start.x); | 328 | const float scale_x = static_cast<float>(src_region.end.x - src_region.start.x) / |
| 329 | const float scale_y = static_cast<float>(src_region.end.y - src_region.start.y); | 329 | static_cast<float>(src_size.width); |
| 330 | const float scale_y = static_cast<float>(src_region.end.y - src_region.start.y) / | ||
| 331 | static_cast<float>(src_size.height); | ||
| 330 | const PushConstants push_constants{ | 332 | const PushConstants push_constants{ |
| 331 | .tex_scale = {scale_x, scale_y}, | 333 | .tex_scale = {scale_x, scale_y}, |
| 332 | .tex_offset = {static_cast<float>(src_region.start.x), | 334 | .tex_offset = {static_cast<float>(src_region.start.x) / static_cast<float>(src_size.width), |
| 333 | static_cast<float>(src_region.start.y)}, | 335 | static_cast<float>(src_region.start.y) / |
| 336 | static_cast<float>(src_size.height)}, | ||
| 334 | }; | 337 | }; |
| 335 | cmdbuf.SetViewport(0, viewport); | 338 | cmdbuf.SetViewport(0, viewport); |
| 336 | cmdbuf.SetScissor(0, scissor); | 339 | cmdbuf.SetScissor(0, scissor); |
| @@ -347,6 +350,51 @@ VkExtent2D GetConversionExtent(const ImageView& src_image_view) { | |||
| 347 | .height = is_rescaled ? resolution.ScaleUp(height) : height, | 350 | .height = is_rescaled ? resolution.ScaleUp(height) : height, |
| 348 | }; | 351 | }; |
| 349 | } | 352 | } |
| 353 | |||
| 354 | void TransitionImageLayout(vk::CommandBuffer& cmdbuf, VkImage image, VkImageLayout target_layout, | ||
| 355 | VkImageLayout source_layout = VK_IMAGE_LAYOUT_GENERAL) { | ||
| 356 | constexpr VkFlags flags{VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | | ||
| 357 | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT}; | ||
| 358 | const VkImageMemoryBarrier barrier{ | ||
| 359 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | ||
| 360 | .pNext = nullptr, | ||
| 361 | .srcAccessMask = flags, | ||
| 362 | .dstAccessMask = flags, | ||
| 363 | .oldLayout = source_layout, | ||
| 364 | .newLayout = target_layout, | ||
| 365 | .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | ||
| 366 | .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, | ||
| 367 | .image = image, | ||
| 368 | .subresourceRange{ | ||
| 369 | .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, | ||
| 370 | .baseMipLevel = 0, | ||
| 371 | .levelCount = 1, | ||
| 372 | .baseArrayLayer = 0, | ||
| 373 | .layerCount = 1, | ||
| 374 | }, | ||
| 375 | }; | ||
| 376 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | ||
| 377 | 0, barrier); | ||
| 378 | } | ||
| 379 | |||
| 380 | void BeginRenderPass(vk::CommandBuffer& cmdbuf, const Framebuffer* framebuffer) { | ||
| 381 | const VkRenderPass render_pass = framebuffer->RenderPass(); | ||
| 382 | const VkFramebuffer framebuffer_handle = framebuffer->Handle(); | ||
| 383 | const VkExtent2D render_area = framebuffer->RenderArea(); | ||
| 384 | const VkRenderPassBeginInfo renderpass_bi{ | ||
| 385 | .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, | ||
| 386 | .pNext = nullptr, | ||
| 387 | .renderPass = render_pass, | ||
| 388 | .framebuffer = framebuffer_handle, | ||
| 389 | .renderArea{ | ||
| 390 | .offset{}, | ||
| 391 | .extent = render_area, | ||
| 392 | }, | ||
| 393 | .clearValueCount = 0, | ||
| 394 | .pClearValues = nullptr, | ||
| 395 | }; | ||
| 396 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); | ||
| 397 | } | ||
| 350 | } // Anonymous namespace | 398 | } // Anonymous namespace |
| 351 | 399 | ||
| 352 | BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, | 400 | BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, |
| @@ -365,7 +413,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_, | |||
| 365 | two_textures_pipeline_layout(device.GetLogical().CreatePipelineLayout( | 413 | two_textures_pipeline_layout(device.GetLogical().CreatePipelineLayout( |
| 366 | PipelineLayoutCreateInfo(two_textures_set_layout.address()))), | 414 | PipelineLayoutCreateInfo(two_textures_set_layout.address()))), |
| 367 | full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)), | 415 | full_screen_vert(BuildShader(device, FULL_SCREEN_TRIANGLE_VERT_SPV)), |
| 368 | blit_color_to_color_frag(BuildShader(device, VULKAN_BLIT_COLOR_FLOAT_FRAG_SPV)), | 416 | blit_color_to_color_frag(BuildShader(device, BLIT_COLOR_FLOAT_FRAG_SPV)), |
| 369 | blit_depth_stencil_frag(BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV)), | 417 | blit_depth_stencil_frag(BuildShader(device, VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV)), |
| 370 | convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), | 418 | convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), |
| 371 | convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), | 419 | convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), |
| @@ -404,6 +452,32 @@ void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView | |||
| 404 | scheduler.InvalidateState(); | 452 | scheduler.InvalidateState(); |
| 405 | } | 453 | } |
| 406 | 454 | ||
| 455 | void BlitImageHelper::BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_image_view, | ||
| 456 | VkImage src_image, VkSampler src_sampler, | ||
| 457 | const Region2D& dst_region, const Region2D& src_region, | ||
| 458 | const Extent3D& src_size) { | ||
| 459 | const BlitImagePipelineKey key{ | ||
| 460 | .renderpass = dst_framebuffer->RenderPass(), | ||
| 461 | .operation = Tegra::Engines::Fermi2D::Operation::SrcCopy, | ||
| 462 | }; | ||
| 463 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | ||
| 464 | const VkPipeline pipeline = FindOrEmplaceColorPipeline(key); | ||
| 465 | scheduler.RequestOutsideRenderPassOperationContext(); | ||
| 466 | scheduler.Record([this, dst_framebuffer, src_image_view, src_image, src_sampler, dst_region, | ||
| 467 | src_region, src_size, pipeline, layout](vk::CommandBuffer cmdbuf) { | ||
| 468 | TransitionImageLayout(cmdbuf, src_image, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL); | ||
| 469 | BeginRenderPass(cmdbuf, dst_framebuffer); | ||
| 470 | const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); | ||
| 471 | UpdateOneTextureDescriptorSet(device, descriptor_set, src_sampler, src_image_view); | ||
| 472 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); | ||
| 473 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, | ||
| 474 | nullptr); | ||
| 475 | BindBlitState(cmdbuf, layout, dst_region, src_region, src_size); | ||
| 476 | cmdbuf.Draw(3, 1, 0, 0); | ||
| 477 | cmdbuf.EndRenderPass(); | ||
| 478 | }); | ||
| 479 | } | ||
| 480 | |||
| 407 | void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, | 481 | void BlitImageHelper::BlitDepthStencil(const Framebuffer* dst_framebuffer, |
| 408 | VkImageView src_depth_view, VkImageView src_stencil_view, | 482 | VkImageView src_depth_view, VkImageView src_stencil_view, |
| 409 | const Region2D& dst_region, const Region2D& src_region, | 483 | const Region2D& dst_region, const Region2D& src_region, |
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 5df679fb4..be8a9a2f6 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | namespace Vulkan { | 11 | namespace Vulkan { |
| 12 | 12 | ||
| 13 | using VideoCommon::Extent3D; | ||
| 14 | using VideoCommon::Offset2D; | ||
| 13 | using VideoCommon::Region2D; | 15 | using VideoCommon::Region2D; |
| 14 | 16 | ||
| 15 | class Device; | 17 | class Device; |
| @@ -36,6 +38,10 @@ public: | |||
| 36 | Tegra::Engines::Fermi2D::Filter filter, | 38 | Tegra::Engines::Fermi2D::Filter filter, |
| 37 | Tegra::Engines::Fermi2D::Operation operation); | 39 | Tegra::Engines::Fermi2D::Operation operation); |
| 38 | 40 | ||
| 41 | void BlitColor(const Framebuffer* dst_framebuffer, VkImageView src_image_view, | ||
| 42 | VkImage src_image, VkSampler src_sampler, const Region2D& dst_region, | ||
| 43 | const Region2D& src_region, const Extent3D& src_size); | ||
| 44 | |||
| 39 | void BlitDepthStencil(const Framebuffer* dst_framebuffer, VkImageView src_depth_view, | 45 | void BlitDepthStencil(const Framebuffer* dst_framebuffer, VkImageView src_depth_view, |
| 40 | VkImageView src_stencil_view, const Region2D& dst_region, | 46 | VkImageView src_stencil_view, const Region2D& dst_region, |
| 41 | const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, | 47 | const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index b75b8eec6..86ef0daeb 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -266,6 +266,35 @@ void RasterizerVulkan::DrawIndirect() { | |||
| 266 | buffer_cache.SetDrawIndirect(nullptr); | 266 | buffer_cache.SetDrawIndirect(nullptr); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | void RasterizerVulkan::DrawTexture() { | ||
| 270 | MICROPROFILE_SCOPE(Vulkan_Drawing); | ||
| 271 | |||
| 272 | SCOPE_EXIT({ gpu.TickWork(); }); | ||
| 273 | FlushWork(); | ||
| 274 | |||
| 275 | query_cache.UpdateCounters(); | ||
| 276 | |||
| 277 | texture_cache.SynchronizeGraphicsDescriptors(); | ||
| 278 | texture_cache.UpdateRenderTargets(false); | ||
| 279 | |||
| 280 | UpdateDynamicStates(); | ||
| 281 | |||
| 282 | const auto& draw_texture_state = maxwell3d->draw_manager->GetDrawTextureState(); | ||
| 283 | const auto& sampler = texture_cache.GetGraphicsSampler(draw_texture_state.src_sampler); | ||
| 284 | const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture); | ||
| 285 | Region2D dst_region = {Offset2D{.x = static_cast<s32>(draw_texture_state.dst_x0), | ||
| 286 | .y = static_cast<s32>(draw_texture_state.dst_y0)}, | ||
| 287 | Offset2D{.x = static_cast<s32>(draw_texture_state.dst_x1), | ||
| 288 | .y = static_cast<s32>(draw_texture_state.dst_y1)}}; | ||
| 289 | Region2D src_region = {Offset2D{.x = static_cast<s32>(draw_texture_state.src_x0), | ||
| 290 | .y = static_cast<s32>(draw_texture_state.src_y0)}, | ||
| 291 | Offset2D{.x = static_cast<s32>(draw_texture_state.src_x1), | ||
| 292 | .y = static_cast<s32>(draw_texture_state.src_y1)}}; | ||
| 293 | blit_image.BlitColor(texture_cache.GetFramebuffer(), texture.RenderTarget(), | ||
| 294 | texture.ImageHandle(), sampler->Handle(), dst_region, src_region, | ||
| 295 | texture.size); | ||
| 296 | } | ||
| 297 | |||
| 269 | void RasterizerVulkan::Clear(u32 layer_count) { | 298 | void RasterizerVulkan::Clear(u32 layer_count) { |
| 270 | MICROPROFILE_SCOPE(Vulkan_Clearing); | 299 | MICROPROFILE_SCOPE(Vulkan_Clearing); |
| 271 | 300 | ||
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 472cc64d9..a0508b57c 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -66,6 +66,7 @@ public: | |||
| 66 | 66 | ||
| 67 | void Draw(bool is_indexed, u32 instance_count) override; | 67 | void Draw(bool is_indexed, u32 instance_count) override; |
| 68 | void DrawIndirect() override; | 68 | void DrawIndirect() override; |
| 69 | void DrawTexture() override; | ||
| 69 | void Clear(u32 layer_count) override; | 70 | void Clear(u32 layer_count) override; |
| 70 | void DispatchCompute() override; | 71 | void DispatchCompute() override; |
| 71 | void ResetCounter(VideoCore::QueryType type) override; | 72 | void ResetCounter(VideoCore::QueryType type) override; |