shader: Ignore global memory ops on devices lacking int64 support
This commit is contained in:
		| @@ -378,7 +378,7 @@ void EmitContext::SetupExtensions() { | |||||||
|     if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { |     if (info.uses_shadow_lod && profile.support_gl_texture_shadow_lod) { | ||||||
|         header += "#extension GL_EXT_texture_shadow_lod : enable\n"; |         header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | ||||||
|     } |     } | ||||||
|     if (info.uses_int64) { |     if (info.uses_int64 && profile.support_int64) { | ||||||
|         header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; |         header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | ||||||
|     } |     } | ||||||
|     if (info.uses_int64_bit_atomics) { |     if (info.uses_int64_bit_atomics) { | ||||||
| @@ -402,7 +402,7 @@ void EmitContext::SetupExtensions() { | |||||||
|         info.uses_subgroup_shuffles || info.uses_fswzadd) { |         info.uses_subgroup_shuffles || info.uses_fswzadd) { | ||||||
|         header += "#extension GL_ARB_shader_ballot : enable\n" |         header += "#extension GL_ARB_shader_ballot : enable\n" | ||||||
|                   "#extension GL_ARB_shader_group_vote : enable\n"; |                   "#extension GL_ARB_shader_group_vote : enable\n"; | ||||||
|         if (!info.uses_int64) { |         if (!info.uses_int64 && profile.support_int64) { | ||||||
|             header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; |             header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | ||||||
|         } |         } | ||||||
|         if (profile.support_gl_warp_intrinsics) { |         if (profile.support_gl_warp_intrinsics) { | ||||||
| @@ -539,7 +539,7 @@ void EmitContext::DefineHelperFunctions() { | |||||||
|     if (info.uses_atomic_s32_max) { |     if (info.uses_atomic_s32_max) { | ||||||
|         header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; |         header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; | ||||||
|     } |     } | ||||||
|     if (info.uses_global_memory) { |     if (info.uses_global_memory && profile.support_int64) { | ||||||
|         header += DefineGlobalMemoryFunctions(); |         header += DefineGlobalMemoryFunctions(); | ||||||
|     } |     } | ||||||
|     if (info.loads_indexed_attributes) { |     if (info.loads_indexed_attributes) { | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| #include "shader_recompiler/backend/glsl/emit_context.h" | #include "shader_recompiler/backend/glsl/emit_context.h" | ||||||
| #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" | ||||||
| #include "shader_recompiler/frontend/ir/value.h" | #include "shader_recompiler/frontend/ir/value.h" | ||||||
|  | #include "shader_recompiler/profile.h" | ||||||
|  |  | ||||||
| namespace Shader::Backend::GLSL { | namespace Shader::Backend::GLSL { | ||||||
| namespace { | namespace { | ||||||
| @@ -38,15 +39,27 @@ void EmitLoadGlobalS16(EmitContext&) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | ||||||
|     ctx.AddU32("{}=LoadGlobal32({});", inst, address); |     if (ctx.profile.support_int64) { | ||||||
|  |         return ctx.AddU32("{}=LoadGlobal32({});", inst, address); | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_GLSL, "Int64 not supported, ignoring memory operation"); | ||||||
|  |     ctx.AddU32("{}=0u;", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | ||||||
|     ctx.AddU32x2("{}=LoadGlobal64({});", inst, address); |     if (ctx.profile.support_int64) { | ||||||
|  |         return ctx.AddU32x2("{}=LoadGlobal64({});", inst, address); | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_GLSL, "Int64 not supported, ignoring memory operation"); | ||||||
|  |     ctx.AddU32x2("{}=uvec2(0);", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | ||||||
|     ctx.AddU32x4("{}=LoadGlobal128({});", inst, address); |     if (ctx.profile.support_int64) { | ||||||
|  |         return ctx.AddU32x4("{}=LoadGlobal128({});", inst, address); | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_GLSL, "Int64 not supported, ignoring memory operation"); | ||||||
|  |     ctx.AddU32x4("{}=uvec4(0);", inst); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitWriteGlobalU8(EmitContext&) { | void EmitWriteGlobalU8(EmitContext&) { | ||||||
| @@ -66,15 +79,24 @@ void EmitWriteGlobalS16(EmitContext&) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value) { | void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value) { | ||||||
|     ctx.Add("WriteGlobal32({},{});", address, value); |     if (ctx.profile.support_int64) { | ||||||
|  |         return ctx.Add("WriteGlobal32({},{});", address, value); | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_GLSL, "Int64 not supported, ignoring memory operation"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value) { | void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value) { | ||||||
|     ctx.Add("WriteGlobal64({},{});", address, value); |     if (ctx.profile.support_int64) { | ||||||
|  |         return ctx.Add("WriteGlobal64({},{});", address, value); | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_GLSL, "Int64 not supported, ignoring memory operation"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value) { | void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value) { | ||||||
|     ctx.Add("WriteGlobal128({},{});", address, value); |     if (ctx.profile.support_int64) { | ||||||
|  |         return ctx.Add("WriteGlobal128({},{});", address, value); | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_GLSL, "Int64 not supported, ignoring memory operation"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitLoadStorageU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | void EmitLoadStorageU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||||||
|   | |||||||
| @@ -830,7 +830,7 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitContext::DefineGlobalMemoryFunctions(const Info& info) { | void EmitContext::DefineGlobalMemoryFunctions(const Info& info) { | ||||||
|     if (!info.uses_global_memory) { |     if (!info.uses_global_memory || !profile.support_int64) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     using DefPtr = Id StorageDefinitions::*; |     using DefPtr = Id StorageDefinitions::*; | ||||||
|   | |||||||
| @@ -84,16 +84,28 @@ void EmitLoadGlobalS16(EmitContext&) { | |||||||
| } | } | ||||||
|  |  | ||||||
| Id EmitLoadGlobal32(EmitContext& ctx, Id address) { | Id EmitLoadGlobal32(EmitContext& ctx, Id address) { | ||||||
|  |     if (ctx.profile.support_int64) { | ||||||
|         return ctx.OpFunctionCall(ctx.U32[1], ctx.load_global_func_u32, address); |         return ctx.OpFunctionCall(ctx.U32[1], ctx.load_global_func_u32, address); | ||||||
|     } |     } | ||||||
|  |     LOG_WARNING(Shader_SPIRV, "Int64 not supported, ignoring memory operation"); | ||||||
|  |     return ctx.Const(0u); | ||||||
|  | } | ||||||
|  |  | ||||||
| Id EmitLoadGlobal64(EmitContext& ctx, Id address) { | Id EmitLoadGlobal64(EmitContext& ctx, Id address) { | ||||||
|  |     if (ctx.profile.support_int64) { | ||||||
|         return ctx.OpFunctionCall(ctx.U32[2], ctx.load_global_func_u32x2, address); |         return ctx.OpFunctionCall(ctx.U32[2], ctx.load_global_func_u32x2, address); | ||||||
|     } |     } | ||||||
|  |     LOG_WARNING(Shader_SPIRV, "Int64 not supported, ignoring memory operation"); | ||||||
|  |     return ctx.Const(0u, 0u); | ||||||
|  | } | ||||||
|  |  | ||||||
| Id EmitLoadGlobal128(EmitContext& ctx, Id address) { | Id EmitLoadGlobal128(EmitContext& ctx, Id address) { | ||||||
|  |     if (ctx.profile.support_int64) { | ||||||
|         return ctx.OpFunctionCall(ctx.U32[4], ctx.load_global_func_u32x4, address); |         return ctx.OpFunctionCall(ctx.U32[4], ctx.load_global_func_u32x4, address); | ||||||
|     } |     } | ||||||
|  |     LOG_WARNING(Shader_SPIRV, "Int64 not supported, ignoring memory operation"); | ||||||
|  |     return ctx.Const(0u, 0u, 0u, 0u); | ||||||
|  | } | ||||||
|  |  | ||||||
| void EmitWriteGlobalU8(EmitContext&) { | void EmitWriteGlobalU8(EmitContext&) { | ||||||
|     throw NotImplementedException("SPIR-V Instruction"); |     throw NotImplementedException("SPIR-V Instruction"); | ||||||
| @@ -112,15 +124,27 @@ void EmitWriteGlobalS16(EmitContext&) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitWriteGlobal32(EmitContext& ctx, Id address, Id value) { | void EmitWriteGlobal32(EmitContext& ctx, Id address, Id value) { | ||||||
|  |     if (ctx.profile.support_int64) { | ||||||
|         ctx.OpFunctionCall(ctx.void_id, ctx.write_global_func_u32, address, value); |         ctx.OpFunctionCall(ctx.void_id, ctx.write_global_func_u32, address, value); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_SPIRV, "Int64 not supported, ignoring memory operation"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitWriteGlobal64(EmitContext& ctx, Id address, Id value) { | void EmitWriteGlobal64(EmitContext& ctx, Id address, Id value) { | ||||||
|  |     if (ctx.profile.support_int64) { | ||||||
|         ctx.OpFunctionCall(ctx.void_id, ctx.write_global_func_u32x2, address, value); |         ctx.OpFunctionCall(ctx.void_id, ctx.write_global_func_u32x2, address, value); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_SPIRV, "Int64 not supported, ignoring memory operation"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitWriteGlobal128(EmitContext& ctx, Id address, Id value) { | void EmitWriteGlobal128(EmitContext& ctx, Id address, Id value) { | ||||||
|  |     if (ctx.profile.support_int64) { | ||||||
|         ctx.OpFunctionCall(ctx.void_id, ctx.write_global_func_u32x4, address, value); |         ctx.OpFunctionCall(ctx.void_id, ctx.write_global_func_u32x4, address, value); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     LOG_WARNING(Shader_SPIRV, "Int64 not supported, ignoring memory operation"); | ||||||
| } | } | ||||||
|  |  | ||||||
| Id EmitLoadStorageU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | Id EmitLoadStorageU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset) { | ||||||
|   | |||||||
| @@ -71,20 +71,20 @@ OPCODE(UndefU32,                                            U32, | |||||||
| OPCODE(UndefU64,                                            U64,                                                                                            ) | OPCODE(UndefU64,                                            U64,                                                                                            ) | ||||||
|  |  | ||||||
| // Memory operations | // Memory operations | ||||||
| OPCODE(LoadGlobalU8,                                        U32,            U64,                                                                            ) | OPCODE(LoadGlobalU8,                                        U32,            Opaque,                                                                         ) | ||||||
| OPCODE(LoadGlobalS8,                                        U32,            U64,                                                                            ) | OPCODE(LoadGlobalS8,                                        U32,            Opaque,                                                                         ) | ||||||
| OPCODE(LoadGlobalU16,                                       U32,            U64,                                                                            ) | OPCODE(LoadGlobalU16,                                       U32,            Opaque,                                                                         ) | ||||||
| OPCODE(LoadGlobalS16,                                       U32,            U64,                                                                            ) | OPCODE(LoadGlobalS16,                                       U32,            Opaque,                                                                         ) | ||||||
| OPCODE(LoadGlobal32,                                        U32,            U64,                                                                            ) | OPCODE(LoadGlobal32,                                        U32,            Opaque,                                                                         ) | ||||||
| OPCODE(LoadGlobal64,                                        U32x2,          U64,                                                                            ) | OPCODE(LoadGlobal64,                                        U32x2,          Opaque,                                                                         ) | ||||||
| OPCODE(LoadGlobal128,                                       U32x4,          U64,                                                                            ) | OPCODE(LoadGlobal128,                                       U32x4,          Opaque,                                                                         ) | ||||||
| OPCODE(WriteGlobalU8,                                       Void,           U64,            U32,                                                            ) | OPCODE(WriteGlobalU8,                                       Void,           Opaque,         U32,                                                            ) | ||||||
| OPCODE(WriteGlobalS8,                                       Void,           U64,            U32,                                                            ) | OPCODE(WriteGlobalS8,                                       Void,           Opaque,         U32,                                                            ) | ||||||
| OPCODE(WriteGlobalU16,                                      Void,           U64,            U32,                                                            ) | OPCODE(WriteGlobalU16,                                      Void,           Opaque,         U32,                                                            ) | ||||||
| OPCODE(WriteGlobalS16,                                      Void,           U64,            U32,                                                            ) | OPCODE(WriteGlobalS16,                                      Void,           Opaque,         U32,                                                            ) | ||||||
| OPCODE(WriteGlobal32,                                       Void,           U64,            U32,                                                            ) | OPCODE(WriteGlobal32,                                       Void,           Opaque,         U32,                                                            ) | ||||||
| OPCODE(WriteGlobal64,                                       Void,           U64,            U32x2,                                                          ) | OPCODE(WriteGlobal64,                                       Void,           Opaque,         U32x2,                                                          ) | ||||||
| OPCODE(WriteGlobal128,                                      Void,           U64,            U32x4,                                                          ) | OPCODE(WriteGlobal128,                                      Void,           Opaque,         U32x4,                                                          ) | ||||||
|  |  | ||||||
| // Storage buffer operations | // Storage buffer operations | ||||||
| OPCODE(LoadStorageU8,                                       U32,            U32,            U32,                                                            ) | OPCODE(LoadStorageU8,                                       U32,            U32,            U32,                                                            ) | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ struct Profile { | |||||||
|     bool support_descriptor_aliasing{}; |     bool support_descriptor_aliasing{}; | ||||||
|     bool support_int8{}; |     bool support_int8{}; | ||||||
|     bool support_int16{}; |     bool support_int16{}; | ||||||
|  |     bool support_int64{}; | ||||||
|     bool support_vertex_instance_id{}; |     bool support_vertex_instance_id{}; | ||||||
|     bool support_float_controls{}; |     bool support_float_controls{}; | ||||||
|     bool support_separate_denorm_behavior{}; |     bool support_separate_denorm_behavior{}; | ||||||
|   | |||||||
| @@ -168,6 +168,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo | |||||||
|           .support_descriptor_aliasing = false, |           .support_descriptor_aliasing = false, | ||||||
|           .support_int8 = false, |           .support_int8 = false, | ||||||
|           .support_int16 = false, |           .support_int16 = false, | ||||||
|  |           .support_int64 = device.HasShaderInt64(), | ||||||
|           .support_vertex_instance_id = true, |           .support_vertex_instance_id = true, | ||||||
|           .support_float_controls = false, |           .support_float_controls = false, | ||||||
|           .support_separate_denorm_behavior = false, |           .support_separate_denorm_behavior = false, | ||||||
|   | |||||||
| @@ -280,6 +280,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxw | |||||||
|         .support_descriptor_aliasing = true, |         .support_descriptor_aliasing = true, | ||||||
|         .support_int8 = true, |         .support_int8 = true, | ||||||
|         .support_int16 = device.IsShaderInt16Supported(), |         .support_int16 = device.IsShaderInt16Supported(), | ||||||
|  |         .support_int64 = device.IsShaderInt64Supported(), | ||||||
|         .support_vertex_instance_id = false, |         .support_vertex_instance_id = false, | ||||||
|         .support_float_controls = true, |         .support_float_controls = true, | ||||||
|         .support_separate_denorm_behavior = float_control.denormBehaviorIndependence == |         .support_separate_denorm_behavior = float_control.denormBehaviorIndependence == | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user