diff options
| author | 2021-07-31 03:04:08 -0300 | |
|---|---|---|
| committer | 2021-11-16 22:11:29 +0100 | |
| commit | cfeb161c7ebf93bf6ac39e430fc998dc13abfc66 (patch) | |
| tree | e77411856862dbe91ef7edb475d19e64ff1db18b | |
| parent | gl_rasterizer: Properly scale viewports and scissors (diff) | |
| download | yuzu-cfeb161c7ebf93bf6ac39e430fc998dc13abfc66.tar.gz yuzu-cfeb161c7ebf93bf6ac39e430fc998dc13abfc66.tar.xz yuzu-cfeb161c7ebf93bf6ac39e430fc998dc13abfc66.zip | |
glsl/glasm: Pass and use scaling parameters in shaders
9 files changed, 51 insertions, 28 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index 4ce1c4f54..004658546 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -448,6 +448,9 @@ std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, I | |||
| 448 | header += fmt::format("SHARED_MEMORY {};", program.shared_memory_size); | 448 | header += fmt::format("SHARED_MEMORY {};", program.shared_memory_size); |
| 449 | header += fmt::format("SHARED shared_mem[]={{program.sharedmem}};"); | 449 | header += fmt::format("SHARED shared_mem[]={{program.sharedmem}};"); |
| 450 | } | 450 | } |
| 451 | if (program.info.uses_rescaling_uniform) { | ||
| 452 | header += "PARAM scaling[1]={program.local[0..0]};"; | ||
| 453 | } | ||
| 451 | header += "TEMP "; | 454 | header += "TEMP "; |
| 452 | for (size_t index = 0; index < ctx.reg_alloc.NumUsedRegisters(); ++index) { | 455 | for (size_t index = 0; index < ctx.reg_alloc.NumUsedRegisters(); ++index) { |
| 453 | header += fmt::format("R{},", index); | 456 | header += fmt::format("R{},", index); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp index 583ed3cf2..05e88cd97 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp | |||
| @@ -612,8 +612,9 @@ void EmitIsTextureScaled(EmitContext& ctx, IR::Inst& inst, const IR::Value& inde | |||
| 612 | if (!index.IsImmediate()) { | 612 | if (!index.IsImmediate()) { |
| 613 | throw NotImplementedException("Non-constant texture rescaling"); | 613 | throw NotImplementedException("Non-constant texture rescaling"); |
| 614 | } | 614 | } |
| 615 | UNIMPLEMENTED(); | 615 | ctx.Add("AND.U RC.x,scaling[0].x,{};" |
| 616 | ctx.Add("MOV.S {}.x,-1;", inst); | 616 | "SNE.S {},RC.x,0;", |
| 617 | 1u << index.U32(), ctx.reg_alloc.Define(inst)); | ||
| 617 | } | 618 | } |
| 618 | 619 | ||
| 619 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord, | 620 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord, |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp index 77ee6dc0e..c0f8ddcad 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp | |||
| @@ -211,7 +211,7 @@ void EmitYDirection(EmitContext& ctx, IR::Inst& inst) { | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) { | 213 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) { |
| 214 | ctx.Add("MOV.F {}.x,program.env[0].x;", inst); | 214 | ctx.Add("MOV.F {}.x,scaling[0].y;", inst); |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { | 217 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 7c9ed9159..97bd59302 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -394,7 +394,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 394 | } | 394 | } |
| 395 | } | 395 | } |
| 396 | if (info.uses_rescaling_uniform) { | 396 | if (info.uses_rescaling_uniform) { |
| 397 | header += "layout(location=0) uniform float down_factor;"; | 397 | header += "layout(location=0) uniform vec4 scaling;"; |
| 398 | } | 398 | } |
| 399 | DefineConstantBuffers(bindings); | 399 | DefineConstantBuffers(bindings); |
| 400 | DefineStorageBuffers(bindings); | 400 | DefineStorageBuffers(bindings); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index 3db3083f9..542a79230 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp | |||
| @@ -446,7 +446,7 @@ void EmitYDirection(EmitContext& ctx, IR::Inst& inst) { | |||
| 446 | } | 446 | } |
| 447 | 447 | ||
| 448 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) { | 448 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) { |
| 449 | ctx.AddF32("{}=down_factor;", inst); | 449 | ctx.AddF32("{}=scaling.y;", inst); |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, std::string_view word_offset) { | 452 | void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, std::string_view word_offset) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 099e0160b..82b6f0d77 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -616,8 +616,8 @@ void EmitIsTextureScaled(EmitContext& ctx, IR::Inst& inst, const IR::Value& inde | |||
| 616 | if (!index.IsImmediate()) { | 616 | if (!index.IsImmediate()) { |
| 617 | throw NotImplementedException("Non-constant texture rescaling"); | 617 | throw NotImplementedException("Non-constant texture rescaling"); |
| 618 | } | 618 | } |
| 619 | UNIMPLEMENTED(); | 619 | const u32 image_index{index.U32()}; |
| 620 | ctx.AddU1("{}=true;", inst); | 620 | ctx.AddU1("{}=(ftou(scaling.x)&{})!=0;", inst, 1u << image_index); |
| 621 | } | 621 | } |
| 622 | 622 | ||
| 623 | void EmitBindlessImageSampleImplicitLod(EmitContext&) { | 623 | void EmitBindlessImageSampleImplicitLod(EmitContext&) { |
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp index a11bd5a02..12093c3c4 100644 --- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp | |||
| @@ -148,14 +148,8 @@ void ComputePipeline::Configure() { | |||
| 148 | const f32 down_factor{is_rescaling ? config_down_factor : 1.0f}; | 148 | const f32 down_factor{is_rescaling ? config_down_factor : 1.0f}; |
| 149 | if (assembly_program.handle != 0) { | 149 | if (assembly_program.handle != 0) { |
| 150 | program_manager.BindComputeAssemblyProgram(assembly_program.handle); | 150 | program_manager.BindComputeAssemblyProgram(assembly_program.handle); |
| 151 | if (info.uses_rescaling_uniform) { | ||
| 152 | glProgramEnvParameter4fARB(GL_COMPUTE_PROGRAM_NV, 0, down_factor, 0.0f, 0.0f, 1.0f); | ||
| 153 | } | ||
| 154 | } else { | 151 | } else { |
| 155 | program_manager.BindComputeProgram(source_program.handle); | 152 | program_manager.BindComputeProgram(source_program.handle); |
| 156 | if (info.uses_rescaling_uniform) { | ||
| 157 | glProgramUniform1f(source_program.handle, 0, down_factor); | ||
| 158 | } | ||
| 159 | } | 153 | } |
| 160 | buffer_cache.UnbindComputeTextureBuffers(); | 154 | buffer_cache.UnbindComputeTextureBuffers(); |
| 161 | size_t texbuf_index{}; | 155 | size_t texbuf_index{}; |
| @@ -187,10 +181,16 @@ void ComputePipeline::Configure() { | |||
| 187 | texture_binding += num_texture_buffers; | 181 | texture_binding += num_texture_buffers; |
| 188 | image_binding += num_image_buffers; | 182 | image_binding += num_image_buffers; |
| 189 | 183 | ||
| 184 | u32 scaling_mask{}; | ||
| 190 | for (const auto& desc : info.texture_descriptors) { | 185 | for (const auto& desc : info.texture_descriptors) { |
| 191 | for (u32 index = 0; index < desc.count; ++index) { | 186 | for (u32 index = 0; index < desc.count; ++index) { |
| 192 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; | 187 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; |
| 193 | textures[texture_binding++] = image_view.Handle(desc.type); | 188 | textures[texture_binding] = image_view.Handle(desc.type); |
| 189 | if (True(texture_cache.GetImage(image_view.image_id).flags & | ||
| 190 | VideoCommon::ImageFlagBits::Rescaled)) { | ||
| 191 | scaling_mask |= 1u << texture_binding; | ||
| 192 | } | ||
| 193 | ++texture_binding; | ||
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | for (const auto& desc : info.image_descriptors) { | 196 | for (const auto& desc : info.image_descriptors) { |
| @@ -202,6 +202,15 @@ void ComputePipeline::Configure() { | |||
| 202 | images[image_binding++] = image_view.StorageView(desc.type, desc.format); | 202 | images[image_binding++] = image_view.StorageView(desc.type, desc.format); |
| 203 | } | 203 | } |
| 204 | } | 204 | } |
| 205 | if (info.uses_rescaling_uniform) { | ||
| 206 | const f32 float_scaling_mask{Common::BitCast<f32>(scaling_mask)}; | ||
| 207 | if (assembly_program.handle != 0) { | ||
| 208 | glProgramLocalParameter4fARB(GL_COMPUTE_PROGRAM_NV, 0, float_scaling_mask, 0.0f, 0.0f, | ||
| 209 | 0.0f); | ||
| 210 | } else { | ||
| 211 | glProgramUniform4f(source_program.handle, 0, float_scaling_mask, 0.0f, 0.0f, 0.0f); | ||
| 212 | } | ||
| 213 | } | ||
| 205 | if (texture_binding != 0) { | 214 | if (texture_binding != 0) { |
| 206 | ASSERT(texture_binding == sampler_binding); | 215 | ASSERT(texture_binding == sampler_binding); |
| 207 | glBindTextures(0, texture_binding, textures.data()); | 216 | glBindTextures(0, texture_binding, textures.data()); |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index 92fda9af0..01aa2897a 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | |||
| @@ -444,23 +444,11 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 444 | WaitForBuild(); | 444 | WaitForBuild(); |
| 445 | } | 445 | } |
| 446 | const bool use_assembly{assembly_programs[0].handle != 0}; | 446 | const bool use_assembly{assembly_programs[0].handle != 0}; |
| 447 | const bool is_rescaling{texture_cache.IsRescaling()}; | ||
| 448 | const f32 config_down_factor{Settings::values.resolution_info.down_factor}; | ||
| 449 | const f32 down_factor{is_rescaling ? config_down_factor : 1.0f}; | ||
| 450 | if (use_assembly) { | 447 | if (use_assembly) { |
| 451 | program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); | 448 | program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); |
| 452 | } else { | 449 | } else { |
| 453 | program_manager.BindSourcePrograms(source_programs); | 450 | program_manager.BindSourcePrograms(source_programs); |
| 454 | } | 451 | } |
| 455 | for (size_t stage = 0; stage < source_programs.size(); ++stage) { | ||
| 456 | if (stage_infos[stage].uses_rescaling_uniform) { | ||
| 457 | if (use_assembly) { | ||
| 458 | glProgramEnvParameter4fARB(AssemblyStage(stage), 0, down_factor, 0.0f, 0.0f, 1.0f); | ||
| 459 | } else { | ||
| 460 | glProgramUniform1f(source_programs[stage].handle, 0, down_factor); | ||
| 461 | } | ||
| 462 | } | ||
| 463 | } | ||
| 464 | const VideoCommon::ImageViewInOut* views_it{views.data()}; | 452 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 465 | GLsizei texture_binding = 0; | 453 | GLsizei texture_binding = 0; |
| 466 | GLsizei image_binding = 0; | 454 | GLsizei image_binding = 0; |
| @@ -476,11 +464,20 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 476 | views_it += num_texture_buffers[stage]; | 464 | views_it += num_texture_buffers[stage]; |
| 477 | views_it += num_image_buffers[stage]; | 465 | views_it += num_image_buffers[stage]; |
| 478 | 466 | ||
| 467 | u32 scaling_mask{}; | ||
| 468 | u32 stage_texture_binding{}; | ||
| 469 | |||
| 479 | const auto& info{stage_infos[stage]}; | 470 | const auto& info{stage_infos[stage]}; |
| 480 | for (const auto& desc : info.texture_descriptors) { | 471 | for (const auto& desc : info.texture_descriptors) { |
| 481 | for (u32 index = 0; index < desc.count; ++index) { | 472 | for (u32 index = 0; index < desc.count; ++index) { |
| 482 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; | 473 | ImageView& image_view{texture_cache.GetImageView((views_it++)->id)}; |
| 483 | textures[texture_binding++] = image_view.Handle(desc.type); | 474 | textures[texture_binding] = image_view.Handle(desc.type); |
| 475 | if (True(texture_cache.GetImage(image_view.image_id).flags & | ||
| 476 | VideoCommon::ImageFlagBits::Rescaled)) { | ||
| 477 | scaling_mask |= 1u << stage_texture_binding; | ||
| 478 | } | ||
| 479 | ++texture_binding; | ||
| 480 | ++stage_texture_binding; | ||
| 484 | } | 481 | } |
| 485 | } | 482 | } |
| 486 | for (const auto& desc : info.image_descriptors) { | 483 | for (const auto& desc : info.image_descriptors) { |
| @@ -492,6 +489,19 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 492 | images[image_binding++] = image_view.StorageView(desc.type, desc.format); | 489 | images[image_binding++] = image_view.StorageView(desc.type, desc.format); |
| 493 | } | 490 | } |
| 494 | } | 491 | } |
| 492 | if (info.uses_rescaling_uniform) { | ||
| 493 | const f32 float_scaling_mask{Common::BitCast<f32>(scaling_mask)}; | ||
| 494 | const bool is_rescaling{texture_cache.IsRescaling()}; | ||
| 495 | const f32 config_down_factor{Settings::values.resolution_info.down_factor}; | ||
| 496 | const f32 down_factor{is_rescaling ? config_down_factor : 1.0f}; | ||
| 497 | if (use_assembly) { | ||
| 498 | glProgramLocalParameter4fARB(AssemblyStage(stage), 0, float_scaling_mask, | ||
| 499 | down_factor, 0.0f, 0.0f); | ||
| 500 | } else { | ||
| 501 | glProgramUniform4f(source_programs[stage].handle, 0, float_scaling_mask, | ||
| 502 | down_factor, 0.0f, 0.0f); | ||
| 503 | } | ||
| 504 | } | ||
| 495 | }}; | 505 | }}; |
| 496 | if constexpr (Spec::enabled_stages[0]) { | 506 | if constexpr (Spec::enabled_stages[0]) { |
| 497 | prepare_stage(0); | 507 | prepare_stage(0); |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index e76ec522a..28c91b368 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -210,7 +210,7 @@ private: | |||
| 210 | GLenum gl_internal_format = GL_NONE; | 210 | GLenum gl_internal_format = GL_NONE; |
| 211 | GLenum gl_format = GL_NONE; | 211 | GLenum gl_format = GL_NONE; |
| 212 | GLenum gl_type = GL_NONE; | 212 | GLenum gl_type = GL_NONE; |
| 213 | TextureCacheRuntime* runtime; | 213 | TextureCacheRuntime* runtime{}; |
| 214 | }; | 214 | }; |
| 215 | 215 | ||
| 216 | class ImageView : public VideoCommon::ImageViewBase { | 216 | class ImageView : public VideoCommon::ImageViewBase { |