Skip to content

Bug cross-compiling HLSL to MSL #194

@DeCarabas

Description

@DeCarabas

I have found a case where SDL_shadercross generates invalid MSL from input HLSL.

Specifically, it generates an invalid attribute index for my StructuredBuffer.

I have this shader HLSL:

struct InstanceData {
  float4x4 transform;
};

cbuffer Uniforms : register(b0, space1) {
  float4x4 mvpMatrix;
};

StructuredBuffer<InstanceData> instances : register(t0, space0);

float4 vs_main(float3 pos : TEXCOORD0, uint iid : SV_InstanceID) : SV_Position {
  return mul(mvpMatrix, mul(instances[iid].transform, float4(pos, 1.0)));
}

Texture2D albedo    : register(t0, space2);
SamplerState samp0  : register(s0, space2);
Texture2D lightmap  : register(t1, space2);
SamplerState samp1  : register(s1, space2);

float4 fs_main(float2 uv : TEXCOORD0, float2 lmuv : TEXCOORD1) : SV_Target0 {
  return albedo.Sample(samp0, uv) * lightmap.Sample(samp1, lmuv);
}

I am compiling this to MSL with the following command line:

shadercross repro.hlsl --dest msl --stage vertex --entrypoint vs_main --output repro_vert.metal

This generates the following broken MSL:

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct type_Uniforms
{
    float4x4 mvpMatrix;
};

struct InstanceData
{
    float4x4 transform;
};

struct type_StructuredBuffer_InstanceData
{
    InstanceData _m0[1];
};

struct vs_main_out
{
    float4 gl_Position [[position]];
};

struct vs_main_in
{
    float3 in_var_TEXCOORD0 [[attribute(0)]];
};

vertex vs_main_out vs_main(vs_main_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_InstanceData& instances [[buffer(4294967295)]], uint gl_InstanceIndex [[instance_id]])
{
    vs_main_out out = {};
    out.gl_Position = Uniforms.mvpMatrix * (instances._m0[gl_InstanceIndex].transform * float4(in.in_var_TEXCOORD0, 1.0));
    return out;
}

The thing to see there is the broken buffer on the instances parameter:

vertex vs_main_out vs_main(... const device type_StructuredBuffer_InstanceData& instances [[buffer(4294967295)]], ...)

A workaround seems to be to split the fragment shader and vertex shader into two different files, and compiling them independently.

(Perhaps something in the cross-compiler is accidentally counting things in one when processing the other?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions