Shader module compilation failed


This topic contains 1 reply, has 2 voices, and was last updated by  Bill Hollings 3 days, 7 hours ago.

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #1353

    kerlingb
    Participant

    I got error when the program calling vkCreateGraphicsPipelines

    
    [***MoltenVK ERROR***] VK_ERROR_INITIALIZATION_FAILED: Shader module compilation failed (code 3):
    
    Compilation failed: 
    
    program_source:146:29: error: use of undeclared identifier 'unsupported_GLSLstd450UnpackHalf2x16'
                    result[n] = unsupported_GLSLstd450UnpackHalf2x16(get_bits(param_5, param_6)).x;
                                ^
    program_source:253:50: error: use of undeclared identifier 'volatile_input_stream'
            return fetch_attribute(param_1, param_2, volatile_input_stream, volatile_input_streamSmplr);
                                                     ^
    program_source:253:73: error: use of undeclared identifier 'volatile_input_streamSmplr'
            return fetch_attribute(param_1, param_2, volatile_input_stream, volatile_input_streamSmplr);
                                                                            ^
    program_source:259:50: error: use of undeclared identifier 'persistent_input_stream'
            return fetch_attribute(param_3, param_4, persistent_input_stream, persistent_input_streamSmplr);
                                                     ^
    program_source:259:75: error: use of undeclared identifier 'persistent_input_streamSmplr'
            return fetch_attribute(param_3, param_4, persistent_input_stream, persistent_input_streamSmplr);
                                                                              ^
    program_source:296:5: error: no matching function for call to 'vs_main'
        vs_main(param, param_1, param_2, v_428, gl_VertexIndex, v_558);
        ^~~~~~~
    program_source:263:6: note: candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'int &' for 5th argument
    void vs_main(thread float4& dst_reg0, thread float4& dst_reg1, thread float4& dst_reg7, constant VertexContextBuffer& v_428, thread int& gl_VertexIndex, constant VertexConstantsBuffer& v_558)
         ^
    

    But when I tried to use MoltenShaderConverter to compile the shader module manually, it didn’t shown any errors.
    Code is attached below.

    
    #version 450
    #extension GL_ARB_separate_shader_objects : enable
    
    layout(std140, set = 0, binding = 0) uniform VertexContextBuffer
    {
    	mat4 scale_offset_mat;
    	ivec4 user_clip_enabled[2];
    	vec4 user_clip_factor[2];
    	uint transform_branch_bits;
    	uint vertex_base_index;
    	ivec4 input_attributes[16];
    };
    layout(set=0, binding=3) uniform usamplerBuffer persistent_input_stream;
    layout(set=0, binding=4) uniform usamplerBuffer volatile_input_stream;
    
    layout(location=10) out vec4 back_diff_color;
    layout(location=0) out vec4 tc0;
    
    layout(std140, set=0, binding = 1) uniform VertexConstantsBuffer
    {
    	vec4 vc[468];
    };
    
    vec4 lit_legacy(vec4 val){
    	vec4 clamped_val = val;
    	clamped_val.x = max(val.x, 0.);
    	clamped_val.y = max(val.y, 0.);
    	vec4 result;
    	result.x = 1.;
    	result.w = 1.;
    	result.y = clamped_val.x;
    	result.z = clamped_val.x > 0. ? exp(clamped_val.w * log(max(clamped_val.y, 1.E-10))) : 0.;
    	return result;
    }
    
    struct attribute_desc
    {
    	int type;
    	int attribute_size;
    	int starting_offset;
    	int stride;
    	int swap_bytes;
    	int is_volatile;
    	int frequency;
    	int divisor;
    	int modulo;
    };
    
    uint get_bits(uvec4 v, int swap)
    {
    	if (swap != 0) return (v.w | v.z << 8 | v.y << 16 | v.x << 24);
    	return (v.x | v.y << 8 | v.z << 16 | v.w << 24);
    }
    
    uint get_bits(uvec2 v, int swap)
    {
    	if (swap != 0) return (v.y | v.x << 8);
    	return (v.x | v.y << 8);
    }
    
    int preserve_sign_s16(uint bits)
    {
    	//convert raw 16 bit value into signed 32-bit integer counterpart
    	uint sign = bits & 0x8000;
    	if (sign != 0) return int(bits | 0xFFFF0000);
    	return int(bits);
    }
    
    #define mov(v, i, s) v[i] = s
    #define get_s16(v, s) preserve_sign_s16(get_bits(v, s))
    
    vec4 fetch_attribute(attribute_desc desc, int vertex_id, usamplerBuffer input_stream)
    {
    	vec4 result = vec4(0., 0., 0., 1.);
    	vec4 scale = vec4(1.);
    	uvec4 tmp;
    	uint bits;
    	bool reverse_order = false;
    
    	int first_byte = (vertex_id * desc.stride) + desc.starting_offset;
    	for (int n = 0; n < 4; n++)
    	{
    		if (n == desc.attribute_size) break;
    
    		switch (desc.type)
    		{
    		case 0:
    			//signed normalized 16-bit
    			tmp.x = texelFetch(input_stream, first_byte++).x;
    			tmp.y = texelFetch(input_stream, first_byte++).x;
    			mov(result, n, get_s16(tmp.xy, desc.swap_bytes));
    			mov(scale, n, 32767.);
    			break;
    		case 1:
    			//float
    			tmp.x = texelFetch(input_stream, first_byte++).x;
    			tmp.y = texelFetch(input_stream, first_byte++).x;
    			tmp.z = texelFetch(input_stream, first_byte++).x;
    			tmp.w = texelFetch(input_stream, first_byte++).x;
    			mov(result, n, uintBitsToFloat(get_bits(tmp, desc.swap_bytes)));
    			break;
    		case 2:
    			//half
    			tmp.x = texelFetch(input_stream, first_byte++).x;
    			tmp.y = texelFetch(input_stream, first_byte++).x;
    			mov(result, n, unpackHalf2x16(uint(get_bits(tmp.xy, desc.swap_bytes))).x);
    			break;
    		case 3:
    			//unsigned byte
    			mov(result, n, texelFetch(input_stream, first_byte++).x);
    			mov(scale, n, 255.);
    			reverse_order = (desc.swap_bytes != 0);
    			break;
    		case 4:
    			//signed word
    			tmp.x = texelFetch(input_stream, first_byte++).x;
    			tmp.y = texelFetch(input_stream, first_byte++).x;
    			mov(result, n, get_s16(tmp.xy, desc.swap_bytes));
    			break;
    		case 5:
    			//cmp
    			tmp.x = texelFetch(input_stream, first_byte++).x;
    			tmp.y = texelFetch(input_stream, first_byte++).x;
    			tmp.z = texelFetch(input_stream, first_byte++).x;
    			tmp.w = texelFetch(input_stream, first_byte++).x;
    			bits = get_bits(tmp, desc.swap_bytes);
    			result.x = preserve_sign_s16((bits & 0x7FF) << 5);
    			result.y = preserve_sign_s16(((bits >> 11) & 0x7FF) << 5);
    			result.z = preserve_sign_s16(((bits >> 22) & 0x3FF) << 6);
    			result.w = 1.;
    			scale = vec4(32767., 32767., 32767., 1.);
    			break;
    		case 6:
    			//ub256
    			mov(result, n, float(texelFetch(input_stream, first_byte++).x));
    			reverse_order = (desc.swap_bytes != 0);
    			break;
    		}
    	}
    
    	result /= scale;
    	return (reverse_order)? result.wzyx: result;
    }
    
    attribute_desc fetch_desc(int location)
    {
    	attribute_desc result;
    	int attribute_flags = input_attributes[location].w;
    	result.type = input_attributes[location].x;
    	result.attribute_size = input_attributes[location].y;
    	result.starting_offset = input_attributes[location].z;
    	result.stride = attribute_flags & 0xFF;
    	result.swap_bytes = (attribute_flags >> 8) & 0x1;
    	result.is_volatile = (attribute_flags >> 9) & 0x1;
    	result.frequency = (attribute_flags >> 10) & 0x3;
    	result.modulo = (attribute_flags >> 12) & 0x1;
    	result.divisor = (attribute_flags >> 13) & 0xFFFF;
    	return result;
    }
    
    vec4 read_location(int location)
    {
    	attribute_desc desc = fetch_desc(location);
    	//if attribute is disabled return 1 (makes all operations with it nop except add/sub - TODO)
    	if (desc.attribute_size == 0) return vec4(1.);
    
    	int vertex_id = gl_VertexIndex - int(vertex_base_index);
    	if (desc.frequency == 0)
    		vertex_id = 0;
    	else if (desc.frequency > 1)
    	{
    		//if a vertex modifier is active; vertex_base must be 0 and is ignored
    		if (desc.modulo != 0)
    			vertex_id = gl_VertexIndex % desc.divisor;
    		else
    			vertex_id = gl_VertexIndex / desc.divisor;
    	}
    
    	if (desc.is_volatile != 0)
    		return fetch_attribute(desc, vertex_id, volatile_input_stream);
    	else
    		return fetch_attribute(desc, vertex_id, persistent_input_stream);
    }
    
    void vs_main(inout vec4 dst_reg0, inout vec4 dst_reg1, inout vec4 dst_reg7)
    {
    	vec4 tmp0;
    	vec4 tmp1;
    	vec4 in_diff_color= read_location(3);
    	vec4 in_pos= read_location(0);
    	vec4 in_tc0= read_location(8);
    	dst_reg1 = (in_diff_color * vc[13]);
    	tmp0.x = vec4(dot(vec4(in_pos.xyzx.xyz, 1.0), vc[4])).x;
    	tmp0.y = vec4(dot(vec4(in_pos.xyzx.xyz, 1.0), vc[5])).y;
    	tmp0.z = vec4(dot(vec4(in_pos.xyzx.xyz, 1.0), vc[6])).z;
    	tmp1.xy = in_tc0.xyxx.xy;
    	tmp1.z = vc[467].xxxx.z;
    	dst_reg7.y = vec4(dot(vec4(tmp1.xyzx.xyz, 1.0), vc[8])).y;
    	dst_reg7.x = vec4(dot(vec4(tmp1.xyzx.xyz, 1.0), vc[7])).x;
    	dst_reg0.w = vec4(dot(vec4(tmp0.xyzx.xyz, 1.0), vc[3])).w;
    	dst_reg0.z = vec4(dot(vec4(tmp0.xyzx.xyz, 1.0), vc[2])).z;
    	dst_reg0.y = vec4(dot(vec4(tmp0.xyzx.xyz, 1.0), vc[1])).y;
    	dst_reg0.x = vec4(dot(vec4(tmp0.xyzx.xyz, 1.0), vc[0])).x;
    
    }
    
    void main ()
    {
    	vec4 dst_reg0= vec4(0.0f, 0.0f, 0.0f, 1.0f);
    	vec4 dst_reg1= vec4(0.0, 0.0, 0.0, 0.0);
    	vec4 dst_reg7= vec4(0.0, 0.0, 0.0, 0.0);
    
    	vs_main(dst_reg0, dst_reg1, dst_reg7);
    
    	gl_Position = dst_reg0;
    	back_diff_color = dst_reg1;
    	tc0 = dst_reg7;
    	gl_Position = gl_Position * scale_offset_mat;
    }
    
    #1362

    Bill Hollings
    Keymaster

    @kerlingb

    The appearance of unsupported_GLSLstd450UnpackHalf2x16() indicates that you are trying to use an unpacking function (ie. GLSL unpackHalf2x16()) that is not supported by Metal. Metal does not support the unpacking of one 32-bit integer into two half float values.

    The other errors, to do with passing arguments between functions, is a bug in the shader converter. We will review that and fix it.

    …Bill

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.