diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp')
-rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp | 69 |
1 files changed, 65 insertions, 4 deletions
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 28e89a0a6..5c56477bf 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 @@ -25,9 +25,24 @@ bool IsInputArray(Stage stage) { stage == Stage::TessellationEval; } -std::string VertexIndex(EmitContext& ctx, std::string_view vertex) { +std::string InputVertexIndex(EmitContext& ctx, std::string_view vertex) { return IsInputArray(ctx.stage) ? fmt::format("[{}]", vertex) : ""; } + +bool IsOutputArray(Stage stage) { + return stage == Stage::Geometry || stage == Stage::TessellationControl; +} + +std::string OutputVertexIndex(EmitContext& ctx, std::string_view vertex) { + switch (ctx.stage) { + case Stage::Geometry: + return fmt::format("[{}]", vertex); + case Stage::TessellationControl: + return "[gl_InvocationID]"; + default: + return ""; + } +} } // namespace void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, @@ -132,12 +147,12 @@ void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding } void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, - [[maybe_unused]] std::string_view vertex) { + std::string_view vertex) { const u32 element{static_cast<u32>(attr) % 4}; const char swizzle{"xyzw"[element]}; if (IR::IsGeneric(attr)) { const u32 index{IR::GenericAttributeIndex(attr)}; - ctx.AddF32("{}=in_attr{}{}.{};", inst, index, VertexIndex(ctx, vertex), swizzle); + ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle); return; } switch (attr) { @@ -150,6 +165,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, case Stage::VertexB: ctx.AddF32("{}=gl_Position.{};", inst, swizzle); break; + case Stage::TessellationEval: + ctx.AddF32("{}=gl_TessCoord.{};", inst, swizzle); + break; + case Stage::TessellationControl: case Stage::Geometry: ctx.AddF32("{}=gl_in[{}].gl_Position.{};", inst, vertex, swizzle); break; @@ -173,6 +192,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, case IR::Attribute::FrontFace: ctx.AddF32("{}=intBitsToFloat(gl_FrontFacing?-1:0);", inst); break; + case IR::Attribute::TessellationEvaluationPointU: + case IR::Attribute::TessellationEvaluationPointV: + ctx.AddF32("{}=gl_TessCoord.{};", inst, swizzle); + break; default: fmt::print("Get attribute {}", attr); throw NotImplementedException("Get attribute {}", attr); @@ -185,7 +208,7 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val const char swizzle{"xyzw"[element]}; if (IR::IsGeneric(attr)) { const u32 index{IR::GenericAttributeIndex(attr)}; - ctx.Add("out_attr{}.{}={};", index, swizzle, value); + ctx.Add("out_attr{}{}.{}={};", index, OutputVertexIndex(ctx, vertex), swizzle, value); return; } switch (attr) { @@ -219,6 +242,44 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val } } +void EmitGetPatch([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, + [[maybe_unused]] IR::Patch patch) { + if (!IR::IsGeneric(patch)) { + throw NotImplementedException("Non-generic patch load"); + } + const u32 index{IR::GenericPatchIndex(patch)}; + const u32 element{IR::GenericPatchElement(patch)}; + const char swizzle{"xyzw"[element]}; + ctx.AddF32("{}=patch{}.{};", inst, index, swizzle); +} + +void EmitSetPatch(EmitContext& ctx, IR::Patch patch, std::string_view value) { + if (IR::IsGeneric(patch)) { + const u32 index{IR::GenericPatchIndex(patch)}; + const u32 element{IR::GenericPatchElement(patch)}; + ctx.Add("patch{}.{}={};", index, "xyzw"[element], value); + return; + } + switch (patch) { + case IR::Patch::TessellationLodLeft: + case IR::Patch::TessellationLodRight: + case IR::Patch::TessellationLodTop: + case IR::Patch::TessellationLodBottom: { + const u32 index{static_cast<u32>(patch) - u32(IR::Patch::TessellationLodLeft)}; + ctx.Add("gl_TessLevelOuter[{}]={};", index, value); + break; + } + case IR::Patch::TessellationLodInteriorU: + ctx.Add("gl_TessLevelInner[0]={};", value); + break; + case IR::Patch::TessellationLodInteriorV: + ctx.Add("gl_TessLevelInner[1]={};", value); + break; + default: + throw NotImplementedException("Patch {}", patch); + } +} + void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, std::string_view value) { const char swizzle{"xyzw"[component]}; ctx.Add("frag_color{}.{}={};", index, swizzle, value); |