Slang着色器编译为SPIR-V后矩阵访问异常(每4个浮点数跳过3个)的问题咨询
Slang着色器编译为SPIR-V后矩阵访问异常(每4个浮点数跳过3个)的问题咨询
我正在尝试为Vulkan框架学习Slang着色器语言,写了一个最基础的全白着色器,但编译出的SPIR-V在N卡Nsight中反编译后显示矩阵访问逻辑异常——每读取4个浮点数就会跳过3个,导致矩阵数据完全错乱,最终渲染结果不对。而对应的GLSL版本编译后却能正常工作,以下是详细信息:
我的Slang着色器代码
module white; struct VertexIn { float3 position : Position; }; struct Camera { float4x4 view; float4x4 projection; float4x4 inverseView; float4x4 inverseProjection; }; struct PushConstants { float32_t4x4 model; }; [[vk::binding(0)]] ConstantBuffer<Camera> camera; [[shader("vertex")]] float4 vertex(VertexIn in, uniform PushConstants pushConstants) : SV_Position { float4x4 mvp = camera.projection * camera.view * pushConstants.model; return mul(mvp, float4(in.position, 1.0f)); } [[shader("fragment")]] float4 fragment() : SV_Target { return float4(1.0, 1.0, 1.0, 1.0); }
预期等效的GLSL代码(可正常工作)
顶点Shader
#version 460 core // 忽略#pragma Position,只是自动关联属性位置的工具 #pragma Position layout(location = 0) in vec3 inPosition; layout(set = 0, binding = 0) uniform Camera { mat4 view; mat4 projection; mat4 inverseView; mat4 inverseProjection; } camera; layout(push_constant) uniform PushConstants { mat4 model; } push; void main() { gl_Position = camera.projection * camera.view * push.model * vec4(inPosition, 1.0); }
片段Shader
#version 460 core layout(location = 0) out vec4 FragColor; void main() { FragColor = vec4(1.0, 1.0, 1.0, 1.0); }
问题现象
GLSL版本编译出的SPIR-V完全符合预期,能正常渲染全白物体,但Slang版本的顶点Shader编译出的SPIR-V被Nsight反编译后,出现了奇怪的矩阵构造和乘法逻辑:
#version 450 struct _MatrixStorage_float4x4_ColMajorstd140 { vec4 data[4]; }; struct _MatrixStorage_float4x4_ColMajorstd430 { vec4 data[4]; }; struct PushConstants_std430 { _MatrixStorage_float4x4_ColMajorstd430 model; }; layout(set = 0, binding = 0, std140) uniform Camera_std140 { _MatrixStorage_float4x4_ColMajorstd140 view; _MatrixStorage_float4x4_ColMajorstd140 projection; _MatrixStorage_float4x4_ColMajorstd140 inverseView; _MatrixStorage_float4x4_ColMajorstd140 inverseProjection; } camera; layout(push_constant, std430) uniform EntryPointParams_std430 { PushConstants_std430 pushConstants; } entryPointParams; layout(location = 0) in vec3 in_position; void main() { mat4 _170 = mat4( vec4(camera.projection.data[0].x, camera.projection.data[1].x, camera.projection.data[2].x, camera.projection.data[3].x), vec4(camera.projection.data[0].y, camera.projection.data[1].y, camera.projection.data[2].y, camera.projection.data[3].y), vec4(camera.projection.data[0].z, camera.projection.data[1].z, camera.projection.data[2].z, camera.projection.data[3].z), vec4(camera.projection.data[0].w, camera.projection.data[1].w, camera.projection.data[2].w, camera.projection.data[3].w)); mat4 _198 = mat4( vec4(camera.view.data[0].x, camera.view.data[1].x, camera.view.data[2].x, camera.view.data[3].x), vec4(camera.view.data[0].y, camera.view.data[1].y, camera.view.data[2].y, camera.view.data[3].y), vec4(camera.view.data[0].z, camera.view.data[1].z, camera.view.data[2].z, camera.view.data[3].z), vec4(camera.view.data[0].w, camera.view.data[1].w, camera.view.data[2].w, camera.view.data[3].w)); mat4 _232 = mat4( vec4(entryPointParams.pushConstants.model.data[0].x, entryPointParams.pushConstants.model.data[1].x, entryPointParams.pushConstants.model.data[2].x, entryPointParams.pushConstants.model.data[3].x), vec4(entryPointParams.pushConstants.model.data[0].y, entryPointParams.pushConstants.model.data[1].y, entryPointParams.pushConstants.model.data[2].y, entryPointParams.pushConstants.model.data[3].y), vec4(entryPointParams.pushConstants.model.data[0].z, entryPointParams.pushConstants.model.data[1].z, entryPointParams.pushConstants.model.data[2].z, entryPointParams.pushConstants.model.data[3].z), vec4(entryPointParams.pushConstants.model.data[0].w, entryPointParams.pushConstants.model.data[1].w, entryPointParams.pushConstants.model.data[2].w, entryPointParams.pushConstants.model.data[3].w)); gl_Position = vec4(in_position, 1.0) * mat4((_170[0] * _198[0]) * _232[0], (_170[1] * _198[1]) * _232[1], (_170[2] * _198[2]) * _232[2], (_170[3] * _198[3]) * _232[3]); }
观察到的核心问题是:矩阵的内存访问完全错乱,比如原本的矩阵
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
被错误地读取为:
[[1, 2, 3, 4], [8, 9, 10, 11], [15, 16, 0, 0], [0, 0, 0, 0]]
我使用的Slang编译代码
std::vector<uint32_t> Coral::Core::SlangShader::CompileSlangToSpirV(const std::string& moduleName, const std::string& entryPointName) { using namespace slang; Slang::ComPtr<IGlobalSession> globalSession; SlangGlobalSessionDesc desc = {}; createGlobalSession(&desc, globalSession.writeRef()); TargetDesc targetDesc; targetDesc.format = SLANG_SPIRV; targetDesc.profile = globalSession->findProfile("vulkan"); const char* searchPaths[] = {"shaders/slang"}; PreprocessorMacroDesc fancyFlag = {"ENABLE_FANCY_FEATU
内容来源于stack exchange
相关产品推荐
相关产品推荐

