From 421847cf1e33d5b95c9aa272bf3cf69afda3d964 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 5 Jun 2021 02:41:29 -0400 Subject: [PATCH] glsl: Implement image atomics and set layer along with some more cleanup/oversight fixes --- .../backend/glsl/emit_context.cpp | 15 +- .../glsl/emit_glsl_context_get_set.cpp | 12 +- .../backend/glsl/emit_glsl_image.cpp | 188 +++++++++++++++++- .../glsl/emit_glsl_not_implemented.cpp | 143 ------------- src/shader_recompiler/profile.h | 1 - 5 files changed, 204 insertions(+), 155 deletions(-) diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 76cf0bdf0..50a7a7447 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp @@ -197,7 +197,7 @@ void SetupOutPerVertex(EmitContext& ctx, std::string& header) { if (ctx.info.stores_clip_distance) { header += "float gl_ClipDistance[];"; } - if (ctx.info.stores_viewport_index && ctx.profile.support_gl_vertex_viewport_layer && + if (ctx.info.stores_viewport_index && ctx.profile.support_viewport_index_layer_non_geometry && ctx.stage != Stage::Geometry) { header += "int gl_ViewportIndex;"; } @@ -314,7 +314,7 @@ void EmitContext::SetupExtensions(std::string&) { header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; } } - if (info.stores_viewport_index && profile.support_gl_vertex_viewport_layer && + if (info.stores_viewport_index && profile.support_viewport_index_layer_non_geometry && stage != Stage::Geometry) { header += "#extension GL_ARB_shader_viewport_layer_array : enable\n"; } @@ -497,12 +497,13 @@ std::string EmitContext::DefineGlobalMemoryFunctions() { void EmitContext::SetupImages(Bindings& bindings) { image_buffer_bindings.reserve(info.image_buffer_descriptors.size()); for (const auto& desc : info.image_buffer_descriptors) { - const auto indices{bindings.image + desc.count}; - for (u32 index = bindings.image; index < indices; ++index) { - header += fmt::format("layout(binding={}) uniform uimageBuffer img{};", bindings.image, - index); - } image_buffer_bindings.push_back(bindings.image); + const auto indices{bindings.image + desc.count}; + const auto format{ImageFormatString(desc.format)}; + for (u32 index = bindings.image; index < indices; ++index) { + header += fmt::format("layout(binding={}{}) uniform uimageBuffer img{};", + bindings.image, format, index); + } bindings.image += desc.count; } image_bindings.reserve(info.image_descriptors.size()); diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp index 83ce6fcbb..4d35be152 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp @@ -269,6 +269,15 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val const u32 element{static_cast(attr) % 4}; const char swizzle{"xyzw"[element]}; switch (attr) { + case IR::Attribute::Layer: + if (ctx.stage != Stage::Geometry && + !ctx.profile.support_viewport_index_layer_non_geometry) { + // LOG_WARNING(..., "Shader stores viewport layer but device does not support viewport + // layer extension"); + break; + } + ctx.Add("gl_Layer=ftoi({});", value); + break; case IR::Attribute::PointSize: ctx.Add("gl_PointSize={};", value); break; @@ -279,7 +288,8 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val ctx.Add("gl_Position.{}={};", swizzle, value); break; case IR::Attribute::ViewportIndex: - if (ctx.stage != Stage::Geometry && !ctx.profile.support_gl_vertex_viewport_layer) { + if (ctx.stage != Stage::Geometry && + !ctx.profile.support_viewport_index_layer_non_geometry) { // LOG_WARNING(..., "Shader stores viewport index but device does not support viewport // layer extension"); break; diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index f022c5f30..e3a69e3a5 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp @@ -45,7 +45,7 @@ std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info case TextureType::ColorArrayCube: return fmt::format("ivec4({})", value); default: - throw NotImplementedException("Offset type {}", info.type.Value()); + throw NotImplementedException("Integer cast for TextureType {}", info.type.Value()); } } @@ -64,7 +64,7 @@ std::string TexelFetchCastToInt(std::string_view value, const IR::TextureInstInf case TextureType::ColorArrayCube: return fmt::format("ivec4({})", value); default: - throw NotImplementedException("Offset type {}", info.type.Value()); + throw NotImplementedException("TexelFetchCast type {}", info.type.Value()); } } @@ -98,7 +98,19 @@ std::string GetOffsetVec(EmitContext& ctx, const IR::Value& offset) { break; } } - return ctx.var_alloc.Consume(offset); + const auto offset_str{ctx.var_alloc.Consume(offset)}; + switch (offset.Type()) { + case IR::Type::U32: + return fmt::format("int({})", offset_str); + case IR::Type::U32x2: + return fmt::format("ivec2({})", offset_str); + case IR::Type::U32x3: + return fmt::format("ivec3({})", offset_str); + case IR::Type::U32x4: + return fmt::format("ivec4({})", offset_str); + default: + throw NotImplementedException("Offset type {}", offset.Type()); + } } std::string PtpOffsets(const IR::Value& offset, const IR::Value& offset2) { @@ -528,6 +540,88 @@ void EmitImageWrite([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst ctx.Add("imageStore({},{},{});", image, TexelFetchCastToInt(coords, info), color); } +void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicAdd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicMin({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicMin({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicMax({},{},int({}));", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicMax({},{},uint({}));", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicInc32(EmitContext&, IR::Inst&, const IR::Value&, std::string_view, + std::string_view) { + NotImplemented(); +} + +void EmitImageAtomicDec32(EmitContext&, IR::Inst&, const IR::Value&, std::string_view, + std::string_view) { + NotImplemented(); +} + +void EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicAnd({},{},{});", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicOr32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicOr({},{},{});", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicXor32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicXor({},{},{});", inst, image, TexelFetchCastToInt(coords, info), + value); +} + +void EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, + std::string_view coords, std::string_view value) { + const auto info{inst.Flags()}; + const auto image{Image(ctx, info, index)}; + ctx.AddU32("{}=imageAtomicExchange({},{},{});", inst, image, TexelFetchCastToInt(coords, info), + value); +} + void EmitBindlessImageSampleImplicitLod(EmitContext&) { NotImplemented(); } @@ -624,4 +718,92 @@ void EmitBoundImageWrite(EmitContext&) { NotImplemented(); } +void EmitBindlessImageAtomicIAdd32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicSMin32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicUMin32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicSMax32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicUMax32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicInc32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicDec32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicAnd32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicOr32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicXor32(EmitContext&) { + NotImplemented(); +} + +void EmitBindlessImageAtomicExchange32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicIAdd32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicSMin32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicUMin32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicSMax32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicUMax32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicInc32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicDec32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicAnd32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicOr32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicXor32(EmitContext&) { + NotImplemented(); +} + +void EmitBoundImageAtomicExchange32(EmitContext&) { + NotImplemented(); +} + } // namespace Shader::Backend::GLSL 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 c64d4325d..5ca73610b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp @@ -250,147 +250,4 @@ void EmitGetInBoundsFromOp(EmitContext& ctx) { NotImplemented(); } -void EmitBindlessImageAtomicIAdd32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicSMin32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicUMin32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicSMax32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicUMax32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicInc32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicDec32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicAnd32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicOr32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicXor32(EmitContext&) { - NotImplemented(); -} - -void EmitBindlessImageAtomicExchange32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicIAdd32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicSMin32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicUMin32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicSMax32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicUMax32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicInc32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicDec32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicAnd32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicOr32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicXor32(EmitContext&) { - NotImplemented(); -} - -void EmitBoundImageAtomicExchange32(EmitContext&) { - NotImplemented(); -} - -void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicInc32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicDec32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicOr32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicXor32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - -void EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, - std::string_view coords, std::string_view value) { - NotImplemented(); -} - } // namespace Shader::Backend::GLSL diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index bc61a911f..3a4495070 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h @@ -85,7 +85,6 @@ struct Profile { bool support_derivative_control{}; bool support_gl_nv_gpu_shader_5{}; bool support_gl_amd_gpu_shader_half_float{}; - bool support_gl_vertex_viewport_layer{}; bool support_gl_texture_shadow_lod{}; bool warp_size_potentially_larger_than_guest{};