能不能提供一种DX12中封装GPU资源的方法,比如顶点缓冲区,常量缓冲区,SRV,UAV等待
时间: 2024-01-02 08:05:23 浏览: 189
使用 ftp-srv 在 nodejs 创建FTP服务器,简单版
5星 · 资源好评率100%
当然可以,以下是一些DX12中封装GPU资源的方法:
1. 顶点缓冲区:
```
// 创建顶点缓冲区描述符
CD3DX12_RESOURCE_DESC vertexBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(vertexBufferSize);
// 创建顶点缓冲区对象
ThrowIfFailed(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), // 上传堆类型
D3D12_HEAP_FLAG_NONE,
&vertexBufferDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&m_vertexBuffer)));
// 将顶点数据复制到顶点缓冲区中
UINT8* pVertexDataBegin;
CD3DX12_RANGE readRange(0, 0); // 只需要对资源进行一次读取操作
ThrowIfFailed(m_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)));
memcpy(pVertexDataBegin, vertices.data(), vertexBufferSize);
m_vertexBuffer->Unmap(0, nullptr);
// 创建顶点缓冲区视图
m_vertexBufferView.BufferLocation = m_vertexBuffer->GetGPUVirtualAddress();
m_vertexBufferView.StrideInBytes = sizeof(Vertex);
m_vertexBufferView.SizeInBytes = vertexBufferSize;
```
2. 常量缓冲区:
```
// 创建常量缓冲区描述符
CD3DX12_RESOURCE_DESC constantBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(ConstantBufferAlignedSize);
// 创建常量缓冲区对象
ThrowIfFailed(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD), // 上传堆类型
D3D12_HEAP_FLAG_NONE,
&constantBufferDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&m_constantBuffer)));
// 创建常量缓冲区视图
m_constantBufferView.BufferLocation = m_constantBuffer->GetGPUVirtualAddress();
m_constantBufferView.SizeInBytes = ConstantBufferAlignedSize;
// 映射常量缓冲区并填充数据
ThrowIfFailed(m_constantBuffer->Map(0, nullptr, reinterpret_cast<void**>(&m_pCbvDataBegin)));
memcpy(m_pCbvDataBegin, &m_constantBufferData, sizeof(m_constantBufferData));
```
3. SRV:
```
// 创建纹理资源描述符
CD3DX12_RESOURCE_DESC textureDesc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM, textureWidth, textureHeight);
// 创建纹理资源对象
ThrowIfFailed(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&textureDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(&texture)));
// 创建纹理资源上传堆
UINT64 textureUploadBufferSize;
device->GetCopyableFootprints(&textureDesc, 0, 1, 0, nullptr, nullptr, nullptr, &textureUploadBufferSize);
CD3DX12_RESOURCE_DESC textureUploadHeapDesc = CD3DX12_RESOURCE_DESC::Buffer(textureUploadBufferSize);
ThrowIfFailed(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
D3D12_HEAP_FLAG_NONE,
&textureUploadHeapDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&textureUploadHeap)));
// 将纹理数据复制到上传堆中
D3D12_SUBRESOURCE_DATA textureData = {};
textureData.pData = texturePixels;
textureData.RowPitch = textureWidth * sizeof(uint32_t);
textureData.SlicePitch = textureData.RowPitch * textureHeight;
UpdateSubresources(commandList.Get(), texture.Get(), textureUploadHeap.Get(), 0, 0, 1, &textureData);
```
4. UAV:
```
// 创建UAV缓冲区描述符
CD3DX12_RESOURCE_DESC uavBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(uavBufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
// 创建UAV缓冲区对象
ThrowIfFailed(device->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&uavBufferDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(&uavBuffer)));
// 创建UAV缓冲区视图
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.NumElements = uavBufferSize / sizeof(float);
uavDesc.Buffer.StructureByteStride = sizeof(float);
uavDesc.Buffer.CounterOffsetInBytes = 0;
uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
device->CreateUnorderedAccessView(uavBuffer.Get(), nullptr, &uavDesc, m_uavDescriptorHeap->GetCpuHandle(UAV_INDEX));
```
阅读全文