首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DirectX-11实例缓冲区返回E_INVALID_ARGS

DirectX-11实例缓冲区返回E_INVALID_ARGS
EN

Stack Overflow用户
提问于 2017-12-02 15:21:39
回答 0查看 112关注 0票数 0

各位。我已经开始在我的游戏引擎中添加实例了。这是我创建的一个泛型函数,这样我就可以传入一个实例缓冲区指针和一些矩阵,以及要绘制的实例列表。然而,在它的第一个循环中,缓冲区是空的,所以它试图初始化它,但失败了,并返回HR = E_INVALID_ARGS。我不是很确定参数的哪一部分是无效的。

我们的目标是为每个实例传递两个XMFLOAT4X4形式的4X4矩阵。

"sizeofXMFLOAT4X4“变量只是一个完整性检查,看看它读取了多少字节(64,4字节*4浮点/ vec *4 vec= 64)。

如果有人能发现这里可能出现的问题并指出它,我将不胜感激。如果您需要更多信息,请告诉我。谢谢。

代码语言:javascript
复制
void StaticSceneryListClass::UpdateInstanceBuffer(ID3D11Buffer *pInstanceBuffer, XMFLOAT4X4 VPMat, XMFLOAT4X4 tileMat,  vector<StaticSceneryStruct> culledInstanceList)
{
//Pass this the buffer you want to update, the VPMat for the frame, and a list of instances to draw and it will fill the buffer with the stuff and things. 
//If the buffer is not initialized yet, it will be initialized too.

//first, create the data needed.
vector<XMFLOAT4X4> instanceMats;

for (int i = 0; i < culledInstanceList.size(); i++)
{
    XMFLOAT4X4 WorldMat = xmCon->MatTranspose(xmCon->MatMultiply(culledInstanceList[i].worldMat, tileMat));
    XMFLOAT4X4 WVP = xmCon->MatTranspose(xmCon->MatMultiply(WorldMat, VPMat));
    instanceMats.push_back(WVP);
    instanceMats.push_back(WorldMat);
}

if (pInstanceBuffer == NULL)
{
    //buffer not initialized yet, initialize it.
    D3D11_BUFFER_DESC instBuffDesc;
    ZeroMemory(&instBuffDesc, sizeof(instBuffDesc));
    sizeofXMFLOAT4X4 = sizeof(XMFLOAT4X4);
    instBuffDesc.Usage = D3D11_USAGE_DYNAMIC;
    instBuffDesc.ByteWidth = sizeofXMFLOAT4X4 * 2 * culledInstanceList.size();
    instBuffDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    instBuffDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    instBuffDesc.MiscFlags = 0;

    D3D11_SUBRESOURCE_DATA instData;
    ZeroMemory(&instData, sizeof(instData));

    instData.pSysMem = &instanceMats[0];
    HRESULT hr = graphicsPointers.pdev->CreateBuffer(&instBuffDesc, &instData, &pInstanceBuffer);

    if (FAILED(hr))
    {
        //Fails here with E_INVALID_ARG
        MessageBox(NULL, "Failed to create instance buffer!", "StaticSceneryList", MB_OK);
    }
}
else
{
    //buffer already initialized, need to use resource may and unmap.
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));

    //  Disable GPU access to the vertex buffer data.
    graphicsPointers.pdevcon->Map(pInstanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
    //  Update the vertex buffer here.
    memcpy(mappedResource.pData, &instanceMats[0], sizeof(XMFLOAT4X4) * 2 * culledInstanceList.size());
    //  Reenable GPU access to the vertex buffer data.
    graphicsPointers.pdevcon->Unmap(pInstanceBuffer, 0);
}

UPDATE1: 12/2/2017 2:02 CST今天早上我一直在运行各种调试测试,结果很有趣。我尝试隔离这个问题,发现为数据传入null或为缓冲区传入新的本地指针没有任何作用。我打开了调试层,但它没有为create buffer语句提供任何输出。我试着使用缓冲区描述的参数,看看它会做什么,但它们给了我一个错误。我添加了一个捕获,如果剔除的列表大小为0,即使它不是16的倍数,它也会偶尔通过,但它实际上从未产生过工作缓冲区。事实上,它通常仍然会失败,因为...S_OK??失败( HR )正在下降,HR为S_OK,这没有多大意义。当我查看buffer指针的内存值时,它从null变为有一个地址,但它不会被"if not null,release and set to null“块捕获。

这样做的一个有趣的副作用是,它会导致各种形式的巨大内存泄漏。进程内存在大约10秒内以近乎线性的速度攀升到3 3gb以上(我在这一点上关闭了程序,它仍然非常灵敏)。

当然,我似乎也偶尔会遇到这种情况,但这种情况似乎永远不会发生,因为缓冲区是否已经初始化的代码还没有触发。

以下是当前更新后的代码:

代码语言:javascript
复制
void StaticSceneryListClass::UpdateInstanceBuffer(ID3D11Buffer *pInstanceBuffer, XMFLOAT4X4 VPMat, XMFLOAT4X4 tileMat, vector<StaticSceneryStruct> culledInstanceList)
{
//Pass this the buffer you want to update, the VPMat for the frame, and a list of instances to draw and it will fill the buffer with the stuff and things. 
//If the buffer is not initialized yet, it will be initialized too.

//Skip this process if there aren't any instances to draw
if (culledInstanceList.size() > 0)
{
    //first, create the data needed.
    vector<XMFLOAT4X4> instanceMats;
    for (int i = 0; i < culledInstanceList.size(); i++)
    {
        XMFLOAT4X4 WorldMat = xmCon->MatTranspose(xmCon->MatMultiply(culledInstanceList[i].worldMat, tileMat));
        XMFLOAT4X4 WVP = xmCon->MatTranspose(xmCon->MatMultiply(WorldMat, VPMat));
        instanceMats.push_back(WVP);
        instanceMats.push_back(WorldMat);
    }

    if (pInstanceBuffer == NULL)
    {
        //buffer not initialized yet, initialize it.
        D3D11_BUFFER_DESC instBuffDesc;
        ZeroMemory(&instBuffDesc, sizeof(instBuffDesc));
        bytewidth = sizeof(XMFLOAT4X4) * 2 * culledInstanceList.size();
        if (bytewidth % 16 != 0)
        {
            //hasn't fallen into here yet, which makes sense.
            MessageBox(NULL, "Instance Buffer Byte Width Not a multiple of 16", "StaticSceneryList", MB_OK);
        }

        instBuffDesc.Usage = D3D11_USAGE_DYNAMIC;
        instBuffDesc.ByteWidth =  bytewidth;
        instBuffDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        instBuffDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
        instBuffDesc.MiscFlags = 0;

        D3D11_SUBRESOURCE_DATA instData;
        ZeroMemory(&instData, sizeof(instData));

        instData.pSysMem = &instanceMats[0];

        HRESULT hr = graphicsPointers.pdev->CreateBuffer(&instBuffDesc, &instData, &pInstanceBuffer);
        //HRESULT hr = graphicsPointers.pdev->CreateBuffer(&instBuffDesc, &instData, &debugInstanceBuffer); //DEBUG
        if (FAILED(hr))
        {
            //Fails here with S_OK lulwut
            MessageBox(NULL, "Failed to create instance buffer!", "StaticSceneryList", MB_OK);
            if (pInstanceBuffer != NULL)
            {
               //This doesn't seem to trigger even though the address is not 0x0000etc
                pInstanceBuffer->Release();
                pInstanceBuffer = NULL;
            }
        }
        else
        {
            //occasionally gets here but it doesn't seem to stick
            MessageBox(NULL, "Successfully created instance buffer.", "StaticSceneryList", MB_OK);
        }
    }
    else
    {
        //never seems to get to here.
        //buffer already initialized, need to use resource may and unmap.
        D3D11_MAPPED_SUBRESOURCE mappedResource;
        ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));

        //  Disable GPU access to the vertex buffer data.
        graphicsPointers.pdevcon->Map(pInstanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
        //  Update the vertex buffer here.
        memcpy(mappedResource.pData, &instanceMats[0], sizeof(XMFLOAT4X4) * 2 * culledInstanceList.size());
        //  Reenable GPU access to the vertex buffer data.
        graphicsPointers.pdevcon->Unmap(pInstanceBuffer, 0);
    }
}//if there is anything to draw
EN

回答

页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47605608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档