glsl: Address Rodrigo's feedback
This commit is contained in:
		| @@ -13,7 +13,7 @@ u32 CbufIndex(size_t offset) { | |||||||
|     return (offset / 4) % 4; |     return (offset / 4) % 4; | ||||||
| } | } | ||||||
|  |  | ||||||
| char CbufSwizzle(size_t offset) { | char Swizzle(size_t offset) { | ||||||
|     return "xyzw"[CbufIndex(offset)]; |     return "xyzw"[CbufIndex(offset)]; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -341,8 +341,8 @@ void EmitContext::SetupExtensions(std::string&) { | |||||||
|             header += "#extension GL_NV_shader_thread_shuffle : enable\n"; |             header += "#extension GL_NV_shader_thread_shuffle : enable\n"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (info.stores_viewport_index && profile.support_viewport_index_layer_non_geometry && |     if ((info.stores_viewport_index || info.stores_layer) && | ||||||
|         stage != Stage::Geometry) { |         profile.support_viewport_index_layer_non_geometry && stage != Stage::Geometry) { | ||||||
|         header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; |         header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; | ||||||
|     } |     } | ||||||
|     if (info.uses_sparse_residency) { |     if (info.uses_sparse_residency) { | ||||||
| @@ -428,16 +428,16 @@ void EmitContext::DefineHelperFunctions() { | |||||||
|         header += "uint CasIncrement(uint op_a,uint op_b){return op_a>=op_b?0u:(op_a+1u);}"; |         header += "uint CasIncrement(uint op_a,uint op_b){return op_a>=op_b?0u:(op_a+1u);}"; | ||||||
|     } |     } | ||||||
|     if (info.uses_global_decrement || info.uses_shared_decrement) { |     if (info.uses_global_decrement || info.uses_shared_decrement) { | ||||||
|         header += "uint CasDecrement(uint op_a,uint " |         header += "uint CasDecrement(uint op_a,uint op_b){" | ||||||
|                   "op_b){return op_a==0||op_a>op_b?op_b:(op_a-1u);}"; |                   "return op_a==0||op_a>op_b?op_b:(op_a-1u);}"; | ||||||
|     } |     } | ||||||
|     if (info.uses_atomic_f32_add) { |     if (info.uses_atomic_f32_add) { | ||||||
|         header += "uint CasFloatAdd(uint op_a,float op_b){return " |         header += "uint CasFloatAdd(uint op_a,float op_b){" | ||||||
|                   "ftou(utof(op_a)+op_b);}"; |                   "return ftou(utof(op_a)+op_b);}"; | ||||||
|     } |     } | ||||||
|     if (info.uses_atomic_f32x2_add) { |     if (info.uses_atomic_f32x2_add) { | ||||||
|         header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " |         header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){" | ||||||
|                   "packHalf2x16(unpackHalf2x16(op_a)+op_b);}"; |                   "return packHalf2x16(unpackHalf2x16(op_a)+op_b);}"; | ||||||
|     } |     } | ||||||
|     if (info.uses_atomic_f32x2_min) { |     if (info.uses_atomic_f32x2_min) { | ||||||
|         header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " |         header += "uint CasFloatMin32x2(uint op_a,vec2 op_b){return " | ||||||
| @@ -476,9 +476,10 @@ void EmitContext::DefineHelperFunctions() { | |||||||
|                         "masked_index=uint(base_index)&3u;switch(base_index>>2){{", |                         "masked_index=uint(base_index)&3u;switch(base_index>>2){{", | ||||||
|                         vertex_arg)}; |                         vertex_arg)}; | ||||||
|         if (info.loads_position) { |         if (info.loads_position) { | ||||||
|             func += fmt::format("case {}:", static_cast<u32>(IR::Attribute::PositionX) >> 2); |  | ||||||
|             const auto position_idx{is_array ? "gl_in[vertex]." : ""}; |             const auto position_idx{is_array ? "gl_in[vertex]." : ""}; | ||||||
|             func += fmt::format("return {}{}[masked_index];", position_idx, position_name); |             func += fmt::format("case {}:return {}{}[masked_index];", | ||||||
|  |                                 static_cast<u32>(IR::Attribute::PositionX) >> 2, position_idx, | ||||||
|  |                                 position_name); | ||||||
|         } |         } | ||||||
|         const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2; |         const u32 base_attribute_value = static_cast<u32>(IR::Attribute::Generic0X) >> 2; | ||||||
|         for (u32 i = 0; i < info.input_generics.size(); ++i) { |         for (u32 i = 0; i < info.input_generics.size(); ++i) { | ||||||
| @@ -486,8 +487,8 @@ void EmitContext::DefineHelperFunctions() { | |||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             const auto vertex_idx{is_array ? "[vertex]" : ""}; |             const auto vertex_idx{is_array ? "[vertex]" : ""}; | ||||||
|             func += fmt::format("case {}:", base_attribute_value + i); |             func += fmt::format("case {}:return in_attr{}{}[masked_index];", | ||||||
|             func += fmt::format("return in_attr{}{}[masked_index];", i, vertex_idx); |                                 base_attribute_value + i, i, vertex_idx); | ||||||
|         } |         } | ||||||
|         func += "default: return 0.0;}}"; |         func += "default: return 0.0;}}"; | ||||||
|         header += func; |         header += func; | ||||||
| @@ -508,8 +509,8 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { | |||||||
|         for (size_t i = 0; i < addr_xy.size(); ++i) { |         for (size_t i = 0; i < addr_xy.size(); ++i) { | ||||||
|             const auto addr_loc{ssbo.cbuf_offset + 4 * i}; |             const auto addr_loc{ssbo.cbuf_offset + 4 * i}; | ||||||
|             const auto size_loc{size_cbuf_offset + 4 * i}; |             const auto size_loc{size_cbuf_offset + 4 * i}; | ||||||
|             addr_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, addr_loc / 16, CbufSwizzle(addr_loc)); |             addr_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, addr_loc / 16, Swizzle(addr_loc)); | ||||||
|             size_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, size_loc / 16, CbufSwizzle(size_loc)); |             size_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, size_loc / 16, Swizzle(size_loc)); | ||||||
|         } |         } | ||||||
|         const auto addr_pack{fmt::format("packUint2x32(uvec2({},{}))", addr_xy[0], addr_xy[1])}; |         const auto addr_pack{fmt::format("packUint2x32(uvec2({},{}))", addr_xy[0], addr_xy[1])}; | ||||||
|         const auto addr_statment{fmt::format("uint64_t {}={};", ssbo_addr, addr_pack)}; |         const auto addr_statment{fmt::format("uint64_t {}={};", ssbo_addr, addr_pack)}; | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ public: | |||||||
|         const auto var_def{var_alloc.AddDefine(inst, type)}; |         const auto var_def{var_alloc.AddDefine(inst, type)}; | ||||||
|         if (var_def.empty()) { |         if (var_def.empty()) { | ||||||
|             // skip assigment. |             // skip assigment. | ||||||
|             code += fmt::format(&format_str[3], std::forward<Args>(args)...); |             code += fmt::format(format_str + 3, std::forward<Args>(args)...); | ||||||
|         } else { |         } else { | ||||||
|             code += fmt::format(format_str, var_def, std::forward<Args>(args)...); |             code += fmt::format(format_str, var_def, std::forward<Args>(args)...); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #include <ranges> | #include <ranges> | ||||||
| #include <string> | #include <string> | ||||||
|  |  | ||||||
|  | #include "common/alignment.h" | ||||||
| #include "shader_recompiler/backend/glsl/emit_context.h" | #include "shader_recompiler/backend/glsl/emit_context.h" | ||||||
| #include "shader_recompiler/backend/glsl/emit_glsl.h" | #include "shader_recompiler/backend/glsl/emit_glsl.h" | ||||||
| #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||||||
| @@ -159,8 +160,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { | |||||||
|                     ctx.var_alloc.Consume(node.data.repeat.cond)); |                     ctx.var_alloc.Consume(node.data.repeat.cond)); | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
|             throw NotImplementedException("AbstractSyntaxNode::Type {}", node.type); |             throw NotImplementedException("AbstractSyntaxNode Type {}", node.type); | ||||||
|             break; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -209,10 +209,11 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo& runtime_info, IR | |||||||
|     const std::string version{fmt::format("#version 450{}\n", GlslVersionSpecifier(ctx))}; |     const std::string version{fmt::format("#version 450{}\n", GlslVersionSpecifier(ctx))}; | ||||||
|     ctx.header.insert(0, version); |     ctx.header.insert(0, version); | ||||||
|     if (program.local_memory_size > 0) { |     if (program.local_memory_size > 0) { | ||||||
|         ctx.header += fmt::format("uint lmem[{}];", program.local_memory_size / 4); |         ctx.header += fmt::format("uint lmem[{}];", Common::AlignUp(program.local_memory_size, 4)); | ||||||
|     } |     } | ||||||
|     if (program.shared_memory_size > 0) { |     if (program.shared_memory_size > 0) { | ||||||
|         ctx.header += fmt::format("shared uint smem[{}];", program.shared_memory_size / 4); |         ctx.header += | ||||||
|  |             fmt::format("shared uint smem[{}];", Common::AlignUp(program.shared_memory_size, 4)); | ||||||
|     } |     } | ||||||
|     ctx.header += "\nvoid main(){\n"; |     ctx.header += "\nvoid main(){\n"; | ||||||
|     if (program.stage == Stage::VertexA || program.stage == Stage::VertexB) { |     if (program.stage == Stage::VertexA || program.stage == Stage::VertexB) { | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ void Alias(IR::Inst& inst, const IR::Value& value) { | |||||||
|     value_inst.DestructiveRemoveUsage(); |     value_inst.DestructiveRemoveUsage(); | ||||||
|     inst.SetDefinition(value_inst.Definition<Id>()); |     inst.SetDefinition(value_inst.Definition<Id>()); | ||||||
| } | } | ||||||
| } // namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) { | void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) { | ||||||
|     Alias(inst, value); |     Alias(inst, value); | ||||||
|   | |||||||
| @@ -13,8 +13,13 @@ namespace { | |||||||
| constexpr std::string_view SWIZZLE{"xyzw"}; | constexpr std::string_view SWIZZLE{"xyzw"}; | ||||||
| void CompositeInsert(EmitContext& ctx, std::string_view result, std::string_view composite, | void CompositeInsert(EmitContext& ctx, std::string_view result, std::string_view composite, | ||||||
|                      std::string_view object, u32 index) { |                      std::string_view object, u32 index) { | ||||||
|  |     if (result == composite) { | ||||||
|  |         // The result is aliased with the composite | ||||||
|  |         ctx.Add("{}.{}={};", composite, SWIZZLE[index], object); | ||||||
|  |     } else { | ||||||
|         ctx.Add("{}={};", result, composite); |         ctx.Add("{}={};", result, composite); | ||||||
|         ctx.Add("{}.{}={};", result, SWIZZLE[index], object); |         ctx.Add("{}.{}={};", result, SWIZZLE[index], object); | ||||||
|  |     } | ||||||
| } | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,12 +31,7 @@ std::string InputVertexIndex(EmitContext& ctx, std::string_view vertex) { | |||||||
| } | } | ||||||
|  |  | ||||||
| std::string OutputVertexIndex(EmitContext& ctx) { | std::string OutputVertexIndex(EmitContext& ctx) { | ||||||
|     switch (ctx.stage) { |     return ctx.stage == Stage::TessellationControl ? "[gl_InvocationID]" : ""; | ||||||
|     case Stage::TessellationControl: |  | ||||||
|         return "[gl_InvocationID]"; |  | ||||||
|     default: |  | ||||||
|         return ""; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| @@ -219,7 +214,11 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, | |||||||
|     case IR::Attribute::ColorFrontDiffuseG: |     case IR::Attribute::ColorFrontDiffuseG: | ||||||
|     case IR::Attribute::ColorFrontDiffuseB: |     case IR::Attribute::ColorFrontDiffuseB: | ||||||
|     case IR::Attribute::ColorFrontDiffuseA: |     case IR::Attribute::ColorFrontDiffuseA: | ||||||
|         ctx.AddF32("{}=gl_FrontMaterial.diffuse.{};", inst, swizzle); |         if (ctx.stage == Stage::Fragment) { | ||||||
|  |             ctx.AddF32("{}=gl_Color.{};", inst, swizzle); | ||||||
|  |         } else { | ||||||
|  |             ctx.AddF32("{}=gl_FrontColor.{};", inst, swizzle); | ||||||
|  |         } | ||||||
|         break; |         break; | ||||||
|     case IR::Attribute::PointSpriteS: |     case IR::Attribute::PointSpriteS: | ||||||
|     case IR::Attribute::PointSpriteT: |     case IR::Attribute::PointSpriteT: | ||||||
| @@ -300,28 +299,36 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val | |||||||
|     case IR::Attribute::ColorFrontDiffuseG: |     case IR::Attribute::ColorFrontDiffuseG: | ||||||
|     case IR::Attribute::ColorFrontDiffuseB: |     case IR::Attribute::ColorFrontDiffuseB: | ||||||
|     case IR::Attribute::ColorFrontDiffuseA: |     case IR::Attribute::ColorFrontDiffuseA: | ||||||
|         ctx.Add("gl_FrontMaterial.diffuse.{}={};", swizzle, value); |         if (ctx.stage == Stage::Fragment) { | ||||||
|  |             ctx.Add("gl_Color.{}={};", swizzle, value); | ||||||
|  |         } else { | ||||||
|  |             ctx.Add("gl_FrontColor.{}={};", swizzle, value); | ||||||
|  |         } | ||||||
|         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: | ||||||
|         ctx.Add("gl_FrontMaterial.specular.{}={};", swizzle, value); |         if (ctx.stage == Stage::Fragment) { | ||||||
|  |             ctx.Add("gl_SecondaryColor.{}={};", swizzle, value); | ||||||
|  |         } else { | ||||||
|  |             ctx.Add("gl_FrontSecondaryColor.{}={};", swizzle, value); | ||||||
|  |         } | ||||||
|         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: | ||||||
|         ctx.Add("gl_BackMaterial.diffuse.{}={};", swizzle, value); |         ctx.Add("gl_BackColor.{}={};", swizzle, value); | ||||||
|         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: | ||||||
|         ctx.Add("gl_BackMaterial.specular.{}={};", swizzle, value); |         ctx.Add("gl_BackSecondaryColor.{}={};", swizzle, value); | ||||||
|         break; |         break; | ||||||
|     case IR::Attribute::FogCoordinate: |     case IR::Attribute::FogCoordinate: | ||||||
|         ctx.Add("gl_FragCoord.x={};", value); |         ctx.Add("gl_FogFragCoord.x={};", value); | ||||||
|         break; |         break; | ||||||
|     case IR::Attribute::ClipDistance0: |     case IR::Attribute::ClipDistance0: | ||||||
|     case IR::Attribute::ClipDistance1: |     case IR::Attribute::ClipDistance1: | ||||||
|   | |||||||
| @@ -14,8 +14,7 @@ void EmitJoin(EmitContext&) { | |||||||
|     throw NotImplementedException("Join shouldn't be emitted"); |     throw NotImplementedException("Join shouldn't be emitted"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitDemoteToHelperInvocation(EmitContext& ctx, | void EmitDemoteToHelperInvocation(EmitContext& ctx) { | ||||||
|                                   [[maybe_unused]] std::string_view continue_label) { |  | ||||||
|     ctx.Add("discard;"); |     ctx.Add("discard;"); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ void EmitConvertS16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertS16F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertS16F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddS32("{}=int(float({}))&0xffff;", inst, value); |     ctx.AddS32("{}=(int({})&0xffff)|(bitfieldExtract(int({}),31,1)<<15);", inst, value, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertS16F64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertS16F64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -29,11 +29,11 @@ void EmitConvertS32F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertS32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertS32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddS32("{}=int(float({}));", inst, value); |     ctx.AddS32("{}=int({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertS32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertS32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddS32("{}=int(double({}));", inst, value); |     ctx.AddS32("{}=int({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertS64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertS64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -42,11 +42,11 @@ void EmitConvertS64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertS64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertS64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddS64("{}=int64_t(double(float({})));", inst, value); |     ctx.AddS64("{}=int64_t(double({}));", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertS64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertS64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddS64("{}=int64_t(double({}));", inst, value); |     ctx.AddS64("{}=int64_t({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertU16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -70,11 +70,11 @@ void EmitConvertU32F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddU32("{}=uint(float({}));", inst, value); |     ctx.AddU32("{}=uint({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertU32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddU32("{}=uint(double({}));", inst, value); |     ctx.AddU32("{}=uint({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertU64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -83,19 +83,19 @@ void EmitConvertU64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertU64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddU64("{}=uint64_t(float({}));", inst, value); |     ctx.AddU64("{}=uint64_t({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddU64("{}=uint64_t(double({}));", inst, value); |     ctx.AddU64("{}=uint64_t({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU64U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertU64U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddU64("{}=uint64_t(uint({}));", inst, value); |     ctx.AddU64("{}=uint64_t({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertU32U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertU32U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddU32("{}=uint(uint64_t({}));", inst, value); |     ctx.AddU32("{}=uint({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF16F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertF16F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -109,11 +109,11 @@ void EmitConvertF32F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF32("{}=float(double({}));", inst, value); |     ctx.AddF32("{}=float({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF64("{}=double(float({}));", inst, value); |     ctx.AddF64("{}=double({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF16S8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertF16S8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -171,7 +171,7 @@ void EmitConvertF32S32(EmitContext& ctx, IR::Inst& inst, std::string_view value) | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF32S64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF32S64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF32("{}=float(double(int64_t({})));", inst, value); |     ctx.AddF32("{}=float(int64_t({}));", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF32U8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertF32U8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -180,15 +180,15 @@ void EmitConvertF32U8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::In | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF32U16(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF32U16(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF32("{}=float(uint({}&0xffff));", inst, value); |     ctx.AddF32("{}=float({}&0xffff);", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF32U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF32U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF32("{}=float(uint({}));", inst, value); |     ctx.AddF32("{}=float({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF32U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF32U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF32("{}=float(double(uint64_t({})));", inst, value); |     ctx.AddF32("{}=float({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF64S8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | void EmitConvertF64S8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | ||||||
| @@ -220,11 +220,11 @@ void EmitConvertF64U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF64U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF64U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF64("{}=double(uint({}));", inst, value); |     ctx.AddF64("{}=double({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | ||||||
|     ctx.AddF64("{}=double(uint64_t({}));", inst, value); |     ctx.AddF64("{}=double({});", inst, value); | ||||||
| } | } | ||||||
|  |  | ||||||
| } // namespace Shader::Backend::GLSL | } // namespace Shader::Backend::GLSL | ||||||
|   | |||||||
| @@ -15,14 +15,13 @@ void Compare(EmitContext& ctx, IR::Inst& inst, std::string_view lhs, std::string | |||||||
|              std::string_view op, bool ordered) { |              std::string_view op, bool ordered) { | ||||||
|     ctx.AddU1("{}={}{}{}", inst, lhs, op, rhs, lhs, rhs); |     ctx.AddU1("{}={}{}{}", inst, lhs, op, rhs, lhs, rhs); | ||||||
|     if (ordered) { |     if (ordered) { | ||||||
|         ctx.code += fmt::format("&&!isnan({})&&!isnan({})", lhs, rhs); |         ctx.Add("&&!isnan({})&&!isnan({});", lhs, rhs); | ||||||
|     } else { |     } else { | ||||||
|         ctx.code += fmt::format("||isnan({})||isnan({})", lhs, rhs); |         ctx.Add("||isnan({})||isnan({});", lhs, rhs); | ||||||
|     } |     } | ||||||
|     ctx.code += ";"; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool Precise(IR::Inst& inst) { | bool IsPrecise(const IR::Inst& inst) { | ||||||
|     return {inst.Flags<IR::FpControl>().no_contraction}; |     return {inst.Flags<IR::FpControl>().no_contraction}; | ||||||
| } | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
| @@ -46,7 +45,7 @@ void EmitFPAdd16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
|     if (Precise(inst)) { |     if (IsPrecise(inst)) { | ||||||
|         ctx.AddPrecF32("{}={}+{};", inst, a, b); |         ctx.AddPrecF32("{}={}+{};", inst, a, b); | ||||||
|     } else { |     } else { | ||||||
|         ctx.AddF32("{}={}+{};", inst, a, b); |         ctx.AddF32("{}={}+{};", inst, a, b); | ||||||
| @@ -54,7 +53,7 @@ void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::stri | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitFPAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitFPAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
|     if (Precise(inst)) { |     if (IsPrecise(inst)) { | ||||||
|         ctx.AddPrecF64("{}={}+{};", inst, a, b); |         ctx.AddPrecF64("{}={}+{};", inst, a, b); | ||||||
|     } else { |     } else { | ||||||
|         ctx.AddF64("{}={}+{};", inst, a, b); |         ctx.AddF64("{}={}+{};", inst, a, b); | ||||||
| @@ -69,7 +68,7 @@ void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i | |||||||
|  |  | ||||||
| void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, | void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, | ||||||
|                  std::string_view c) { |                  std::string_view c) { | ||||||
|     if (Precise(inst)) { |     if (IsPrecise(inst)) { | ||||||
|         ctx.AddPrecF32("{}=fma({},{},{});", inst, a, b, c); |         ctx.AddPrecF32("{}=fma({},{},{});", inst, a, b, c); | ||||||
|     } else { |     } else { | ||||||
|         ctx.AddF32("{}=fma({},{},{});", inst, a, b, c); |         ctx.AddF32("{}=fma({},{},{});", inst, a, b, c); | ||||||
| @@ -78,7 +77,7 @@ void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::stri | |||||||
|  |  | ||||||
| void EmitFPFma64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, | void EmitFPFma64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, | ||||||
|                  std::string_view c) { |                  std::string_view c) { | ||||||
|     if (Precise(inst)) { |     if (IsPrecise(inst)) { | ||||||
|         ctx.AddPrecF64("{}=fma({},{},{});", inst, a, b, c); |         ctx.AddPrecF64("{}=fma({},{},{});", inst, a, b, c); | ||||||
|     } else { |     } else { | ||||||
|         ctx.AddF64("{}=fma({},{},{});", inst, a, b, c); |         ctx.AddF64("{}=fma({},{},{});", inst, a, b, c); | ||||||
| @@ -107,7 +106,7 @@ void EmitFPMul16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
|     if (Precise(inst)) { |     if (IsPrecise(inst)) { | ||||||
|         ctx.AddPrecF32("{}={}*{};", inst, a, b); |         ctx.AddPrecF32("{}={}*{};", inst, a, b); | ||||||
|     } else { |     } else { | ||||||
|         ctx.AddF32("{}={}*{};", inst, a, b); |         ctx.AddF32("{}={}*{};", inst, a, b); | ||||||
| @@ -115,7 +114,7 @@ void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::stri | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitFPMul64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitFPMul64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
|     if (Precise(inst)) { |     if (IsPrecise(inst)) { | ||||||
|         ctx.AddPrecF64("{}={}*{};", inst, a, b); |         ctx.AddPrecF64("{}={}*{};", inst, a, b); | ||||||
|     } else { |     } else { | ||||||
|         ctx.AddF64("{}={}*{};", inst, a, b); |         ctx.AddF64("{}={}*{};", inst, a, b); | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | |||||||
| void EmitReference(EmitContext& ctx, const IR::Value& value); | void EmitReference(EmitContext& ctx, const IR::Value& value); | ||||||
| void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); | ||||||
| void EmitJoin(EmitContext& ctx); | void EmitJoin(EmitContext& ctx); | ||||||
| void EmitDemoteToHelperInvocation(EmitContext& ctx, std::string_view continue_label); | void EmitDemoteToHelperInvocation(EmitContext& ctx); | ||||||
| void EmitBarrier(EmitContext& ctx); | void EmitBarrier(EmitContext& ctx); | ||||||
| void EmitWorkgroupMemoryBarrier(EmitContext& ctx); | void EmitWorkgroupMemoryBarrier(EmitContext& ctx); | ||||||
| void EmitDeviceMemoryBarrier(EmitContext& ctx); | void EmitDeviceMemoryBarrier(EmitContext& ctx); | ||||||
|   | |||||||
| @@ -28,12 +28,12 @@ void EmitSelectU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::stri | |||||||
|  |  | ||||||
| void EmitSelectU32(EmitContext& ctx, IR::Inst& inst, std::string_view cond, | void EmitSelectU32(EmitContext& ctx, IR::Inst& inst, std::string_view cond, | ||||||
|                    std::string_view true_value, std::string_view false_value) { |                    std::string_view true_value, std::string_view false_value) { | ||||||
|     ctx.AddU32("{}={}?{}:{};", inst, cond, true_value, false_value); |     ctx.AddU32("{}={}?uint({}):uint({});", inst, cond, true_value, false_value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSelectU64(EmitContext& ctx, IR::Inst& inst, std::string_view cond, | void EmitSelectU64(EmitContext& ctx, IR::Inst& inst, std::string_view cond, | ||||||
|                    std::string_view true_value, std::string_view false_value) { |                    std::string_view true_value, std::string_view false_value) { | ||||||
|     ctx.AddU64("{}={}?{}:{};", inst, cond, true_value, false_value); |     ctx.AddU64("{}={}?uint64_t({}):uint64_t({});", inst, cond, true_value, false_value); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSelectF16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond, | void EmitSelectF16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond, | ||||||
|   | |||||||
| @@ -89,23 +89,23 @@ void EmitSubgroupBallot(EmitContext& ctx, IR::Inst& inst, std::string_view pred) | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSubgroupEqMask(EmitContext& ctx, IR::Inst& inst) { | void EmitSubgroupEqMask(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     ctx.AddU32("{}=uvec2(gl_SubGroupEqMaskARB).x;", inst); |     ctx.AddU32("{}=uint(gl_SubGroupEqMaskARB.x);", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSubgroupLtMask(EmitContext& ctx, IR::Inst& inst) { | void EmitSubgroupLtMask(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     ctx.AddU32("{}=uvec2(gl_SubGroupLtMaskARB).x;", inst); |     ctx.AddU32("{}=uint(gl_SubGroupLtMaskARB.x);", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSubgroupLeMask(EmitContext& ctx, IR::Inst& inst) { | void EmitSubgroupLeMask(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     ctx.AddU32("{}=uvec2(gl_SubGroupLeMaskARB).x;", inst); |     ctx.AddU32("{}=uint(gl_SubGroupLeMaskARB.x);", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSubgroupGtMask(EmitContext& ctx, IR::Inst& inst) { | void EmitSubgroupGtMask(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     ctx.AddU32("{}=uvec2(gl_SubGroupGtMaskARB).x;", inst); |     ctx.AddU32("{}=uint(gl_SubGroupGtMaskARB.x);", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitSubgroupGeMask(EmitContext& ctx, IR::Inst& inst) { | void EmitSubgroupGeMask(EmitContext& ctx, IR::Inst& inst) { | ||||||
|     ctx.AddU32("{}=uvec2(gl_SubGroupGeMaskARB).x;", inst); |     ctx.AddU32("{}=uint(gl_SubGroupGeMaskARB.x);", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitShuffleIndex(EmitContext& ctx, IR::Inst& inst, std::string_view value, | void EmitShuffleIndex(EmitContext& ctx, IR::Inst& inst, std::string_view value, | ||||||
|   | |||||||
| @@ -116,7 +116,7 @@ std::string VarAlloc::Define(IR::Inst& inst, GlslVarType type) { | |||||||
|         id.type.Assign(type); |         id.type.Assign(type); | ||||||
|         GetUseTracker(type).uses_temp = true; |         GetUseTracker(type).uses_temp = true; | ||||||
|         inst.SetDefinition<Id>(id); |         inst.SetDefinition<Id>(id); | ||||||
|         return "t" + Representation(inst.Definition<Id>()); |         return 't' + Representation(inst.Definition<Id>()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user