diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
11 files changed, 251 insertions, 314 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp index e69de29bb..59522fdbd 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_control_flow.cpp | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||
| 9 | #include "shader_recompiler/exception.h" | ||
| 10 | |||
| 11 | namespace Shader::Backend::GLSL { | ||
| 12 | |||
| 13 | void EmitJoin(EmitContext&) { | ||
| 14 | throw NotImplementedException("Join shouldn't be emitted"); | ||
| 15 | } | ||
| 16 | |||
| 17 | void EmitDemoteToHelperInvocation(EmitContext& ctx, | ||
| 18 | [[maybe_unused]] std::string_view continue_label) { | ||
| 19 | ctx.Add("discard;"); | ||
| 20 | } | ||
| 21 | |||
| 22 | } // namespace Shader::Backend::GLSL | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp index 9ed5bb319..8d823e466 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp | |||
| @@ -14,8 +14,7 @@ void EmitConvertS16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 14 | NotImplemented(); | 14 | NotImplemented(); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | void EmitConvertS16F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 17 | void EmitConvertS16F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 18 | [[maybe_unused]] std::string_view value) { | ||
| 19 | ctx.AddS32("{}=int(float({}))&0xffff;", inst, value); | 18 | ctx.AddS32("{}=int(float({}))&0xffff;", inst, value); |
| 20 | } | 19 | } |
| 21 | 20 | ||
| @@ -29,13 +28,11 @@ void EmitConvertS32F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 29 | NotImplemented(); | 28 | NotImplemented(); |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | void EmitConvertS32F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 31 | void EmitConvertS32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 33 | [[maybe_unused]] std::string_view value) { | ||
| 34 | ctx.AddS32("{}=int(float({}));", inst, value); | 32 | ctx.AddS32("{}=int(float({}));", inst, value); |
| 35 | } | 33 | } |
| 36 | 34 | ||
| 37 | void EmitConvertS32F64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 35 | void EmitConvertS32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 38 | [[maybe_unused]] std::string_view value) { | ||
| 39 | ctx.AddS32("{}=int(double({}));", inst, value); | 36 | ctx.AddS32("{}=int(double({}));", inst, value); |
| 40 | } | 37 | } |
| 41 | 38 | ||
| @@ -44,13 +41,11 @@ void EmitConvertS64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 44 | NotImplemented(); | 41 | NotImplemented(); |
| 45 | } | 42 | } |
| 46 | 43 | ||
| 47 | void EmitConvertS64F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 44 | void EmitConvertS64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 48 | [[maybe_unused]] std::string_view value) { | ||
| 49 | ctx.AddS64("{}=int64_t(double(float({})));", inst, value); | 45 | ctx.AddS64("{}=int64_t(double(float({})));", inst, value); |
| 50 | } | 46 | } |
| 51 | 47 | ||
| 52 | void EmitConvertS64F64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 48 | void EmitConvertS64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 53 | [[maybe_unused]] std::string_view value) { | ||
| 54 | ctx.AddS64("{}=int64_t(double({}));", inst, value); | 49 | ctx.AddS64("{}=int64_t(double({}));", inst, value); |
| 55 | } | 50 | } |
| 56 | 51 | ||
| @@ -74,13 +69,11 @@ void EmitConvertU32F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 74 | NotImplemented(); | 69 | NotImplemented(); |
| 75 | } | 70 | } |
| 76 | 71 | ||
| 77 | void EmitConvertU32F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 72 | void EmitConvertU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 78 | [[maybe_unused]] std::string_view value) { | ||
| 79 | ctx.AddU32("{}=uint(float({}));", inst, value); | 73 | ctx.AddU32("{}=uint(float({}));", inst, value); |
| 80 | } | 74 | } |
| 81 | 75 | ||
| 82 | void EmitConvertU32F64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 76 | void EmitConvertU32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 83 | [[maybe_unused]] std::string_view value) { | ||
| 84 | ctx.AddU32("{}=uint(double({}));", inst, value); | 77 | ctx.AddU32("{}=uint(double({}));", inst, value); |
| 85 | } | 78 | } |
| 86 | 79 | ||
| @@ -89,23 +82,19 @@ void EmitConvertU64F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 89 | NotImplemented(); | 82 | NotImplemented(); |
| 90 | } | 83 | } |
| 91 | 84 | ||
| 92 | void EmitConvertU64F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 85 | void EmitConvertU64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 93 | [[maybe_unused]] std::string_view value) { | ||
| 94 | ctx.AddU64("{}=uint64_t(float({}));", inst, value); | 86 | ctx.AddU64("{}=uint64_t(float({}));", inst, value); |
| 95 | } | 87 | } |
| 96 | 88 | ||
| 97 | void EmitConvertU64F64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 89 | void EmitConvertU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 98 | [[maybe_unused]] std::string_view value) { | ||
| 99 | ctx.AddU64("{}=uint64_t(double({}));", inst, value); | 90 | ctx.AddU64("{}=uint64_t(double({}));", inst, value); |
| 100 | } | 91 | } |
| 101 | 92 | ||
| 102 | void EmitConvertU64U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 93 | void EmitConvertU64U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 103 | [[maybe_unused]] std::string_view value) { | ||
| 104 | ctx.AddU64("{}=uint64_t(uint({}));", inst, value); | 94 | ctx.AddU64("{}=uint64_t(uint({}));", inst, value); |
| 105 | } | 95 | } |
| 106 | 96 | ||
| 107 | void EmitConvertU32U64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 97 | void EmitConvertU32U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 108 | [[maybe_unused]] std::string_view value) { | ||
| 109 | ctx.AddU32("{}=uint(uint64_t({}));", inst, value); | 98 | ctx.AddU32("{}=uint(uint64_t({}));", inst, value); |
| 110 | } | 99 | } |
| 111 | 100 | ||
| @@ -119,13 +108,11 @@ void EmitConvertF32F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 119 | NotImplemented(); | 108 | NotImplemented(); |
| 120 | } | 109 | } |
| 121 | 110 | ||
| 122 | void EmitConvertF32F64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 111 | void EmitConvertF32F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 123 | [[maybe_unused]] std::string_view value) { | ||
| 124 | ctx.AddF32("{}=float(double({}));", inst, value); | 112 | ctx.AddF32("{}=float(double({}));", inst, value); |
| 125 | } | 113 | } |
| 126 | 114 | ||
| 127 | void EmitConvertF64F32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 115 | void EmitConvertF64F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 128 | [[maybe_unused]] std::string_view value) { | ||
| 129 | ctx.AddF64("{}=double(float({}));", inst, value); | 116 | ctx.AddF64("{}=double(float({}));", inst, value); |
| 130 | } | 117 | } |
| 131 | 118 | ||
| @@ -179,13 +166,11 @@ void EmitConvertF32S16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 179 | NotImplemented(); | 166 | NotImplemented(); |
| 180 | } | 167 | } |
| 181 | 168 | ||
| 182 | void EmitConvertF32S32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 169 | void EmitConvertF32S32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 183 | [[maybe_unused]] std::string_view value) { | ||
| 184 | ctx.AddF32("{}=float(int({}));", inst, value); | 170 | ctx.AddF32("{}=float(int({}));", inst, value); |
| 185 | } | 171 | } |
| 186 | 172 | ||
| 187 | void EmitConvertF32S64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 173 | void EmitConvertF32S64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 188 | [[maybe_unused]] std::string_view value) { | ||
| 189 | ctx.AddF32("{}=float(double(int64_t({})));", inst, value); | 174 | ctx.AddF32("{}=float(double(int64_t({})));", inst, value); |
| 190 | } | 175 | } |
| 191 | 176 | ||
| @@ -194,18 +179,15 @@ void EmitConvertF32U8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::In | |||
| 194 | NotImplemented(); | 179 | NotImplemented(); |
| 195 | } | 180 | } |
| 196 | 181 | ||
| 197 | void EmitConvertF32U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 182 | void EmitConvertF32U16(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 198 | [[maybe_unused]] std::string_view value) { | ||
| 199 | ctx.AddF32("{}=float(uint({}&0xffff));", inst, value); | 183 | ctx.AddF32("{}=float(uint({}&0xffff));", inst, value); |
| 200 | } | 184 | } |
| 201 | 185 | ||
| 202 | void EmitConvertF32U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 186 | void EmitConvertF32U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 203 | [[maybe_unused]] std::string_view value) { | ||
| 204 | ctx.AddF32("{}=float(uint({}));", inst, value); | 187 | ctx.AddF32("{}=float(uint({}));", inst, value); |
| 205 | } | 188 | } |
| 206 | 189 | ||
| 207 | void EmitConvertF32U64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 190 | void EmitConvertF32U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 208 | [[maybe_unused]] std::string_view value) { | ||
| 209 | ctx.AddF32("{}=float(double(uint64_t({})));", inst, value); | 191 | ctx.AddF32("{}=float(double(uint64_t({})));", inst, value); |
| 210 | } | 192 | } |
| 211 | 193 | ||
| @@ -219,13 +201,11 @@ void EmitConvertF64S16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 219 | NotImplemented(); | 201 | NotImplemented(); |
| 220 | } | 202 | } |
| 221 | 203 | ||
| 222 | void EmitConvertF64S32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 204 | void EmitConvertF64S32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 223 | [[maybe_unused]] std::string_view value) { | ||
| 224 | ctx.AddF64("{}=double(int({}));", inst, value); | 205 | ctx.AddF64("{}=double(int({}));", inst, value); |
| 225 | } | 206 | } |
| 226 | 207 | ||
| 227 | void EmitConvertF64S64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 208 | void EmitConvertF64S64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 228 | [[maybe_unused]] std::string_view value) { | ||
| 229 | ctx.AddF64("{}=double(int64_t({}));", inst, value); | 209 | ctx.AddF64("{}=double(int64_t({}));", inst, value); |
| 230 | } | 210 | } |
| 231 | 211 | ||
| @@ -239,13 +219,11 @@ void EmitConvertF64U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 239 | NotImplemented(); | 219 | NotImplemented(); |
| 240 | } | 220 | } |
| 241 | 221 | ||
| 242 | void EmitConvertF64U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 222 | void EmitConvertF64U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 243 | [[maybe_unused]] std::string_view value) { | ||
| 244 | ctx.AddF64("{}=double(uint({}));", inst, value); | 223 | ctx.AddF64("{}=double(uint({}));", inst, value); |
| 245 | } | 224 | } |
| 246 | 225 | ||
| 247 | void EmitConvertF64U64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 226 | void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 248 | [[maybe_unused]] std::string_view value) { | ||
| 249 | ctx.AddF64("{}=double(uint64_t({}));", inst, value); | 227 | ctx.AddF64("{}=double(uint64_t({}));", inst, value); |
| 250 | } | 228 | } |
| 251 | 229 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index e3a69e3a5..00fe288e2 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -12,8 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Shader::Backend::GLSL { | 13 | namespace Shader::Backend::GLSL { |
| 14 | namespace { | 14 | namespace { |
| 15 | std::string Texture(EmitContext& ctx, const IR::TextureInstInfo& info, | 15 | std::string Texture(EmitContext& ctx, const IR::TextureInstInfo& info) { |
| 16 | [[maybe_unused]] const IR::Value& index) { | ||
| 17 | if (info.type == TextureType::Buffer) { | 16 | if (info.type == TextureType::Buffer) { |
| 18 | return fmt::format("tex{}", ctx.texture_buffer_bindings.at(info.descriptor_index)); | 17 | return fmt::format("tex{}", ctx.texture_buffer_bindings.at(info.descriptor_index)); |
| 19 | } else { | 18 | } else { |
| @@ -21,8 +20,7 @@ std::string Texture(EmitContext& ctx, const IR::TextureInstInfo& info, | |||
| 21 | } | 20 | } |
| 22 | } | 21 | } |
| 23 | 22 | ||
| 24 | std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info, | 23 | std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info) { |
| 25 | [[maybe_unused]] const IR::Value& index) { | ||
| 26 | if (info.type == TextureType::Buffer) { | 24 | if (info.type == TextureType::Buffer) { |
| 27 | return fmt::format("img{}", ctx.image_buffer_bindings.at(info.descriptor_index)); | 25 | return fmt::format("img{}", ctx.image_buffer_bindings.at(info.descriptor_index)); |
| 28 | } else { | 26 | } else { |
| @@ -139,16 +137,14 @@ IR::Inst* PrepareSparse(IR::Inst& inst) { | |||
| 139 | } | 137 | } |
| 140 | } // Anonymous namespace | 138 | } // Anonymous namespace |
| 141 | 139 | ||
| 142 | void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 140 | void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, |
| 143 | [[maybe_unused]] const IR::Value& index, | 141 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 144 | [[maybe_unused]] std::string_view coords, | 142 | std::string_view bias_lc, const IR::Value& offset) { |
| 145 | [[maybe_unused]] std::string_view bias_lc, | ||
| 146 | [[maybe_unused]] const IR::Value& offset) { | ||
| 147 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 143 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 148 | if (info.has_lod_clamp) { | 144 | if (info.has_lod_clamp) { |
| 149 | throw NotImplementedException("EmitImageSampleImplicitLod Lod clamp samples"); | 145 | throw NotImplementedException("EmitImageSampleImplicitLod Lod clamp samples"); |
| 150 | } | 146 | } |
| 151 | const auto texture{Texture(ctx, info, index)}; | 147 | const auto texture{Texture(ctx, info)}; |
| 152 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | 148 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; |
| 153 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 149 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 154 | const auto sparse_inst{PrepareSparse(inst)}; | 150 | const auto sparse_inst{PrepareSparse(inst)}; |
| @@ -179,11 +175,9 @@ void EmitImageSampleImplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | |||
| 179 | } | 175 | } |
| 180 | } | 176 | } |
| 181 | 177 | ||
| 182 | void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 178 | void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, |
| 183 | [[maybe_unused]] const IR::Value& index, | 179 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 184 | [[maybe_unused]] std::string_view coords, | 180 | std::string_view lod_lc, const IR::Value& offset) { |
| 185 | [[maybe_unused]] std::string_view lod_lc, | ||
| 186 | [[maybe_unused]] const IR::Value& offset) { | ||
| 187 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 181 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 188 | if (info.has_bias) { | 182 | if (info.has_bias) { |
| 189 | throw NotImplementedException("EmitImageSampleExplicitLod Bias texture samples"); | 183 | throw NotImplementedException("EmitImageSampleExplicitLod Bias texture samples"); |
| @@ -191,7 +185,7 @@ void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | |||
| 191 | if (info.has_lod_clamp) { | 185 | if (info.has_lod_clamp) { |
| 192 | throw NotImplementedException("EmitImageSampleExplicitLod Lod clamp samples"); | 186 | throw NotImplementedException("EmitImageSampleExplicitLod Lod clamp samples"); |
| 193 | } | 187 | } |
| 194 | const auto texture{Texture(ctx, info, index)}; | 188 | const auto texture{Texture(ctx, info)}; |
| 195 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 189 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 196 | const auto sparse_inst{PrepareSparse(inst)}; | 190 | const auto sparse_inst{PrepareSparse(inst)}; |
| 197 | if (!sparse_inst) { | 191 | if (!sparse_inst) { |
| @@ -214,13 +208,10 @@ void EmitImageSampleExplicitLod([[maybe_unused]] EmitContext& ctx, [[maybe_unuse | |||
| 214 | } | 208 | } |
| 215 | } | 209 | } |
| 216 | 210 | ||
| 217 | void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx, | 211 | void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, |
| 218 | [[maybe_unused]] IR::Inst& inst, | ||
| 219 | [[maybe_unused]] const IR::Value& index, | 212 | [[maybe_unused]] const IR::Value& index, |
| 220 | [[maybe_unused]] std::string_view coords, | 213 | std::string_view coords, std::string_view dref, |
| 221 | [[maybe_unused]] std::string_view dref, | 214 | std::string_view bias_lc, const IR::Value& offset) { |
| 222 | [[maybe_unused]] std::string_view bias_lc, | ||
| 223 | [[maybe_unused]] const IR::Value& offset) { | ||
| 224 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 215 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 225 | const auto sparse_inst{PrepareSparse(inst)}; | 216 | const auto sparse_inst{PrepareSparse(inst)}; |
| 226 | if (sparse_inst) { | 217 | if (sparse_inst) { |
| @@ -232,7 +223,7 @@ void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx, | |||
| 232 | if (info.has_lod_clamp) { | 223 | if (info.has_lod_clamp) { |
| 233 | throw NotImplementedException("EmitImageSampleDrefImplicitLod Lod clamp samples"); | 224 | throw NotImplementedException("EmitImageSampleDrefImplicitLod Lod clamp samples"); |
| 234 | } | 225 | } |
| 235 | const auto texture{Texture(ctx, info, index)}; | 226 | const auto texture{Texture(ctx, info)}; |
| 236 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | 227 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; |
| 237 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; | 228 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; |
| 238 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; | 229 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; |
| @@ -272,13 +263,10 @@ void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx, | |||
| 272 | } | 263 | } |
| 273 | } | 264 | } |
| 274 | 265 | ||
| 275 | void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | 266 | void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, |
| 276 | [[maybe_unused]] IR::Inst& inst, | ||
| 277 | [[maybe_unused]] const IR::Value& index, | 267 | [[maybe_unused]] const IR::Value& index, |
| 278 | [[maybe_unused]] std::string_view coords, | 268 | std::string_view coords, std::string_view dref, |
| 279 | [[maybe_unused]] std::string_view dref, | 269 | std::string_view lod_lc, const IR::Value& offset) { |
| 280 | [[maybe_unused]] std::string_view lod_lc, | ||
| 281 | [[maybe_unused]] const IR::Value& offset) { | ||
| 282 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 270 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 283 | const auto sparse_inst{PrepareSparse(inst)}; | 271 | const auto sparse_inst{PrepareSparse(inst)}; |
| 284 | if (sparse_inst) { | 272 | if (sparse_inst) { |
| @@ -290,7 +278,7 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | |||
| 290 | if (info.has_lod_clamp) { | 278 | if (info.has_lod_clamp) { |
| 291 | throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); | 279 | throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); |
| 292 | } | 280 | } |
| 293 | const auto texture{Texture(ctx, info, index)}; | 281 | const auto texture{Texture(ctx, info)}; |
| 294 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; | 282 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; |
| 295 | const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && needs_shadow_ext}; | 283 | const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && needs_shadow_ext}; |
| 296 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; | 284 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; |
| @@ -325,13 +313,10 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | |||
| 325 | } | 313 | } |
| 326 | } | 314 | } |
| 327 | 315 | ||
| 328 | void EmitImageGather([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 316 | void EmitImageGather(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 329 | [[maybe_unused]] const IR::Value& index, | 317 | std::string_view coords, const IR::Value& offset, const IR::Value& offset2) { |
| 330 | [[maybe_unused]] std::string_view coords, | ||
| 331 | [[maybe_unused]] const IR::Value& offset, | ||
| 332 | [[maybe_unused]] const IR::Value& offset2) { | ||
| 333 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 318 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 334 | const auto texture{Texture(ctx, info, index)}; | 319 | const auto texture{Texture(ctx, info)}; |
| 335 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 320 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 336 | const auto sparse_inst{PrepareSparse(inst)}; | 321 | const auto sparse_inst{PrepareSparse(inst)}; |
| 337 | if (!sparse_inst) { | 322 | if (!sparse_inst) { |
| @@ -370,14 +355,11 @@ void EmitImageGather([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Ins | |||
| 370 | info.gather_component); | 355 | info.gather_component); |
| 371 | } | 356 | } |
| 372 | 357 | ||
| 373 | void EmitImageGatherDref([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 358 | void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 374 | [[maybe_unused]] const IR::Value& index, | 359 | std::string_view coords, const IR::Value& offset, const IR::Value& offset2, |
| 375 | [[maybe_unused]] std::string_view coords, | 360 | std::string_view dref) { |
| 376 | [[maybe_unused]] const IR::Value& offset, | ||
| 377 | [[maybe_unused]] const IR::Value& offset2, | ||
| 378 | [[maybe_unused]] std::string_view dref) { | ||
| 379 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 361 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 380 | const auto texture{Texture(ctx, info, index)}; | 362 | const auto texture{Texture(ctx, info)}; |
| 381 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 363 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 382 | const auto sparse_inst{PrepareSparse(inst)}; | 364 | const auto sparse_inst{PrepareSparse(inst)}; |
| 383 | if (!sparse_inst) { | 365 | if (!sparse_inst) { |
| @@ -413,10 +395,8 @@ void EmitImageGatherDref([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR: | |||
| 413 | *sparse_inst, texture, CastToIntVec(coords, info), dref, offsets, texel); | 395 | *sparse_inst, texture, CastToIntVec(coords, info), dref, offsets, texel); |
| 414 | } | 396 | } |
| 415 | 397 | ||
| 416 | void EmitImageFetch([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 398 | void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 417 | [[maybe_unused]] const IR::Value& index, | 399 | std::string_view coords, std::string_view offset, std::string_view lod, |
| 418 | [[maybe_unused]] std::string_view coords, | ||
| 419 | [[maybe_unused]] std::string_view offset, [[maybe_unused]] std::string_view lod, | ||
| 420 | [[maybe_unused]] std::string_view ms) { | 400 | [[maybe_unused]] std::string_view ms) { |
| 421 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 401 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 422 | if (info.has_bias) { | 402 | if (info.has_bias) { |
| @@ -425,7 +405,7 @@ void EmitImageFetch([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | |||
| 425 | if (info.has_lod_clamp) { | 405 | if (info.has_lod_clamp) { |
| 426 | throw NotImplementedException("EmitImageFetch Lod clamp samples"); | 406 | throw NotImplementedException("EmitImageFetch Lod clamp samples"); |
| 427 | } | 407 | } |
| 428 | const auto texture{Texture(ctx, info, index)}; | 408 | const auto texture{Texture(ctx, info)}; |
| 429 | const auto sparse_inst{PrepareSparse(inst)}; | 409 | const auto sparse_inst{PrepareSparse(inst)}; |
| 430 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 410 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 431 | if (!sparse_inst) { | 411 | if (!sparse_inst) { |
| @@ -453,11 +433,10 @@ void EmitImageFetch([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | |||
| 453 | } | 433 | } |
| 454 | } | 434 | } |
| 455 | 435 | ||
| 456 | void EmitImageQueryDimensions([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 436 | void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, |
| 457 | [[maybe_unused]] const IR::Value& index, | 437 | [[maybe_unused]] const IR::Value& index, std::string_view lod) { |
| 458 | [[maybe_unused]] std::string_view lod) { | ||
| 459 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 438 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 460 | const auto texture{Texture(ctx, info, index)}; | 439 | const auto texture{Texture(ctx, info)}; |
| 461 | switch (info.type) { | 440 | switch (info.type) { |
| 462 | case TextureType::Color1D: | 441 | case TextureType::Color1D: |
| 463 | return ctx.AddU32x4( | 442 | return ctx.AddU32x4( |
| @@ -481,20 +460,16 @@ void EmitImageQueryDimensions([[maybe_unused]] EmitContext& ctx, [[maybe_unused] | |||
| 481 | throw LogicError("Unspecified image type {}", info.type.Value()); | 460 | throw LogicError("Unspecified image type {}", info.type.Value()); |
| 482 | } | 461 | } |
| 483 | 462 | ||
| 484 | void EmitImageQueryLod([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 463 | void EmitImageQueryLod(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 485 | [[maybe_unused]] const IR::Value& index, | 464 | std::string_view coords) { |
| 486 | [[maybe_unused]] std::string_view coords) { | ||
| 487 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 465 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 488 | const auto texture{Texture(ctx, info, index)}; | 466 | const auto texture{Texture(ctx, info)}; |
| 489 | return ctx.AddF32x4("{}=vec4(textureQueryLod({},{}),0.0,0.0);", inst, texture, coords); | 467 | return ctx.AddF32x4("{}=vec4(textureQueryLod({},{}),0.0,0.0);", inst, texture, coords); |
| 490 | } | 468 | } |
| 491 | 469 | ||
| 492 | void EmitImageGradient([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 470 | void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 493 | [[maybe_unused]] const IR::Value& index, | 471 | std::string_view coords, const IR::Value& derivatives, |
| 494 | [[maybe_unused]] std::string_view coords, | 472 | const IR::Value& offset, [[maybe_unused]] const IR::Value& lod_clamp) { |
| 495 | [[maybe_unused]] const IR::Value& derivatives, | ||
| 496 | [[maybe_unused]] const IR::Value& offset, | ||
| 497 | [[maybe_unused]] const IR::Value& lod_clamp) { | ||
| 498 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 473 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 499 | if (info.has_lod_clamp) { | 474 | if (info.has_lod_clamp) { |
| 500 | throw NotImplementedException("EmitImageGradient Lod clamp samples"); | 475 | throw NotImplementedException("EmitImageGradient Lod clamp samples"); |
| @@ -506,7 +481,7 @@ void EmitImageGradient([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 506 | if (!offset.IsEmpty()) { | 481 | if (!offset.IsEmpty()) { |
| 507 | throw NotImplementedException("EmitImageGradient offset"); | 482 | throw NotImplementedException("EmitImageGradient offset"); |
| 508 | } | 483 | } |
| 509 | const auto texture{Texture(ctx, info, index)}; | 484 | const auto texture{Texture(ctx, info)}; |
| 510 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 485 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 511 | const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp}; | 486 | const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp}; |
| 512 | const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)}; | 487 | const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)}; |
| @@ -519,63 +494,65 @@ void EmitImageGradient([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 519 | } | 494 | } |
| 520 | } | 495 | } |
| 521 | 496 | ||
| 522 | void EmitImageRead([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 497 | void EmitImageRead(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 523 | [[maybe_unused]] const IR::Value& index, | 498 | std::string_view coords) { |
| 524 | [[maybe_unused]] std::string_view coords) { | ||
| 525 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 499 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 526 | const auto sparse_inst{PrepareSparse(inst)}; | 500 | const auto sparse_inst{PrepareSparse(inst)}; |
| 527 | if (sparse_inst) { | 501 | if (sparse_inst) { |
| 528 | throw NotImplementedException("EmitImageRead Sparse"); | 502 | throw NotImplementedException("EmitImageRead Sparse"); |
| 529 | } | 503 | } |
| 530 | const auto image{Image(ctx, info, index)}; | 504 | const auto image{Image(ctx, info)}; |
| 531 | ctx.AddU32x4("{}=uvec4(imageLoad({},{}));", inst, image, TexelFetchCastToInt(coords, info)); | 505 | ctx.AddU32x4("{}=uvec4(imageLoad({},{}));", inst, image, TexelFetchCastToInt(coords, info)); |
| 532 | } | 506 | } |
| 533 | 507 | ||
| 534 | void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 508 | void EmitImageWrite(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 535 | [[maybe_unused]] const IR::Value& index, | 509 | std::string_view coords, std::string_view color) { |
| 536 | [[maybe_unused]] std::string_view coords, | ||
| 537 | [[maybe_unused]] std::string_view color) { | ||
| 538 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 510 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 539 | const auto image{Image(ctx, info, index)}; | 511 | const auto image{Image(ctx, info)}; |
| 540 | ctx.Add("imageStore({},{},{});", image, TexelFetchCastToInt(coords, info), color); | 512 | ctx.Add("imageStore({},{},{});", image, TexelFetchCastToInt(coords, info), color); |
| 541 | } | 513 | } |
| 542 | 514 | ||
| 543 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 515 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, |
| 544 | std::string_view coords, std::string_view value) { | 516 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 517 | std::string_view value) { | ||
| 545 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 518 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 546 | const auto image{Image(ctx, info, index)}; | 519 | const auto image{Image(ctx, info)}; |
| 547 | ctx.AddU32("{}=imageAtomicAdd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 520 | ctx.AddU32("{}=imageAtomicAdd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 548 | value); | 521 | value); |
| 549 | } | 522 | } |
| 550 | 523 | ||
| 551 | void EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 524 | void EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, |
| 552 | std::string_view coords, std::string_view value) { | 525 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 526 | std::string_view value) { | ||
| 553 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 527 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 554 | const auto image{Image(ctx, info, index)}; | 528 | const auto image{Image(ctx, info)}; |
| 555 | ctx.AddU32("{}=imageAtomicMin({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), | 529 | ctx.AddU32("{}=imageAtomicMin({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 556 | value); | 530 | value); |
| 557 | } | 531 | } |
| 558 | 532 | ||
| 559 | void EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 533 | void EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, |
| 560 | std::string_view coords, std::string_view value) { | 534 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 535 | std::string_view value) { | ||
| 561 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 536 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 562 | const auto image{Image(ctx, info, index)}; | 537 | const auto image{Image(ctx, info)}; |
| 563 | ctx.AddU32("{}=imageAtomicMin({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), | 538 | ctx.AddU32("{}=imageAtomicMin({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 564 | value); | 539 | value); |
| 565 | } | 540 | } |
| 566 | 541 | ||
| 567 | void EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 542 | void EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, |
| 568 | std::string_view coords, std::string_view value) { | 543 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 544 | std::string_view value) { | ||
| 569 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 545 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 570 | const auto image{Image(ctx, info, index)}; | 546 | const auto image{Image(ctx, info)}; |
| 571 | ctx.AddU32("{}=imageAtomicMax({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), | 547 | ctx.AddU32("{}=imageAtomicMax({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 572 | value); | 548 | value); |
| 573 | } | 549 | } |
| 574 | 550 | ||
| 575 | void EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 551 | void EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, |
| 576 | std::string_view coords, std::string_view value) { | 552 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 553 | std::string_view value) { | ||
| 577 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 554 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 578 | const auto image{Image(ctx, info, index)}; | 555 | const auto image{Image(ctx, info)}; |
| 579 | ctx.AddU32("{}=imageAtomicMax({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), | 556 | ctx.AddU32("{}=imageAtomicMax({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 580 | value); | 557 | value); |
| 581 | } | 558 | } |
| @@ -590,34 +567,35 @@ void EmitImageAtomicDec32(EmitContext&, IR::Inst&, const IR::Value&, std::string | |||
| 590 | NotImplemented(); | 567 | NotImplemented(); |
| 591 | } | 568 | } |
| 592 | 569 | ||
| 593 | void EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 570 | void EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 594 | std::string_view coords, std::string_view value) { | 571 | std::string_view coords, std::string_view value) { |
| 595 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 572 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 596 | const auto image{Image(ctx, info, index)}; | 573 | const auto image{Image(ctx, info)}; |
| 597 | ctx.AddU32("{}=imageAtomicAnd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 574 | ctx.AddU32("{}=imageAtomicAnd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 598 | value); | 575 | value); |
| 599 | } | 576 | } |
| 600 | 577 | ||
| 601 | void EmitImageAtomicOr32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 578 | void EmitImageAtomicOr32(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 602 | std::string_view coords, std::string_view value) { | 579 | std::string_view coords, std::string_view value) { |
| 603 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 580 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 604 | const auto image{Image(ctx, info, index)}; | 581 | const auto image{Image(ctx, info)}; |
| 605 | ctx.AddU32("{}=imageAtomicOr({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 582 | ctx.AddU32("{}=imageAtomicOr({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 606 | value); | 583 | value); |
| 607 | } | 584 | } |
| 608 | 585 | ||
| 609 | void EmitImageAtomicXor32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 586 | void EmitImageAtomicXor32(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, |
| 610 | std::string_view coords, std::string_view value) { | 587 | std::string_view coords, std::string_view value) { |
| 611 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 588 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 612 | const auto image{Image(ctx, info, index)}; | 589 | const auto image{Image(ctx, info)}; |
| 613 | ctx.AddU32("{}=imageAtomicXor({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 590 | ctx.AddU32("{}=imageAtomicXor({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 614 | value); | 591 | value); |
| 615 | } | 592 | } |
| 616 | 593 | ||
| 617 | void EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | 594 | void EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, |
| 618 | std::string_view coords, std::string_view value) { | 595 | [[maybe_unused]] const IR::Value& index, std::string_view coords, |
| 596 | std::string_view value) { | ||
| 619 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 597 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 620 | const auto image{Image(ctx, info, index)}; | 598 | const auto image{Image(ctx, info)}; |
| 621 | ctx.AddU32("{}=imageAtomicExchange({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 599 | ctx.AddU32("{}=imageAtomicExchange({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 622 | value); | 600 | value); |
| 623 | } | 601 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image_atomic.cpp deleted file mode 100644 index e69de29bb..000000000 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image_atomic.cpp +++ /dev/null | |||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index 12094139f..1257575c0 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h | |||
| @@ -30,14 +30,7 @@ void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | |||
| 30 | void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | 30 | void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); |
| 31 | void EmitReference(EmitContext& ctx, const IR::Value& value); | 31 | void EmitReference(EmitContext& ctx, const IR::Value& value); |
| 32 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); | 32 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); |
| 33 | void EmitBranch(EmitContext& ctx, std::string_view label); | ||
| 34 | void EmitBranchConditional(EmitContext& ctx, std::string_view condition, | ||
| 35 | std::string_view true_label, std::string_view false_label); | ||
| 36 | void EmitLoopMerge(EmitContext& ctx, std::string_view merge_label, std::string_view continue_label); | ||
| 37 | void EmitSelectionMerge(EmitContext& ctx, std::string_view merge_label); | ||
| 38 | void EmitReturn(EmitContext& ctx); | ||
| 39 | void EmitJoin(EmitContext& ctx); | 33 | void EmitJoin(EmitContext& ctx); |
| 40 | void EmitUnreachable(EmitContext& ctx); | ||
| 41 | void EmitDemoteToHelperInvocation(EmitContext& ctx, std::string_view continue_label); | 34 | void EmitDemoteToHelperInvocation(EmitContext& ctx, std::string_view continue_label); |
| 42 | void EmitBarrier(EmitContext& ctx); | 35 | void EmitBarrier(EmitContext& ctx); |
| 43 | void EmitWorkgroupMemoryBarrier(EmitContext& ctx); | 36 | void EmitWorkgroupMemoryBarrier(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp index 1c7413cd4..6e04c6cb2 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp | |||
| @@ -156,13 +156,11 @@ void EmitBitwiseNot32(EmitContext& ctx, IR::Inst& inst, std::string_view value) | |||
| 156 | ctx.AddU32("{}=~{};", inst, value); | 156 | ctx.AddU32("{}=~{};", inst, value); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | void EmitFindSMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 159 | void EmitFindSMsb32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 160 | [[maybe_unused]] std::string_view value) { | ||
| 161 | ctx.AddU32("{}=findMSB(int({}));", inst, value); | 160 | ctx.AddU32("{}=findMSB(int({}));", inst, value); |
| 162 | } | 161 | } |
| 163 | 162 | ||
| 164 | void EmitFindUMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 163 | void EmitFindUMsb32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 165 | [[maybe_unused]] std::string_view value) { | ||
| 166 | ctx.AddU32("{}=findMSB(uint({}));", inst, value); | 164 | ctx.AddU32("{}=findMSB(uint({}));", inst, value); |
| 167 | } | 165 | } |
| 168 | 166 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp index 500e5c290..af3dadf71 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp | |||
| @@ -21,19 +21,19 @@ void SsboWriteCas(EmitContext& ctx, const IR::Value& binding, std::string_view o | |||
| 21 | } | 21 | } |
| 22 | } // Anonymous namespace | 22 | } // Anonymous namespace |
| 23 | 23 | ||
| 24 | void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) { | 24 | void EmitLoadGlobalU8(EmitContext&) { |
| 25 | NotImplemented(); | 25 | NotImplemented(); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | void EmitLoadGlobalS8([[maybe_unused]] EmitContext& ctx) { | 28 | void EmitLoadGlobalS8(EmitContext&) { |
| 29 | NotImplemented(); | 29 | NotImplemented(); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | void EmitLoadGlobalU16([[maybe_unused]] EmitContext& ctx) { | 32 | void EmitLoadGlobalU16(EmitContext&) { |
| 33 | NotImplemented(); | 33 | NotImplemented(); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void EmitLoadGlobalS16([[maybe_unused]] EmitContext& ctx) { | 36 | void EmitLoadGlobalS16(EmitContext&) { |
| 37 | NotImplemented(); | 37 | NotImplemented(); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| @@ -49,19 +49,19 @@ void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, std::string_view addres | |||
| 49 | ctx.AddU32x4("{}=LoadGlobal128({});", inst, address); | 49 | ctx.AddU32x4("{}=LoadGlobal128({});", inst, address); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void EmitWriteGlobalU8([[maybe_unused]] EmitContext& ctx) { | 52 | void EmitWriteGlobalU8(EmitContext&) { |
| 53 | NotImplemented(); | 53 | NotImplemented(); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | void EmitWriteGlobalS8([[maybe_unused]] EmitContext& ctx) { | 56 | void EmitWriteGlobalS8(EmitContext&) { |
| 57 | NotImplemented(); | 57 | NotImplemented(); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | void EmitWriteGlobalU16([[maybe_unused]] EmitContext& ctx) { | 60 | void EmitWriteGlobalU16(EmitContext&) { |
| 61 | NotImplemented(); | 61 | NotImplemented(); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | void EmitWriteGlobalS16([[maybe_unused]] EmitContext& ctx) { | 64 | void EmitWriteGlobalS16(EmitContext&) { |
| 65 | NotImplemented(); | 65 | NotImplemented(); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| @@ -77,33 +77,29 @@ void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_ | |||
| 77 | ctx.Add("WriteGlobal128({},{});", address, value); | 77 | ctx.Add("WriteGlobal128({},{});", address, value); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | void EmitLoadStorageU8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 80 | void EmitLoadStorageU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 81 | [[maybe_unused]] const IR::Value& binding, | 81 | const IR::Value& offset) { |
| 82 | [[maybe_unused]] const IR::Value& offset) { | ||
| 83 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 82 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 84 | ctx.AddU32("{}=bitfieldExtract({}_ssbo{}[{}>>2],int({}%4)*8,8);", inst, ctx.stage_name, | 83 | ctx.AddU32("{}=bitfieldExtract({}_ssbo{}[{}>>2],int({}%4)*8,8);", inst, ctx.stage_name, |
| 85 | binding.U32(), offset_var, offset_var); | 84 | binding.U32(), offset_var, offset_var); |
| 86 | } | 85 | } |
| 87 | 86 | ||
| 88 | void EmitLoadStorageS8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 87 | void EmitLoadStorageS8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 89 | [[maybe_unused]] const IR::Value& binding, | 88 | const IR::Value& offset) { |
| 90 | [[maybe_unused]] const IR::Value& offset) { | ||
| 91 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 89 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 92 | ctx.AddS32("{}=bitfieldExtract(int({}_ssbo{}[{}>>2]),int({}%4)*8,8);", inst, ctx.stage_name, | 90 | ctx.AddS32("{}=bitfieldExtract(int({}_ssbo{}[{}>>2]),int({}%4)*8,8);", inst, ctx.stage_name, |
| 93 | binding.U32(), offset_var, offset_var); | 91 | binding.U32(), offset_var, offset_var); |
| 94 | } | 92 | } |
| 95 | 93 | ||
| 96 | void EmitLoadStorageU16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 94 | void EmitLoadStorageU16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 97 | [[maybe_unused]] const IR::Value& binding, | 95 | const IR::Value& offset) { |
| 98 | [[maybe_unused]] const IR::Value& offset) { | ||
| 99 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 96 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 100 | ctx.AddU32("{}=bitfieldExtract({}_ssbo{}[{}>>2],int(({}>>1)%2)*16,16);", inst, ctx.stage_name, | 97 | ctx.AddU32("{}=bitfieldExtract({}_ssbo{}[{}>>2],int(({}>>1)%2)*16,16);", inst, ctx.stage_name, |
| 101 | binding.U32(), offset_var, offset_var); | 98 | binding.U32(), offset_var, offset_var); |
| 102 | } | 99 | } |
| 103 | 100 | ||
| 104 | void EmitLoadStorageS16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 101 | void EmitLoadStorageS16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 105 | [[maybe_unused]] const IR::Value& binding, | 102 | const IR::Value& offset) { |
| 106 | [[maybe_unused]] const IR::Value& offset) { | ||
| 107 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 103 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 108 | ctx.AddS32("{}=bitfieldExtract(int({}_ssbo{}[{}>>2]),int(({}>>1)%2)*16,16);", inst, | 104 | ctx.AddS32("{}=bitfieldExtract(int({}_ssbo{}[{}>>2]),int(({}>>1)%2)*16,16);", inst, |
| 109 | ctx.stage_name, binding.U32(), offset_var, offset_var); | 105 | ctx.stage_name, binding.U32(), offset_var, offset_var); |
| @@ -132,37 +128,29 @@ void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& bindi | |||
| 132 | binding.U32(), offset_var); | 128 | binding.U32(), offset_var); |
| 133 | } | 129 | } |
| 134 | 130 | ||
| 135 | void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx, | 131 | void EmitWriteStorageU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 136 | [[maybe_unused]] const IR::Value& binding, | 132 | std::string_view value) { |
| 137 | [[maybe_unused]] const IR::Value& offset, | ||
| 138 | [[maybe_unused]] std::string_view value) { | ||
| 139 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 133 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 140 | const auto bit_offset{fmt::format("int({}%4)*8", offset_var)}; | 134 | const auto bit_offset{fmt::format("int({}%4)*8", offset_var)}; |
| 141 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8); | 135 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8); |
| 142 | } | 136 | } |
| 143 | 137 | ||
| 144 | void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, | 138 | void EmitWriteStorageS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 145 | [[maybe_unused]] const IR::Value& binding, | 139 | std::string_view value) { |
| 146 | [[maybe_unused]] const IR::Value& offset, | ||
| 147 | [[maybe_unused]] std::string_view value) { | ||
| 148 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 140 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 149 | const auto bit_offset{fmt::format("int({}%4)*8", offset_var)}; | 141 | const auto bit_offset{fmt::format("int({}%4)*8", offset_var)}; |
| 150 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8); | 142 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8); |
| 151 | } | 143 | } |
| 152 | 144 | ||
| 153 | void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, | 145 | void EmitWriteStorageU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 154 | [[maybe_unused]] const IR::Value& binding, | 146 | std::string_view value) { |
| 155 | [[maybe_unused]] const IR::Value& offset, | ||
| 156 | [[maybe_unused]] std::string_view value) { | ||
| 157 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 147 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 158 | const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)}; | 148 | const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)}; |
| 159 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16); | 149 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16); |
| 160 | } | 150 | } |
| 161 | 151 | ||
| 162 | void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, | 152 | void EmitWriteStorageS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 163 | [[maybe_unused]] const IR::Value& binding, | 153 | std::string_view value) { |
| 164 | [[maybe_unused]] const IR::Value& offset, | ||
| 165 | [[maybe_unused]] std::string_view value) { | ||
| 166 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 154 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 167 | const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)}; | 155 | const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)}; |
| 168 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16); | 156 | SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16); |
| @@ -181,10 +169,8 @@ void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Va | |||
| 181 | ctx.Add("{}_ssbo{}[({}+4)>>2]={}.y;", ctx.stage_name, binding.U32(), offset_var, value); | 169 | ctx.Add("{}_ssbo{}[({}+4)>>2]={}.y;", ctx.stage_name, binding.U32(), offset_var, value); |
| 182 | } | 170 | } |
| 183 | 171 | ||
| 184 | void EmitWriteStorage128([[maybe_unused]] EmitContext& ctx, | 172 | void EmitWriteStorage128(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 185 | [[maybe_unused]] const IR::Value& binding, | 173 | std::string_view value) { |
| 186 | [[maybe_unused]] const IR::Value& offset, | ||
| 187 | [[maybe_unused]] std::string_view value) { | ||
| 188 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 174 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 189 | ctx.Add("{}_ssbo{}[{}>>2]={}.x;", ctx.stage_name, binding.U32(), offset_var, value); | 175 | ctx.Add("{}_ssbo{}[{}>>2]={}.x;", ctx.stage_name, binding.U32(), offset_var, value); |
| 190 | ctx.Add("{}_ssbo{}[({}+4)>>2]={}.y;", ctx.stage_name, binding.U32(), offset_var, value); | 176 | ctx.Add("{}_ssbo{}[({}+4)>>2]={}.y;", ctx.stage_name, binding.U32(), offset_var, 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 f17a07955..f420fe388 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -14,84 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | namespace Shader::Backend::GLSL { | 15 | namespace Shader::Backend::GLSL { |
| 16 | 16 | ||
| 17 | void EmitPhi(EmitContext& ctx, IR::Inst& phi) { | ||
| 18 | const size_t num_args{phi.NumArgs()}; | ||
| 19 | for (size_t i = 0; i < num_args; ++i) { | ||
| 20 | ctx.var_alloc.Consume(phi.Arg(i)); | ||
| 21 | } | ||
| 22 | if (!phi.Definition<Id>().is_valid) { | ||
| 23 | // The phi node wasn't forward defined | ||
| 24 | ctx.var_alloc.PhiDefine(phi, phi.Arg(0).Type()); | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | void EmitVoid(EmitContext& ctx) {} | ||
| 29 | |||
| 30 | void EmitReference(EmitContext& ctx, const IR::Value& value) { | ||
| 31 | ctx.var_alloc.Consume(value); | ||
| 32 | } | ||
| 33 | |||
| 34 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | ||
| 35 | IR::Inst& phi{*phi_value.InstRecursive()}; | ||
| 36 | const auto phi_type{phi.Arg(0).Type()}; | ||
| 37 | if (!phi.Definition<Id>().is_valid) { | ||
| 38 | // The phi node wasn't forward defined | ||
| 39 | ctx.var_alloc.PhiDefine(phi, phi_type); | ||
| 40 | } | ||
| 41 | const auto phi_reg{ctx.var_alloc.Consume(IR::Value{&phi})}; | ||
| 42 | const auto val_reg{ctx.var_alloc.Consume(value)}; | ||
| 43 | if (phi_reg == val_reg) { | ||
| 44 | return; | ||
| 45 | } | ||
| 46 | ctx.Add("{}={};", phi_reg, val_reg); | ||
| 47 | } | ||
| 48 | |||
| 49 | void EmitBranch(EmitContext& ctx, std::string_view label) { | ||
| 50 | NotImplemented(); | ||
| 51 | } | ||
| 52 | |||
| 53 | void EmitBranchConditional(EmitContext& ctx, std::string_view condition, | ||
| 54 | std::string_view true_label, std::string_view false_label) { | ||
| 55 | NotImplemented(); | ||
| 56 | } | ||
| 57 | |||
| 58 | void EmitLoopMerge(EmitContext& ctx, std::string_view merge_label, | ||
| 59 | std::string_view continue_label) { | ||
| 60 | NotImplemented(); | ||
| 61 | } | ||
| 62 | |||
| 63 | void EmitSelectionMerge(EmitContext& ctx, std::string_view merge_label) { | ||
| 64 | NotImplemented(); | ||
| 65 | } | ||
| 66 | |||
| 67 | void EmitReturn(EmitContext& ctx) { | ||
| 68 | NotImplemented(); | ||
| 69 | } | ||
| 70 | |||
| 71 | void EmitJoin(EmitContext& ctx) { | ||
| 72 | NotImplemented(); | ||
| 73 | } | ||
| 74 | |||
| 75 | void EmitUnreachable(EmitContext& ctx) { | ||
| 76 | NotImplemented(); | ||
| 77 | } | ||
| 78 | |||
| 79 | void EmitDemoteToHelperInvocation(EmitContext& ctx, std::string_view continue_label) { | ||
| 80 | ctx.Add("discard;"); | ||
| 81 | } | ||
| 82 | |||
| 83 | void EmitPrologue(EmitContext& ctx) {} | ||
| 84 | |||
| 85 | void EmitEpilogue(EmitContext& ctx) {} | ||
| 86 | |||
| 87 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { | ||
| 88 | ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream)); | ||
| 89 | } | ||
| 90 | |||
| 91 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { | ||
| 92 | ctx.Add("EndStreamPrimitive(int({}));", ctx.var_alloc.Consume(stream)); | ||
| 93 | } | ||
| 94 | |||
| 95 | void EmitGetRegister(EmitContext& ctx) { | 17 | void EmitGetRegister(EmitContext& ctx) { |
| 96 | NotImplemented(); | 18 | NotImplemented(); |
| 97 | } | 19 | } |
| @@ -156,26 +78,6 @@ void EmitSetOFlag(EmitContext& ctx) { | |||
| 156 | NotImplemented(); | 78 | NotImplemented(); |
| 157 | } | 79 | } |
| 158 | 80 | ||
| 159 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { | ||
| 160 | ctx.AddU1("{}=false;", inst); | ||
| 161 | } | ||
| 162 | |||
| 163 | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) { | ||
| 164 | NotImplemented(); | ||
| 165 | } | ||
| 166 | |||
| 167 | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst) { | ||
| 168 | NotImplemented(); | ||
| 169 | } | ||
| 170 | |||
| 171 | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst) { | ||
| 172 | ctx.AddU32("{}=0u;", inst); | ||
| 173 | } | ||
| 174 | |||
| 175 | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) { | ||
| 176 | NotImplemented(); | ||
| 177 | } | ||
| 178 | |||
| 179 | void EmitGetZeroFromOp(EmitContext& ctx) { | 81 | void EmitGetZeroFromOp(EmitContext& ctx) { |
| 180 | NotImplemented(); | 82 | NotImplemented(); |
| 181 | } | 83 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp index 578bc349f..5b6175903 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp | |||
| @@ -9,68 +9,55 @@ | |||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
| 12 | void EmitLoadSharedU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 12 | void EmitLoadSharedU8(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 13 | [[maybe_unused]] std::string_view offset) { | ||
| 14 | ctx.AddU32("{}=bitfieldExtract(smem[{}>>2],int({}%4)*8,8);", inst, offset, offset); | 13 | ctx.AddU32("{}=bitfieldExtract(smem[{}>>2],int({}%4)*8,8);", inst, offset, offset); |
| 15 | } | 14 | } |
| 16 | 15 | ||
| 17 | void EmitLoadSharedS8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 16 | void EmitLoadSharedS8(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 18 | [[maybe_unused]] std::string_view offset) { | ||
| 19 | ctx.AddS32("{}=bitfieldExtract(int(smem[{}>>2]),int({}%4)*8,8);", inst, offset, offset); | 17 | ctx.AddS32("{}=bitfieldExtract(int(smem[{}>>2]),int({}%4)*8,8);", inst, offset, offset); |
| 20 | } | 18 | } |
| 21 | 19 | ||
| 22 | void EmitLoadSharedU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 20 | void EmitLoadSharedU16(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 23 | [[maybe_unused]] std::string_view offset) { | ||
| 24 | ctx.AddU32("{}=bitfieldExtract(smem[{}>>2],int(({}>>1)%2)*16,16);", inst, offset, offset); | 21 | ctx.AddU32("{}=bitfieldExtract(smem[{}>>2],int(({}>>1)%2)*16,16);", inst, offset, offset); |
| 25 | } | 22 | } |
| 26 | 23 | ||
| 27 | void EmitLoadSharedS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 24 | void EmitLoadSharedS16(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 28 | [[maybe_unused]] std::string_view offset) { | ||
| 29 | ctx.AddS32("{}=bitfieldExtract(int(smem[{}>>2]),int(({}>>1)%2)*16,16);", inst, offset, offset); | 25 | ctx.AddS32("{}=bitfieldExtract(int(smem[{}>>2]),int(({}>>1)%2)*16,16);", inst, offset, offset); |
| 30 | } | 26 | } |
| 31 | 27 | ||
| 32 | void EmitLoadSharedU32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 28 | void EmitLoadSharedU32(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 33 | [[maybe_unused]] std::string_view offset) { | ||
| 34 | ctx.AddU32("{}=smem[{}>>2];", inst, offset); | 29 | ctx.AddU32("{}=smem[{}>>2];", inst, offset); |
| 35 | } | 30 | } |
| 36 | 31 | ||
| 37 | void EmitLoadSharedU64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 32 | void EmitLoadSharedU64(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 38 | [[maybe_unused]] std::string_view offset) { | ||
| 39 | ctx.AddU32x2("{}=uvec2(smem[{}>>2],smem[({}+4)>>2]);", inst, offset, offset); | 33 | ctx.AddU32x2("{}=uvec2(smem[{}>>2],smem[({}+4)>>2]);", inst, offset, offset); |
| 40 | } | 34 | } |
| 41 | 35 | ||
| 42 | void EmitLoadSharedU128([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 36 | void EmitLoadSharedU128(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 43 | [[maybe_unused]] std::string_view offset) { | ||
| 44 | ctx.AddU32x4("{}=uvec4(smem[{}>>2],smem[({}+4)>>2],smem[({}+8)>>2],smem[({}+12)>>2]);", inst, | 37 | ctx.AddU32x4("{}=uvec4(smem[{}>>2],smem[({}+4)>>2],smem[({}+8)>>2],smem[({}+12)>>2]);", inst, |
| 45 | offset, offset, offset, offset); | 38 | offset, offset, offset, offset); |
| 46 | } | 39 | } |
| 47 | 40 | ||
| 48 | void EmitWriteSharedU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view offset, | 41 | void EmitWriteSharedU8(EmitContext& ctx, std::string_view offset, std::string_view value) { |
| 49 | [[maybe_unused]] std::string_view value) { | ||
| 50 | ctx.Add("smem[{}>>2]=bitfieldInsert(smem[{}>>2],{},int({}%4)*8,8);", offset, offset, value, | 42 | ctx.Add("smem[{}>>2]=bitfieldInsert(smem[{}>>2],{},int({}%4)*8,8);", offset, offset, value, |
| 51 | offset); | 43 | offset); |
| 52 | } | 44 | } |
| 53 | 45 | ||
| 54 | void EmitWriteSharedU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view offset, | 46 | void EmitWriteSharedU16(EmitContext& ctx, std::string_view offset, std::string_view value) { |
| 55 | [[maybe_unused]] std::string_view value) { | ||
| 56 | ctx.Add("smem[{}>>2]=bitfieldInsert(smem[{}>>2],{},int(({}>>1)%2)*16,16);", offset, offset, | 47 | ctx.Add("smem[{}>>2]=bitfieldInsert(smem[{}>>2],{},int(({}>>1)%2)*16,16);", offset, offset, |
| 57 | value, offset); | 48 | value, offset); |
| 58 | } | 49 | } |
| 59 | 50 | ||
| 60 | void EmitWriteSharedU32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view offset, | 51 | void EmitWriteSharedU32(EmitContext& ctx, std::string_view offset, std::string_view value) { |
| 61 | [[maybe_unused]] std::string_view value) { | ||
| 62 | ctx.Add("smem[{}>>2]={};", offset, value); | 52 | ctx.Add("smem[{}>>2]={};", offset, value); |
| 63 | } | 53 | } |
| 64 | 54 | ||
| 65 | void EmitWriteSharedU64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view offset, | 55 | void EmitWriteSharedU64(EmitContext& ctx, std::string_view offset, std::string_view value) { |
| 66 | [[maybe_unused]] std::string_view value) { | ||
| 67 | ctx.Add("smem[{}>>2]={}.x;", offset, value); | 56 | ctx.Add("smem[{}>>2]={}.x;", offset, value); |
| 68 | ctx.Add("smem[({}+4)>>2]={}.y;", offset, value); | 57 | ctx.Add("smem[({}+4)>>2]={}.y;", offset, value); |
| 69 | } | 58 | } |
| 70 | 59 | ||
| 71 | void EmitWriteSharedU128([[maybe_unused]] EmitContext& ctx, | 60 | void EmitWriteSharedU128(EmitContext& ctx, std::string_view offset, std::string_view value) { |
| 72 | [[maybe_unused]] std::string_view offset, | ||
| 73 | [[maybe_unused]] std::string_view value) { | ||
| 74 | ctx.Add("smem[{}>>2]={}.x;", offset, value); | 61 | ctx.Add("smem[{}>>2]={}.x;", offset, value); |
| 75 | ctx.Add("smem[({}+4)>>2]={}.y;", offset, value); | 62 | ctx.Add("smem[({}+4)>>2]={}.y;", offset, value); |
| 76 | ctx.Add("smem[({}+8)>>2]={}.z;", offset, value); | 63 | ctx.Add("smem[({}+8)>>2]={}.z;", offset, value); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp index e69de29bb..2155b8802 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_special.cpp | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | ||
| 10 | |||
| 11 | namespace Shader::Backend::GLSL { | ||
| 12 | |||
| 13 | void EmitPhi(EmitContext& ctx, IR::Inst& phi) { | ||
| 14 | const size_t num_args{phi.NumArgs()}; | ||
| 15 | for (size_t i = 0; i < num_args; ++i) { | ||
| 16 | ctx.var_alloc.Consume(phi.Arg(i)); | ||
| 17 | } | ||
| 18 | if (!phi.Definition<Id>().is_valid) { | ||
| 19 | // The phi node wasn't forward defined | ||
| 20 | ctx.var_alloc.PhiDefine(phi, phi.Arg(0).Type()); | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | void EmitVoid(EmitContext&) {} | ||
| 25 | |||
| 26 | void EmitReference(EmitContext& ctx, const IR::Value& value) { | ||
| 27 | ctx.var_alloc.Consume(value); | ||
| 28 | } | ||
| 29 | |||
| 30 | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | ||
| 31 | IR::Inst& phi{*phi_value.InstRecursive()}; | ||
| 32 | const auto phi_type{phi.Arg(0).Type()}; | ||
| 33 | if (!phi.Definition<Id>().is_valid) { | ||
| 34 | // The phi node wasn't forward defined | ||
| 35 | ctx.var_alloc.PhiDefine(phi, phi_type); | ||
| 36 | } | ||
| 37 | const auto phi_reg{ctx.var_alloc.Consume(IR::Value{&phi})}; | ||
| 38 | const auto val_reg{ctx.var_alloc.Consume(value)}; | ||
| 39 | if (phi_reg == val_reg) { | ||
| 40 | return; | ||
| 41 | } | ||
| 42 | ctx.Add("{}={};", phi_reg, val_reg); | ||
| 43 | } | ||
| 44 | |||
| 45 | void EmitPrologue(EmitContext&) { | ||
| 46 | // TODO | ||
| 47 | } | ||
| 48 | |||
| 49 | void EmitEpilogue(EmitContext&) { | ||
| 50 | // TODO | ||
| 51 | } | ||
| 52 | |||
| 53 | void EmitEmitVertex(EmitContext& ctx, const IR::Value& stream) { | ||
| 54 | ctx.Add("EmitStreamVertex(int({}));", ctx.var_alloc.Consume(stream)); | ||
| 55 | } | ||
| 56 | |||
| 57 | void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { | ||
| 58 | ctx.Add("EndStreamPrimitive(int({}));", ctx.var_alloc.Consume(stream)); | ||
| 59 | } | ||
| 60 | |||
| 61 | } // namespace Shader::Backend::GLSL | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp index e69de29bb..15bf02dd6 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_undefined.cpp | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <string_view> | ||
| 6 | |||
| 7 | #include "shader_recompiler/backend/glsl/emit_context.h" | ||
| 8 | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||
| 9 | |||
| 10 | namespace Shader::Backend::GLSL { | ||
| 11 | |||
| 12 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { | ||
| 13 | ctx.AddU1("{}=false;", inst); | ||
| 14 | } | ||
| 15 | |||
| 16 | void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) { | ||
| 17 | ctx.AddU32("{}=0u;", inst); | ||
| 18 | } | ||
| 19 | |||
| 20 | void EmitUndefU16(EmitContext& ctx, IR::Inst& inst) { | ||
| 21 | ctx.AddU32("{}=0u;", inst); | ||
| 22 | } | ||
| 23 | |||
| 24 | void EmitUndefU32(EmitContext& ctx, IR::Inst& inst) { | ||
| 25 | ctx.AddU32("{}=0u;", inst); | ||
| 26 | } | ||
| 27 | |||
| 28 | void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) { | ||
| 29 | ctx.AddU64("{}=0u;", inst); | ||
| 30 | } | ||
| 31 | |||
| 32 | } // namespace Shader::Backend::GLSL | ||