Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access TIntermediate with public headers #3533

Open
timiimit opened this issue Mar 1, 2024 · 2 comments
Open

Access TIntermediate with public headers #3533

timiimit opened this issue Mar 1, 2024 · 2 comments

Comments

@timiimit
Copy link

timiimit commented Mar 1, 2024

Main issue

After calling TShader::parse() I have been using:

shader->getIntermediate()->getNumEntryPoints();
shader->getIntermediate()->getNumErrors();

when converting HLSL to SPIRV because TShader::parse() sometimes still succeeded in some undesirable cases. For example when entry points don't exist. So I used getIntermediate() to do extra checking. But that's no longer possible since the removal of some public header files.

Is there another way to do this?

Extra question

Another thing that I wasn't yet using, but was planning to in the future is glslang::TIntermTraverser to do some extra application-specific code checks.

class MyTraverser : public glslang::TIntermTraverser { ... };

auto* root = shader->getIntermediate()->getTreeRoot();
MyTraverser traverser;
root->traverse(&traverser);

So I would also like to know if this is something that will not be possible or if this was removed by mistake.

@timiimit
Copy link
Author

timiimit commented Mar 5, 2024

Maybe it would be helpful to describe the compile & link approach I've been using.

Pseudocode:

hlsl = read_file()
for each of 5 shader stages
{
    stage = new TShader(stages[i]);
    stage->setStringsWithLengthsAndNames(hlsl)
    stage->setEntryPoint(entryPointNames[i])
    success = stage->parse()
    entrypoints = stage->getIntermediate()->getNumEntryPoints()
    errors = stage->getIntermediate()->getNumErrors()
    if (entrypoints != 1 || entrypoints != 0)
        success = false

    if (success)
        program.addShader(stage)
}
program.link()

It should be noted that hlsl source might not contain entrypoints of all shader stages. So I cannot just do addShader for all shader stages, because then linking will fail with errors such as this:

Linked geometry stage:

WARNING: Linking geometry stage: Entry point not found
ERROR: Linking geometry stage: At least one shader must specify an input layout primitive
ERROR: Linking geometry stage: At least one shader must specify an output layout primitive
ERROR: Linking geometry stage: At least one shader must specify a layout(max_vertices = value)

@timiimit
Copy link
Author

timiimit commented Mar 5, 2024

Right after writing previous comment, I thought of a different approach. Now I tried to create separate TProgram for each TShader. So that I can compile and link each stage individually.

But it seems that now I encountered another problem where Domain shader stage (EShLangTessEvaluation) does not need an entrypoint to compile and link. So both compilation and linking is successful and spirv is generated. Also spirv-cross seems to be able to convert it to glsl. But it only generates this

#version 460

void main()
{
}

This glsl then fails to link for real in OpenGL when being used as a tesselation evaluation shader with error message:

Tessellation evaluation info
----------------------------
Internal error: assembly compile error for tessellation evaluation shader at offset 228:
-- error message --
line 10, column 1:  error: program missing TESS_MODE declaration
-- internal assembly text --
!!NVtep5.0
OPTION NV_internal;
OPTION NV_bindless_texture;
# cgc version 3.4.0001, build date Feb 22 2024
# command line args: 
#vendor NVIDIA Corporation
#version 3.4.0.1 COP Build Date Feb 22 2024
#profile gp5tp
#program main
TEMP T;
END
# 0 instructions, 0 R-regs

Since I have never used this stage I don't really know what is and isn't considered valid. As a temporary workaround I added

if (currentShaderStage == EShLangTessEvaluation && spirv.size() < 512)
    continue;

after glslang::GlslangToSpv because it seems to always produce small spirv.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant