From 2a713337165df4d5c4228458999a680e9ab65369 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 27 May 2021 22:28:33 -0400 Subject: [PATCH] glsl: Fix bindings, add some CC ops --- .../backend/glsl/emit_context.cpp | 57 +++++++++++-------- .../backend/glsl/emit_context.h | 5 +- .../glsl/emit_glsl_context_get_set.cpp | 33 ++++++----- .../backend/glsl/emit_glsl_image.cpp | 13 ++--- .../backend/glsl/emit_glsl_instructions.h | 4 +- .../backend/glsl/emit_glsl_integer.cpp | 29 +++++++++- .../glsl/emit_glsl_not_implemented.cpp | 2 +- .../backend/glsl/emit_glsl_select.cpp | 7 +-- 8 files changed, 92 insertions(+), 58 deletions(-) diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 0ddc0443b..7bd6b3605 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -20,6 +20,20 @@ std::string_view InterpDecorator(Interpolation interp) { } throw InvalidArgument("Invalid interpolation {}", interp); } + +std::string_view SamplerType(TextureType type) { + switch (type) { + case TextureType::Color2D: + return "sampler2D"; + case TextureType::ColorArray2D: + return "sampler2DArray"; + case TextureType::Color3D: + return "sampler3D"; + default: + throw NotImplementedException("Texture type: {}", type); + } +} + } // namespace EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, @@ -31,27 +45,23 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile switch (program.stage) { case Stage::VertexA: case Stage::VertexB: - stage_name = "vertex"; - attrib_name = "vertex"; + stage_name = "vs"; // TODO: add only what's used by the shader header += "out gl_PerVertex {vec4 gl_Position;float gl_PointSize;float gl_ClipDistance[];};"; break; case Stage::TessellationControl: case Stage::TessellationEval: - stage_name = "primitive"; - attrib_name = "primitive"; + stage_name = "ts"; break; case Stage::Geometry: - stage_name = "primitive"; - attrib_name = "vertex"; + stage_name = "gs"; break; case Stage::Fragment: - stage_name = "fragment"; - attrib_name = "fragment"; + stage_name = "fs"; break; case Stage::Compute: - stage_name = "invocation"; + stage_name = "cs"; header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;\n", program.workgroup_size[0], program.workgroup_size[1], program.workgroup_size[2]); @@ -77,12 +87,12 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile Add("layout(location={}) out vec4 out_attr{};", index, index); } } - DefineConstantBuffers(); - DefineStorageBuffers(); - DefineHelperFunctions(); + DefineConstantBuffers(bindings); + DefineStorageBuffers(bindings); SetupImages(bindings); - Add("void main(){{"); + DefineHelperFunctions(); + Add("void main(){{"); if (stage == Stage::VertexA || stage == Stage::VertexB) { Add("gl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);"); } @@ -112,27 +122,25 @@ void EmitContext::SetupExtensions(std::string& header) { } } -void EmitContext::DefineConstantBuffers() { +void EmitContext::DefineConstantBuffers(Bindings& bindings) { if (info.constant_buffer_descriptors.empty()) { return; } - u32 binding{}; for (const auto& desc : info.constant_buffer_descriptors) { - Add("layout(std140,binding={}) uniform cbuf_{}{{vec4 cbuf{}[{}];}};", binding, desc.index, - desc.index, 4 * 1024); - ++binding; + Add("layout(std140,binding={}) uniform {}_cbuf_{}{{vec4 {}_cbuf{}[{}];}};", + bindings.uniform_buffer, stage_name, desc.index, stage_name, desc.index, 4 * 1024); + bindings.uniform_buffer += desc.count; } } -void EmitContext::DefineStorageBuffers() { +void EmitContext::DefineStorageBuffers(Bindings& bindings) { if (info.storage_buffers_descriptors.empty()) { return; } - u32 binding{}; for (const auto& desc : info.storage_buffers_descriptors) { - Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", binding, binding, - desc.cbuf_index, desc.count); - ++binding; + Add("layout(std430,binding={}) buffer ssbo_{}{{uint ssbo{}[];}};", bindings.storage_buffer, + bindings.storage_buffer, desc.cbuf_index); + bindings.storage_buffer += desc.count; } } @@ -203,10 +211,11 @@ void EmitContext::SetupImages(Bindings& bindings) { } texture_bindings.reserve(info.texture_descriptors.size()); for (const auto& desc : info.texture_descriptors) { + const auto sampler_type{SamplerType(desc.type)}; texture_bindings.push_back(bindings.texture); const auto indices{bindings.texture + desc.count}; for (u32 index = bindings.texture; index < indices; ++index) { - Add("layout(binding={}) uniform sampler2D tex{};", bindings.texture, index); + Add("layout(binding={}) uniform {} tex{};", bindings.texture, sampler_type, index); } bindings.texture += desc.count; } diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h index 07dad6e57..9dff921db 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.h +++ b/src/shader_recompiler/backend/glsl/emit_context.h @@ -127,7 +127,6 @@ public: Stage stage{}; std::string_view stage_name = "invalid"; - std::string_view attrib_name = "invalid"; std::vector texture_buffer_bindings; std::vector image_buffer_bindings; @@ -138,8 +137,8 @@ public: private: void SetupExtensions(std::string& header); - void DefineConstantBuffers(); - void DefineStorageBuffers(); + void DefineConstantBuffers(Bindings& bindings); + void DefineStorageBuffers(Bindings& bindings); void DefineHelperFunctions(); void SetupImages(Bindings& bindings); }; diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index 38ad9de35..67d308c49 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp @@ -43,23 +43,24 @@ void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, const IR::Value& offset) { if (offset.IsImmediate()) { - ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}].{});", inst, binding.U32(), offset.U32() / 16, - OffsetSwizzle(offset.U32())); + ctx.AddU32("{}=floatBitsToUint({}_cbuf{}[{}].{});", inst, ctx.stage_name, binding.U32(), + offset.U32() / 16, OffsetSwizzle(offset.U32())); } else { const auto offset_var{ctx.reg_alloc.Consume(offset)}; - ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}/16][({}/4)%4]);", inst, binding.U32(), offset_var, - offset_var); + ctx.AddU32("{}=floatBitsToUint({}_cbuf{}[{}/16][({}/4)%4]);", inst, ctx.stage_name, + binding.U32(), offset_var, offset_var); } } void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, const IR::Value& offset) { if (offset.IsImmediate()) { - ctx.AddF32("{}=cbuf{}[{}].{};", inst, binding.U32(), offset.U32() / 16, + ctx.AddF32("{}={}_cbuf{}[{}].{};", inst, ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32())); } else { const auto offset_var{ctx.reg_alloc.Consume(offset)}; - ctx.AddF32("{}=cbuf{}[{}/16][({}/4)%4];", inst, binding.U32(), offset_var, offset_var); + ctx.AddF32("{}={}_cbuf{}[{}/16][({}/4)%4];", inst, ctx.stage_name, binding.U32(), + offset_var, offset_var); } } @@ -68,15 +69,17 @@ void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding if (offset.IsImmediate()) { const auto u32_offset{offset.U32()}; const auto index{(u32_offset / 4) % 4}; - ctx.AddU32x2("{}=uvec2(floatBitsToUint(cbuf{}[{}].{}),floatBitsToUint(cbuf{}[{}].{}));", - inst, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), - binding.U32(), (offset.U32() + 1) / 16, OffsetSwizzle(offset.U32() + 1)); + ctx.AddU32x2( + "{}=uvec2(floatBitsToUint({}_cbuf{}[{}].{}),floatBitsToUint({}_cbuf{}[{}].{}));", inst, + ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), + ctx.stage_name, binding.U32(), (offset.U32() + 1) / 16, + OffsetSwizzle(offset.U32() + 1)); } else { const auto offset_var{ctx.reg_alloc.Consume(offset)}; - ctx.AddU32x2("{}=uvec2(floatBitsToUint(cbuf{}[{}/16][({}/" - "4)%4]),floatBitsToUint(cbuf{}[({}+1)/16][(({}+1/4))%4]));", - inst, binding.U32(), offset_var, offset_var, binding.U32(), offset_var, - offset_var); + ctx.AddU32x2("{}=uvec2(floatBitsToUint({}_cbuf{}[{}/16][({}/" + "4)%4]),floatBitsToUint({}_cbuf{}[({}+1)/16][(({}+1/4))%4]));", + inst, ctx.stage_name, binding.U32(), offset_var, offset_var, ctx.stage_name, + binding.U32(), offset_var, offset_var); } } @@ -107,10 +110,10 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, } break; case IR::Attribute::InstanceId: - ctx.AddS32("{}=gl_InstanceID;", inst, ctx.attrib_name); + ctx.AddS32("{}=gl_InstanceID;", inst); break; case IR::Attribute::VertexId: - ctx.AddS32("{}=gl_VertexID;", inst, ctx.attrib_name); + ctx.AddS32("{}=gl_VertexID;", inst); break; default: fmt::print("Get attribute {}", attr); diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 6b7f1eaad..c070fba0e 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp @@ -32,14 +32,13 @@ void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse if (info.has_lod_clamp) { throw NotImplementedException("Lod clamp samples"); } - if (!offset.IsEmpty()) { - throw NotImplementedException("Offset"); - } - if (info.type != TextureType::Color2D) { - throw NotImplementedException("Texture type: {}", info.type.Value()); - } const auto texture{Texture(ctx, info, index)}; - ctx.AddF32x4("{}=texture({},{});", inst, texture, coords); + if (!offset.IsEmpty()) { + ctx.AddF32x4("{}=textureOffset({},{},ivec2({}));", inst, texture, coords, + ctx.reg_alloc.Consume(offset)); + } else { + ctx.AddF32x4("{}=texture({},{});", inst, texture, coords); + } } void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index f08ed0ece..b54fe684e 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h @@ -207,8 +207,8 @@ void EmitCompositeInsertF64x3(EmitContext& ctx, std::string_view composite, std: u32 index); void EmitCompositeInsertF64x4(EmitContext& ctx, std::string_view composite, std::string_view object, u32 index); -void EmitSelectU1(EmitContext& ctx, std::string_view cond, std::string_view true_value, - std::string_view false_value); +void EmitSelectU1(EmitContext& ctx, IR::Inst& inst, std::string_view cond, + std::string_view true_value, std::string_view false_value); void EmitSelectU8(EmitContext& ctx, std::string_view cond, std::string_view true_value, std::string_view false_value); void EmitSelectU16(EmitContext& ctx, std::string_view cond, std::string_view true_value, diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp index ce6e12623..84e01b151 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp @@ -8,8 +8,30 @@ #include "shader_recompiler/frontend/ir/value.h" namespace Shader::Backend::GLSL { +namespace { +void SetZeroFlag(EmitContext& ctx, IR::Inst& inst, std::string_view result) { + IR::Inst* const zero{inst.GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}; + if (!zero) { + return; + } + ctx.AddU1("{}={}==0;", *zero, result); + zero->Invalidate(); +} + +void SetSignFlag(EmitContext& ctx, IR::Inst& inst, std::string_view result) { + IR::Inst* const sign{inst.GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp)}; + if (!sign) { + return; + } + ctx.AddU1("{}=int({})<0;", *sign, result); + sign->Invalidate(); +} +} // Anonymous namespace void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { - ctx.AddU32("{}={}+{};", inst, a, b); + const auto result{ctx.reg_alloc.Define(inst)}; + ctx.Add("uint {}={}+{};", result, a, b); + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); } void EmitIAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { @@ -98,7 +120,10 @@ void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, std::string_view bas void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, std::string_view base, std::string_view offset, std::string_view count) { - ctx.AddU32("{}=bitfieldExtract({}, int({}), int({}));", inst, base, offset, count); + const auto result{ctx.reg_alloc.Define(inst)}; + ctx.Add("uint {}=bitfieldExtract({},int({}),int({}));", result, base, offset, count); + SetZeroFlag(ctx, inst, result); + SetSignFlag(ctx, inst, result); } void EmitBitReverse32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp index 110d3322e..3bac8899b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp @@ -29,7 +29,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) { } void EmitVoid(EmitContext& ctx) { - NotImplemented(); + // NotImplemented(); } void EmitReference(EmitContext&) { diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp index 1f2790b7d..ad3713f2d 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp @@ -8,10 +8,9 @@ #include "shader_recompiler/frontend/ir/value.h" namespace Shader::Backend::GLSL { -void EmitSelectU1([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond, - [[maybe_unused]] std::string_view true_value, - [[maybe_unused]] std::string_view false_value) { - throw NotImplementedException("GLSL Instruction"); +void EmitSelectU1(EmitContext& ctx, IR::Inst& inst, std::string_view cond, + std::string_view true_value, std::string_view false_value) { + ctx.AddU1("{}={}?{}:{};", inst, cond, true_value, false_value); } void EmitSelectU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond,