diff options
| author | 2021-06-17 20:34:58 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:38 -0400 | |
| commit | 59fead3a47227b513c0ca35090919823f44faecf (patch) | |
| tree | 0e80ab3e37cb6dd6d350b9e582268085a5c52a99 | |
| parent | spirv: Handle small storage buffer loads on devices with no support (diff) | |
| download | yuzu-59fead3a47227b513c0ca35090919823f44faecf.tar.gz yuzu-59fead3a47227b513c0ca35090919823f44faecf.tar.xz yuzu-59fead3a47227b513c0ca35090919823f44faecf.zip | |
spirv: Properly handle devices without int8 and int16
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_context.cpp | 52 | ||||
| -rw-r--r-- | src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | 54 |
2 files changed, 67 insertions, 39 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 32c21f3b4..4c6501129 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -911,37 +911,45 @@ void EmitContext::DefineConstantBuffers(const Info& info, u32& binding) { | |||
| 911 | if (info.constant_buffer_descriptors.empty()) { | 911 | if (info.constant_buffer_descriptors.empty()) { |
| 912 | return; | 912 | return; |
| 913 | } | 913 | } |
| 914 | if (profile.support_descriptor_aliasing) { | 914 | IR::Type types{info.used_constant_buffer_types}; |
| 915 | if (True(info.used_constant_buffer_types & IR::Type::U8)) { | 915 | if (!profile.support_descriptor_aliasing) { |
| 916 | DefineConstBuffers(*this, info, &UniformDefinitions::U32x4, binding, U32[4], 'u', | ||
| 917 | sizeof(u32[4])); | ||
| 918 | for (const ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { | ||
| 919 | binding += desc.count; | ||
| 920 | } | ||
| 921 | } | ||
| 922 | if (True(types & IR::Type::U8)) { | ||
| 923 | if (profile.support_int8) { | ||
| 916 | DefineConstBuffers(*this, info, &UniformDefinitions::U8, binding, U8, 'u', sizeof(u8)); | 924 | DefineConstBuffers(*this, info, &UniformDefinitions::U8, binding, U8, 'u', sizeof(u8)); |
| 917 | DefineConstBuffers(*this, info, &UniformDefinitions::S8, binding, S8, 's', sizeof(s8)); | 925 | DefineConstBuffers(*this, info, &UniformDefinitions::S8, binding, S8, 's', sizeof(s8)); |
| 926 | } else { | ||
| 927 | types |= IR::Type::U32; | ||
| 918 | } | 928 | } |
| 919 | if (True(info.used_constant_buffer_types & IR::Type::U16)) { | 929 | } |
| 930 | if (True(types & IR::Type::U16)) { | ||
| 931 | if (profile.support_int16) { | ||
| 920 | DefineConstBuffers(*this, info, &UniformDefinitions::U16, binding, U16, 'u', | 932 | DefineConstBuffers(*this, info, &UniformDefinitions::U16, binding, U16, 'u', |
| 921 | sizeof(u16)); | 933 | sizeof(u16)); |
| 922 | DefineConstBuffers(*this, info, &UniformDefinitions::S16, binding, S16, 's', | 934 | DefineConstBuffers(*this, info, &UniformDefinitions::S16, binding, S16, 's', |
| 923 | sizeof(s16)); | 935 | sizeof(s16)); |
| 936 | } else { | ||
| 937 | types |= IR::Type::U32; | ||
| 924 | } | 938 | } |
| 925 | if (True(info.used_constant_buffer_types & IR::Type::U32)) { | ||
| 926 | DefineConstBuffers(*this, info, &UniformDefinitions::U32, binding, U32[1], 'u', | ||
| 927 | sizeof(u32)); | ||
| 928 | } | ||
| 929 | if (True(info.used_constant_buffer_types & IR::Type::F32)) { | ||
| 930 | DefineConstBuffers(*this, info, &UniformDefinitions::F32, binding, F32[1], 'f', | ||
| 931 | sizeof(f32)); | ||
| 932 | } | ||
| 933 | if (True(info.used_constant_buffer_types & IR::Type::U32x2)) { | ||
| 934 | DefineConstBuffers(*this, info, &UniformDefinitions::U32x2, binding, U32[2], 'u', | ||
| 935 | sizeof(u32[2])); | ||
| 936 | } | ||
| 937 | binding += static_cast<u32>(info.constant_buffer_descriptors.size()); | ||
| 938 | } else { | ||
| 939 | DefineConstBuffers(*this, info, &UniformDefinitions::U32x4, binding, U32[4], 'u', | ||
| 940 | sizeof(u32[4])); | ||
| 941 | for (const ConstantBufferDescriptor& desc : info.constant_buffer_descriptors) { | ||
| 942 | binding += desc.count; | ||
| 943 | } | ||
| 944 | } | 939 | } |
| 940 | if (True(types & IR::Type::U32)) { | ||
| 941 | DefineConstBuffers(*this, info, &UniformDefinitions::U32, binding, U32[1], 'u', | ||
| 942 | sizeof(u32)); | ||
| 943 | } | ||
| 944 | if (True(types & IR::Type::F32)) { | ||
| 945 | DefineConstBuffers(*this, info, &UniformDefinitions::F32, binding, F32[1], 'f', | ||
| 946 | sizeof(f32)); | ||
| 947 | } | ||
| 948 | if (True(types & IR::Type::U32x2)) { | ||
| 949 | DefineConstBuffers(*this, info, &UniformDefinitions::U32x2, binding, U32[2], 'u', | ||
| 950 | sizeof(u32[2])); | ||
| 951 | } | ||
| 952 | binding += static_cast<u32>(info.constant_buffer_descriptors.size()); | ||
| 945 | } | 953 | } |
| 946 | 954 | ||
| 947 | void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) { | 955 | void EmitContext::DefineStorageBuffers(const Info& info, u32& binding) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 4ac1fbae5..2e364baec 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -144,6 +144,10 @@ Id GetCbuf(EmitContext& ctx, Id result_type, Id UniformDefinitions::*member_ptr, | |||
| 144 | return ctx.OpLoad(result_type, access_chain); | 144 | return ctx.OpLoad(result_type, access_chain); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | Id GetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | ||
| 148 | return GetCbuf(ctx, ctx.U32[1], &UniformDefinitions::U32, sizeof(u32), binding, offset); | ||
| 149 | } | ||
| 150 | |||
| 147 | Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 151 | Id GetCbufU32x4(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 148 | return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset); | 152 | return GetCbuf(ctx, ctx.U32[4], &UniformDefinitions::U32x4, sizeof(u32[4]), binding, offset); |
| 149 | } | 153 | } |
| @@ -203,58 +207,74 @@ void EmitGetLoopSafetyVariable(EmitContext&) { | |||
| 203 | } | 207 | } |
| 204 | 208 | ||
| 205 | Id EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 209 | Id EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 206 | if (ctx.profile.support_descriptor_aliasing) { | 210 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) { |
| 207 | const Id load{GetCbuf(ctx, ctx.U8, &UniformDefinitions::U8, sizeof(u8), binding, offset)}; | 211 | const Id load{GetCbuf(ctx, ctx.U8, &UniformDefinitions::U8, sizeof(u8), binding, offset)}; |
| 208 | return ctx.OpUConvert(ctx.U32[1], load); | 212 | return ctx.OpUConvert(ctx.U32[1], load); |
| 213 | } | ||
| 214 | Id element{}; | ||
| 215 | if (ctx.profile.support_descriptor_aliasing) { | ||
| 216 | element = GetCbufU32(ctx, binding, offset); | ||
| 209 | } else { | 217 | } else { |
| 210 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; | 218 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; |
| 211 | const Id element{GetCbufElement(ctx, vector, offset, 0u)}; | 219 | element = GetCbufElement(ctx, vector, offset, 0u); |
| 212 | const Id bit_offset{ctx.BitOffset8(offset)}; | ||
| 213 | return ctx.OpBitFieldUExtract(ctx.U32[1], element, bit_offset, ctx.Const(8u)); | ||
| 214 | } | 220 | } |
| 221 | const Id bit_offset{ctx.BitOffset8(offset)}; | ||
| 222 | return ctx.OpBitFieldUExtract(ctx.U32[1], element, bit_offset, ctx.Const(8u)); | ||
| 215 | } | 223 | } |
| 216 | 224 | ||
| 217 | Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 225 | Id EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 218 | if (ctx.profile.support_descriptor_aliasing) { | 226 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int8) { |
| 219 | const Id load{GetCbuf(ctx, ctx.S8, &UniformDefinitions::S8, sizeof(s8), binding, offset)}; | 227 | const Id load{GetCbuf(ctx, ctx.S8, &UniformDefinitions::S8, sizeof(s8), binding, offset)}; |
| 220 | return ctx.OpSConvert(ctx.U32[1], load); | 228 | return ctx.OpSConvert(ctx.U32[1], load); |
| 229 | } | ||
| 230 | Id element{}; | ||
| 231 | if (ctx.profile.support_descriptor_aliasing) { | ||
| 232 | element = GetCbufU32(ctx, binding, offset); | ||
| 221 | } else { | 233 | } else { |
| 222 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; | 234 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; |
| 223 | const Id element{GetCbufElement(ctx, vector, offset, 0u)}; | 235 | element = GetCbufElement(ctx, vector, offset, 0u); |
| 224 | const Id bit_offset{ctx.BitOffset8(offset)}; | ||
| 225 | return ctx.OpBitFieldSExtract(ctx.U32[1], element, bit_offset, ctx.Const(8u)); | ||
| 226 | } | 236 | } |
| 237 | const Id bit_offset{ctx.BitOffset8(offset)}; | ||
| 238 | return ctx.OpBitFieldSExtract(ctx.U32[1], element, bit_offset, ctx.Const(8u)); | ||
| 227 | } | 239 | } |
| 228 | 240 | ||
| 229 | Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 241 | Id EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 230 | if (ctx.profile.support_descriptor_aliasing) { | 242 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) { |
| 231 | const Id load{ | 243 | const Id load{ |
| 232 | GetCbuf(ctx, ctx.U16, &UniformDefinitions::U16, sizeof(u16), binding, offset)}; | 244 | GetCbuf(ctx, ctx.U16, &UniformDefinitions::U16, sizeof(u16), binding, offset)}; |
| 233 | return ctx.OpUConvert(ctx.U32[1], load); | 245 | return ctx.OpUConvert(ctx.U32[1], load); |
| 246 | } | ||
| 247 | Id element{}; | ||
| 248 | if (ctx.profile.support_descriptor_aliasing) { | ||
| 249 | element = GetCbufU32(ctx, binding, offset); | ||
| 234 | } else { | 250 | } else { |
| 235 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; | 251 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; |
| 236 | const Id element{GetCbufElement(ctx, vector, offset, 0u)}; | 252 | element = GetCbufElement(ctx, vector, offset, 0u); |
| 237 | const Id bit_offset{ctx.BitOffset16(offset)}; | ||
| 238 | return ctx.OpBitFieldUExtract(ctx.U32[1], element, bit_offset, ctx.Const(16u)); | ||
| 239 | } | 253 | } |
| 254 | const Id bit_offset{ctx.BitOffset16(offset)}; | ||
| 255 | return ctx.OpBitFieldUExtract(ctx.U32[1], element, bit_offset, ctx.Const(16u)); | ||
| 240 | } | 256 | } |
| 241 | 257 | ||
| 242 | Id EmitGetCbufS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 258 | Id EmitGetCbufS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 243 | if (ctx.profile.support_descriptor_aliasing) { | 259 | if (ctx.profile.support_descriptor_aliasing && ctx.profile.support_int16) { |
| 244 | const Id load{ | 260 | const Id load{ |
| 245 | GetCbuf(ctx, ctx.S16, &UniformDefinitions::S16, sizeof(s16), binding, offset)}; | 261 | GetCbuf(ctx, ctx.S16, &UniformDefinitions::S16, sizeof(s16), binding, offset)}; |
| 246 | return ctx.OpSConvert(ctx.U32[1], load); | 262 | return ctx.OpSConvert(ctx.U32[1], load); |
| 263 | } | ||
| 264 | Id element{}; | ||
| 265 | if (ctx.profile.support_descriptor_aliasing) { | ||
| 266 | element = GetCbufU32(ctx, binding, offset); | ||
| 247 | } else { | 267 | } else { |
| 248 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; | 268 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; |
| 249 | const Id element{GetCbufElement(ctx, vector, offset, 0u)}; | 269 | element = GetCbufElement(ctx, vector, offset, 0u); |
| 250 | const Id bit_offset{ctx.BitOffset16(offset)}; | ||
| 251 | return ctx.OpBitFieldSExtract(ctx.U32[1], element, bit_offset, ctx.Const(16u)); | ||
| 252 | } | 270 | } |
| 271 | const Id bit_offset{ctx.BitOffset16(offset)}; | ||
| 272 | return ctx.OpBitFieldSExtract(ctx.U32[1], element, bit_offset, ctx.Const(16u)); | ||
| 253 | } | 273 | } |
| 254 | 274 | ||
| 255 | Id EmitGetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | 275 | Id EmitGetCbufU32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { |
| 256 | if (ctx.profile.support_descriptor_aliasing) { | 276 | if (ctx.profile.support_descriptor_aliasing) { |
| 257 | return GetCbuf(ctx, ctx.U32[1], &UniformDefinitions::U32, sizeof(u32), binding, offset); | 277 | return GetCbufU32(ctx, binding, offset); |
| 258 | } else { | 278 | } else { |
| 259 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; | 279 | const Id vector{GetCbufU32x4(ctx, binding, offset)}; |
| 260 | return GetCbufElement(ctx, vector, offset, 0u); | 280 | return GetCbufElement(ctx, vector, offset, 0u); |