Fixed CBV creation on Direct3D12 backend

This commit is contained in:
Alexandro Sánchez Bach 2016-02-24 22:31:27 +01:00
parent f95b28fe28
commit de2a3addf4
14 changed files with 76 additions and 26 deletions

View file

@ -5,6 +5,7 @@ Looking to contribute something to Nucleus? **Here's how you can help**.
Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved.
## Issues
The [issue tracker](https://github.com/AlexAltea/nucleus/issues) is the preferred channel for [bug reports](#bug-reports) and [features requests](#feature-requests), but please respect the following restrictions:
@ -29,6 +30,7 @@ A bug is a *demonstrable problem* that is caused by the code in the repository.
Feature requests are always welcome. Before opening one, please take a moment to find out whether your idea fits with the scope and aims of the project. Please verify that your idea is not already referenced in the [Roadmap](docs/development/roadmap.md).
## Pull requests
**Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code, adding new frontends), otherwise you risk spending a lot of time working on something that the might be rejected while reviewing.
@ -36,5 +38,5 @@ Feature requests are always welcome. Before opening one, please take a moment to
Check the following documents:
* [Roadmap](docs/development/roadmap.md): Planned tasks that you can contribute to.
* [Conventions](docs/development/conventions.md): Conding style and conventions to follow.
* [Conventions](docs/development/conventions.md): Coding style and conventions to follow.
* [Overview](docs/development/overview.md): Details about how the project is structured.

View file

