Merge pull request #1102 from KhronosGroup/fix-1096
MSL: Deal with Modf/Frexp where output is access chain to scalar.
This commit is contained in:
commit
87513f9ac0
@ -0,0 +1,17 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
fragment void main0()
|
||||
{
|
||||
float3 col;
|
||||
int2 _18;
|
||||
float _23;
|
||||
float _21 = modf(0.1500000059604644775390625, _23);
|
||||
col.x = _23;
|
||||
int _24;
|
||||
float _22 = frexp(0.1500000059604644775390625, _24);
|
||||
_18.y = _24;
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 7
|
||||
; Bound: 17
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource ESSL 310
|
||||
OpName %main "main"
|
||||
OpName %col "col"
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%float_0_150000006 = OpConstant %float 0.150000006
|
||||
%v3float = OpTypeVector %float 3
|
||||
%_ptr_Function_v3float = OpTypePointer Function %v3float
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%int_1 = OpConstant %int 1
|
||||
%v2int = OpTypeVector %int 2
|
||||
%_ptr_Function_v2int = OpTypePointer Function %v2int
|
||||
%_ptr_Function_int = OpTypePointer Function %int
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%col = OpVariable %_ptr_Function_v3float Function
|
||||
%icol = OpVariable %_ptr_Function_v2int Function
|
||||
%ptr_x = OpAccessChain %_ptr_Function_float %col %int_0
|
||||
%ptr_y = OpAccessChain %_ptr_Function_int %icol %int_1
|
||||
%16 = OpExtInst %float %1 Modf %float_0_150000006 %ptr_x
|
||||
%17 = OpExtInst %float %1 Frexp %float_0_150000006 %ptr_y
|
||||
OpReturn
|
||||
OpFunctionEnd
|
@ -5260,6 +5260,32 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
|
||||
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
|
||||
break;
|
||||
|
||||
case GLSLstd450Modf:
|
||||
case GLSLstd450Frexp:
|
||||
{
|
||||
// Special case. If the variable is a scalar access chain, we cannot use it directly. We have to emit a temporary.
|
||||
auto *ptr = maybe_get<SPIRExpression>(args[1]);
|
||||
if (ptr && ptr->access_chain && is_scalar(expression_type(args[1])))
|
||||
{
|
||||
register_call_out_argument(args[1]);
|
||||
forced_temporaries.insert(id);
|
||||
|
||||
// Need to create temporaries and copy over to access chain after.
|
||||
// We cannot directly take the reference of a vector swizzle in MSL, even if it's scalar ...
|
||||
uint32_t &tmp_id = extra_sub_expressions[id];
|
||||
if (!tmp_id)
|
||||
tmp_id = ir.increase_bound_by(1);
|
||||
|
||||
uint32_t tmp_type_id = get_pointee_type_id(ptr->expression_type);
|
||||
emit_uninitialized_temporary_expression(tmp_type_id, tmp_id);
|
||||
emit_binary_func_op(result_type, id, args[0], tmp_id, eop == GLSLstd450Modf ? "modf" : "frexp");
|
||||
statement(to_expression(args[1]), " = ", to_expression(tmp_id), ";");
|
||||
}
|
||||
else
|
||||
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user