summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/pipeline_helper.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp24
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp16
-rw-r--r--src/video_core/shader_environment.cpp17
-rw-r--r--src/video_core/shader_environment.h9
9 files changed, 96 insertions, 7 deletions
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 1d20a79ec..daceb05f4 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -503,6 +503,17 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
503 float_image_scaling_mask, down_factor, 0.0f); 503 float_image_scaling_mask, down_factor, 0.0f);
504 } 504 }
505 } 505 }
506 if (info.uses_render_area) {
507 const auto render_area_width(static_cast<GLfloat>(regs.render_area.width));
508 const auto render_area_height(static_cast<GLfloat>(regs.render_area.height));
509 if (use_assembly) {
510 glProgramLocalParameter4fARB(AssemblyStage(stage), 1, render_area_width,
511 render_area_height, 0.0f, 0.0f);
512 } else {
513 glProgramUniform4f(source_programs[stage].handle, 1, render_area_width,
514 render_area_height, 0.0f, 0.0f);
515 }
516 }
506 }}; 517 }};
507 if constexpr (Spec::enabled_stages[0]) { 518 if constexpr (Spec::enabled_stages[0]) {
508 prepare_stage(0); 519 prepare_stage(0);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 1590b21de..79d7908d4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -618,6 +618,16 @@ void RasterizerOpenGL::SyncViewport() {
618 } 618 }
619 flags[Dirty::Viewport0 + index] = false; 619 flags[Dirty::Viewport0 + index] = false;
620 620
621 if (!regs.viewport_transform_enabled) {
622 const auto x = static_cast<GLfloat>(regs.render_area.x);
623 const auto y = static_cast<GLfloat>(regs.render_area.y);
624 const auto width = static_cast<GLfloat>(regs.render_area.width);
625 const auto height = static_cast<GLfloat>(regs.render_area.height);
626 glViewportIndexedf(static_cast<GLuint>(index), x, y, width != 0.0f ? width : 1.0f,
627 height != 0.0f ? height : 1.0f);
628 continue;
629 }
630
621 const auto& src = regs.viewport_transform[index]; 631 const auto& src = regs.viewport_transform[index];
622 GLfloat x = conv(src.translate_x - src.scale_x); 632 GLfloat x = conv(src.translate_x - src.scale_x);
623 GLfloat y = conv(src.translate_y - src.scale_y); 633 GLfloat y = conv(src.translate_y - src.scale_y);
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index e94cfdb1a..977709518 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -49,7 +49,7 @@ using VideoCommon::LoadPipelines;
49using VideoCommon::SerializePipeline; 49using VideoCommon::SerializePipeline;
50using Context = ShaderContext::Context; 50using Context = ShaderContext::Context;
51 51
52constexpr u32 CACHE_VERSION = 6; 52constexpr u32 CACHE_VERSION = 7;
53 53
54template <typename Container> 54template <typename Container>
55auto MakeSpan(Container& container) { 55auto MakeSpan(Container& container) {
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h
index b24f3424a..b7843e995 100644
--- a/src/video_core/renderer_vulkan/pipeline_helper.h
+++ b/src/video_core/renderer_vulkan/pipeline_helper.h
@@ -68,13 +68,15 @@ public:
68 } 68 }
69 69
70 vk::PipelineLayout CreatePipelineLayout(VkDescriptorSetLayout descriptor_set_layout) const { 70 vk::PipelineLayout CreatePipelineLayout(VkDescriptorSetLayout descriptor_set_layout) const {
71 using Shader::Backend::SPIRV::RenderAreaLayout;
71 using Shader::Backend::SPIRV::RescalingLayout; 72 using Shader::Backend::SPIRV::RescalingLayout;
72 const u32 size_offset = is_compute ? sizeof(RescalingLayout::down_factor) : 0u; 73 const u32 size_offset = is_compute ? sizeof(RescalingLayout::down_factor) : 0u;
73 const VkPushConstantRange range{ 74 const VkPushConstantRange range{
74 .stageFlags = static_cast<VkShaderStageFlags>( 75 .stageFlags = static_cast<VkShaderStageFlags>(
75 is_compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS), 76 is_compute ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS),
76 .offset = 0, 77 .offset = 0,
77 .size = static_cast<u32>(sizeof(RescalingLayout)) - size_offset, 78 .size = static_cast<u32>(sizeof(RescalingLayout)) - size_offset +
79 static_cast<u32>(sizeof(RenderAreaLayout)),
78 }; 80 };
79 return device->GetLogical().CreatePipelineLayout({ 81 return device->GetLogical().CreatePipelineLayout({
80 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 82 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
@@ -167,6 +169,12 @@ private:
167 u32 image_bit{1u}; 169 u32 image_bit{1u};
168}; 170};
169 171
172class RenderAreaPushConstant {
173public:
174 bool uses_render_area{};
175 std::array<f32, 4> words{};
176};
177
170inline void PushImageDescriptors(TextureCache& texture_cache, 178inline void PushImageDescriptors(TextureCache& texture_cache,
171 UpdateDescriptorQueue& update_descriptor_queue, 179 UpdateDescriptorQueue& update_descriptor_queue,
172 const Shader::Info& info, RescalingPushConstant& rescaling, 180 const Shader::Info& info, RescalingPushConstant& rescaling,
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index c3f66c8a3..b4372a839 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -31,6 +31,7 @@ namespace {
31using boost::container::small_vector; 31using boost::container::small_vector;
32using boost::container::static_vector; 32using boost::container::static_vector;
33using Shader::ImageBufferDescriptor; 33using Shader::ImageBufferDescriptor;
34using Shader::Backend::SPIRV::RENDERAREA_LAYOUT_OFFSET;
34using Shader::Backend::SPIRV::RESCALING_LAYOUT_DOWN_FACTOR_OFFSET; 35using Shader::Backend::SPIRV::RESCALING_LAYOUT_DOWN_FACTOR_OFFSET;
35using Shader::Backend::SPIRV::RESCALING_LAYOUT_WORDS_OFFSET; 36using Shader::Backend::SPIRV::RESCALING_LAYOUT_WORDS_OFFSET;
36using Tegra::Texture::TexturePair; 37using Tegra::Texture::TexturePair;
@@ -433,12 +434,19 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
433 update_descriptor_queue.Acquire(); 434 update_descriptor_queue.Acquire();
434 435
435 RescalingPushConstant rescaling; 436 RescalingPushConstant rescaling;
437 RenderAreaPushConstant render_area;
436 const VkSampler* samplers_it{samplers.data()}; 438 const VkSampler* samplers_it{samplers.data()};
437 const VideoCommon::ImageViewInOut* views_it{views.data()}; 439 const VideoCommon::ImageViewInOut* views_it{views.data()};
438 const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { 440 const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
439 buffer_cache.BindHostStageBuffers(stage); 441 buffer_cache.BindHostStageBuffers(stage);
440 PushImageDescriptors(texture_cache, update_descriptor_queue, stage_infos[stage], rescaling, 442 PushImageDescriptors(texture_cache, update_descriptor_queue, stage_infos[stage], rescaling,
441 samplers_it, views_it); 443 samplers_it, views_it);
444 const auto& info{stage_infos[0]};
445 if (info.uses_render_area) {
446 render_area.uses_render_area = true;
447 render_area.words = {static_cast<float>(regs.render_area.width),
448 static_cast<float>(regs.render_area.height)};
449 }
442 }}; 450 }};
443 if constexpr (Spec::enabled_stages[0]) { 451 if constexpr (Spec::enabled_stages[0]) {
444 prepare_stage(0); 452 prepare_stage(0);
@@ -455,10 +463,11 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
455 if constexpr (Spec::enabled_stages[4]) { 463 if constexpr (Spec::enabled_stages[4]) {
456 prepare_stage(4); 464 prepare_stage(4);
457 } 465 }
458 ConfigureDraw(rescaling); 466 ConfigureDraw(rescaling, render_area);
459} 467}
460 468
461void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling) { 469void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
470 const RenderAreaPushConstant& render_are) {
462 texture_cache.UpdateRenderTargets(false); 471 texture_cache.UpdateRenderTargets(false);
463 scheduler.RequestRenderpass(texture_cache.GetFramebuffer()); 472 scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
464 473
@@ -474,7 +483,9 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling) {
474 const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)}; 483 const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)};
475 const void* const descriptor_data{update_descriptor_queue.UpdateData()}; 484 const void* const descriptor_data{update_descriptor_queue.UpdateData()};
476 scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(), 485 scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(),
477 is_rescaling, update_rescaling](vk::CommandBuffer cmdbuf) { 486 is_rescaling, update_rescaling,
487 uses_render_area = render_are.uses_render_area,
488 render_area_data = render_are.words](vk::CommandBuffer cmdbuf) {
478 if (bind_pipeline) { 489 if (bind_pipeline) {
479 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 490 cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
480 } 491 }
@@ -483,11 +494,16 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling) {
483 rescaling_data.data()); 494 rescaling_data.data());
484 if (update_rescaling) { 495 if (update_rescaling) {
485 const f32 config_down_factor{Settings::values.resolution_info.down_factor}; 496 const f32 config_down_factor{Settings::values.resolution_info.down_factor};
486 const f32 scale_down_factor{is_rescaling ? config_down_factor : 1.0f}; 497 const f32 scale_down_factor{is_rescaling ? config_down_factor : 2.0f};
487 cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS, 498 cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS,
488 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET, sizeof(scale_down_factor), 499 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET, sizeof(scale_down_factor),
489 &scale_down_factor); 500 &scale_down_factor);
490 } 501 }
502 if (uses_render_area) {
503 cmdbuf.PushConstants(*pipeline_layout, VK_SHADER_STAGE_ALL_GRAPHICS,
504 RENDERAREA_LAYOUT_OFFSET, sizeof(render_area_data),
505 &render_area_data);
506 }
491 if (!descriptor_set_layout) { 507 if (!descriptor_set_layout) {
492 return; 508 return;
493 } 509 }
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
index 85602592b..6bf577d25 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
@@ -62,6 +62,7 @@ class Device;
62class PipelineStatistics; 62class PipelineStatistics;
63class RenderPassCache; 63class RenderPassCache;
64class RescalingPushConstant; 64class RescalingPushConstant;
65class RenderAreaPushConstant;
65class Scheduler; 66class Scheduler;
66class UpdateDescriptorQueue; 67class UpdateDescriptorQueue;
67 68
@@ -119,7 +120,8 @@ private:
119 template <typename Spec> 120 template <typename Spec>
120 void ConfigureImpl(bool is_indexed); 121 void ConfigureImpl(bool is_indexed);
121 122
122 void ConfigureDraw(const RescalingPushConstant& rescaling); 123 void ConfigureDraw(const RescalingPushConstant& rescaling,
124 const RenderAreaPushConstant& render_are);
123 125
124 void MakePipeline(VkRenderPass render_pass); 126 void MakePipeline(VkRenderPass render_pass);
125 127
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index d94dbf873..5af3c930b 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -683,6 +683,22 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
683 if (!state_tracker.TouchViewports()) { 683 if (!state_tracker.TouchViewports()) {
684 return; 684 return;
685 } 685 }
686 if (!regs.viewport_transform_enabled) {
687 const auto x = static_cast<float>(regs.render_area.x);
688 const auto y = static_cast<float>(regs.render_area.y);
689 const auto width = static_cast<float>(regs.render_area.width);
690 const auto height = static_cast<float>(regs.render_area.height);
691 VkViewport viewport{
692 .x = x,
693 .y = y,
694 .width = width != 0.0f ? width : 1.0f,
695 .height = height != 0.0f ? height : 1.0f,
696 .minDepth = 0.0f,
697 .maxDepth = 1.0f,
698 };
699 scheduler.Record([viewport](vk::CommandBuffer cmdbuf) { cmdbuf.SetViewport(0, viewport); });
700 return;
701 }
686 const bool is_rescaling{texture_cache.IsRescaling()}; 702 const bool is_rescaling{texture_cache.IsRescaling()};
687 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; 703 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
688 const std::array viewports{ 704 const std::array viewports{
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index fbabb3219..63bcf9337 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -188,6 +188,8 @@ void GenericEnvironment::Serialize(std::ofstream& file) const {
188 .write(reinterpret_cast<const char*>(&start_address), sizeof(start_address)) 188 .write(reinterpret_cast<const char*>(&start_address), sizeof(start_address))
189 .write(reinterpret_cast<const char*>(&cached_lowest), sizeof(cached_lowest)) 189 .write(reinterpret_cast<const char*>(&cached_lowest), sizeof(cached_lowest))
190 .write(reinterpret_cast<const char*>(&cached_highest), sizeof(cached_highest)) 190 .write(reinterpret_cast<const char*>(&cached_highest), sizeof(cached_highest))
191 .write(reinterpret_cast<const char*>(&viewport_transform_state),
192 sizeof(viewport_transform_state))
191 .write(reinterpret_cast<const char*>(&stage), sizeof(stage)) 193 .write(reinterpret_cast<const char*>(&stage), sizeof(stage))
192 .write(reinterpret_cast<const char*>(code.data()), code_size); 194 .write(reinterpret_cast<const char*>(code.data()), code_size);
193 for (const auto& [key, type] : texture_types) { 195 for (const auto& [key, type] : texture_types) {
@@ -309,6 +311,12 @@ Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) {
309 handle); 311 handle);
310} 312}
311 313
314u32 GraphicsEnvironment::ReadViewportTransformState() {
315 const auto& regs{maxwell3d->regs};
316 viewport_transform_state = regs.viewport_transform_enabled;
317 return viewport_transform_state;
318}
319
312ComputeEnvironment::ComputeEnvironment(Tegra::Engines::KeplerCompute& kepler_compute_, 320ComputeEnvironment::ComputeEnvironment(Tegra::Engines::KeplerCompute& kepler_compute_,
313 Tegra::MemoryManager& gpu_memory_, GPUVAddr program_base_, 321 Tegra::MemoryManager& gpu_memory_, GPUVAddr program_base_,
314 u32 start_address_) 322 u32 start_address_)
@@ -340,6 +348,10 @@ Shader::TextureType ComputeEnvironment::ReadTextureType(u32 handle) {
340 return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, handle); 348 return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, qmd.linked_tsc != 0, handle);
341} 349}
342 350
351u32 ComputeEnvironment::ReadViewportTransformState() {
352 return viewport_transform_state;
353}
354
343void FileEnvironment::Deserialize(std::ifstream& file) { 355void FileEnvironment::Deserialize(std::ifstream& file) {
344 u64 code_size{}; 356 u64 code_size{};
345 u64 num_texture_types{}; 357 u64 num_texture_types{};
@@ -352,6 +364,7 @@ void FileEnvironment::Deserialize(std::ifstream& file) {
352 .read(reinterpret_cast<char*>(&start_address), sizeof(start_address)) 364 .read(reinterpret_cast<char*>(&start_address), sizeof(start_address))
353 .read(reinterpret_cast<char*>(&read_lowest), sizeof(read_lowest)) 365 .read(reinterpret_cast<char*>(&read_lowest), sizeof(read_lowest))
354 .read(reinterpret_cast<char*>(&read_highest), sizeof(read_highest)) 366 .read(reinterpret_cast<char*>(&read_highest), sizeof(read_highest))
367 .read(reinterpret_cast<char*>(&viewport_transform_state), sizeof(viewport_transform_state))
355 .read(reinterpret_cast<char*>(&stage), sizeof(stage)); 368 .read(reinterpret_cast<char*>(&stage), sizeof(stage));
356 code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64))); 369 code = std::make_unique<u64[]>(Common::DivCeil(code_size, sizeof(u64)));
357 file.read(reinterpret_cast<char*>(code.get()), code_size); 370 file.read(reinterpret_cast<char*>(code.get()), code_size);
@@ -409,6 +422,10 @@ Shader::TextureType FileEnvironment::ReadTextureType(u32 handle) {
409 return it->second; 422 return it->second;
410} 423}
411 424
425u32 FileEnvironment::ReadViewportTransformState() {
426 return viewport_transform_state;
427}
428
412u32 FileEnvironment::LocalMemorySize() const { 429u32 FileEnvironment::LocalMemorySize() const {
413 return local_memory_size; 430 return local_memory_size;
414} 431}
diff --git a/src/video_core/shader_environment.h b/src/video_core/shader_environment.h
index 8b3b8e9f5..a05833f38 100644
--- a/src/video_core/shader_environment.h
+++ b/src/video_core/shader_environment.h
@@ -85,6 +85,8 @@ protected:
85 u32 cached_highest = 0; 85 u32 cached_highest = 0;
86 u32 initial_offset = 0; 86 u32 initial_offset = 0;
87 87
88 u32 viewport_transform_state = 1;
89
88 bool has_unbound_instructions = false; 90 bool has_unbound_instructions = false;
89}; 91};
90 92
@@ -102,6 +104,8 @@ public:
102 104
103 Shader::TextureType ReadTextureType(u32 handle) override; 105 Shader::TextureType ReadTextureType(u32 handle) override;
104 106
107 u32 ReadViewportTransformState() override;
108
105private: 109private:
106 Tegra::Engines::Maxwell3D* maxwell3d{}; 110 Tegra::Engines::Maxwell3D* maxwell3d{};
107 size_t stage_index{}; 111 size_t stage_index{};
@@ -120,6 +124,8 @@ public:
120 124
121 Shader::TextureType ReadTextureType(u32 handle) override; 125 Shader::TextureType ReadTextureType(u32 handle) override;
122 126
127 u32 ReadViewportTransformState() override;
128
123private: 129private:
124 Tegra::Engines::KeplerCompute* kepler_compute{}; 130 Tegra::Engines::KeplerCompute* kepler_compute{};
125}; 131};
@@ -143,6 +149,8 @@ public:
143 149
144 [[nodiscard]] Shader::TextureType ReadTextureType(u32 handle) override; 150 [[nodiscard]] Shader::TextureType ReadTextureType(u32 handle) override;
145 151
152 [[nodiscard]] u32 ReadViewportTransformState() override;
153
146 [[nodiscard]] u32 LocalMemorySize() const override; 154 [[nodiscard]] u32 LocalMemorySize() const override;
147 155
148 [[nodiscard]] u32 SharedMemorySize() const override; 156 [[nodiscard]] u32 SharedMemorySize() const override;
@@ -164,6 +172,7 @@ private:
164 u32 read_lowest{}; 172 u32 read_lowest{};
165 u32 read_highest{}; 173 u32 read_highest{};
166 u32 initial_offset{}; 174 u32 initial_offset{};
175 u32 viewport_transform_state = 1;
167}; 176};
168 177
169void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs, 178void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs,