KhronosGroup / glslang

Khronos-reference front end for GLSL/ESSL, partial front end for HLSL, and a SPIR-V generator.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

HLSL: crash, while compiling HULL shader

Try opened this issue · comments

commented

Found, while working on spirv-cross tessellation shader. This shader is result of cross-compilation of simple glsl shader.
Shader code:

static float4 gl_Position;
static float gl_TessLevelOuter[4];
static float gl_TessLevelInner[2];
static float3 vFoo;

struct SPIRV_Cross_HS_Point_Input
{
    float4 gl_Position : SV_Position;
};

struct SPIRV_Cross_Input
{
};

struct SPIRV_Cross_Output
{
    float3 vFoo : TEXCOORD0;
    float gl_TessLevelOuter[3] : SV_TessFactor;
    float gl_TessLevelInner : SV_InsideTessFactor;
};

struct SPIRV_Cross_HS_Point_Output
{
};

void tesc_main(InputPatch<SPIRV_Cross_HS_Point_Input,32> gl_in)
{
    gl_TessLevelInner[0] = 8.8999996185302734375f;
    gl_TessLevelInner[1] = 6.900000095367431640625f;
    gl_TessLevelOuter[0] = 8.8999996185302734375f;
    gl_TessLevelOuter[1] = 6.900000095367431640625f;
    gl_TessLevelOuter[2] = 3.900000095367431640625f;
    gl_TessLevelOuter[3] = 4.900000095367431640625f;
    vFoo = 1.0f.xxx;
}

SPIRV_Cross_Output tesc_patch_constant(InputPatch<SPIRV_Cross_HS_Point_Input, 32> gl_in)
{
    tesc_main(gl_in);
    SPIRV_Cross_Output stage_output;
    stage_output.gl_TessLevelOuter[0] = gl_TessLevelOuter[0];
    stage_output.gl_TessLevelOuter[1] = gl_TessLevelOuter[1];
    stage_output.gl_TessLevelOuter[2] = gl_TessLevelOuter[2];
    stage_output.gl_TessLevelInner = gl_TessLevelInner[0];
    stage_output.vFoo = vFoo;
    return stage_output;
}

[outputcontrolpoints(1)]
[domain("tri")]
[partitioning("fractional_even")]
[outputtopology("triangle_cw")]
[patchconstantfunc("tesc_patch_constant")]
SPIRV_Cross_HS_Point_Output main(SPIRV_Cross_Input stage_input, InputPatch<SPIRV_Cross_HS_Point_Input, 32> gl_in)
{
    tesc_main(gl_in);
    SPIRV_Cross_HS_Point_Output stage_output;
    return stage_output;
}

GLSL:

#version 310 es
#extension GL_EXT_tessellation_shader : require

layout(location = 0) patch out vec3 vFoo;

layout(vertices = 1) out;

void main()
{
    gl_TessLevelInner[0] = 8.9;
    gl_TessLevelInner[1] = 6.9;
    gl_TessLevelOuter[0] = 8.9;
    gl_TessLevelOuter[1] = 6.9;
    gl_TessLevelOuter[2] = 3.9;
    gl_TessLevelOuter[3] = 4.9;
    vFoo = vec3(1.0);
}

While, tessellation shader without output is not particulary useful kind of shader, but it's valid one (from syntax point of view).

Crash stack:

1   std::vector<glslang::TTypeLoc,glslang::pool_allocator<glslang::TTypeLoc>>::operator[] vector              1484
2   glslang::TType::TType                                                                 Types.h             1643
3   glslang::HlslParseContext::flatten                                                    hlslParseHelper.cpp 1190
4   <lambda_c0d8cf1ab0cf9dc4c0965069d8b0a181>::operator()                                 hlslParseHelper.cpp 2099
5   glslang::HlslParseContext::transformEntryPoint                                        hlslParseHelper.cpp 2106
6   glslang::HlslParseContext::handleFunctionDefinition                                   hlslParseHelper.cpp 1680
7   glslang::HlslGrammar::acceptFunctionBody                                              hlslGrammar.cpp     2691
8   glslang::HlslGrammar::acceptFunctionDefinition                                        hlslGrammar.cpp     2683
9   glslang::HlslGrammar::acceptDeclaration                                               hlslGrammar.cpp     432 
10  glslang::HlslGrammar::acceptDeclarationList                                           hlslGrammar.cpp     164 
11  glslang::HlslGrammar::acceptCompilationUnit                                           hlslGrammar.cpp     129 
12  glslang::HlslGrammar::parse                                                           hlslGrammar.cpp     66 
13  glslang::HlslParseContext::parseShaderStrings                                         hlslParseHelper.cpp 134
14  `anonymous namespace'::DoFullParse::operator()                                        ShaderLang.cpp      1236 
15  `anonymous namespace'::ProcessDeferred<`anonymous namespace'::DoFullParse>            ShaderLang.cpp      1019
16  `anonymous namespace'::CompileDeferred                                                ShaderLang.cpp      1325
17  glslang::TShader::parse                                                               ShaderLang.cpp      1915
18  glslang::TShader::parse                                                               ShaderLang.h        670 
19  CompileAndLinkShaderUnits                                                             StandAlone.cpp      1331
20  CompileAndLinkShaderFiles                                                             StandAlone.cpp      1487

Context:

// Top level variable flattening: construct data
void HlslParseContext::flatten(const TVariable& variable, bool linkage, bool arrayed)
{
    const TType& type = variable.getType();

    // If it's a standalone built-in, there is nothing to flatten
    if (type.isBuiltIn() && !type.isStruct())
        return;

    auto entry = flattenMap.insert(std::make_pair(variable.getUniqueId(),
                                                  TFlattenData(type.getQualifier().layoutBinding,
                                                               type.getQualifier().layoutLocation)));

    // if flattening arrayed io struct, array each member of dereferenced type
    if (arrayed) {
        const TType dereferencedType(type, 0); // <--- fetching of first member of structure, without checking for struct size
        flatten(variable, dereferencedType, entry.first->second, variable.getName(), linkage,
                type.getQualifier(), type.getArraySizes());
    } else {
        flatten(variable, type, entry.first->second, variable.getName(), linkage,
                type.getQualifier(), nullptr);
    }
}