glsl: Implement legacy varyings
This commit is contained in:
		| @@ -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"; | ||||
|     } | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 ""; | ||||
|   | ||||
| @@ -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 && | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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{}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user