Помогите понять, что не так в этом простой трубопроводе DirectX12. Я довольно новичок в DirectX12 и не смог найти какого -либо простого рабочего примера C ++ Compute Shader в Интернете. Шейдер, затем скопируйте из BUFER Buffer в постановку буфера и, наконец, прочитайте из него и печатайте значения. Вот как это должно работать. Но все печатные значения 0. Любая справка оценена. Надеюсь, это поможет будущим читателям. Github Repo с этим примером и Cmake BuildSystem https://github.com/ysolovyov/directx12_ ... er_example
#define NOMINMAX
#include
#include
#include
#include
#define IID_GRAPHICS_PPV_ARGS IID_PPV_ARGS
#include
using Microsoft::WRL::ComPtr;
const char* shaderSource = R"(
RWBuffer uavBuffer : register(u0); // UAV (writeable buffer)
[numthreads(1, 1, 1)]
void main(uint3 DTid : SV_DispatchThreadID) {
// Write some data to the buffer
uavBuffer[DTid.x] = sqrt((float)DTid.x);
}
)";
int main()
{
const UINT numElements = 16;
ComPtr device;
ComPtr commandQueue;
ComPtr commandAllocator;
ComPtr commandList;
UINT64 fenceValue = 0;
ComPtr fence;
HANDLE eventHandle;
ComPtr rootSignature;
ComPtr computePSO;
ComPtr shaderBlob;
ComPtr uavHeap;
ComPtr stagingBuffer;
ComPtr uavBuffer;
// Create the device
THROW_IF_FAILED(D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&device)));
// Create a command queue
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
THROW_IF_FAILED(device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&commandQueue)));
// Create command list
THROW_IF_FAILED(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COMPUTE, IID_PPV_ARGS(&commandAllocator)));
THROW_IF_FAILED(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COMPUTE, commandAllocator.Get(), nullptr, IID_PPV_ARGS(&commandList)));
// Create fence
THROW_IF_FAILED(device->CreateFence(fenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)));
eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr);
// Create output buffer (UAV)
// Create a buffer to be used as a UAV
D3D12_HEAP_PROPERTIES heapProps = {};
heapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
D3D12_RESOURCE_DESC bufferDesc = {};
bufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
bufferDesc.Width = numElements * sizeof(float); // Total size of the buffer
bufferDesc.Height = 1;
bufferDesc.DepthOrArraySize = 1;
bufferDesc.MipLevels = 1;
bufferDesc.Format = DXGI_FORMAT_UNKNOWN;
bufferDesc.SampleDesc.Count = 1;
bufferDesc.SampleDesc.Quality = 0;
bufferDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
bufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
THROW_IF_FAILED(device->CreateCommittedResource(
&heapProps,
D3D12_HEAP_FLAG_NONE,
&bufferDesc,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
nullptr,
IID_PPV_ARGS(&uavBuffer)));
// Create staging buffer
D3D12_RESOURCE_DESC stagingBufferDesc = {};
stagingBufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
stagingBufferDesc.Width = sizeof(float) * numElements; // The size of the buffer.
stagingBufferDesc.Height = 1;
stagingBufferDesc.DepthOrArraySize = 1;
stagingBufferDesc.MipLevels = 1;
stagingBufferDesc.Format = DXGI_FORMAT_UNKNOWN;
stagingBufferDesc.SampleDesc.Count = 1;
stagingBufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
D3D12_HEAP_PROPERTIES stagingHeapProps = {};
stagingHeapProps.Type = D3D12_HEAP_TYPE_READBACK; // This is a readback buffer.
stagingHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
stagingHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
THROW_IF_FAILED(device->CreateCommittedResource(
&stagingHeapProps,
D3D12_HEAP_FLAG_NONE,
&stagingBufferDesc,
D3D12_RESOURCE_STATE_COPY_DEST, // Initial state for copying
nullptr,
IID_PPV_ARGS(&stagingBuffer)));
D3D12_DESCRIPTOR_HEAP_DESC uavHeapDesc = {};
uavHeapDesc.NumDescriptors = 1; // We are creating one UAV
uavHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
uavHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; // Must be visible to shaders
THROW_IF_FAILED(device->CreateDescriptorHeap(&uavHeapDesc, IID_PPV_ARGS(&uavHeap)));
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.Format = DXGI_FORMAT_UNKNOWN; // Buffer format
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.FirstElement = 0;
uavDesc.Buffer.NumElements = numElements;
uavDesc.Buffer.StructureByteStride = sizeof(float);
uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
CD3DX12_CPU_DESCRIPTOR_HANDLE uavHandle(uavHeap->GetCPUDescriptorHandleForHeapStart());
device->CreateUnorderedAccessView(uavBuffer.Get(), nullptr, &uavDesc, uavHandle);
THROW_IF_FAILED(D3DCompile(shaderSource, strlen(shaderSource), nullptr, nullptr, nullptr, "main", "cs_5_0", 0, 0, &shaderBlob, nullptr));
D3D12_ROOT_PARAMETER rootParams[1] = {};
D3D12_DESCRIPTOR_RANGE descRange = {};
descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV;
descRange.NumDescriptors = 1;
descRange.BaseShaderRegister = 0; // u0
rootParams[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
rootParams[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
rootParams[0].DescriptorTable.NumDescriptorRanges = 1;
rootParams[0].DescriptorTable.pDescriptorRanges = &descRange;
D3D12_ROOT_SIGNATURE_DESC rootSigDesc = {};
rootSigDesc.NumParameters = 1;
rootSigDesc.pParameters = rootParams;
rootSigDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
ComPtr rootSignatureBlob;
THROW_IF_FAILED(D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &rootSignatureBlob, nullptr));
THROW_IF_FAILED(device->CreateRootSignature(0, rootSignatureBlob->GetBufferPointer(), rootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&rootSignature)));
D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.pRootSignature = rootSignature.Get();
psoDesc.CS = { shaderBlob->GetBufferPointer(), shaderBlob->GetBufferSize() };
THROW_IF_FAILED(device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&computePSO)));
ID3D12DescriptorHeap* heaps[] = { uavHeap.Get() };
commandList->SetDescriptorHeaps(1, heaps);
commandList->SetPipelineState(computePSO.Get());
commandList->SetComputeRootSignature(rootSignature.Get());
commandList->SetComputeRootDescriptorTable(0, uavHeap->GetGPUDescriptorHandleForHeapStart());
commandList->Dispatch(numElements, 1, 1);
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(uavBuffer.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE));
commandList->CopyResource(stagingBuffer.Get(), uavBuffer.Get());
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(uavBuffer.Get(), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS));
commandList->Close();
ID3D12CommandList* commandLists[] = { commandList.Get() };
commandQueue->ExecuteCommandLists(ARRAYSIZE(commandLists), commandLists);
commandQueue->Signal(fence.Get(), ++fenceValue);
// Wait for the fence to reach the signal value before proceeding
fence->SetEventOnCompletion(fenceValue, eventHandle);
WaitForSingleObject(eventHandle, INFINITE);
// Map the staging buffer and read the data
float* data = nullptr;
stagingBuffer->Map(0, nullptr, reinterpret_cast(&data));
for (size_t i = 0; i < numElements; ++i) {
std::cout
Подробнее здесь: https://stackoverflow.com/questions/794 ... e-question
DirectX12 вычислить вопрос о трубопроводе Шейдера ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение