【问题标题】:D3D11 Create Shader: Encoded Vertex Shader size doesn't match specified sizeD3D11 创建着色器:编码的顶点着色器大小与指定大小不匹配
【发布时间】:2017-01-06 04:18:03
【问题描述】:

我正在使用 DirectX 11 开发游戏引擎,但无法让着色器正确编码。我正在将着色器预编译为 .csh 文件并使用字节码创建着色器。

当我尝试创建任何着色器时出现此错误,但在此示例中,我将使用我的 PassThrough 顶点着色器。

D3D11 ERROR: ID3D11Device::CreateVertexShader: Encoded Vertex Shader size doesn't match specified size. [ STATE_CREATION ERROR #166: CREATEVERTEXSHADER_INVALIDSHADERBYTECODE]

着色器:

#include "../VertexLayouts.hlsli"
// structs in included file
struct PASS_THROUGH_VS
{
    float3 pos : POSITION;
    float2 texCoord : TEXCOORD;
};

struct PASS_THROUGH_PS
{
    float4 pos : SV_POSITION;
    float2 texCoord : TEXCOORD;
};


PASS_THROUGH_PS main( PASS_THROUGH_VS input )
{
    PASS_THROUGH_PS output = (PASS_THROUGH_PS)(0);
    output.pos = float4(input.pos, 1);
    output.texCoord = input.texCoord;
    return output;
}

使用以下设置: PassThrough_PS properties

在 Renderer.h 中

#include "Vertex Shaders\PassThrough_VS.csh"

在 Renderer.cpp 中

HRESULT hrReturn;

    hrReturn = CreateVertexShader(&PassThrough_VS, sizeof(PassThrough_VS), Pass_Through_VS);
    if (FAILED(hrReturn)) {}
        //return hrReturn;

HRESULT CRenderer::CreateVertexShader(const void* ptrByteCode, SIZE_T szByteCodeLength, eVertexShaderType type)
{
    HRESULT hrReturn;
    tVertShader newShader = {};
    hrReturn = D3Device->CreateVertexShader(&ptrByteCode, szByteCodeLength, nullptr, &(newShader.m_id3dShader)); // WHERE ERROR OCCURS
    if (FAILED(hrReturn))
        return hrReturn;
    newShader.m_ptrByteCode = ptrByteCode;
    newShader.m_szByteCodeLength = szByteCodeLength;
    D3VertexShaders[type] = newShader;
    return hrReturn;
}

【问题讨论】:

  • 我已经对每个着色器模型进行了尝试,更新了我的驱动程序并返回并尝试了一个以前有效但现在不行的简单顶点着色器。
  • 另一个问题是 .cso 或 .csh 的原因是什么?我被教导如何使用 .csh 方法,但我一生都无法记住老师给出的理由。此外,这似乎是一种非常罕见的技术,因为 google 或 bing 上没有关于该文件类型的任何内容。

标签: c++ rendering directx-11 vertex-shader


【解决方案1】:

问题是您传递的是指向指针的指针,因此实际上并未将着色器 blob 数据传递给 Direct3D。

HRESULT CRenderer::CreateVertexShader(const void* ptrByteCode, SIZE_T szByteCodeLength, eVertexShaderType type)
{
    HRESULT hrReturn;
    tVertShader newShader = {};
    hrReturn = D3Device->CreateVertexShader(&ptrByteCode, szByteCodeLength,
        nullptr, &(newShader.m_id3dShader));
    ...    

正确的代码是:

HRESULT CRenderer::CreateVertexShader(const void* ptrByteCode, SIZE_T szByteCodeLength, eVertexShaderType type)
{
    HRESULT hrReturn;
    tVertShader newShader = {};
    hrReturn = D3Device->CreateVertexShader(ptrByteCode, szByteCodeLength,
        nullptr, &(newShader.m_id3dShader));
    ...    

你应该看看DirectX Tool Kit,尤其是tutorials

您没有包含有关 tVertShader 类型的任何详细信息,但您很可能遇到引用计数问题。考虑使用Microsoft::WRL::ComPtr 而不是原始指针来管理 Direct3D COM 对象的生命周期。见this article

【讨论】:

  • 感谢您的回复。我目前正在工作,所以在我尝试解决方案之前还需要一点时间。确实我有参考问题,我之前使用过comptrs,但我似乎有多个地方资源被错误分配。在 tVertex 结构中,着色器由 ID3D11 着色器指针保存,字节码是 const void*。
猜你喜欢
  • 1970-01-01
  • 2016-03-24
  • 2011-05-24
  • 2020-03-25
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
相关资源
最近更新 更多