summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-08-01 18:57:45 -0300
committerGravatar Fernando Sahmkow2021-11-16 22:11:29 +0100
commite66d5b88a6f1c2d85c5cd8e351c6ed52c96a0ecf (patch)
tree0107548906df0b9d42e89451489be6a54ed71bf3 /src/video_core
parentshader: Properly blacklist and scale image loads (diff)
downloadyuzu-e66d5b88a6f1c2d85c5cd8e351c6ed52c96a0ecf.tar.gz
yuzu-e66d5b88a6f1c2d85c5cd8e351c6ed52c96a0ecf.tar.xz
yuzu-e66d5b88a6f1c2d85c5cd8e351c6ed52c96a0ecf.zip
shader: Properly scale image reads and add GL SPIR-V support
Thanks for everything!
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp24
-rw-r--r--src/video_core/renderer_vulkan/pipeline_helper.h22
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp3
5 files changed, 57 insertions, 26 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 187a28e4d..d4dd10bb6 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -5,6 +5,7 @@
5#include <algorithm> 5#include <algorithm>
6#include <span> 6#include <span>
7 7
8#include "shader_recompiler/backend/glasm/emit_glasm.h"
8#include "video_core/buffer_cache/buffer_cache.h" 9#include "video_core/buffer_cache/buffer_cache.h"
9#include "video_core/renderer_opengl/gl_buffer_cache.h" 10#include "video_core/renderer_opengl/gl_buffer_cache.h"
10#include "video_core/renderer_opengl/gl_device.h" 11#include "video_core/renderer_opengl/gl_device.h"
@@ -229,8 +230,10 @@ void BufferCacheRuntime::BindStorageBuffer(size_t stage, u32 binding_index, Buff
229 .padding = 0, 230 .padding = 0,
230 }; 231 };
231 buffer.MakeResident(is_written ? GL_READ_WRITE : GL_READ_ONLY); 232 buffer.MakeResident(is_written ? GL_READ_WRITE : GL_READ_ONLY);
232 glProgramLocalParametersI4uivNV(PROGRAM_LUT[stage], binding_index, 1, 233 glProgramLocalParametersI4uivNV(
233 reinterpret_cast<const GLuint*>(&ssbo)); 234 PROGRAM_LUT[stage],
235 Shader::Backend::GLASM::PROGRAM_LOCAL_PARAMETER_STORAGE_BUFFER_BASE + binding_index, 1,
236 reinterpret_cast<const GLuint*>(&ssbo));
234 } 237 }
235} 238}
236 239
@@ -250,8 +253,10 @@ void BufferCacheRuntime::BindComputeStorageBuffer(u32 binding_index, Buffer& buf
250 .padding = 0, 253 .padding = 0,
251 }; 254 };
252 buffer.MakeResident(is_written ? GL_READ_WRITE : GL_READ_ONLY); 255 buffer.MakeResident(is_written ? GL_READ_WRITE : GL_READ_ONLY);
253 glProgramLocalParametersI4uivNV(GL_COMPUTE_PROGRAM_NV, binding_index, 1, 256 glProgramLocalParametersI4uivNV(
254 reinterpret_cast<const GLuint*>(&ssbo)); 257 GL_COMPUTE_PROGRAM_NV,
258 Shader::Backend::GLASM::PROGRAM_LOCAL_PARAMETER_STORAGE_BUFFER_BASE + binding_index, 1,
259 reinterpret_cast<const GLuint*>(&ssbo));
255 } 260 }
256} 261}
257 262
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index 60c65047b..9af61c340 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -181,33 +181,40 @@ void ComputePipeline::Configure() {
181 texture_binding += num_texture_buffers; 181 texture_binding += num_texture_buffers;
182 image_binding += num_image_buffers; 182 image_binding += num_image_buffers;
183 183
184 u32 scaling_mask{}; 184 u32 texture_scaling_mask{};
185 for (const auto& desc : info.texture_descriptors) { 185 for (const auto& desc : info.texture_descriptors) {
186 for (u32 index = 0; index < desc.count; ++index) { 186 for (u32 index = 0; index < desc.count; ++index) {
187 ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; 187 ImageView& image_view{texture_cache.GetImageView((views_it++)->id)};
188 textures[texture_binding] = image_view.Handle(desc.type); 188 textures[texture_binding] = image_view.Handle(desc.type);
189 if (texture_cache.IsRescaling(image_view)) { 189 if (texture_cache.IsRescaling(image_view)) {
190 scaling_mask |= 1u << texture_binding; 190 texture_scaling_mask |= 1u << texture_binding;
191 } 191 }
192 ++texture_binding; 192 ++texture_binding;
193 } 193 }
194 } 194 }
195 u32 image_scaling_mask{};
195 for (const auto& desc : info.image_descriptors) { 196 for (const auto& desc : info.image_descriptors) {
196 for (u32 index = 0; index < desc.count; ++index) { 197 for (u32 index = 0; index < desc.count; ++index) {
197 ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; 198 ImageView& image_view{texture_cache.GetImageView((views_it++)->id)};
198 if (desc.is_written) { 199 if (desc.is_written) {
199 texture_cache.MarkModification(image_view.image_id); 200 texture_cache.MarkModification(image_view.image_id);
200 } 201 }
201 images[image_binding++] = image_view.StorageView(desc.type, desc.format); 202 images[image_binding] = image_view.StorageView(desc.type, desc.format);
203 if (texture_cache.IsRescaling(image_view)) {
204 image_scaling_mask |= 1u << image_binding;
205 }
206 ++image_binding;
202 } 207 }
203 } 208 }
204 if (info.uses_rescaling_uniform) { 209 if (info.uses_rescaling_uniform) {
205 const f32 float_scaling_mask{Common::BitCast<f32>(scaling_mask)}; 210 const f32 float_texture_scaling_mask{Common::BitCast<f32>(texture_scaling_mask)};
211 const f32 float_image_scaling_mask{Common::BitCast<f32>(image_scaling_mask)};
206 if (assembly_program.handle != 0) { 212 if (assembly_program.handle != 0) {
207 glProgramLocalParameter4fARB(GL_COMPUTE_PROGRAM_NV, 0, float_scaling_mask, 0.0f, 0.0f, 213 glProgramLocalParameter4fARB(GL_COMPUTE_PROGRAM_NV, 0, float_texture_scaling_mask,
208 0.0f); 214 float_image_scaling_mask, 0.0f, 0.0f);
209 } else { 215 } else {
210 glProgramUniform4f(source_program.handle, 0, float_scaling_mask, 0.0f, 0.0f, 0.0f); 216 glProgramUniform4f(source_program.handle, 0, float_texture_scaling_mask,
217 float_image_scaling_mask, 0.0f, 0.0f);
211 } 218 }
212 } 219 }
213 if (texture_binding != 0) { 220 if (texture_binding != 0) {
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 11559d6ce..f8495896c 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -464,8 +464,10 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
464 views_it += num_texture_buffers[stage]; 464 views_it += num_texture_buffers[stage];
465 views_it += num_image_buffers[stage]; 465 views_it += num_image_buffers[stage];
466 466
467 u32 scaling_mask{}; 467 u32 texture_scaling_mask{};
468 u32 image_scaling_mask{};
468 u32 stage_texture_binding{}; 469 u32 stage_texture_binding{};
470 u32 stage_image_binding{};
469 471
470 const auto& info{stage_infos[stage]}; 472 const auto& info{stage_infos[stage]};
471 for (const auto& desc : info.texture_descriptors) { 473 for (const auto& desc : info.texture_descriptors) {
@@ -473,7 +475,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
473 ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; 475 ImageView& image_view{texture_cache.GetImageView((views_it++)->id)};
474 textures[texture_binding] = image_view.Handle(desc.type); 476 textures[texture_binding] = image_view.Handle(desc.type);
475 if (texture_cache.IsRescaling(image_view)) { 477 if (texture_cache.IsRescaling(image_view)) {
476 scaling_mask |= 1u << stage_texture_binding; 478 texture_scaling_mask |= 1u << stage_texture_binding;
477 } 479 }
478 ++texture_binding; 480 ++texture_binding;
479 ++stage_texture_binding; 481 ++stage_texture_binding;
@@ -485,20 +487,26 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
485 if (desc.is_written) { 487 if (desc.is_written) {
486 texture_cache.MarkModification(image_view.image_id); 488 texture_cache.MarkModification(image_view.image_id);
487 } 489 }
488 images[image_binding++] = image_view.StorageView(desc.type, desc.format); 490 images[image_binding] = image_view.StorageView(desc.type, desc.format);
491 if (texture_cache.IsRescaling(image_view)) {
492 image_scaling_mask |= 1u << stage_image_binding;
493 }
494 ++image_binding;
495 ++stage_image_binding;
489 } 496 }
490 } 497 }
491 if (info.uses_rescaling_uniform) { 498 if (info.uses_rescaling_uniform) {
492 const f32 float_scaling_mask{Common::BitCast<f32>(scaling_mask)}; 499 const f32 float_texture_scaling_mask{Common::BitCast<f32>(texture_scaling_mask)};
500 const f32 float_image_scaling_mask{Common::BitCast<f32>(image_scaling_mask)};
493 const bool is_rescaling{texture_cache.IsRescaling()}; 501 const bool is_rescaling{texture_cache.IsRescaling()};
494 const f32 config_down_factor{Settings::values.resolution_info.down_factor}; 502 const f32 config_down_factor{Settings::values.resolution_info.down_factor};
495 const f32 down_factor{is_rescaling ? config_down_factor : 1.0f}; 503 const f32 down_factor{is_rescaling ? config_down_factor : 1.0f};
496 if (use_assembly) { 504 if (use_assembly) {
497 glProgramLocalParameter4fARB(AssemblyStage(stage), 0, float_scaling_mask, 505 glProgramLocalParameter4fARB(AssemblyStage(stage), 0, float_texture_scaling_mask,
498 down_factor, 0.0f, 0.0f); 506 float_image_scaling_mask, down_factor, 0.0f);
499 } else { 507 } else {
500 glProgramUniform4f(source_programs[stage].handle, 0, float_scaling_mask, 508 glProgramUniform4f(source_programs[stage].handle, 0, float_texture_scaling_mask,
501 down_factor, 0.0f, 0.0f); 509 float_image_scaling_mask, down_factor, 0.0f);
502 } 510 }
503 } 511 }
504 }}; 512 }};
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h
index bce4220c6..85ae726d1 100644
--- a/src/video_core/renderer_vulkan/pipeline_helper.h
+++ b/src/video_core/renderer_vulkan/pipeline_helper.h
@@ -10,6 +10,7 @@
10 10
11#include "common/assert.h" 11#include "common/assert.h"
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "shader_recompiler/backend/spirv/emit_spirv.h"
13#include "shader_recompiler/shader_info.h" 14#include "shader_recompiler/shader_info.h"
14#include "video_core/renderer_vulkan/vk_texture_cache.h" 15#include "video_core/renderer_vulkan/vk_texture_cache.h"
15#include "video_core/renderer_vulkan/vk_update_descriptor.h" 16#include "video_core/renderer_vulkan/vk_update_descriptor.h"
@@ -20,7 +21,7 @@
20 21
21namespace Vulkan { 22namespace Vulkan {
22 23
23constexpr size_t MAX_RESCALING_WORDS = 4; 24using Shader::Backend::SPIRV::NUM_TEXTURE_AND_IMAGE_SCALING_WORDS;
24 25
25class DescriptorLayoutBuilder { 26class DescriptorLayoutBuilder {
26public: 27public:
@@ -74,7 +75,8 @@ public:
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 = (is_compute ? 0 : sizeof(f32)) + sizeof(std::array<u32, MAX_RESCALING_WORDS>), 78 .size = (is_compute ? 0 : sizeof(f32)) +
79 sizeof(std::array<u32, NUM_TEXTURE_AND_IMAGE_SCALING_WORDS>),
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,
@@ -146,14 +148,25 @@ public:
146 } 148 }
147 } 149 }
148 150
149 const std::array<u32, MAX_RESCALING_WORDS>& Data() const noexcept { 151 void PushImage(bool is_rescaled) noexcept {
152 *image_ptr |= is_rescaled ? image_bit : 0;
153 image_bit <<= 1;
154 if (image_bit == 0) {
155 image_bit = 1u;
156 ++image_ptr;
157 }
158 }
159
160 const std::array<u32, NUM_TEXTURE_AND_IMAGE_SCALING_WORDS>& Data() const noexcept {
150 return words; 161 return words;
151 } 162 }
152 163
153private: 164private:
154 std::array<u32, MAX_RESCALING_WORDS> words{}; 165 std::array<u32, NUM_TEXTURE_AND_IMAGE_SCALING_WORDS> words{};
155 u32* texture_ptr{words.data()}; 166 u32* texture_ptr{words.data()};
167 u32* image_ptr{words.data() + Shader::Backend::SPIRV::NUM_TEXTURE_SCALING_WORDS};
156 u32 texture_bit{1u}; 168 u32 texture_bit{1u};
169 u32 image_bit{1u};
157}; 170};
158 171
159inline void PushImageDescriptors(TextureCache& texture_cache, 172inline void PushImageDescriptors(TextureCache& texture_cache,
@@ -181,6 +194,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache,
181 } 194 }
182 const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)}; 195 const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)};
183 update_descriptor_queue.AddImage(vk_image_view); 196 update_descriptor_queue.AddImage(vk_image_view);
197 rescaling.PushImage(texture_cache.IsRescaling(image_view));
184 } 198 }
185 } 199 }
186} 200}
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 691ef0841..eb8b4e08b 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -139,9 +139,6 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
139 } else { 139 } else {
140 info.previous_stage_stores.mask.set(); 140 info.previous_stage_stores.mask.set();
141 } 141 }
142 for (const auto& stage : programs) {
143 info.num_textures += Shader::NumDescriptors(stage.info.texture_descriptors);
144 }
145 const Shader::Stage stage{program.stage}; 142 const Shader::Stage stage{program.stage};
146 const bool has_geometry{key.unique_hashes[4] != 0 && !programs[4].is_geometry_passthrough}; 143 const bool has_geometry{key.unique_hashes[4] != 0 && !programs[4].is_geometry_passthrough};
147 const bool gl_ndc{key.state.ndc_minus_one_to_one != 0}; 144 const bool gl_ndc{key.state.ndc_minus_one_to_one != 0};