diff options
| author | 2021-06-07 20:39:30 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:37 -0400 | |
| commit | c5422041134ed2645e7cd32152e36f9d04c66da3 (patch) | |
| tree | e417bbe88e598fd74dffc576c79427ce5d268cac /src/shader_recompiler/backend/glsl | |
| parent | glsl: Conditionally add GL_ARB_sparse_texture2 (diff) | |
| download | yuzu-c5422041134ed2645e7cd32152e36f9d04c66da3.tar.gz yuzu-c5422041134ed2645e7cd32152e36f9d04c66da3.tar.xz yuzu-c5422041134ed2645e7cd32152e36f9d04c66da3.zip | |
glsl: Implement indexed attribute loads
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
5 files changed, 64 insertions, 29 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index d6b3c7aba..ed0955da0 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -104,8 +104,22 @@ std::string_view SamplerType(TextureType type, bool is_depth) { | |||
| 104 | 104 | ||
| 105 | std::string_view ImageType(TextureType type) { | 105 | std::string_view ImageType(TextureType type) { |
| 106 | switch (type) { | 106 | switch (type) { |
| 107 | case TextureType::Color1D: | ||
| 108 | return "uimage1D"; | ||
| 109 | case TextureType::ColorArray1D: | ||
| 110 | return "uimage1DArray"; | ||
| 107 | case TextureType::Color2D: | 111 | case TextureType::Color2D: |
| 108 | return "uimage2D"; | 112 | return "uimage2D"; |
| 113 | case TextureType::ColorArray2D: | ||
| 114 | return "uimage2DArray"; | ||
| 115 | case TextureType::Color3D: | ||
| 116 | return "uimage3D"; | ||
| 117 | case TextureType::ColorCube: | ||
| 118 | return "uimageCube"; | ||
| 119 | case TextureType::ColorArrayCube: | ||
| 120 | return "uimageCubeArray"; | ||
| 121 | case TextureType::Buffer: | ||
| 122 | return "uimageBuffer"; | ||
| 109 | default: | 123 | default: |
| 110 | throw NotImplementedException("Image type: {}", type); | 124 | throw NotImplementedException("Image type: {}", type); |
| 111 | } | 125 | } |
| @@ -250,6 +264,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 250 | break; | 264 | break; |
| 251 | case Stage::Fragment: | 265 | case Stage::Fragment: |
| 252 | stage_name = "fs"; | 266 | stage_name = "fs"; |
| 267 | position_name = "gl_FragCoord"; | ||
| 253 | break; | 268 | break; |
| 254 | case Stage::Compute: | 269 | case Stage::Compute: |
| 255 | stage_name = "cs"; | 270 | stage_name = "cs"; |
| @@ -449,6 +464,33 @@ void EmitContext::DefineHelperFunctions() { | |||
| 449 | if (info.uses_global_memory) { | 464 | if (info.uses_global_memory) { |
| 450 | header += DefineGlobalMemoryFunctions(); | 465 | header += DefineGlobalMemoryFunctions(); |
| 451 | } | 466 | } |
| 467 | if (info.loads_indexed_attributes) { | ||
| 468 | const bool is_array{stage == Stage::Geometry}; | ||
| 469 | const auto vertex_arg{is_array ? ",uint vertex" : ""}; | ||
| 470 | std::string func{ | ||
| 471 | fmt::format("float IndexedAttrLoad(int offset{}){{int base_index=offset>>2;uint " | ||
| 472 | "masked_index=uint(base_index)&3u;switch(base_index>>2){{", | ||
| 473 | vertex_arg)}; | ||
| 474 | if (info.loads_position) { | ||
| 475 | func += fmt::format("case {}:", static_cast<u32>(IR::Attribute::PositionX) >> 2); | ||
| 476 | const auto position_idx{is_array ? "gl_in[vertex]." : ""}; | ||
| 477 | func += fmt::format("return {}{}[masked_index];", position_idx, position_name); | ||
| 478 | } | ||
| 479 | const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2; | ||
| 480 | for (u32 i = 0; i < info.input_generics.size(); ++i) { | ||
| 481 | if (!info.input_generics[i].used) { | ||
| 482 | continue; | ||
| 483 | } | ||
| 484 | const auto vertex_idx{is_array ? "[vertex]" : ""}; | ||
| 485 | func += fmt::format("case {}:", base_attribute_value + i); | ||
| 486 | func += fmt::format("return in_attr{}{}[masked_index];", i, vertex_idx); | ||
| 487 | } | ||
| 488 | func += "default: return 0.0;}}"; | ||
| 489 | header += func; | ||
| 490 | } | ||
| 491 | if (info.stores_indexed_attributes) { | ||
| 492 | // TODO | ||
| 493 | } | ||
| 452 | } | 494 | } |
| 453 | 495 | ||
| 454 | std::string EmitContext::DefineGlobalMemoryFunctions() { | 496 | std::string EmitContext::DefineGlobalMemoryFunctions() { |
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h index 9bdca184f..dce99586e 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.h +++ b/src/shader_recompiler/backend/glsl/emit_context.h | |||
| @@ -150,6 +150,7 @@ public: | |||
| 150 | 150 | ||
| 151 | Stage stage{}; | 151 | Stage stage{}; |
| 152 | std::string_view stage_name = "invalid"; | 152 | std::string_view stage_name = "invalid"; |
| 153 | std::string_view position_name = "gl_Position"; | ||
| 153 | 154 | ||
| 154 | std::vector<u32> texture_buffer_bindings; | 155 | std::vector<u32> texture_buffer_bindings; |
| 155 | std::vector<u32> image_buffer_bindings; | 156 | std::vector<u32> image_buffer_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 cfcdd45a2..d09187ea7 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 | |||
| @@ -206,26 +206,12 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, | |||
| 206 | case IR::Attribute::PositionX: | 206 | case IR::Attribute::PositionX: |
| 207 | case IR::Attribute::PositionY: | 207 | case IR::Attribute::PositionY: |
| 208 | case IR::Attribute::PositionZ: | 208 | case IR::Attribute::PositionZ: |
| 209 | case IR::Attribute::PositionW: | 209 | case IR::Attribute::PositionW: { |
| 210 | switch (ctx.stage) { | 210 | const bool is_array{IsInputArray(ctx.stage)}; |
| 211 | case Stage::VertexA: | 211 | const auto input_decorator{is_array ? fmt::format("gl_in[{}].", vertex) : ""}; |
| 212 | case Stage::VertexB: | 212 | ctx.AddF32("{}={}{}.{};", inst, input_decorator, ctx.position_name, swizzle); |
| 213 | ctx.AddF32("{}=gl_Position.{};", inst, swizzle); | ||
| 214 | break; | ||
| 215 | case Stage::TessellationEval: | ||
| 216 | ctx.AddF32("{}=gl_TessCoord.{};", inst, swizzle); | ||
| 217 | break; | ||
| 218 | case Stage::TessellationControl: | ||
| 219 | case Stage::Geometry: | ||
| 220 | ctx.AddF32("{}=gl_in[{}].gl_Position.{};", inst, vertex, swizzle); | ||
| 221 | break; | ||
| 222 | case Stage::Fragment: | ||
| 223 | ctx.AddF32("{}=gl_FragCoord.{};", inst, swizzle); | ||
| 224 | break; | ||
| 225 | default: | ||
| 226 | throw NotImplementedException("Get Position for stage {}", ctx.stage); | ||
| 227 | } | ||
| 228 | break; | 213 | break; |
| 214 | } | ||
| 229 | case IR::Attribute::PointSpriteS: | 215 | case IR::Attribute::PointSpriteS: |
| 230 | case IR::Attribute::PointSpriteT: | 216 | case IR::Attribute::PointSpriteT: |
| 231 | ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle); | 217 | ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle); |
| @@ -311,6 +297,20 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val | |||
| 311 | } | 297 | } |
| 312 | } | 298 | } |
| 313 | 299 | ||
| 300 | void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, std::string_view offset, | ||
| 301 | std::string_view vertex) { | ||
| 302 | const bool is_array{ctx.stage == Stage::Geometry}; | ||
| 303 | const auto vertex_arg{is_array ? fmt::format(",{}", vertex) : ""}; | ||
| 304 | ctx.AddF32("{}=IndexedAttrLoad(int({}){});", inst, offset, vertex_arg); | ||
| 305 | } | ||
| 306 | |||
| 307 | void EmitSetAttributeIndexed([[maybe_unused]] EmitContext& ctx, | ||
| 308 | [[maybe_unused]] std::string_view offset, | ||
| 309 | [[maybe_unused]] std::string_view value, | ||
| 310 | [[maybe_unused]] std::string_view vertex) { | ||
| 311 | NotImplemented(); | ||
| 312 | } | ||
| 313 | |||
| 314 | void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch) { | 314 | void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch) { |
| 315 | if (!IR::IsGeneric(patch)) { | 315 | if (!IR::IsGeneric(patch)) { |
| 316 | throw NotImplementedException("Non-generic patch load"); | 316 | throw NotImplementedException("Non-generic patch load"); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index 90dcfcef7..12094139f 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h | |||
| @@ -72,7 +72,8 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, | |||
| 72 | std::string_view vertex); | 72 | std::string_view vertex); |
| 73 | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value, | 73 | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value, |
| 74 | std::string_view vertex); | 74 | std::string_view vertex); |
| 75 | void EmitGetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view vertex); | 75 | void EmitGetAttributeIndexed(EmitContext& ctx, IR::Inst& inst, std::string_view offset, |
| 76 | std::string_view vertex); | ||
| 76 | void EmitSetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view value, | 77 | void EmitSetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view value, |
| 77 | std::string_view vertex); | 78 | std::string_view vertex); |
| 78 | void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch); | 79 | void EmitGetPatch(EmitContext& ctx, IR::Inst& inst, IR::Patch patch); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp index 37e4b453b..b292db9d4 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -124,15 +124,6 @@ void EmitGetIndirectBranchVariable(EmitContext& ctx) { | |||
| 124 | NotImplemented(); | 124 | NotImplemented(); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | void EmitGetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view vertex) { | ||
| 128 | NotImplemented(); | ||
| 129 | } | ||
| 130 | |||
| 131 | void EmitSetAttributeIndexed(EmitContext& ctx, std::string_view offset, std::string_view value, | ||
| 132 | std::string_view vertex) { | ||
| 133 | NotImplemented(); | ||
| 134 | } | ||
| 135 | |||
| 136 | void EmitSetSampleMask(EmitContext& ctx, std::string_view value) { | 127 | void EmitSetSampleMask(EmitContext& ctx, std::string_view value) { |
| 137 | NotImplemented(); | 128 | NotImplemented(); |
| 138 | } | 129 | } |