@ -166,6 +166,9 @@ void RSXFragmentProgram::decompile(const rsx_fp_instruction_t* buffer) {
tempsHalf.resize(48);
samplers.resize(16);
// TODO: Always place FragCoord position as input. Do the same with other inputs and outputs in all shader stages
getInputReg(0);
// Temporary values
Literal src0, src1, src2;
Literal tmp0, tmp1, tmp2;

View file

@ -24,6 +24,7 @@ PGRAPH::PGRAPH(std::shared_ptr<gfx::IBackend> backend, RSX* rsx, mem::Memory* me
gfx::VertexBufferDesc vtxBufferDesc;
vtxBufferDesc.size = 468 * sizeof(V128);
vtxBufferDesc.cbvCreation = true;
vpeConstantMemory = graphics->createVertexBuffer(vtxBufferDesc);
}
@ -260,6 +261,8 @@ void PGRAPH::Begin(Primitive primitive) {
cacheFP[fpHash] = std::move(fp);
}
gfx::PipelineDesc pipelineDesc = {};
pipelineDesc.numCBVs = 1;
pipelineDesc.numSRVs = 0;
pipelineDesc.vs = cacheVP[vpHash]->shader;
pipelineDesc.ps = cacheFP[fpHash]->shader;
pipelineDesc.cbState.colorTarget[0].enableBlend = p.blend_enable;
@ -293,6 +296,7 @@ void PGRAPH::Begin(Primitive primitive) {
vpeConstantMemory->unmap();
cmdBuffer->cmdBindPipeline(cachePipeline[pipelineHash].get());
cmdBuffer->cmdSetDescriptors({vpeConstantMemory}, {});
}
void PGRAPH::End() {

View file

@ -12,11 +12,15 @@
#include <dxgi1_4.h>
#include <d3dcompiler.h>
// Debugging
#if defined(NUCLEUS_BUILD_DEBUG)
#include <initguid.h>
#include <dxgidebug.h>
#endif
// Helper
#include "externals/direct3d12/d3dx12.h"
// Function types: dxgi.dll
typedef HRESULT(WINAPI *PFN_CreateDXGIFactory)(REFIID, void **);
typedef HRESULT(WINAPI *PFN_CreateDXGIFactory1)(REFIID, void **);

View file

@ -244,18 +244,18 @@ Pipeline* Direct3D12Backend::createPipeline(const PipelineDesc& desc) {
auto* pipeline = new Direct3D12Pipeline();
// Root signature parameters
D3D12_DESCRIPTOR_RANGE range = {};
range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
range.NumDescriptors = 1;
range.BaseShaderRegister = 0;
range.RegisterSpace = 0;
range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND;
CD3DX12_DESCRIPTOR_RANGE ranges[2];
ranges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
ranges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);
D3D12_ROOT_PARAMETER parameter;
parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
parameter.DescriptorTable.NumDescriptorRanges = 1;
parameter.DescriptorTable.pDescriptorRanges = &range;
parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
Size index = 0;
std::vector<CD3DX12_ROOT_PARAMETER> parameters(desc.numCBVs + desc.numSRVs);
for (Size reg = 0; reg < desc.numCBVs; reg++) {
parameters[index++].InitAsDescriptorTable(1, &ranges[0], D3D12_SHADER_VISIBILITY_ALL);
}
for (Size reg = 0; reg < desc.numSRVs; reg++) {
parameters[index++].InitAsDescriptorTable(1, &ranges[1], D3D12_SHADER_VISIBILITY_PIXEL);
}
// Samplers
std::vector<D3D12_STATIC_SAMPLER_DESC> d3dSamplers(desc.samplers.size());
@ -278,8 +278,8 @@ Pipeline* Direct3D12Backend::createPipeline(const PipelineDesc& desc) {
// Root signature
D3D12_ROOT_SIGNATURE_DESC rootSignatureDesc = {};
rootSignatureDesc.NumParameters = 1;
rootSignatureDesc.pParameters = &parameter;
rootSignatureDesc.NumParameters = parameters.size();
rootSignatureDesc.pParameters = parameters.data();
rootSignatureDesc.NumStaticSamplers = d3dSamplers.size();
rootSignatureDesc.pStaticSamplers = d3dSamplers.data();
rootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
@ -400,7 +400,24 @@ Texture* Direct3D12Backend::createTexture(const TextureDesc& desc) {
VertexBuffer* Direct3D12Backend::createVertexBuffer(const VertexBufferDesc& desc) {
UINT64 size = desc.size;
if (desc.cbvCreation) {
size = (size + 255) & ~255; // CB size is required to be 256-byte aligned
}
auto* vtxBuffer = new Direct3D12VertexBuffer(device, size);
if (desc.cbvCreation) {
HRESULT hr;
D3D12_DESCRIPTOR_HEAP_DESC cbvHeapDesc = {};
cbvHeapDesc.NumDescriptors = 1;
cbvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
cbvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
hr = device->CreateDescriptorHeap(&cbvHeapDesc, IID_PPV_ARGS(&vtxBuffer->cbvHeap));
D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {};
cbvDesc.BufferLocation = vtxBuffer->resource->GetGPUVirtualAddress();
cbvDesc.SizeInBytes = size;
device->CreateConstantBufferView(&cbvDesc, vtxBuffer->cbvHeap->GetCPUDescriptorHandleForHeapStart());
}
return vtxBuffer;
}

View file

@ -82,13 +82,24 @@ void Direct3D12CommandBuffer::cmdDrawIndexed(U32 firstIndex, U32 indexCount, U32
list->DrawIndexedInstanced(indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
void Direct3D12CommandBuffer::cmdSetTexture(U32 index, const Texture* texture) {
const auto* d3dTexture = static_cast<const Direct3D12Texture*>(texture);
assert_true(d3dTexture != nullptr, "Direct3D12CommandBuffer::cmdSetTexture: Invalid texture specified");
void Direct3D12CommandBuffer::cmdSetDescriptors(const std::vector<VertexBuffer*>& buffers, const std::vector<Texture*>& textures) {
Size size = buffers.size() + textures.size();
ID3D12DescriptorHeap* heap = d3dTexture->srvHeap;
list->SetDescriptorHeaps(1, &heap);
list->SetGraphicsRootDescriptorTable(index, heap->GetGPUDescriptorHandleForHeapStart());
std::vector<ID3D12DescriptorHeap*> heaps(size);
Size index = 0;
for (const auto* buffer : buffers) {
const auto* d3dBuffer = static_cast<const Direct3D12VertexBuffer*>(buffer);
heaps[index++] = d3dBuffer->cbvHeap;
}
for (const auto* texture : textures) {
const auto* d3dTexture = static_cast<const Direct3D12Texture*>(texture);
heaps[index++] = d3dTexture->srvHeap;
}
list->SetDescriptorHeaps(heaps.size(), heaps.data());
for (Size i = 0; i < size; i++) {
list->SetGraphicsRootDescriptorTable(i, heaps[i]->GetGPUDescriptorHandleForHeapStart());
}
}
void Direct3D12CommandBuffer::cmdSetVertexBuffers(U32 index, U32 vtxBufferCount, VertexBuffer** vtxBuffer, U32* offsets, U32* strides) {

View file

@ -33,7 +33,7 @@ public:
virtual void cmdClearDepthStencil(DepthStencilTarget* target, F32 depthValue, U8 stencilValue) override;
virtual void cmdDraw(U32 firstVertex, U32 vertexCount, U32 firstInstance, U32 instanceCount) override;
virtual void cmdDrawIndexed(U32 firstIndex, U32 indexCount, U32 vertexOffset, U32 firstInstance, U32 instanceCount) override;
virtual void cmdSetTexture(U32 index, const Texture* texture) override;
virtual void cmdSetDescriptors(const std::vector<VertexBuffer*>& buffers, const std::vector<Texture*>& textures) override;
virtual void cmdSetVertexBuffers(U32 index, U32 vtxBufferCount, VertexBuffer** vtxBuffer, U32* offsets, U32* strides) override;
virtual void cmdSetPrimitiveTopology(PrimitiveTopology topology) override;
virtual void cmdSetTargets(U32 colorCount, ColorTarget** colorTargets, DepthStencilTarget* depthStencilTarget) override;

View file

@ -14,6 +14,8 @@ namespace direct3d12 {
class Direct3D12VertexBuffer : public Direct3D12Resource, public VertexBuffer {
public:
ID3D12DescriptorHeap* cbvHeap;
Direct3D12VertexBuffer(ID3D12Device* device, UINT64 size);
~Direct3D12VertexBuffer();
};

View file

@ -72,10 +72,10 @@ public:
/**
* Bind a texture to a pipeline sampler
* @param[in] index Index of the sampler
* @param[in] texture Texture to bind
* @param[in] buffers Uniform buffers to bind
* @param[in] texture Textures to bind
*/
virtual void cmdSetTexture(U32 index, const Texture* texture) = 0;
virtual void cmdSetDescriptors(const std::vector<VertexBuffer*>& buffers, const std::vector<Texture*>& textures) = 0;
/**
* Pushes a command to set the vertex buffer for an input slots

View file

@ -13,6 +13,7 @@ namespace gfx {
struct VertexBufferDesc {
U64 size;
bool cbvCreation;
};
class VertexBuffer : public virtual Resource {

View file

@ -173,7 +173,7 @@ void UI::renderImages() {
}
if (texture != textureImages[i].first) {
texture = textureImages[i].first;
cmdBuffer->cmdSetTexture(0, texture);
cmdBuffer->cmdSetDescriptors({}, {texture});
}
cmdBuffer->cmdDraw(4 * i, 4, 0, 1);
if (isColorTarget) {
@ -209,7 +209,7 @@ void UI::renderText() {
for (size_t i = 0; i < dataText.size(); i++) {
if (texture != textureText[i].first) {
texture = textureText[i].first;
cmdBuffer->cmdSetTexture(0, texture);
cmdBuffer->cmdSetDescriptors({}, {texture});
}
cmdBuffer->cmdDraw(4 * i, 4, 0, 1);
}

View file

@ -24,6 +24,8 @@ gfx::Pipeline* WidgetContainer::createPipeline(gfx::IBackend& backend) {
fragDesc.module = gfx::frontend::ShaderParser::parse(reinterpret_cast<const char*>(resPS.data), resPS.size);
gfx::PipelineDesc pipelineDesc = {};
pipelineDesc.numCBVs = 0;
pipelineDesc.numSRVs = 0;
pipelineDesc.vs = backend.createShader(vertDesc);
pipelineDesc.ps = backend.createShader(fragDesc);
pipelineDesc.iaState.topology = gfx::TOPOLOGY_TRIANGLE_STRIP;

View file

@ -29,6 +29,8 @@ gfx::Pipeline* WidgetImage::createPipeline(gfx::IBackend& backend) {
fragDesc.module = gfx::frontend::ShaderParser::parse(reinterpret_cast<const char*>(resPS.data), resPS.size);
gfx::PipelineDesc pipelineDesc = {};
pipelineDesc.numCBVs = 0;
pipelineDesc.numSRVs = 1;
pipelineDesc.vs = backend.createShader(vertDesc);
pipelineDesc.ps = backend.createShader(fragDesc);
pipelineDesc.iaState.topology = gfx::TOPOLOGY_TRIANGLE_STRIP;

View file

@ -24,6 +24,8 @@ gfx::Pipeline* WidgetText::createPipeline(gfx::IBackend& backend) {
fragDesc.module = gfx::frontend::ShaderParser::parse(reinterpret_cast<const char*>(resPS.data), resPS.size);
gfx::PipelineDesc pipelineDesc = {};
pipelineDesc.numCBVs = 0;
pipelineDesc.numSRVs = 1;
pipelineDesc.vs = backend.createShader(vertDesc);
pipelineDesc.ps = backend.createShader(fragDesc);
pipelineDesc.iaState.topology = gfx::TOPOLOGY_TRIANGLE_STRIP;