|
|
@ -25,9 +25,24 @@ bool IsInputArray(Stage stage) { |
|
|
stage == Stage::TessellationEval; |
|
|
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) : ""; |
|
|
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
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
|
|
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, |
|
|
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 u32 element{static_cast<u32>(attr) % 4}; |
|
|
const char swizzle{"xyzw"[element]}; |
|
|
const char swizzle{"xyzw"[element]}; |
|
|
if (IR::IsGeneric(attr)) { |
|
|
if (IR::IsGeneric(attr)) { |
|
|
const u32 index{IR::GenericAttributeIndex(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; |
|
|
return; |
|
|
} |
|
|
} |
|
|
switch (attr) { |
|
|
switch (attr) { |
|
|
@ -150,6 +165,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, |
|
|
case Stage::VertexB: |
|
|
case Stage::VertexB: |
|
|
ctx.AddF32("{}=gl_Position.{};", inst, swizzle); |
|
|
ctx.AddF32("{}=gl_Position.{};", inst, swizzle); |
|
|
break; |
|
|
break; |
|
|
|
|
|
case Stage::TessellationEval: |
|
|
|
|
|
ctx.AddF32("{}=gl_TessCoord.{};", inst, swizzle); |
|
|
|
|
|
break; |
|
|
|
|
|
case Stage::TessellationControl: |
|
|
case Stage::Geometry: |
|
|
case Stage::Geometry: |
|
|
ctx.AddF32("{}=gl_in[{}].gl_Position.{};", inst, vertex, swizzle); |
|
|
ctx.AddF32("{}=gl_in[{}].gl_Position.{};", inst, vertex, swizzle); |
|
|
break; |
|
|
break; |
|
|
@ -173,6 +192,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, |
|
|
case IR::Attribute::FrontFace: |
|
|
case IR::Attribute::FrontFace: |
|
|
ctx.AddF32("{}=intBitsToFloat(gl_FrontFacing?-1:0);", inst); |
|
|
ctx.AddF32("{}=intBitsToFloat(gl_FrontFacing?-1:0);", inst); |
|
|
break; |
|
|
break; |
|
|
|
|
|
case IR::Attribute::TessellationEvaluationPointU: |
|
|
|
|
|
case IR::Attribute::TessellationEvaluationPointV: |
|
|
|
|
|
ctx.AddF32("{}=gl_TessCoord.{};", inst, swizzle); |
|
|
|
|
|
break; |
|
|
default: |
|
|
default: |
|
|
fmt::print("Get attribute {}", attr); |
|
|
fmt::print("Get attribute {}", attr); |
|
|
throw NotImplementedException("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]}; |
|
|
const char swizzle{"xyzw"[element]}; |
|
|
if (IR::IsGeneric(attr)) { |
|
|
if (IR::IsGeneric(attr)) { |
|
|
const u32 index{IR::GenericAttributeIndex(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; |
|
|
return; |
|
|
} |
|
|
} |
|
|
switch (attr) { |
|
|
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) { |
|
|
void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, std::string_view value) { |
|
|
const char swizzle{"xyzw"[component]}; |
|
|
const char swizzle{"xyzw"[component]}; |
|
|
ctx.Add("frag_color{}.{}={};", index, swizzle, value); |
|
|
ctx.Add("frag_color{}.{}={};", index, swizzle, value); |
|
|
|