如何最好地组织常量缓冲区

问题描述 投票:0回答:1

cb

我的主要问题是:最大的性能冲击发生在哪里?在使用MapUnmap更新缓冲区数据时,还是绑定cbuffers本身时?

目前,我正在为一个 "shader-wrapper "类在以下两种实现中做出选择。

持有14个ID3D11Buffer*的数组。

class VertexShader
{
...

public:
    Bind(context)
    {
        // Bind all 14 buffers at once
        context->VSSetConstantBuffers(0, 14, &m_ppCBuffers[0]);
        context->VSSetShader(pVS, nullptr, 0);
    }

    // Set the data for a buffer in a particular slot
    SetData(slot, size, pData)
    {
        D3D11_MAPPED_SUBRESOURCE mappedBuffer = {};
        context->Map(buffers[slot], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedBuffer);
        memcpy(mappedBuffer.pData, pData, size);
        context->Unmap(buffers[slot], 0);
    }


private:
    ID3D11Buffer*       buffers[14];
    ID3D11VertexShader* pVS;
}

这种方法可以让着色器将所有的cbuffers绑定在一个14的批次中,如果着色器的cbuffers注册到b0、b1、b3,那么数组就会像-> [cbWiCTextureLoader for this project!

谢谢。

class VertexShader
{
...

public:
    Bind(context)
    {
        // all the buffers bind themselves
        for(auto cb : bufferMap)
            cb->Bind(context);

        context->VSSetShader(pVS, nullptr, 0);
    }

    // Set the data for a buffer with a particular ID
    SetData(std::string, size, pData)
    {
        // table lookup into bufferMap, then Map/Unmap
    }


private:
    std::unordered_map<std::string, ConstantBuffer*> bufferMap;
    ID3D11VertexShader* pVS;
}

我对如何在我正在做的一个非常基本的D3D11引擎中组织常量缓冲区有一些麻烦。我的主要问题是:最大的性能冲击发生在哪里?...

恒定缓冲区是Direct3D 10的一个主要功能,所以早在2007年的Gamefest上,就有一个关于这个主题的最佳演讲。

Windows to Reality: 在你的游戏中获得Direct3D 10图形的最大优势。
directx-11 direct3d direct3d11
1个回答
0
投票

最初的意图是让CBs按照更新频率来组织:比如一个CB用于 "每级 "的东西,另一个用于 "每帧 "的东西,另一个用于 "每个对象",另一个用于 "每个通道 "等等。因此,我们的假设是,如果你改变了一个CB的任何部分,你将上传整个事情。CPU和GPU之间的Bandwdith是这里的真正瓶颈。

为了使这种方法有效,你基本上需要将所有的着色器设置为使用相同的方案。这可能很难管理,特别是当许多现代材质系统是艺术驱动的时候。

CBs的另一种方法是像动态VB一样使用它们来提交粒子,你用短命的常量来填充它,提交工作,然后每一帧都重置这个东西。这种方法基本上是人们在很多情况下为DirectX 12所做的。问题是,如果没有更新部分CB的能力,就太慢了。DirectX 11.1中的 "部分恒定缓冲区更新和偏移 "可选功能就是一种让这个工作的方法。也就是说,这个功能在Windows 7上不支持,在新版本的Windows上是 "可选 "的,所以你必须支持两个代码路径才能使用它。TL;DR:

从技术上讲,你可以一次绑定很多CB,但关键是要让那些经常变化的CB保持小规模。同时假设对一个CB的任何改变都需要在每次改变它时将整个东西更新到GPU上。

© www.soinside.com 2019 - 2024. All rights reserved.