diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_context.cpp | 50 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | 33 |
2 files changed, 74 insertions, 9 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 846d38bfc..5048c8b68 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -91,11 +91,42 @@ std::string_view SamplerType(TextureType type, bool is_depth) { | |||
| 91 | case TextureType::Buffer: | 91 | case TextureType::Buffer: |
| 92 | return "samplerBuffer"; | 92 | return "samplerBuffer"; |
| 93 | default: | 93 | default: |
| 94 | fmt::print("Texture type: {}", type); | ||
| 95 | throw NotImplementedException("Texture type: {}", type); | 94 | throw NotImplementedException("Texture type: {}", type); |
| 96 | } | 95 | } |
| 97 | } | 96 | } |
| 98 | 97 | ||
| 98 | std::string_view ImageType(TextureType type) { | ||
| 99 | switch (type) { | ||
| 100 | case TextureType::Color2D: | ||
| 101 | return "uimage2D"; | ||
| 102 | default: | ||
| 103 | throw NotImplementedException("Image type: {}", type); | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | std::string_view ImageFormatString(ImageFormat format) { | ||
| 108 | switch (format) { | ||
| 109 | case ImageFormat::Typeless: | ||
| 110 | return ""; | ||
| 111 | case ImageFormat::R8_UINT: | ||
| 112 | return ",r8ui"; | ||
| 113 | case ImageFormat::R8_SINT: | ||
| 114 | return ",r8i"; | ||
| 115 | case ImageFormat::R16_UINT: | ||
| 116 | return ",r16ui"; | ||
| 117 | case ImageFormat::R16_SINT: | ||
| 118 | return ",r16i"; | ||
| 119 | case ImageFormat::R32_UINT: | ||
| 120 | return ",r32ui"; | ||
| 121 | case ImageFormat::R32G32_UINT: | ||
| 122 | return ",rg32ui"; | ||
| 123 | case ImageFormat::R32G32B32A32_UINT: | ||
| 124 | return ",rgba32ui"; | ||
| 125 | default: | ||
| 126 | throw NotImplementedException("Image format: {}", format); | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 99 | std::string_view GetTessMode(TessPrimitive primitive) { | 130 | std::string_view GetTessMode(TessPrimitive primitive) { |
| 100 | switch (primitive) { | 131 | switch (primitive) { |
| 101 | case TessPrimitive::Triangles: | 132 | case TessPrimitive::Triangles: |
| @@ -250,6 +281,7 @@ void EmitContext::SetupExtensions(std::string&) { | |||
| 250 | // TODO: track this usage | 281 | // TODO: track this usage |
| 251 | header += "#extension GL_ARB_sparse_texture2 : enable\n"; | 282 | header += "#extension GL_ARB_sparse_texture2 : enable\n"; |
| 252 | header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | 283 | header += "#extension GL_EXT_texture_shadow_lod : enable\n"; |
| 284 | header += "#extension GL_EXT_shader_image_load_formatted : enable\n"; | ||
| 253 | if (info.uses_int64) { | 285 | if (info.uses_int64) { |
| 254 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | 286 | header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; |
| 255 | } | 287 | } |
| @@ -396,15 +428,25 @@ void EmitContext::DefineHelperFunctions() { | |||
| 396 | void EmitContext::SetupImages(Bindings& bindings) { | 428 | void EmitContext::SetupImages(Bindings& bindings) { |
| 397 | image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); | 429 | image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); |
| 398 | for (const auto& desc : info.image_buffer_descriptors) { | 430 | for (const auto& desc : info.image_buffer_descriptors) { |
| 399 | throw NotImplementedException("image_buffer_descriptors"); | 431 | const auto indices{bindings.image + desc.count}; |
| 432 | for (u32 index = bindings.image; index < indices; ++index) { | ||
| 433 | header += fmt::format("layout(binding={}) uniform uimageBuffer img{};", bindings.image, | ||
| 434 | index); | ||
| 435 | } | ||
| 400 | image_buffer_bindings.push_back(bindings.image); | 436 | image_buffer_bindings.push_back(bindings.image); |
| 401 | bindings.image += desc.count; | 437 | bindings.image += desc.count; |
| 402 | } | 438 | } |
| 403 | image_bindings.reserve(info.image_descriptors.size()); | 439 | image_bindings.reserve(info.image_descriptors.size()); |
| 404 | for (const auto& desc : info.image_descriptors) { | 440 | for (const auto& desc : info.image_descriptors) { |
| 405 | throw NotImplementedException("image_bindings"); | ||
| 406 | |||
| 407 | image_bindings.push_back(bindings.image); | 441 | image_bindings.push_back(bindings.image); |
| 442 | const auto format{ImageFormatString(desc.format)}; | ||
| 443 | const auto image_type{ImageType(desc.type)}; | ||
| 444 | const auto qualifier{desc.is_written ? "" : "readonly "}; | ||
| 445 | const auto indices{bindings.image + desc.count}; | ||
| 446 | for (u32 index = bindings.image; index < indices; ++index) { | ||
| 447 | header += fmt::format("layout(binding={}{})uniform {}{} img{};", bindings.image, format, | ||
| 448 | qualifier, image_type, index); | ||
| 449 | } | ||
| 408 | bindings.image += desc.count; | 450 | bindings.image += desc.count; |
| 409 | } | 451 | } |
| 410 | texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); | 452 | texture_buffer_bindings.reserve(info.texture_buffer_descriptors.size()); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index c62451e23..8c54f0fb3 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -14,15 +14,25 @@ namespace { | |||
| 14 | std::string Texture(EmitContext& ctx, const IR::TextureInstInfo& info, | 14 | std::string Texture(EmitContext& ctx, const IR::TextureInstInfo& info, |
| 15 | [[maybe_unused]] const IR::Value& index) { | 15 | [[maybe_unused]] const IR::Value& index) { |
| 16 | if (info.type == TextureType::Buffer) { | 16 | if (info.type == TextureType::Buffer) { |
| 17 | throw NotImplementedException("TextureType::Buffer"); | 17 | return fmt::format("tex{}", ctx.texture_buffer_bindings.at(info.descriptor_index)); |
| 18 | } else { | 18 | } else { |
| 19 | return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index)); | 19 | return fmt::format("tex{}", ctx.texture_bindings.at(info.descriptor_index)); |
| 20 | } | 20 | } |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info, | ||
| 24 | [[maybe_unused]] const IR::Value& index) { | ||
| 25 | if (info.type == TextureType::Buffer) { | ||
| 26 | return fmt::format("img{}", ctx.image_buffer_bindings.at(info.descriptor_index)); | ||
| 27 | } else { | ||
| 28 | return fmt::format("img{}", ctx.image_bindings.at(info.descriptor_index)); | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 23 | std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) { | 32 | std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) { |
| 24 | switch (info.type) { | 33 | switch (info.type) { |
| 25 | case TextureType::Color1D: | 34 | case TextureType::Color1D: |
| 35 | case TextureType::Buffer: | ||
| 26 | return fmt::format("int({})", value); | 36 | return fmt::format("int({})", value); |
| 27 | case TextureType::ColorArray1D: | 37 | case TextureType::ColorArray1D: |
| 28 | case TextureType::Color2D: | 38 | case TextureType::Color2D: |
| @@ -41,6 +51,7 @@ std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info | |||
| 41 | std::string TexelFetchCastToInt(std::string_view value, const IR::TextureInstInfo& info) { | 51 | std::string TexelFetchCastToInt(std::string_view value, const IR::TextureInstInfo& info) { |
| 42 | switch (info.type) { | 52 | switch (info.type) { |
| 43 | case TextureType::Color1D: | 53 | case TextureType::Color1D: |
| 54 | case TextureType::Buffer: | ||
| 44 | return fmt::format("int({})", value); | 55 | return fmt::format("int({})", value); |
| 45 | case TextureType::ColorArray1D: | 56 | case TextureType::ColorArray1D: |
| 46 | case TextureType::Color2D: | 57 | case TextureType::Color2D: |
| @@ -349,8 +360,12 @@ void EmitImageFetch([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | |||
| 349 | ctx.Add("{}=texelFetchOffset({},{},int({}),{});", texel, texture, | 360 | ctx.Add("{}=texelFetchOffset({},{},int({}),{});", texel, texture, |
| 350 | TexelFetchCastToInt(coords, info), lod, TexelFetchCastToInt(offset, info)); | 361 | TexelFetchCastToInt(coords, info), lod, TexelFetchCastToInt(offset, info)); |
| 351 | } else { | 362 | } else { |
| 352 | ctx.Add("{}=texelFetch({},{},int({}));", texel, texture, | 363 | if (info.type == TextureType::Buffer) { |
| 353 | TexelFetchCastToInt(coords, info), lod); | 364 | ctx.Add("{}=texelFetch({},int({}));", texel, texture, coords); |
| 365 | } else { | ||
| 366 | ctx.Add("{}=texelFetch({},{},int({}));", texel, texture, | ||
| 367 | TexelFetchCastToInt(coords, info), lod); | ||
| 368 | } | ||
| 354 | } | 369 | } |
| 355 | return; | 370 | return; |
| 356 | } | 371 | } |
| @@ -434,14 +449,22 @@ void EmitImageGradient([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 434 | void EmitImageRead([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 449 | void EmitImageRead([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 435 | [[maybe_unused]] const IR::Value& index, | 450 | [[maybe_unused]] const IR::Value& index, |
| 436 | [[maybe_unused]] std::string_view coords) { | 451 | [[maybe_unused]] std::string_view coords) { |
| 437 | NotImplemented(); | 452 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 453 | const auto sparse_inst{PrepareSparse(inst)}; | ||
| 454 | if (sparse_inst) { | ||
| 455 | throw NotImplementedException("EmitImageRead Sparse"); | ||
| 456 | } | ||
| 457 | const auto image{Image(ctx, info, index)}; | ||
| 458 | ctx.AddU32x4("{}=uvec4(imageLoad({},{}));", inst, image, TexelFetchCastToInt(coords, info)); | ||
| 438 | } | 459 | } |
| 439 | 460 | ||
| 440 | void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 461 | void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 441 | [[maybe_unused]] const IR::Value& index, | 462 | [[maybe_unused]] const IR::Value& index, |
| 442 | [[maybe_unused]] std::string_view coords, | 463 | [[maybe_unused]] std::string_view coords, |
| 443 | [[maybe_unused]] std::string_view color) { | 464 | [[maybe_unused]] std::string_view color) { |
| 444 | NotImplemented(); | 465 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| 466 | const auto image{Image(ctx, info, index)}; | ||
| 467 | ctx.Add("imageStore({},{},{});", image, TexelFetchCastToInt(coords, info), color); | ||
| 445 | } | 468 | } |
| 446 | 469 | ||
| 447 | void EmitBindlessImageSampleImplicitLod(EmitContext&) { | 470 | void EmitBindlessImageSampleImplicitLod(EmitContext&) { |