shader-slang / slang

Making it easier to work with shaders
MIT License
1.81k stars 164 forks source link

Slang parser in VS Code throwing unfixable compatibility system errors #4585

Closed natevm closed 2 days ago

natevm commented 2 weeks ago

I'm trying to write a simple ray generation shader, but with a recent update to my slang extension to VS code, the parser seems to be going a bit crazy wrt compatibility modes.

[shader("raygeneration")]
void simpleRayGen(uniform RayGenData record) {
    uint2 pixelID = DispatchRaysIndex().xy;
    // ...
}

the above code reports a rather chaotic error that I have a hard time deciphering:

entrypoint 'simpleRayGen' requires capability 'textualTarget + hlsl + sm_4_0 + sm_4_1 + sm_5_0 + sm_5_1 + sm_6_0 + sm_6_1 + sm_6_2 + sm_6_3 + sm_6_4 + sm_6_5 + anyhit | textualTarget + hlsl + sm_4_0 + sm_4_1 + sm_5_0 + sm_5_1 + sm_6_0 + sm_6_1 + sm_6_2 + sm_6_3 + sm_6_4 + sm_6_5 + closesthit | textualTarget + hlsl + sm_4_0 + sm_4_1 + sm_5_0 + sm_5_1 + sm_6_0 + sm_6_1 + sm_6_2 + sm_6_3 + sm_6_4 + sm_6_5 + intersection | textualTarget + glsl + glsl_spirv_1_0 + glsl_spirv_1_1 + glsl_spirv_1_2 + glsl_spirv_1_3 + glsl_spirv_1_4 + GLSL_130 + GLSL_140 + anyhit + GL_ARB_sparse_texture_clamp + GL_EXT_ray_query + GL_EXT_ray_tracing + GL_EXT_samplerless_texture_functions | textualTarget + glsl + glsl_spirv_1_0 + glsl_spirv_1_1 + glsl_spirv_1_2 + glsl_spirv_1_3 + glsl_spirv_1_4 + GLSL_130 + GLSL_140 + closesthit + GL_ARB_sparse_texture_clamp + GL_EXT_ray_query + GL_EXT_ray_tracing + GL_EXT_samplerless_texture_functions | textualTarget + glsl + glsl_spirv_1_0 + glsl_spirv_1_1 + glsl_spirv_1_2 + glsl_spirv_1_3 + glsl_spirv_1_4 + GLSL_130 + GLSL_140 + intersection + GL_ARB_sparse_texture_clamp + GL_EXT_ray_query + GL_EXT_ray_tracing + GL_EXT_samplerless_texture_functions | spirv_1_0 + spirv_1_1 + spirv_1_2 + spirv_1_3 + spirv_1_4 + anyhit + SPV_KHR_ray_tracing + SPV_KHR_ray_query + SPV_GOOGLE_user_type + spvImageQuery + spvImageGatherExtended + spvMinLod + spvRayTracingKHR + spvRayQueryKHR | spirv_1_0 + spirv_1_1 + spirv_1_2 + spirv_1_3 + spirv_1_4 + closesthit + SPV_KHR_ray_tracing + SPV_KHR_ray_query + SPV_GOOGLE_user_type + spvImageQuery + spvImageGatherExtended + spvMinLod + spvRayTracingKHR + spvRayQueryKHR | spirv_1_0 + spirv_1_1 + spirv_1_2 + spirv_1_3 + spirv_1_4 + intersection + SPV_KHR_ray_tracing + SPV_KHR_ray_query + SPV_GOOGLE_user_type + spvImageQuery + spvImageGatherExtended + spvMinLod + spvRayTracingKHR + spvRayQueryKHR', which is incompatible with the current compilation target 'textualTarget + hlsl + raygen | textualTarget + glsl + raygen | textualTarget + c + raygen | textualTarget + cpp + raygen | textualTarget + cuda + raygen | textualTarget + metal + raygen | spirv_1_0 + raygen'.(36107) deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex' deviceCode.slang(33, 19): see using of 'DispatchRaysIndex'

natevm commented 2 weeks ago

