Shader module compilation failed


This topic contains 2 replies, has 2 voices, and was last updated by  Bill Hollings 9 months, 3 weeks ago.

Viewing 3 posts - 1 through 3 (of 3 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

    #1396

    Bill Hollings
    Keymaster

    The second issue has been fixed now.

    Good news! MoltenVK is transitioning to an open-source model. It has not been made public yet…but if you provide your GitHub user ID via our Contact form (or see the button below), we can provide you with access to the open-source MoltenVK Beta on GitHub.

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

The forum ‘MoltenVK Support’ is closed to new topics and replies.