glsl: Implement legacy varyings

This commit is contained in:
ameerj 2021-06-12 20:14:56 -04:00
parent ff3de0fb6b
commit 6aa1bf7b6f
6 changed files with 81 additions and 8 deletions

View file

@ -200,6 +200,27 @@ std::string_view OutputPrimitive(OutputTopology 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) {
if (!StoresPerVertexAttributes(ctx.stage)) {
return;
@ -215,18 +236,34 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) {
ctx.stage != Stage::Geometry) {
header += "int gl_ViewportIndex;";
}
SetupLegacyOutPerVertex(ctx, header);
header += "};";
if (ctx.info.stores_viewport_index && ctx.stage == Stage::Geometry) {
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
EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_,
const RuntimeInfo& runtime_info_)
: info{program.info}, profile{profile_}, runtime_info{runtime_info_} {
header += "#pragma optionNV(fastmath off)\n";
SetupExtensions(header);
SetupExtensions();
stage = program.stage;
switch (program.stage) {
case Stage::VertexA:
@ -271,6 +308,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
break;
}
SetupOutPerVertex(*this, header);
SetupLegacyInPerFragment(*this, header);
for (size_t index = 0; index < info.input_generics.size(); ++index) {
const auto& generic{info.input_generics[index]};
if (generic.used) {
@ -306,7 +345,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
DefineConstants();
}
void EmitContext::SetupExtensions(std::string&) {
void EmitContext::SetupExtensions() {
if (profile.support_gl_texture_shadow_lod) {
header += "#extension GL_EXT_texture_shadow_lod : enable\n";
}

View file

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

View file

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

View file

@ -98,6 +98,10 @@ void GetCbuf16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, const
bit_offset);
}
}
u32 TexCoordIndex(IR::Attribute attr) {
return (static_cast<u32>(attr) - static_cast<u32>(IR::Attribute::FixedFncTexture0S)) / 4;
}
} // Anonymous namespace
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);
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) {
case IR::Attribute::PrimitiveId:
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) {
if (IR::IsGeneric(attr)) {
const u32 index{IR::GenericAttributeIndex(attr)};
const u32 element{IR::GenericAttributeElement(attr)};
const GenericElementInfo& info{ctx.output_generics.at(index).at(element)};
const u32 attr_element{IR::GenericAttributeElement(attr)};
const GenericElementInfo& info{ctx.output_generics.at(index).at(attr_element)};
const auto output_decorator{OutputVertexIndex(ctx)};
if (info.num_components == 1) {
ctx.Add("{}{}={};", info.name, output_decorator, value);
} 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);
}
return;
}
const u32 element{static_cast<u32>(attr) % 4};
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) {
case IR::Attribute::Layer:
if (ctx.stage != Stage::Geometry &&

View file

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

View file

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