It appears that this was caused by a missing curly brace that failed to close the body of the entry point. Still, it would be nice to have a nicer error message here.

natevm commented 2 weeks ago

I suppose what would be ideal is if slang's parser could catch that there's a [shader("")] attribute within the body of another entry point in the same file, and throw an error that "[shader('...')]" is not allowed within another entry point's scope, rather than globbing the requirements for all the other entry points within the first.

natevm commented 2 weeks ago

Related complaint:

When I use an intrinsic like "ObjectRayOrigin()" in an entry point clearly marked as [shader("raygeneration")], Slang should tell me that "ObjectRayOrigin" isn't allowed in a ray generation entry point.

With the new compatibility system, the errors are pretty useless:

[shader("raygeneration")]
void simpleRayGen(uniform RayGenData record) {
  ObjectRayOrigin();
}

The error message from the parser for the code above underlines simpleRayGen, and gives:

entrypoint 'simpleRayGen' requires capability 'textualTarget + hlsl + sm_4_0 + sm_4_1 + sm_5_0 + sm_5_1 + sm_6_0 + sm_6_1 + sm_6_2 + sm_6_3 + sm_6_4 + sm_6_5 + intersection | textualTarget + hlsl + sm_4_0 + sm_4_1 + sm_5_0 + sm_5_1 + sm_6_0 + sm_6_1 + sm_6_2 + sm_6_3 + sm_6_4 + sm_6_5 + closesthit | textualTarget + hlsl + sm_4_0 + sm_4_1 + sm_5_0 + sm_5_1 + sm_6_0 + sm_6_1 + sm_6_2 + sm_6_3 + sm_6_4 + sm_6_5 + anyhit | textualTarget + glsl + glsl_spirv_1_0 + glsl_spirv_1_1 + glsl_spirv_1_2 + glsl_spirv_1_3 + glsl_spirv_1_4 + intersection + GL_EXT_ray_tracing | textualTarget + glsl + glsl_spirv_1_0 + glsl_spirv_1_1 + glsl_spirv_1_2 + glsl_spirv_1_3 + glsl_spirv_1_4 + closesthit + GL_EXT_ray_tracing | textualTarget + glsl + glsl_spirv_1_0 + glsl_spirv_1_1 + glsl_spirv_1_2 + glsl_spirv_1_3 + glsl_spirv_1_4 + anyhit + GL_EXT_ray_tracing | textualTarget + cuda + intersection | textualTarget + cuda + closesthit | textualTarget + cuda + anyhit | spirv_1_0 + spirv_1_1 + spirv_1_2 + spirv_1_3 + spirv_1_4 + intersection + SPV_KHR_ray_tracing + SPV_KHR_ray_query + spvRayTracingKHR + spvRayQueryKHR | spirv_1_0 + spirv_1_1 + spirv_1_2 + spirv_1_3 + spirv_1_4 + closesthit + SPV_KHR_ray_tracing + SPV_KHR_ray_query + spvRayTracingKHR + spvRayQueryKHR | spirv_1_0 + spirv_1_1 + spirv_1_2 + spirv_1_3 + spirv_1_4 + anyhit + SPV_KHR_ray_tracing + SPV_KHR_ray_query + spvRayTracingKHR + spvRayQueryKHR', which is incompatible with the current compilation target 'textualTarget + hlsl + raygen | textualTarget + glsl + raygen | textualTarget + c + raygen | textualTarget + cpp + raygen | textualTarget + cuda + raygen | textualTarget + metal + raygen | spirv_1_0 + raygen'.(36107) deviceCode.slang(33, 3): see using of 'ObjectRayOrigin'

Albeit unintentional, this kind of error is a terrible workflow for programmers, and reminds me of the notorious template errors from C++.

csyonghe commented 2 weeks ago

Instead of printing out the full capability definition, we should only print out the missing key capability atoms. In this case, the message should be something like:

entrypoint 'simpleRayGen' is using functions or types that are not defined for target raygen. Given the current definition, it is only valid for 'sm_6_5+intersection | sm_6_5 + closesthit | sm_6_5 + anyhit | ...'.

ArielG-NV commented 1 week ago

Related to #4347, #4172, #4683