diff options
Diffstat (limited to 'src')
12 files changed, 62 insertions, 41 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index bd40356a1..14c009535 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -327,11 +327,12 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 327 | 327 | ||
| 328 | for (size_t index = 0; index < info.input_generics.size(); ++index) { | 328 | for (size_t index = 0; index < info.input_generics.size(); ++index) { |
| 329 | const auto& generic{info.input_generics[index]}; | 329 | const auto& generic{info.input_generics[index]}; |
| 330 | if (generic.used) { | 330 | if (!generic.used || !runtime_info.previous_stage_stores_generic[index]) { |
| 331 | header += fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, | 331 | continue; |
| 332 | InterpDecorator(generic.interpolation), index, | ||
| 333 | InputArrayDecorator(stage)); | ||
| 334 | } | 332 | } |
| 333 | header += | ||
| 334 | fmt::format("layout(location={}){}in vec4 in_attr{}{};", index, | ||
| 335 | InterpDecorator(generic.interpolation), index, InputArrayDecorator(stage)); | ||
| 335 | } | 336 | } |
| 336 | for (size_t index = 0; index < info.uses_patches.size(); ++index) { | 337 | for (size_t index = 0; index < info.uses_patches.size(); ++index) { |
| 337 | if (!info.uses_patches[index]) { | 338 | if (!info.uses_patches[index]) { |
| @@ -349,10 +350,10 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 349 | } | 350 | } |
| 350 | } | 351 | } |
| 351 | for (size_t index = 0; index < info.stores_generics.size(); ++index) { | 352 | for (size_t index = 0; index < info.stores_generics.size(); ++index) { |
| 352 | // TODO: Properly resolve attribute issues | 353 | if (!info.stores_generics[index]) { |
| 353 | if (info.stores_generics[index] || StageInitializesVaryings()) { | 354 | continue; |
| 354 | DefineGenericOutput(index, program.invocations); | ||
| 355 | } | 355 | } |
| 356 | DefineGenericOutput(index, program.invocations); | ||
| 356 | } | 357 | } |
| 357 | DefineConstantBuffers(bindings); | 358 | DefineConstantBuffers(bindings); |
| 358 | DefineStorageBuffers(bindings); | 359 | DefineStorageBuffers(bindings); |
| @@ -362,17 +363,6 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 362 | DefineConstants(); | 363 | DefineConstants(); |
| 363 | } | 364 | } |
| 364 | 365 | ||
| 365 | bool EmitContext::StageInitializesVaryings() const noexcept { | ||
| 366 | switch (stage) { | ||
| 367 | case Stage::VertexA: | ||
| 368 | case Stage::VertexB: | ||
| 369 | case Stage::Geometry: | ||
| 370 | return true; | ||
| 371 | default: | ||
| 372 | return false; | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | void EmitContext::SetupExtensions() { | 366 | void EmitContext::SetupExtensions() { |
| 377 | if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { | 367 | if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { |
| 378 | header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | 368 | header += "#extension GL_EXT_texture_shadow_lod : enable\n"; |
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h index 4a50556e1..8fa87c02c 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.h +++ b/src/shader_recompiler/backend/glsl/emit_context.h | |||
| @@ -136,8 +136,6 @@ public: | |||
| 136 | code += '\n'; | 136 | code += '\n'; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | [[nodiscard]] bool StageInitializesVaryings() const noexcept; | ||
| 140 | |||
| 141 | std::string header; | 139 | std::string header; |
| 142 | std::string code; | 140 | std::string code; |
| 143 | VarAlloc var_alloc; | 141 | VarAlloc var_alloc; |
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 a241d18fe..663ff3753 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 | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" |
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | #include "shader_recompiler/profile.h" | 10 | #include "shader_recompiler/profile.h" |
| 11 | #include "shader_recompiler/runtime_info.h" | ||
| 11 | 12 | ||
| 12 | namespace Shader::Backend::GLSL { | 13 | namespace Shader::Backend::GLSL { |
| 13 | namespace { | 14 | namespace { |
| @@ -179,6 +180,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, | |||
| 179 | const char swizzle{"xyzw"[element]}; | 180 | const char swizzle{"xyzw"[element]}; |
| 180 | if (IR::IsGeneric(attr)) { | 181 | if (IR::IsGeneric(attr)) { |
| 181 | const u32 index{IR::GenericAttributeIndex(attr)}; | 182 | const u32 index{IR::GenericAttributeIndex(attr)}; |
| 183 | if (!ctx.runtime_info.previous_stage_stores_generic[index]) { | ||
| 184 | ctx.AddF32("{}=0.f;", inst, attr); | ||
| 185 | return; | ||
| 186 | } | ||
| 182 | ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle); | 187 | ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle); |
| 183 | return; | 188 | return; |
| 184 | } | 189 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp index f8e8aaa67..1a2d3dcea 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp | |||
| @@ -12,11 +12,12 @@ | |||
| 12 | 12 | ||
| 13 | namespace Shader::Backend::GLSL { | 13 | namespace Shader::Backend::GLSL { |
| 14 | namespace { | 14 | namespace { |
| 15 | void InitializeVaryings(EmitContext& ctx) { | 15 | void InitializeOutputVaryings(EmitContext& ctx) { |
| 16 | ctx.Add("gl_Position=vec4(0,0,0,1);"); | 16 | if (ctx.stage == Stage::VertexB || ctx.stage == Stage::Geometry) { |
| 17 | // TODO: Properly resolve attribute issues | 17 | ctx.Add("gl_Position=vec4(0,0,0,1);"); |
| 18 | for (size_t index = 0; index < ctx.info.stores_generics.size() / 2; ++index) { | 18 | } |
| 19 | if (!ctx.info.stores_generics[index]) { | 19 | for (size_t index = 0; index < 16; ++index) { |
| 20 | if (ctx.info.stores_generics[index]) { | ||
| 20 | ctx.Add("out_attr{}=vec4(0,0,0,1);", index); | 21 | ctx.Add("out_attr{}=vec4(0,0,0,1);", index); |
| 21 | } | 22 | } |
| 22 | } | 23 | } |
| @@ -56,9 +57,8 @@ void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& | |||
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | void EmitPrologue(EmitContext& ctx) { | 59 | void EmitPrologue(EmitContext& ctx) { |
| 59 | if (ctx.StageInitializesVaryings()) { | 60 | InitializeOutputVaryings(ctx); |
| 60 | InitializeVaryings(ctx); | 61 | |
| 61 | } | ||
| 62 | if (ctx.stage == Stage::Fragment && ctx.profile.need_declared_frag_colors) { | 62 | if (ctx.stage == Stage::Fragment && ctx.profile.need_declared_frag_colors) { |
| 63 | for (size_t index = 0; index < ctx.info.stores_frag_color.size(); ++index) { | 63 | for (size_t index = 0; index < ctx.info.stores_frag_color.size(); ++index) { |
| 64 | if (ctx.info.stores_frag_color[index]) { | 64 | if (ctx.info.stores_frag_color[index]) { |
| @@ -73,7 +73,7 @@ void EmitEpilogue(EmitContext&) {} | |||
| 73 | 73 | ||
| 74 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { | 74 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { |
| 75 | ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream)); | 75 | ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream)); |
| 76 | InitializeVaryings(ctx); | 76 | InitializeOutputVaryings(ctx); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { | 79 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 007b79650..612d087ad 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -1209,6 +1209,9 @@ void EmitContext::DefineInputs(const Info& info) { | |||
| 1209 | tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); | 1209 | tess_coord = DefineInput(*this, F32[3], false, spv::BuiltIn::TessCoord); |
| 1210 | } | 1210 | } |
| 1211 | for (size_t index = 0; index < info.input_generics.size(); ++index) { | 1211 | for (size_t index = 0; index < info.input_generics.size(); ++index) { |
| 1212 | if (!runtime_info.previous_stage_stores_generic[index]) { | ||
| 1213 | continue; | ||
| 1214 | } | ||
| 1212 | const InputVarying generic{info.input_generics[index]}; | 1215 | const InputVarying generic{info.input_generics[index]}; |
| 1213 | if (!generic.used) { | 1216 | if (!generic.used) { |
| 1214 | continue; | 1217 | continue; |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 42fff74e3..4ac1fbae5 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -286,7 +286,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { | |||
| 286 | if (IR::IsGeneric(attr)) { | 286 | if (IR::IsGeneric(attr)) { |
| 287 | const u32 index{IR::GenericAttributeIndex(attr)}; | 287 | const u32 index{IR::GenericAttributeIndex(attr)}; |
| 288 | const std::optional<AttrInfo> type{AttrTypes(ctx, index)}; | 288 | const std::optional<AttrInfo> type{AttrTypes(ctx, index)}; |
| 289 | if (!type) { | 289 | if (!type || !ctx.runtime_info.previous_stage_stores_generic[index]) { |
| 290 | // Attribute is disabled | 290 | // Attribute is disabled |
| 291 | return ctx.Const(0.0f); | 291 | return ctx.Const(0.0f); |
| 292 | } | 292 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 5250509c1..ed8729fca 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp | |||
| @@ -192,7 +192,9 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b | |||
| 192 | result.local_memory_size = std::max(vertex_a.local_memory_size, vertex_b.local_memory_size); | 192 | result.local_memory_size = std::max(vertex_a.local_memory_size, vertex_b.local_memory_size); |
| 193 | for (size_t index = 0; index < 32; ++index) { | 193 | for (size_t index = 0; index < 32; ++index) { |
| 194 | result.info.input_generics[index].used |= vertex_b.info.input_generics[index].used; | 194 | result.info.input_generics[index].used |= vertex_b.info.input_generics[index].used; |
| 195 | result.info.stores_generics[index] |= vertex_b.info.stores_generics[index]; | 195 | if (vertex_b.info.stores_generics[index]) { |
| 196 | result.info.stores_generics[index] = true; | ||
| 197 | } | ||
| 196 | } | 198 | } |
| 197 | Optimization::JoinTextureInfo(result.info, vertex_b.info); | 199 | Optimization::JoinTextureInfo(result.info, vertex_b.info); |
| 198 | Optimization::JoinStorageInfo(result.info, vertex_b.info); | 200 | Optimization::JoinStorageInfo(result.info, vertex_b.info); |
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp index 47933df97..bab32b58b 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -79,7 +79,7 @@ void GetAttribute(Info& info, IR::Attribute attr) { | |||
| 79 | 79 | ||
| 80 | void SetAttribute(Info& info, IR::Attribute attr) { | 80 | void SetAttribute(Info& info, IR::Attribute attr) { |
| 81 | if (IR::IsGeneric(attr)) { | 81 | if (IR::IsGeneric(attr)) { |
| 82 | info.stores_generics.at(IR::GenericAttributeIndex(attr)) = true; | 82 | info.stores_generics[IR::GenericAttributeIndex(attr)] = true; |
| 83 | return; | 83 | return; |
| 84 | } | 84 | } |
| 85 | if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) { | 85 | if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) { |
| @@ -956,7 +956,9 @@ void GatherInfoFromHeader(Environment& env, Info& info) { | |||
| 956 | } | 956 | } |
| 957 | if (info.stores_indexed_attributes) { | 957 | if (info.stores_indexed_attributes) { |
| 958 | for (size_t i = 0; i < info.stores_generics.size(); i++) { | 958 | for (size_t i = 0; i < info.stores_generics.size(); i++) { |
| 959 | info.stores_generics[i] |= header.vtg.IsOutputGenericVectorActive(i); | 959 | if (header.vtg.IsOutputGenericVectorActive(i)) { |
| 960 | info.stores_generics[i] = true; | ||
| 961 | } | ||
| 960 | } | 962 | } |
| 961 | info.stores_clip_distance |= header.vtg.omap_systemc.clip_distances != 0; | 963 | info.stores_clip_distance |= header.vtg.omap_systemc.clip_distances != 0; |
| 962 | info.stores_position |= header.vtg.omap_systemb.position != 0; | 964 | info.stores_position |= header.vtg.omap_systemb.position != 0; |
diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h index d4b047b4d..63fe2afaf 100644 --- a/src/shader_recompiler/runtime_info.h +++ b/src/shader_recompiler/runtime_info.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <bitset> | ||
| 8 | #include <optional> | 9 | #include <optional> |
| 9 | #include <vector> | 10 | #include <vector> |
| 10 | 11 | ||
| @@ -59,6 +60,8 @@ struct TransformFeedbackVarying { | |||
| 59 | 60 | ||
| 60 | struct RuntimeInfo { | 61 | struct RuntimeInfo { |
| 61 | std::array<AttributeType, 32> generic_input_types{}; | 62 | std::array<AttributeType, 32> generic_input_types{}; |
| 63 | std::bitset<32> previous_stage_stores_generic{}; | ||
| 64 | |||
| 62 | bool convert_depth_mode{}; | 65 | bool convert_depth_mode{}; |
| 63 | bool force_early_z{}; | 66 | bool force_early_z{}; |
| 64 | 67 | ||
| @@ -72,11 +75,12 @@ struct RuntimeInfo { | |||
| 72 | std::optional<CompareFunction> alpha_test_func; | 75 | std::optional<CompareFunction> alpha_test_func; |
| 73 | float alpha_test_reference{}; | 76 | float alpha_test_reference{}; |
| 74 | 77 | ||
| 75 | // Static y negate value | 78 | /// Static Y negate value |
| 76 | bool y_negate{}; | 79 | bool y_negate{}; |
| 77 | // Use storage buffers instead of global pointers on GLASM | 80 | /// Use storage buffers instead of global pointers on GLASM |
| 78 | bool glasm_use_storage_buffers{}; | 81 | bool glasm_use_storage_buffers{}; |
| 79 | 82 | ||
| 83 | /// Transform feedback state for each varying | ||
| 80 | std::vector<TransformFeedbackVarying> xfb_varyings; | 84 | std::vector<TransformFeedbackVarying> xfb_varyings; |
| 81 | }; | 85 | }; |
| 82 | 86 | ||
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h index e9ebc16a4..a20e15d2e 100644 --- a/src/shader_recompiler/shader_info.h +++ b/src/shader_recompiler/shader_info.h | |||
| @@ -140,7 +140,7 @@ struct Info { | |||
| 140 | bool stores_sample_mask{}; | 140 | bool stores_sample_mask{}; |
| 141 | bool stores_frag_depth{}; | 141 | bool stores_frag_depth{}; |
| 142 | 142 | ||
| 143 | std::array<bool, 32> stores_generics{}; | 143 | std::bitset<32> stores_generics{}; |
| 144 | bool stores_layer{}; | 144 | bool stores_layer{}; |
| 145 | bool stores_viewport_index{}; | 145 | bool stores_viewport_index{}; |
| 146 | bool stores_point_size{}; | 146 | bool stores_point_size{}; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index b459397f5..b8b24dd3d 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -58,8 +58,15 @@ auto MakeSpan(Container& container) { | |||
| 58 | 58 | ||
| 59 | Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, | 59 | Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, |
| 60 | const Shader::IR::Program& program, | 60 | const Shader::IR::Program& program, |
| 61 | const Shader::IR::Program* previous_program, | ||
| 61 | bool glasm_use_storage_buffers, bool use_assembly_shaders) { | 62 | bool glasm_use_storage_buffers, bool use_assembly_shaders) { |
| 62 | Shader::RuntimeInfo info; | 63 | Shader::RuntimeInfo info; |
| 64 | if (previous_program) { | ||
| 65 | info.previous_stage_stores_generic = previous_program->info.stores_generics; | ||
| 66 | } else { | ||
| 67 | // Mark all stores as available | ||
| 68 | info.previous_stage_stores_generic.flip(); | ||
| 69 | } | ||
| 63 | switch (program.stage) { | 70 | switch (program.stage) { |
| 64 | case Shader::Stage::VertexB: | 71 | case Shader::Stage::VertexB: |
| 65 | case Shader::Stage::Geometry: | 72 | case Shader::Stage::Geometry: |
| @@ -400,6 +407,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||
| 400 | OGLProgram source_program; | 407 | OGLProgram source_program; |
| 401 | std::array<std::string, 5> sources; | 408 | std::array<std::string, 5> sources; |
| 402 | Shader::Backend::Bindings binding; | 409 | Shader::Backend::Bindings binding; |
| 410 | Shader::IR::Program* previous_program{}; | ||
| 403 | const bool use_glasm{device.UseAssemblyShaders()}; | 411 | const bool use_glasm{device.UseAssemblyShaders()}; |
| 404 | const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; | 412 | const size_t first_index = uses_vertex_a && uses_vertex_b ? 1 : 0; |
| 405 | for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) { | 413 | for (size_t index = first_index; index < Maxwell::MaxShaderProgram; ++index) { |
| @@ -413,12 +421,13 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( | |||
| 413 | infos[stage_index] = &program.info; | 421 | infos[stage_index] = &program.info; |
| 414 | 422 | ||
| 415 | const auto runtime_info{ | 423 | const auto runtime_info{ |
| 416 | MakeRuntimeInfo(key, program, glasm_use_storage_buffers, use_glasm)}; | 424 | MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm)}; |
| 417 | if (use_glasm) { | 425 | if (use_glasm) { |
| 418 | sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); | 426 | sources[stage_index] = EmitGLASM(profile, runtime_info, program, binding); |
| 419 | } else { | 427 | } else { |
| 420 | sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); | 428 | sources[stage_index] = EmitGLSL(profile, runtime_info, program, binding); |
| 421 | } | 429 | } |
| 430 | previous_program = &program; | ||
| 422 | } | 431 | } |
| 423 | auto* const thread_worker{build_in_parallel ? workers.get() : nullptr}; | 432 | auto* const thread_worker{build_in_parallel ? workers.get() : nullptr}; |
| 424 | VideoCore::ShaderNotify* const notify{build_in_parallel ? &shader_notify : nullptr}; | 433 | VideoCore::ShaderNotify* const notify{build_in_parallel ? &shader_notify : nullptr}; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 72e6f4207..dc028306a 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -90,7 +90,7 @@ Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp compariso | |||
| 90 | return {}; | 90 | return {}; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribute& attr) { | 93 | Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribute& attr) { |
| 94 | if (attr.enabled == 0) { | 94 | if (attr.enabled == 0) { |
| 95 | return Shader::AttributeType::Disabled; | 95 | return Shader::AttributeType::Disabled; |
| 96 | } | 96 | } |
| @@ -124,9 +124,15 @@ Shader::AttributeType AttributeType(const FixedPipelineState& state, size_t inde | |||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineCacheKey& key, | 126 | Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineCacheKey& key, |
| 127 | const Shader::IR::Program& program) { | 127 | const Shader::IR::Program& program, |
| 128 | const Shader::IR::Program* previous_program) { | ||
| 128 | Shader::RuntimeInfo info; | 129 | Shader::RuntimeInfo info; |
| 129 | 130 | if (previous_program) { | |
| 131 | info.previous_stage_stores_generic = previous_program->info.stores_generics; | ||
| 132 | } else { | ||
| 133 | // Mark all stores as available | ||
| 134 | info.previous_stage_stores_generic.flip(); | ||
| 135 | } | ||
| 130 | const Shader::Stage stage{program.stage}; | 136 | const Shader::Stage stage{program.stage}; |
| 131 | const bool has_geometry{key.unique_hashes[4] != 0}; | 137 | const bool has_geometry{key.unique_hashes[4] != 0}; |
| 132 | const bool gl_ndc{key.state.ndc_minus_one_to_one != 0}; | 138 | const bool gl_ndc{key.state.ndc_minus_one_to_one != 0}; |
| @@ -499,6 +505,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | |||
| 499 | std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; | 505 | std::array<const Shader::Info*, Maxwell::MaxShaderStage> infos{}; |
| 500 | std::array<vk::ShaderModule, Maxwell::MaxShaderStage> modules; | 506 | std::array<vk::ShaderModule, Maxwell::MaxShaderStage> modules; |
| 501 | 507 | ||
| 508 | const Shader::IR::Program* previous_stage{}; | ||
| 502 | Shader::Backend::Bindings binding; | 509 | Shader::Backend::Bindings binding; |
| 503 | for (size_t index = uses_vertex_a && uses_vertex_b ? 1 : 0; index < Maxwell::MaxShaderProgram; | 510 | for (size_t index = uses_vertex_a && uses_vertex_b ? 1 : 0; index < Maxwell::MaxShaderProgram; |
| 504 | ++index) { | 511 | ++index) { |
| @@ -511,7 +518,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | |||
| 511 | const size_t stage_index{index - 1}; | 518 | const size_t stage_index{index - 1}; |
| 512 | infos[stage_index] = &program.info; | 519 | infos[stage_index] = &program.info; |
| 513 | 520 | ||
| 514 | const Shader::RuntimeInfo runtime_info{MakeRuntimeInfo(key, program)}; | 521 | const Shader::RuntimeInfo runtime_info{MakeRuntimeInfo(key, program, previous_stage)}; |
| 515 | const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)}; | 522 | const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)}; |
| 516 | device.SaveShader(code); | 523 | device.SaveShader(code); |
| 517 | modules[stage_index] = BuildShader(device, code); | 524 | modules[stage_index] = BuildShader(device, code); |
| @@ -519,6 +526,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | |||
| 519 | const std::string name{fmt::format("Shader {:016x}", key.unique_hashes[index])}; | 526 | const std::string name{fmt::format("Shader {:016x}", key.unique_hashes[index])}; |
| 520 | modules[stage_index].SetObjectNameEXT(name.c_str()); | 527 | modules[stage_index].SetObjectNameEXT(name.c_str()); |
| 521 | } | 528 | } |
| 529 | previous_stage = &program; | ||
| 522 | } | 530 | } |
| 523 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; | 531 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; |
| 524 | VideoCore::ShaderNotify* const notify{build_in_parallel ? &shader_notify : nullptr}; | 532 | VideoCore::ShaderNotify* const notify{build_in_parallel ? &shader_notify : nullptr}; |