如何在调度着色器之前写入 ID3D11UnorderedAccessView 的缓冲区?

How can I write to my ID3D11UnorderedAccessView's buffer before dispatching my shader?

本文关键字:ID3D11UnorderedAccessView 缓冲区 调度      更新时间:2023-10-16

假设我有

ID3D11UnorderedAccessView* pDataView

我有

byte* pRawData

如何使用prawdata设置pdataview的缓冲区?

注意:失败和chr是错误检查摩克群。

更新:Soonts给出了一个答案,当我创建无人机时,似乎可以解决问题,但是为了完整的利益,我也希望能够在创建两者都可以从CPU上成功更新其缓冲区。我并没有那么成功。如果我有:

        template <typename T>
        static inline void CreateUnorderedAccessViewFromFile(
            _In_ ID3D11Device* pDevice,
            _In_ ID3D11DeviceContext* pDeviceContext,
            _In_ HANDLE dataFile,
            _Out_ ID3D11Buffer** ppBuffer,
            _Out_ ID3D11UnorderedAccessView** ppUav)
        {
            uint64_t fileSize;
            //CBR(::GetFileSizeEx(handle, &fileSize));
            //Custom size for testing purposes
            fileSize = 0x800;
            D3D11_BUFFER_DESC bufferDesc =
            {
                fileSize, // ByteWidth
                D3D11_USAGE_DEFAULT, // Usage
                D3D11_BIND_UNORDERED_ACCESS, // BindFlags
                D3D11_CPU_ACCESS_WRITE, // CPUAccessFlags
                D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, // MiscFlags
                sizeof(T), // StructureByteStride
            };
            CHR(pDevice->CreateBuffer(
                &bufferDesc,
                nullptr,
                ppBuffer));

            D3D11_MAPPED_SUBRESOURCE mappedResource;
            HRESULT hr = pDeviceContext->Map(
                *ppBuffer,
                0,
                D3D11_MAP_WRITE_DISCARD,
                0,
                &mappedResource);
            byte* ppData = reinterpret_cast<byte*>(mappedResource.pData);
            for (uint64_t i = 0; i < fileSize; i += 0x10000)
            {
                DWORD readSize = min(fileSize - i, 0x10000);
                if (!ReadFile(
                    dataFile,
                    ppData,
                    readSize,
                    NULL,
                    NULL))
                {
                    uint32_t lastError = ::GetLastError();
                    CBR(lastError != ERROR_IO_PENDING);
                }
            }
            pDeviceContext->Unmap(
                *ppBuffer,
                0);
            D3D11_UNORDERED_ACCESS_VIEW_DESC uaView =
            {
                DXGI_FORMAT_UNKNOWN, // Format
                D3D11_UAV_DIMENSION_BUFFER, // ViewDimension
            };
            uaView.Buffer.FirstElement = 0;
            uaView.Buffer.Flags = 0;
            uaView.Buffer.NumElements = fileSize / sizeof(T);
            CHR(pDevice->CreateUnorderedAccessView(
                *ppBuffer,
                &uaView,
                ppUav));
        }

为什么我可以在地图上hr是e_invalidarg?

注意:失败和chr是错误检查宏。

首先,您需要使用数据来创建一个缓冲区。

如果您的数据是2D纹理,请调用ID3D11DEVICE :: CreateTexture2D。不要忘记d3d11_texture2d_desc中的d3d11_bind_unordered_access :: bindflags字段。您可以在第二个参数中通过byte* pRawData,在D3D11_SUBRESOURCE_DATA结构中。

如果您的数据是结构的1D阵列,请致电ID3D11DEVICE :: CreateBuffer,您应该再次通过D3D11_BIND_UNORDERED_ACCESS和您的初始数据。

无人机支持的其他资源:1D纹理,1D纹理阵列,2D纹理阵列,3D纹理。这一切都取决于您的数据,以及您的着色器处理。

最后,调用ID3D11DEVICE :: CREATEUNORDORDEDACCESSVIEW通过ID3D11TEXTURE2D或ID3D11BUFFER或其他一些资源。ID3D11TEXTURE2D,ID3D11BUFFER和其他人从ID3D11Resource继承,因此您可以通过其中的任何一个。

更新:如果您已经创建了同时创建,并且只需更新,请在PDAtaview上调用GetResource即可从视图中获取资源。然后更新缓冲区ID3DD11DEVICONTEXT :: MAP,MEMCPY,ID3D11DEVICECONTEXT :: UNMAP。只需确保您创建了允许的资源,即D3D11_CPU_ACCESS_WRITE。

更新:如评论者所说,您无法直接从CPU更新无人机资源。解决方案?使用d3d11_cpu_access_write创建D3D11_USAGE_STAGIG资源的相同格式和尺寸,使用例如,例如,使用例如CPU更新它。MAP/UNMAP,然后调用ID3D11DeviceContext :: CopyResource从分期资源复制到UA资源。

相关文章:
  • 没有找到相关文章