diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
5 files changed, 109 insertions, 111 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index cbcf0a1eb..ed10eca8a 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -559,53 +559,45 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { | |||
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | void EmitContext::SetupImages(Bindings& bindings) { | 561 | void EmitContext::SetupImages(Bindings& bindings) { |
| 562 | image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); | 562 | image_buffers.reserve(info.image_buffer_descriptors.size()); |
| 563 | for (const auto& desc : info.image_buffer_descriptors) { | 563 | for (const auto& desc : info.image_buffer_descriptors) { |
| 564 | image_buffer_bindings.push_back(bindings.image); | 564 | image_buffers.push_back({bindings.image, desc.count}); |
| 565 | const auto indices{bindings.image + desc.count}; | ||
| 566 | const auto format{ImageFormatString(desc.format)}; | 565 | const auto format{ImageFormatString(desc.format)}; |
| 567 | for (u32 index = bindings.image; index < indices; ++index) { | 566 | const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; |
| 568 | header += fmt::format("layout(binding={}{}) uniform uimageBuffer img{};", | 567 | header += fmt::format("layout(binding={}{}) uniform uimageBuffer img{}{};", bindings.image, |
| 569 | bindings.image, format, index); | 568 | format, bindings.image, array_decorator); |
| 570 | } | ||
| 571 | bindings.image += desc.count; | 569 | bindings.image += desc.count; |
| 572 | } | 570 | } |
| 573 | image_bindings.reserve(info.image_descriptors.size()); | 571 | images.reserve(info.image_descriptors.size()); |
| 574 | for (const auto& desc : info.image_descriptors) { | 572 | for (const auto& desc : info.image_descriptors) { |
| 575 | image_bindings.push_back(bindings.image); | 573 | images.push_back({bindings.image, desc.count}); |
| 576 | const auto format{ImageFormatString(desc.format)}; | 574 | const auto format{ImageFormatString(desc.format)}; |
| 577 | const auto image_type{ImageType(desc.type)}; | 575 | const auto image_type{ImageType(desc.type)}; |
| 578 | const auto qualifier{desc.is_written ? "" : "readonly "}; | 576 | const auto qualifier{desc.is_written ? "" : "readonly "}; |
| 579 | const auto indices{bindings.image + desc.count}; | 577 | const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; |
| 580 | for (u32 index = bindings.image; index < indices; ++index) { | 578 | header += fmt::format("layout(binding={}{})uniform {}{} img{}{};", bindings.image, format, |
| 581 | header += fmt::format("layout(binding={}{})uniform {}{} img{};", bindings.image, format, | 579 | qualifier, image_type, bindings.image, array_decorator); |
| 582 | qualifier, image_type, index); | ||
| 583 | } | ||
| 584 | bindings.image += desc.count; | 580 | bindings.image += desc.count; |
| 585 | } | 581 | } |
| 586 | } | 582 | } |
| 587 | 583 | ||
| 588 | void EmitContext::SetupTextures(Bindings& bindings) { | 584 | void EmitContext::SetupTextures(Bindings& bindings) { |
| 589 | texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); | 585 | texture_buffers.reserve(info.texture_buffer_descriptors.size()); |
| 590 | for (const auto& desc : info.texture_buffer_descriptors) { | 586 | for (const auto& desc : info.texture_buffer_descriptors) { |
| 591 | texture_buffer_bindings.push_back(bindings.texture); | 587 | texture_buffers.push_back({bindings.texture, desc.count}); |
| 592 | const auto sampler_type{SamplerType(TextureType::Buffer, false)}; | 588 | const auto sampler_type{SamplerType(TextureType::Buffer, false)}; |
| 593 | const auto indices{bindings.texture + desc.count}; | 589 | const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; |
| 594 | for (u32 index = bindings.texture; index < indices; ++index) { | 590 | header += fmt::format("layout(binding={}) uniform {} tex{}{};", bindings.texture, |
| 595 | header += fmt::format("layout(binding={}) uniform {} tex{};", bindings.texture, | 591 | sampler_type, bindings.texture, array_decorator); |
| 596 | sampler_type, index); | ||
| 597 | } | ||
| 598 | bindings.texture += desc.count; | 592 | bindings.texture += desc.count; |
| 599 | } | 593 | } |
| 600 | texture_bindings.reserve(info.texture_descriptors.size()); | 594 | textures.reserve(info.texture_descriptors.size()); |
| 601 | for (const auto& desc : info.texture_descriptors) { | 595 | for (const auto& desc : info.texture_descriptors) { |
| 596 | textures.push_back({bindings.texture, desc.count}); | ||
| 602 | const auto sampler_type{SamplerType(desc.type, desc.is_depth)}; | 597 | const auto sampler_type{SamplerType(desc.type, desc.is_depth)}; |
| 603 | texture_bindings.push_back(bindings.texture); | 598 | const auto array_decorator{desc.count > 1 ? fmt::format("[{}]", desc.count) : ""}; |
| 604 | const auto indices{bindings.texture + desc.count}; | 599 | header += fmt::format("layout(binding={}) uniform {} tex{}{};", bindings.texture, |
| 605 | for (u32 index = bindings.texture; index < indices; ++index) { | 600 | sampler_type, bindings.texture, array_decorator); |
| 606 | header += fmt::format("layout(binding={}) uniform {} tex{};", bindings.texture, | ||
| 607 | sampler_type, index); | ||
| 608 | } | ||
| 609 | bindings.texture += desc.count; | 601 | bindings.texture += desc.count; |
| 610 | } | 602 | } |
| 611 | } | 603 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h index 9d8be0c9a..685f56089 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.h +++ b/src/shader_recompiler/backend/glsl/emit_context.h | |||
| @@ -36,6 +36,11 @@ struct GenericElementInfo { | |||
| 36 | u32 num_components{}; | 36 | u32 num_components{}; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | struct TextureImageDefinition { | ||
| 40 | u32 binding; | ||
| 41 | u32 count; | ||
| 42 | }; | ||
| 43 | |||
| 39 | class EmitContext { | 44 | class EmitContext { |
| 40 | public: | 45 | public: |
| 41 | explicit EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, | 46 | explicit EmitContext(IR::Program& program, Bindings& bindings, const Profile& profile_, |
| @@ -142,10 +147,10 @@ public: | |||
| 142 | std::string_view stage_name = "invalid"; | 147 | std::string_view stage_name = "invalid"; |
| 143 | std::string_view position_name = "gl_Position"; | 148 | std::string_view position_name = "gl_Position"; |
| 144 | 149 | ||
| 145 | std::vector<u32> texture_buffer_bindings; | 150 | std::vector<TextureImageDefinition> texture_buffers; |
| 146 | std::vector<u32> image_buffer_bindings; | 151 | std::vector<TextureImageDefinition> image_buffers; |
| 147 | std::vector<u32> texture_bindings; | 152 | std::vector<TextureImageDefinition> textures; |
| 148 | std::vector<u32> image_bindings; | 153 | std::vector<TextureImageDefinition> images; |
| 149 | std::array<std::array<GenericElementInfo, 4>, 32> output_generics{}; | 154 | std::array<std::array<GenericElementInfo, 4>, 32> output_generics{}; |
| 150 | 155 | ||
| 151 | bool uses_y_direction{}; | 156 | bool uses_y_direction{}; |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 00fe288e2..6a98f7ac2 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -12,20 +12,18 @@ | |||
| 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, const IR::Value& index) { |
| 16 | if (info.type == TextureType::Buffer) { | 16 | const auto def{info.type == TextureType::Buffer ? ctx.texture_buffers.at(info.descriptor_index) |
| 17 | return fmt::format("tex{}", ctx.texture_buffer_bindings.at(info.descriptor_index)); | 17 | : ctx.textures.at(info.descriptor_index)}; |
| 18 | } else { | 18 | const auto index_offset{def.count > 1 ? fmt::format("[{}]", ctx.var_alloc.Consume(index)) : ""}; |
| 19 | return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index)); | 19 | return fmt::format("tex{}{}", def.binding, index_offset); |
| 20 | } | ||
| 21 | } | 20 | } |
| 22 | 21 | ||
| 23 | std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info) { | 22 | std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info, const IR::Value& index) { |
| 24 | if (info.type == TextureType::Buffer) { | 23 | const auto def{info.type == TextureType::Buffer ? ctx.image_buffers.at(info.descriptor_index) |
| 25 | return fmt::format("img{}", ctx.image_buffer_bindings.at(info.descriptor_index)); | 24 | : ctx.images.at(info.descriptor_index)}; |
| 26 | } else { | 25 | const auto index_offset{def.count > 1 ? fmt::format("[{}]", ctx.var_alloc.Consume(index)) : ""}; |
| 27 | return fmt::format("img{}", ctx.image_bindings.at(info.descriptor_index)); | 26 | return fmt::format("img{}{}", def.binding, index_offset); |
| 28 | } | ||
| 29 | } | 27 | } |
| 30 | 28 | ||
| 31 | std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) { | 29 | std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) { |
| @@ -137,14 +135,14 @@ IR::Inst* PrepareSparse(IR::Inst& inst) { | |||
| 137 | } | 135 | } |
| 138 | } // Anonymous namespace | 136 | } // Anonymous namespace |
| 139 | 137 | ||
| 140 | void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, | 138 | void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 141 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 139 | std::string_view coords, std::string_view bias_lc, |
| 142 | std::string_view bias_lc, const IR::Value& offset) { | 140 | const IR::Value& offset) { |
| 143 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 141 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 144 | if (info.has_lod_clamp) { | 142 | if (info.has_lod_clamp) { |
| 145 | throw NotImplementedException("EmitImageSampleImplicitLod Lod clamp samples"); | 143 | throw NotImplementedException("EmitImageSampleImplicitLod Lod clamp samples"); |
| 146 | } | 144 | } |
| 147 | const auto texture{Texture(ctx, info)}; | 145 | const auto texture{Texture(ctx, info, index)}; |
| 148 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | 146 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; |
| 149 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 147 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 150 | const auto sparse_inst{PrepareSparse(inst)}; | 148 | const auto sparse_inst{PrepareSparse(inst)}; |
| @@ -175,9 +173,9 @@ void EmitImageSampleImplicitLod(EmitContext& ctx, IR::Inst& inst, | |||
| 175 | } | 173 | } |
| 176 | } | 174 | } |
| 177 | 175 | ||
| 178 | void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, | 176 | void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 179 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 177 | std::string_view coords, std::string_view lod_lc, |
| 180 | std::string_view lod_lc, const IR::Value& offset) { | 178 | const IR::Value& offset) { |
| 181 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 179 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 182 | if (info.has_bias) { | 180 | if (info.has_bias) { |
| 183 | throw NotImplementedException("EmitImageSampleExplicitLod Bias texture samples"); | 181 | throw NotImplementedException("EmitImageSampleExplicitLod Bias texture samples"); |
| @@ -185,7 +183,7 @@ void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, | |||
| 185 | if (info.has_lod_clamp) { | 183 | if (info.has_lod_clamp) { |
| 186 | throw NotImplementedException("EmitImageSampleExplicitLod Lod clamp samples"); | 184 | throw NotImplementedException("EmitImageSampleExplicitLod Lod clamp samples"); |
| 187 | } | 185 | } |
| 188 | const auto texture{Texture(ctx, info)}; | 186 | const auto texture{Texture(ctx, info, index)}; |
| 189 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 187 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 190 | const auto sparse_inst{PrepareSparse(inst)}; | 188 | const auto sparse_inst{PrepareSparse(inst)}; |
| 191 | if (!sparse_inst) { | 189 | if (!sparse_inst) { |
| @@ -208,8 +206,7 @@ void EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst& inst, | |||
| 208 | } | 206 | } |
| 209 | } | 207 | } |
| 210 | 208 | ||
| 211 | void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, | 209 | void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 212 | [[maybe_unused]] const IR::Value& index, | ||
| 213 | std::string_view coords, std::string_view dref, | 210 | std::string_view coords, std::string_view dref, |
| 214 | std::string_view bias_lc, const IR::Value& offset) { | 211 | std::string_view bias_lc, const IR::Value& offset) { |
| 215 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 212 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| @@ -223,7 +220,7 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, | |||
| 223 | if (info.has_lod_clamp) { | 220 | if (info.has_lod_clamp) { |
| 224 | throw NotImplementedException("EmitImageSampleDrefImplicitLod Lod clamp samples"); | 221 | throw NotImplementedException("EmitImageSampleDrefImplicitLod Lod clamp samples"); |
| 225 | } | 222 | } |
| 226 | const auto texture{Texture(ctx, info)}; | 223 | const auto texture{Texture(ctx, info, index)}; |
| 227 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; | 224 | const auto bias{info.has_bias ? fmt::format(",{}", bias_lc) : ""}; |
| 228 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; | 225 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; |
| 229 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; | 226 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; |
| @@ -263,8 +260,7 @@ void EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst& inst, | |||
| 263 | } | 260 | } |
| 264 | } | 261 | } |
| 265 | 262 | ||
| 266 | void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, | 263 | void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 267 | [[maybe_unused]] const IR::Value& index, | ||
| 268 | std::string_view coords, std::string_view dref, | 264 | std::string_view coords, std::string_view dref, |
| 269 | std::string_view lod_lc, const IR::Value& offset) { | 265 | std::string_view lod_lc, const IR::Value& offset) { |
| 270 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 266 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| @@ -278,7 +274,7 @@ void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, | |||
| 278 | if (info.has_lod_clamp) { | 274 | if (info.has_lod_clamp) { |
| 279 | throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); | 275 | throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); |
| 280 | } | 276 | } |
| 281 | const auto texture{Texture(ctx, info)}; | 277 | const auto texture{Texture(ctx, info, index)}; |
| 282 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; | 278 | const bool needs_shadow_ext{NeedsShadowLodExt(info.type)}; |
| 283 | const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && needs_shadow_ext}; | 279 | const bool use_grad{!ctx.profile.support_gl_texture_shadow_lod && needs_shadow_ext}; |
| 284 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; | 280 | const auto cast{needs_shadow_ext ? "vec4" : "vec3"}; |
| @@ -313,10 +309,10 @@ void EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst& inst, | |||
| 313 | } | 309 | } |
| 314 | } | 310 | } |
| 315 | 311 | ||
| 316 | void EmitImageGather(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 312 | void EmitImageGather(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 317 | std::string_view coords, const IR::Value& offset, const IR::Value& offset2) { | 313 | std::string_view coords, const IR::Value& offset, const IR::Value& offset2) { |
| 318 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 314 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 319 | const auto texture{Texture(ctx, info)}; | 315 | const auto texture{Texture(ctx, info, index)}; |
| 320 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 316 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 321 | const auto sparse_inst{PrepareSparse(inst)}; | 317 | const auto sparse_inst{PrepareSparse(inst)}; |
| 322 | if (!sparse_inst) { | 318 | if (!sparse_inst) { |
| @@ -355,11 +351,11 @@ void EmitImageGather(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR | |||
| 355 | info.gather_component); | 351 | info.gather_component); |
| 356 | } | 352 | } |
| 357 | 353 | ||
| 358 | void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 354 | void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 359 | std::string_view coords, const IR::Value& offset, const IR::Value& offset2, | 355 | std::string_view coords, const IR::Value& offset, const IR::Value& offset2, |
| 360 | std::string_view dref) { | 356 | std::string_view dref) { |
| 361 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 357 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 362 | const auto texture{Texture(ctx, info)}; | 358 | const auto texture{Texture(ctx, info, index)}; |
| 363 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 359 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 364 | const auto sparse_inst{PrepareSparse(inst)}; | 360 | const auto sparse_inst{PrepareSparse(inst)}; |
| 365 | if (!sparse_inst) { | 361 | if (!sparse_inst) { |
| @@ -395,7 +391,7 @@ void EmitImageGatherDref(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] cons | |||
| 395 | *sparse_inst, texture, CastToIntVec(coords, info), dref, offsets, texel); | 391 | *sparse_inst, texture, CastToIntVec(coords, info), dref, offsets, texel); |
| 396 | } | 392 | } |
| 397 | 393 | ||
| 398 | void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 394 | void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 399 | std::string_view coords, std::string_view offset, std::string_view lod, | 395 | std::string_view coords, std::string_view offset, std::string_view lod, |
| 400 | [[maybe_unused]] std::string_view ms) { | 396 | [[maybe_unused]] std::string_view ms) { |
| 401 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 397 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| @@ -405,7 +401,7 @@ void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR: | |||
| 405 | if (info.has_lod_clamp) { | 401 | if (info.has_lod_clamp) { |
| 406 | throw NotImplementedException("EmitImageFetch Lod clamp samples"); | 402 | throw NotImplementedException("EmitImageFetch Lod clamp samples"); |
| 407 | } | 403 | } |
| 408 | const auto texture{Texture(ctx, info)}; | 404 | const auto texture{Texture(ctx, info, index)}; |
| 409 | const auto sparse_inst{PrepareSparse(inst)}; | 405 | const auto sparse_inst{PrepareSparse(inst)}; |
| 410 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 406 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 411 | if (!sparse_inst) { | 407 | if (!sparse_inst) { |
| @@ -433,10 +429,10 @@ void EmitImageFetch(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR: | |||
| 433 | } | 429 | } |
| 434 | } | 430 | } |
| 435 | 431 | ||
| 436 | void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, | 432 | void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 437 | [[maybe_unused]] const IR::Value& index, std::string_view lod) { | 433 | std::string_view lod) { |
| 438 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 434 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 439 | const auto texture{Texture(ctx, info)}; | 435 | const auto texture{Texture(ctx, info, index)}; |
| 440 | switch (info.type) { | 436 | switch (info.type) { |
| 441 | case TextureType::Color1D: | 437 | case TextureType::Color1D: |
| 442 | return ctx.AddU32x4( | 438 | return ctx.AddU32x4( |
| @@ -460,14 +456,14 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, | |||
| 460 | throw LogicError("Unspecified image type {}", info.type.Value()); | 456 | throw LogicError("Unspecified image type {}", info.type.Value()); |
| 461 | } | 457 | } |
| 462 | 458 | ||
| 463 | void EmitImageQueryLod(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 459 | void EmitImageQueryLod(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 464 | std::string_view coords) { | 460 | std::string_view coords) { |
| 465 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 461 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 466 | const auto texture{Texture(ctx, info)}; | 462 | const auto texture{Texture(ctx, info, index)}; |
| 467 | return ctx.AddF32x4("{}=vec4(textureQueryLod({},{}),0.0,0.0);", inst, texture, coords); | 463 | return ctx.AddF32x4("{}=vec4(textureQueryLod({},{}),0.0,0.0);", inst, texture, coords); |
| 468 | } | 464 | } |
| 469 | 465 | ||
| 470 | void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 466 | void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 471 | std::string_view coords, const IR::Value& derivatives, | 467 | std::string_view coords, const IR::Value& derivatives, |
| 472 | const IR::Value& offset, [[maybe_unused]] const IR::Value& lod_clamp) { | 468 | const IR::Value& offset, [[maybe_unused]] const IR::Value& lod_clamp) { |
| 473 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 469 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| @@ -481,7 +477,7 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const | |||
| 481 | if (!offset.IsEmpty()) { | 477 | if (!offset.IsEmpty()) { |
| 482 | throw NotImplementedException("EmitImageGradient offset"); | 478 | throw NotImplementedException("EmitImageGradient offset"); |
| 483 | } | 479 | } |
| 484 | const auto texture{Texture(ctx, info)}; | 480 | const auto texture{Texture(ctx, info, index)}; |
| 485 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | 481 | const auto texel{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; |
| 486 | const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp}; | 482 | const bool multi_component{info.num_derivates > 1 || info.has_lod_clamp}; |
| 487 | const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)}; | 483 | const auto derivatives_vec{ctx.var_alloc.Consume(derivatives)}; |
| @@ -494,65 +490,60 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const | |||
| 494 | } | 490 | } |
| 495 | } | 491 | } |
| 496 | 492 | ||
| 497 | void EmitImageRead(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 493 | void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 498 | std::string_view coords) { | 494 | std::string_view coords) { |
| 499 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 495 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 500 | const auto sparse_inst{PrepareSparse(inst)}; | 496 | const auto sparse_inst{PrepareSparse(inst)}; |
| 501 | if (sparse_inst) { | 497 | if (sparse_inst) { |
| 502 | throw NotImplementedException("EmitImageRead Sparse"); | 498 | throw NotImplementedException("EmitImageRead Sparse"); |
| 503 | } | 499 | } |
| 504 | const auto image{Image(ctx, info)}; | 500 | const auto image{Image(ctx, info, index)}; |
| 505 | ctx.AddU32x4("{}=uvec4(imageLoad({},{}));", inst, image, TexelFetchCastToInt(coords, info)); | 501 | ctx.AddU32x4("{}=uvec4(imageLoad({},{}));", inst, image, TexelFetchCastToInt(coords, info)); |
| 506 | } | 502 | } |
| 507 | 503 | ||
| 508 | void EmitImageWrite(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 504 | void EmitImageWrite(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 509 | std::string_view coords, std::string_view color) { | 505 | std::string_view coords, std::string_view color) { |
| 510 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 506 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 511 | const auto image{Image(ctx, info)}; | 507 | const auto image{Image(ctx, info, index)}; |
| 512 | ctx.Add("imageStore({},{},{});", image, TexelFetchCastToInt(coords, info), color); | 508 | ctx.Add("imageStore({},{},{});", image, TexelFetchCastToInt(coords, info), color); |
| 513 | } | 509 | } |
| 514 | 510 | ||
| 515 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, | 511 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 516 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 512 | std::string_view coords, std::string_view value) { |
| 517 | std::string_view value) { | ||
| 518 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 513 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 519 | const auto image{Image(ctx, info)}; | 514 | const auto image{Image(ctx, info, index)}; |
| 520 | ctx.AddU32("{}=imageAtomicAdd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 515 | ctx.AddU32("{}=imageAtomicAdd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 521 | value); | 516 | value); |
| 522 | } | 517 | } |
| 523 | 518 | ||
| 524 | void EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, | 519 | void EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 525 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 520 | std::string_view coords, std::string_view value) { |
| 526 | std::string_view value) { | ||
| 527 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 521 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 528 | const auto image{Image(ctx, info)}; | 522 | const auto image{Image(ctx, info, index)}; |
| 529 | ctx.AddU32("{}=imageAtomicMin({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), | 523 | ctx.AddU32("{}=imageAtomicMin({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 530 | value); | 524 | value); |
| 531 | } | 525 | } |
| 532 | 526 | ||
| 533 | void EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, | 527 | void EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 534 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 528 | std::string_view coords, std::string_view value) { |
| 535 | std::string_view value) { | ||
| 536 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 529 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 537 | const auto image{Image(ctx, info)}; | 530 | const auto image{Image(ctx, info, index)}; |
| 538 | ctx.AddU32("{}=imageAtomicMin({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), | 531 | ctx.AddU32("{}=imageAtomicMin({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 539 | value); | 532 | value); |
| 540 | } | 533 | } |
| 541 | 534 | ||
| 542 | void EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, | 535 | void EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 543 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 536 | std::string_view coords, std::string_view value) { |
| 544 | std::string_view value) { | ||
| 545 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 537 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 546 | const auto image{Image(ctx, info)}; | 538 | const auto image{Image(ctx, info, index)}; |
| 547 | ctx.AddU32("{}=imageAtomicMax({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), | 539 | ctx.AddU32("{}=imageAtomicMax({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 548 | value); | 540 | value); |
| 549 | } | 541 | } |
| 550 | 542 | ||
| 551 | void EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, | 543 | void EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 552 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 544 | std::string_view coords, std::string_view value) { |
| 553 | std::string_view value) { | ||
| 554 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 545 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 555 | const auto image{Image(ctx, info)}; | 546 | const auto image{Image(ctx, info, index)}; |
| 556 | ctx.AddU32("{}=imageAtomicMax({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), | 547 | ctx.AddU32("{}=imageAtomicMax({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), |
| 557 | value); | 548 | value); |
| 558 | } | 549 | } |
| @@ -567,35 +558,34 @@ void EmitImageAtomicDec32(EmitContext&, IR::Inst&, const IR::Value&, std::string | |||
| 567 | NotImplemented(); | 558 | NotImplemented(); |
| 568 | } | 559 | } |
| 569 | 560 | ||
| 570 | void EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 561 | void EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 571 | std::string_view coords, std::string_view value) { | 562 | std::string_view coords, std::string_view value) { |
| 572 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 563 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 573 | const auto image{Image(ctx, info)}; | 564 | const auto image{Image(ctx, info, index)}; |
| 574 | ctx.AddU32("{}=imageAtomicAnd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 565 | ctx.AddU32("{}=imageAtomicAnd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 575 | value); | 566 | value); |
| 576 | } | 567 | } |
| 577 | 568 | ||
| 578 | void EmitImageAtomicOr32(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 569 | void EmitImageAtomicOr32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 579 | std::string_view coords, std::string_view value) { | 570 | std::string_view coords, std::string_view value) { |
| 580 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 571 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 581 | const auto image{Image(ctx, info)}; | 572 | const auto image{Image(ctx, info, index)}; |
| 582 | ctx.AddU32("{}=imageAtomicOr({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 573 | ctx.AddU32("{}=imageAtomicOr({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 583 | value); | 574 | value); |
| 584 | } | 575 | } |
| 585 | 576 | ||
| 586 | void EmitImageAtomicXor32(EmitContext& ctx, IR::Inst& inst, [[maybe_unused]] const IR::Value& index, | 577 | void EmitImageAtomicXor32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 587 | std::string_view coords, std::string_view value) { | 578 | std::string_view coords, std::string_view value) { |
| 588 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 579 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 589 | const auto image{Image(ctx, info)}; | 580 | const auto image{Image(ctx, info, index)}; |
| 590 | ctx.AddU32("{}=imageAtomicXor({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 581 | ctx.AddU32("{}=imageAtomicXor({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 591 | value); | 582 | value); |
| 592 | } | 583 | } |
| 593 | 584 | ||
| 594 | void EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, | 585 | void EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, |
| 595 | [[maybe_unused]] const IR::Value& index, std::string_view coords, | 586 | std::string_view coords, std::string_view value) { |
| 596 | std::string_view value) { | ||
| 597 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 587 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 598 | const auto image{Image(ctx, info)}; | 588 | const auto image{Image(ctx, info, index)}; |
| 599 | ctx.AddU32("{}=imageAtomicExchange({},{},{});", inst, image, TexelFetchCastToInt(coords, info), | 589 | ctx.AddU32("{}=imageAtomicExchange({},{},{});", inst, image, TexelFetchCastToInt(coords, info), |
| 600 | value); | 590 | value); |
| 601 | } | 591 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp index 7aa6096e6..49fba9073 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_select.cpp | |||
| @@ -28,12 +28,12 @@ void EmitSelectU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::stri | |||
| 28 | 28 | ||
| 29 | void EmitSelectU32(EmitContext& ctx, IR::Inst& inst, std::string_view cond, | 29 | void EmitSelectU32(EmitContext& ctx, IR::Inst& inst, std::string_view cond, |
| 30 | std::string_view true_value, std::string_view false_value) { | 30 | std::string_view true_value, std::string_view false_value) { |
| 31 | ctx.AddU32("{}={}?uint({}):uint({});", inst, cond, true_value, false_value); | 31 | ctx.AddU32("{}={}?{}:{};", inst, cond, true_value, false_value); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | void EmitSelectU64(EmitContext& ctx, IR::Inst& inst, std::string_view cond, | 34 | void EmitSelectU64(EmitContext& ctx, IR::Inst& inst, std::string_view cond, |
| 35 | std::string_view true_value, std::string_view false_value) { | 35 | std::string_view true_value, std::string_view false_value) { |
| 36 | ctx.AddU64("{}={}?uint64_t({}):uint64_t({});", inst, cond, true_value, false_value); | 36 | ctx.AddU64("{}={}?{}:{};", inst, cond, true_value, false_value); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void EmitSelectF16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond, | 39 | void EmitSelectF16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] std::string_view cond, |
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 7abc6575f..8a13bf617 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_shared_memory.cpp | |||
| @@ -9,6 +9,17 @@ | |||
| 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 | namespace { | ||
| 13 | constexpr char cas_loop[]{"for(;;){{uint old_value={};uint " | ||
| 14 | "cas_result=atomicCompSwap({},old_value,bitfieldInsert({},{},{},{}));" | ||
| 15 | "if(cas_result==old_value){{break;}}}}"}; | ||
| 16 | |||
| 17 | void SharedWriteCas(EmitContext& ctx, std::string_view offset, std::string_view value, | ||
| 18 | std::string_view bit_offset, u32 num_bits) { | ||
| 19 | const auto smem{fmt::format("smem[{}>>2]", offset)}; | ||
| 20 | ctx.Add(cas_loop, smem, smem, smem, value, bit_offset, num_bits); | ||
| 21 | } | ||
| 22 | } // Anonymous namespace | ||
| 12 | void EmitLoadSharedU8(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { | 23 | void EmitLoadSharedU8(EmitContext& ctx, IR::Inst& inst, std::string_view offset) { |
| 13 | ctx.AddU32("{}=bitfieldExtract(smem[{}>>2],int({}%4)*8,8);", inst, offset, offset); | 24 | ctx.AddU32("{}=bitfieldExtract(smem[{}>>2],int({}%4)*8,8);", inst, offset, offset); |
| 14 | } | 25 | } |
| @@ -39,13 +50,13 @@ void EmitLoadSharedU128(EmitContext& ctx, IR::Inst& inst, std::string_view offse | |||
| 39 | } | 50 | } |
| 40 | 51 | ||
| 41 | void EmitWriteSharedU8(EmitContext& ctx, std::string_view offset, std::string_view value) { | 52 | void EmitWriteSharedU8(EmitContext& ctx, std::string_view offset, std::string_view value) { |
| 42 | ctx.Add("smem[{}>>2]=bitfieldInsert(smem[{}>>2],{},int({}%4)*8,8);", offset, offset, value, | 53 | const auto bit_offset{fmt::format("int({}%4)*8", offset)}; |
| 43 | offset); | 54 | SharedWriteCas(ctx, offset, value, bit_offset, 8); |
| 44 | } | 55 | } |
| 45 | 56 | ||
| 46 | void EmitWriteSharedU16(EmitContext& ctx, std::string_view offset, std::string_view value) { | 57 | void EmitWriteSharedU16(EmitContext& ctx, std::string_view offset, std::string_view value) { |
| 47 | ctx.Add("smem[{}>>2]=bitfieldInsert(smem[{}>>2],{},int(({}>>1)%2)*16,16);", offset, offset, | 58 | const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset)}; |
| 48 | value, offset); | 59 | SharedWriteCas(ctx, offset, value, bit_offset, 16); |
| 49 | } | 60 | } |
| 50 | 61 | ||
| 51 | void EmitWriteSharedU32(EmitContext& ctx, std::string_view offset, std::string_view value) { | 62 | void EmitWriteSharedU32(EmitContext& ctx, std::string_view offset, std::string_view value) { |