1
$\begingroup$

I am trying to compile some really simple shaders with DXC but, when creating PSO, I get:

D3D12 ERROR: ID3D12Device::CreateVertexShader: Vertex Shader is corrupt or in an unrecognized format. [ STATE_CREATION ERROR #67: CREATEVERTEXSHADER_INVALIDSHADERBYTECODE]
D3D12 ERROR: ID3D12Device::CreatePixelShader: Pixel Shader is corrupt or in an unrecognized format. [ STATE_CREATION ERROR #93: CREATEPIXELSHADER_INVALIDSHADERBYTECODE]
The parameter is incorrect.

The shader I try to compile:

struct pixel_data
{
    float4 position : SV_POSITION;
    float2 uv : TEXCOORD0;
};


pixel_data vs_main( uint vertexID : SV_VertexID )
{
    float2 vertexOffset = float2((vertexID & 2) ? 1.f : -1.f, (vertexID & 1) ? 1.f : -1.f);

    pixel_data output;
    output.position = float4(vertexOffset, 1.f, 1.f);
    output.uv = vertexOffset * float2(0.5f, -0.5f) + 0.5f;

    return output;
}


float4 ps_main( pixel_data input ) : SV_TARGET
{
    return float4(input.uv, 1.f, 1.f);
}

and code for compiling:

struct
{
    ShaderObj shaders[MAX_SHADER];
    uint lastShaderID;

    #ifdef _PC_ 
        IDxcLibrary *dxcLibrary;
        IDxcCompiler *dxcCompiler;
        IDxcValidator *dxcValidator;
    #endif // #ifdef _PC_ 
} shadersObjects;


#ifdef _PC_ 
    void Shader::Init()
    {
        shadersObjects.lastShaderID = 0;

        DX_RESULT( DxcCreateInstance( CLSID_DxcLibrary, IID_PPV_ARGS( &shadersObjects.dxcLibrary ) ) );
        DX_RESULT( DxcCreateInstance( CLSID_DxcCompiler, IID_PPV_ARGS( &shadersObjects.dxcCompiler ) ) );
        DX_RESULT( DxcCreateInstance( CLSID_DxcValidator, IID_PPV_ARGS( &shadersObjects.dxcValidator ) ) );
    }


    inline static IDxcBlob *CompileShader(char const *const fileName, wchar_t const *const entryPoint, wchar_t const *const targetProfile)
    {
        uint const SHADER_PATH_LEN = wcslen( shadersPath );

        uint fileNameLength = SHADER_PATH_LEN + strlen( fileName );
        wchar_t *wFileName = new wchar_t[fileNameLength + 1];
        memcpy( wFileName, shadersPath, sizeof( wchar_t ) * SHADER_PATH_LEN );
        Misc::CharToWchar( wFileName + SHADER_PATH_LEN, fileName );

        wchar_t const *compileArguments[] =
        {           
            L"/WX",                         // Treat warnings as errors
            //L"/Zi",                       // Enable debug information
            //L"/res_may_alias",            // Assume that UAVs/SRVs may alias,

        };

        uint codePage = CP_UTF8;
        IDxcBlobEncoding *sourceBlob;
        DX_RESULT( shadersObjects.dxcLibrary->CreateBlobFromFile( wFileName, &codePage, &sourceBlob));

        IDxcIncludeHandler *includeHandler;
        DX_RESULT( shadersObjects.dxcLibrary->CreateIncludeHandler( &includeHandler ) );
        IDxcOperationResult *compileResult;
        DX_RESULT( shadersObjects.dxcCompiler->Compile(
            sourceBlob, // pSource
            wFileName, // pSourceName
            entryPoint, // pEntryPoint
            targetProfile, // pTargetProfile
            compileArguments, 1, // pArguments, argCount
            nullptr, 0, // pDefines, defineCount
            includeHandler, // pIncludeHandler
            &compileResult) // ppResult
        );
        includeHandler->Release();

        HRESULT compileHResult;
        compileResult->GetStatus(&compileHResult);
        if (FAILED(compileHResult))
        {
            if (compileResult)
            {
                IDxcBlobEncoding *errorsBlob;
                compileHResult = compileResult->GetErrorBuffer(&errorsBlob);
                if (errorsBlob)
                {
                    if (SUCCEEDED(compileHResult))
                    {
                        DebugPrint("%ls:%ls\n%s\n", wFileName, entryPoint, (const char *)errorsBlob->GetBufferPointer());
                    }

                    errorsBlob->Release();
                }

                compileResult->Release();
                compileResult = nullptr;
            }
        }

        delete[] wFileName;
        sourceBlob->Release();
        if (compileResult)
        {
            IDxcBlob *code;
            compileResult->GetResult( &code );
            compileResult->Release();

            IDxcOperationResult *validateResult;
            DX_RESULT( shadersObjects.dxcValidator->Validate( code, DxcValidatorFlags_InPlaceEdit, &validateResult ) );
            HRESULT validateHResult;
            validateResult->GetStatus( &validateHResult );
            if ( FAILED( validateHResult ) )
            {
                IDxcBlobEncoding *errorsBlob;
                validateHResult = validateResult->GetErrorBuffer( &errorsBlob );

                if ( errorsBlob )
                {
                    if ( SUCCEEDED( validateHResult ) )
                    {
                        DebugPrint( "%ls:%ls\n%s\n", wFileName, entryPoint, (const char *)errorsBlob->GetBufferPointer() );
                    }

                    errorsBlob->Release();
                }
            }

            validateResult->Release();
            return code;
        }

        return nullptr;
    }


    ShaderObj* Shader::CreateShader(char const* vsFileName, char const* psFileName, ...)
    {
        IDxcBlob *vsCode = CompileShader( vsFileName, L"vs_main", L"vs_6_4");
        if ( !vsCode )
            return nullptr;

        IDxcBlob *psCode = CompileShader( psFileName, L"ps_main", L"ps_6_4" );
        if ( !psCode )
        {
            vsCode->Release();
            return nullptr;
        }

        D3D12_GRAPHICS_PIPELINE_STATE_DESC descPso = {};
        descPso.pRootSignature = GfxDevice::GetGraphicsRootSignature();

        descPso.VS.pShaderBytecode = vsCode->GetBufferPointer();
        descPso.VS.BytecodeLength = vsCode->GetBufferSize();

        descPso.PS.pShaderBytecode = psCode->GetBufferPointer();
        descPso.PS.BytecodeLength = psCode->GetBufferSize();

        descPso.RasterizerState = RasterizationState::shaded_NoMSAA;

        descPso.DepthStencilState = DepthStencilState::disabled;

        descPso.BlendState.AlphaToCoverageEnable = FALSE;
        descPso.BlendState.IndependentBlendEnable = FALSE;
        descPso.BlendState.RenderTarget[0] = BlendState::disabled;

        descPso.InputLayout.NumElements = 0;
        descPso.InputLayout.pInputElementDescs = nullptr;
        descPso.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;

        descPso.NumRenderTargets = 1;
        descPso.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
        descPso.DSVFormat = DXGI_FORMAT_UNKNOWN;

        descPso.SampleDesc.Count = 1;
        descPso.SampleMask = UINT_MAX;

        ID3D12PipelineState *pso;
        HRESULT posCreateHresult = GfxDevice::GetGfxDevice()->CreateGraphicsPipelineState( &descPso, IID_PPV_ARGS( &pso ) );
        vsCode->Release();
        psCode->Release();

        if ( FAILED( posCreateHresult ) )
        {
            DX_RESULT( posCreateHresult );
            return nullptr;
        }

        ShaderObj *shader = &shadersObjects.shaders[shadersObjects.lastShaderID];
        ++shadersObjects.lastShaderID;
        shader->pso = pso;

        return shader;
    }


    void Shader::Release()
    {
        shadersObjects.dxcLibrary->Release();
        shadersObjects.dxcCompiler->Release();
        shadersObjects.dxcValidator->Release();

        for (uint i = 0; i < shadersObjects.lastShaderID; ++i)
        {
            shadersObjects.shaders[i].pso->Release();
        }
    }
#endif // #ifdef _PC_ 

I have tried using CreateBlobWithEncodingFromPinned with source loaded from file and from char* array (in case there was some strange encoding in the file).

Everything is ok until the PSO, shaders get compiled and validated.

I tried to change some params in PSO description but it seems like Create*Shader are first in PSO creation.

I have dev mode enabled in windows.

Any idea?

$\endgroup$
1
$\begingroup$

This can be caused by the compiler creating unsigned bytecode. For the compiler to sign the bytecode, you have to have a copy of dxil.dll in the same folder as the dxcompiler.dll at runtime. See Using the GitHub dxcompiler.dll for some more info. The dxil.dll is available in the official DXC releases.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.