glsl: Implement legacy varyings

master
ameerj 2021-06-12 20:14:56 +07:00
parent ff3de0fb6b
commit 6aa1bf7b6f
6 changed files with 81 additions and 8 deletions

@ -200,6 +200,27 @@ std::string_view OutputPrimitive(OutputTopology topology) {
throw InvalidArgument("Invalid output topology {}", topology); throw InvalidArgument("Invalid output topology {}", topology);
} }
void SetupLegacyOutPerVertex(EmitContext& ctx, std::string& header) {
if (!ctx.info.stores_legacy_varyings) {
return;
}
if (ctx.info.stores_fixed_fnc_textures) {
header += "vec4 gl_TexCoord[8];";
}
if (ctx.info.stores_color_front_diffuse) {
header += "vec4 gl_FrontColor;";
}
if (ctx.info.stores_color_front_specular) {
header += "vec4 gl_FrontSecondaryColor;";
}
if (ctx.info.stores_color_back_diffuse) {
header += "vec4 gl_BackColor;";
}
if (ctx.info.stores_color_back_specular) {
header += "vec4 gl_BackSecondaryColor;";
}
}
void SetupOutPerVertex(EmitContext& ctx, std::string& header) { void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
if (!StoresPerVertexAttributes(ctx.stage)) { if (!StoresPerVertexAttributes(ctx.stage)) {
return; return;
@ -215,18 +236,34 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
ctx.stage != Stage::Geometry) { ctx.stage != Stage::Geometry) {
header += "int gl_ViewportIndex;"; header += "int gl_ViewportIndex;";
} }
SetupLegacyOutPerVertex(ctx, header);
header += "};"; header += "};";
if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) { if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) {
header += "out int gl_ViewportIndex;"; header += "out int gl_ViewportIndex;";
} }
} }
void SetupLegacyInPerFragment(EmitContext& ctx, std::string& header) {
if (!ctx.info.loads_legacy_varyings) {
return;
}
header += "in gl_PerFragment{";
if (ctx.info.loads_fixed_fnc_textures) {
header += "vec4 gl_TexCoord[8];";
}
if (ctx.info.loads_color_front_diffuse) {
header += "vec4 gl_Color;";
}
header += "};";
}
} // Anonymous namespace } // Anonymous namespace
EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
const RuntimeInfo& runtime_info_) const RuntimeInfo& runtime_info_)
: info{program.info}, profile{profile_}, runtime_info{runtime_info_} { : info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
header += "#pragma optionNV(fastmath off)\n"; header += "#pragma optionNV(fastmath off)\n";
SetupExtensions(header); SetupExtensions();
stage = program.stage; stage = program.stage;
switch (program.stage) { switch (program.stage) {
case Stage::VertexA: case Stage::VertexA:
@ -271,6 +308,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
break; break;
} }
SetupOutPerVertex(*this, header); SetupOutPerVertex(*this, header);
SetupLegacyInPerFragment(*this, header);
for (size_t index = 0; index < info.input_generics.size(); ++index) { for (size_t index = 0; index < info.input_generics.size(); ++index) {
const auto& generic{info.input_generics[index]}; const auto& generic{info.input_generics[index]};
if (generic.used) { if (generic.used) {
@ -306,7 +345,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
DefineConstants(); DefineConstants();
} }
void EmitContext::SetupExtensions(std::string&) { void EmitContext::SetupExtensions() {
if (profile.support_gl_texture_shadow_lod) { if (profile.support_gl_texture_shadow_lod) {
header += "#extension GL_EXT_texture_shadow_lod : enable\n"; header += "#extension GL_EXT_texture_shadow_lod : enable\n";
} }

@ -157,7 +157,7 @@ public:
bool uses_cc_carry{}; bool uses_cc_carry{};
private: private:
void SetupExtensions(std::string& header); void SetupExtensions();
void DefineConstantBuffers(Bindings& bindings); void DefineConstantBuffers(Bindings& bindings);
void DefineStorageBuffers(Bindings& bindings); void DefineStorageBuffers(Bindings& bindings);
void DefineGenericOutput(size_t index, u32 invocations); void DefineGenericOutput(size_t index, u32 invocations);

@ -166,7 +166,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
} }
std::string GlslVersionSpecifier(const EmitContext& ctx) { std::string GlslVersionSpecifier(const EmitContext& ctx) {
if (ctx.uses_y_direction) { if (ctx.uses_y_direction || ctx.info.stores_legacy_varyings) {
return " compatibility"; return " compatibility";
} }
return ""; return "";

@ -98,6 +98,10 @@ void GetCbuf16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, const
bit_offset); bit_offset);
} }
} }
u32 TexCoordIndex(IR::Attribute attr) {
return (static_cast<u32>(attr) - static_cast<u32>(IR::Attribute::FixedFncTexture0S)) / 4;
}
} // Anonymous namespace } // Anonymous namespace
void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
@ -178,6 +182,17 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle); ctx.AddF32("{}=in_attr{}{}.{};", inst, index, InputVertexIndex(ctx, vertex), swizzle);
return; return;
} }
// GLSL only exposes 8 legacy texcoords
if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) {
// LOG_WARNING(..., "GLSL does not allow access to gl_TexCoord[{}]", TexCoordIndex(attr));
ctx.AddF32("{}=0.f;", inst);
return;
}
if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) {
const u32 index{TexCoordIndex(attr)};
ctx.AddF32("{}=gl_TexCoord[{}].{};", inst, index, swizzle);
return;
}
switch (attr) { switch (attr) {
case IR::Attribute::PrimitiveId: case IR::Attribute::PrimitiveId:
ctx.AddF32("{}=itof(gl_PrimitiveID);", inst); ctx.AddF32("{}=itof(gl_PrimitiveID);", inst);
@ -227,19 +242,29 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val
[[maybe_unused]] std::string_view vertex) { [[maybe_unused]] std::string_view vertex) {
if (IR::IsGeneric(attr)) { if (IR::IsGeneric(attr)) {
const u32 index{IR::GenericAttributeIndex(attr)}; const u32 index{IR::GenericAttributeIndex(attr)};
const u32 element{IR::GenericAttributeElement(attr)}; const u32 attr_element{IR::GenericAttributeElement(attr)};
const GenericElementInfo& info{ctx.output_generics.at(index).at(element)}; const GenericElementInfo& info{ctx.output_generics.at(index).at(attr_element)};
const auto output_decorator{OutputVertexIndex(ctx)}; const auto output_decorator{OutputVertexIndex(ctx)};
if (info.num_components == 1) { if (info.num_components == 1) {
ctx.Add("{}{}={};", info.name, output_decorator, value); ctx.Add("{}{}={};", info.name, output_decorator, value);
} else { } else {
const u32 index_element{element - info.first_element}; const u32 index_element{attr_element - info.first_element};
ctx.Add("{}{}.{}={};", info.name, output_decorator, "xyzw"[index_element], value); ctx.Add("{}{}.{}={};", info.name, output_decorator, "xyzw"[index_element], value);
} }
return; return;
} }
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]};
// GLSL only exposes 8 legacy texcoords
if (attr >= IR::Attribute::FixedFncTexture8S && attr <= IR::Attribute::FixedFncTexture9Q) {
// LOG_WARNING(..., "GLSL does not allow access to gl_TexCoord[{}]", TexCoordIndex(attr));
return;
}
if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture7Q) {
const u32 index{TexCoordIndex(attr)};
ctx.Add("gl_TexCoord[{}].{}={};", index, swizzle, value);
return;
}
switch (attr) { switch (attr) {
case IR::Attribute::Layer: case IR::Attribute::Layer:
if (ctx.stage != Stage::Geometry && if (ctx.stage != Stage::Geometry &&

@ -35,6 +35,7 @@ void GetAttribute(Info& info, IR::Attribute attr) {
} }
if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) { if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) {
info.loads_fixed_fnc_textures = true; info.loads_fixed_fnc_textures = true;
info.loads_legacy_varyings = true;
return; return;
} }
switch (attr) { switch (attr) {
@ -52,6 +53,7 @@ void GetAttribute(Info& info, IR::Attribute attr) {
case IR::Attribute::ColorFrontDiffuseB: case IR::Attribute::ColorFrontDiffuseB:
case IR::Attribute::ColorFrontDiffuseA: case IR::Attribute::ColorFrontDiffuseA:
info.loads_color_front_diffuse = true; info.loads_color_front_diffuse = true;
info.loads_legacy_varyings = true;
break; break;
case IR::Attribute::PointSpriteS: case IR::Attribute::PointSpriteS:
case IR::Attribute::PointSpriteT: case IR::Attribute::PointSpriteT:
@ -82,6 +84,7 @@ void SetAttribute(Info& info, IR::Attribute attr) {
} }
if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) { if (attr >= IR::Attribute::FixedFncTexture0S && attr <= IR::Attribute::FixedFncTexture9Q) {
info.stores_fixed_fnc_textures = true; info.stores_fixed_fnc_textures = true;
info.stores_legacy_varyings = true;
return; return;
} }
switch (attr) { switch (attr) {
@ -105,24 +108,28 @@ void SetAttribute(Info& info, IR::Attribute attr) {
case IR::Attribute::ColorFrontDiffuseB: case IR::Attribute::ColorFrontDiffuseB:
case IR::Attribute::ColorFrontDiffuseA: case IR::Attribute::ColorFrontDiffuseA:
info.stores_color_front_diffuse = true; info.stores_color_front_diffuse = true;
info.stores_legacy_varyings = true;
break; break;
case IR::Attribute::ColorFrontSpecularR: case IR::Attribute::ColorFrontSpecularR:
case IR::Attribute::ColorFrontSpecularG: case IR::Attribute::ColorFrontSpecularG:
case IR::Attribute::ColorFrontSpecularB: case IR::Attribute::ColorFrontSpecularB:
case IR::Attribute::ColorFrontSpecularA: case IR::Attribute::ColorFrontSpecularA:
info.stores_color_front_specular = true; info.stores_color_front_specular = true;
info.stores_legacy_varyings = true;
break; break;
case IR::Attribute::ColorBackDiffuseR: case IR::Attribute::ColorBackDiffuseR:
case IR::Attribute::ColorBackDiffuseG: case IR::Attribute::ColorBackDiffuseG:
case IR::Attribute::ColorBackDiffuseB: case IR::Attribute::ColorBackDiffuseB:
case IR::Attribute::ColorBackDiffuseA: case IR::Attribute::ColorBackDiffuseA:
info.stores_color_back_diffuse = true; info.stores_color_back_diffuse = true;
info.stores_legacy_varyings = true;
break; break;
case IR::Attribute::ColorBackSpecularR: case IR::Attribute::ColorBackSpecularR:
case IR::Attribute::ColorBackSpecularG: case IR::Attribute::ColorBackSpecularG:
case IR::Attribute::ColorBackSpecularB: case IR::Attribute::ColorBackSpecularB:
case IR::Attribute::ColorBackSpecularA: case IR::Attribute::ColorBackSpecularA:
info.stores_color_front_specular = true; info.stores_color_back_specular = true;
info.stores_legacy_varyings = true;
break; break;
case IR::Attribute::ClipDistance0: case IR::Attribute::ClipDistance0:
case IR::Attribute::ClipDistance1: case IR::Attribute::ClipDistance1:

@ -128,6 +128,7 @@ struct Info {
bool loads_instance_id{}; bool loads_instance_id{};
bool loads_vertex_id{}; bool loads_vertex_id{};
bool loads_front_face{}; bool loads_front_face{};
bool loads_legacy_varyings{};
bool loads_tess_coord{}; bool loads_tess_coord{};
@ -150,6 +151,7 @@ struct Info {
bool stores_clip_distance{}; bool stores_clip_distance{};
bool stores_fog_coordinate{}; bool stores_fog_coordinate{};
bool stores_viewport_mask{}; bool stores_viewport_mask{};
bool stores_legacy_varyings{};
bool stores_tess_level_outer{}; bool stores_tess_level_outer{};
bool stores_tess_level_inner{}; bool stores_tess_level_inner{};