D3D12: Added temporary staging buffers.

This commit is contained in:
Branimir Karadžić 2015-08-08 18:06:33 -07:00
parent 437656b870
commit 8e12de0e57
3 changed files with 89 additions and 92 deletions

View file

@ -32,9 +32,9 @@ namespace bgfx
#define _DX_RELEASE(_ptr, _expected, _check) \
BX_MACRO_BLOCK_BEGIN \
if (NULL != _ptr) \
if (NULL != (_ptr) ) \
{ \
ULONG count = _ptr->Release(); \
ULONG count = (_ptr)->Release(); \
_check(isGraphicsDebuggerPresent() || _expected == count, "%p RefCount is %d (expected %d).", _ptr, count, _expected); BX_UNUSED(count); \
_ptr = NULL; \
} \

View file

@ -43,6 +43,23 @@ namespace bgfx { namespace d3d12
};
BX_STATIC_ASSERT(BX_COUNTOF(s_primInfo) == BX_COUNTOF(s_primName)+1);
struct DrawIndirectCommand
{
// D3D12_GPU_VIRTUAL_ADDRESS srv;
D3D12_GPU_VIRTUAL_ADDRESS cbv;
D3D12_VERTEX_BUFFER_VIEW vbv;
D3D12_DRAW_ARGUMENTS draw;
};
struct DrawIndexedIndirectCommand
{
// D3D12_GPU_VIRTUAL_ADDRESS srv;
D3D12_GPU_VIRTUAL_ADDRESS cbv;
D3D12_VERTEX_BUFFER_VIEW vbv;
D3D12_INDEX_BUFFER_VIEW ibv;
D3D12_DRAW_INDEXED_ARGUMENTS drawIndexed;
};
static const uint32_t s_checkMsaa[] =
{
0,
@ -775,14 +792,6 @@ namespace bgfx { namespace d3d12
{ D3D12_INDIRECT_ARGUMENT_TYPE_DRAW, 0 },
};
struct DrawIndirectCommand
{
// D3D12_GPU_VIRTUAL_ADDRESS srv;
D3D12_GPU_VIRTUAL_ADDRESS cbv;
D3D12_VERTEX_BUFFER_VIEW vbv;
D3D12_DRAW_ARGUMENTS draw;
};
D3D12_COMMAND_SIGNATURE_DESC drawCommandSignature =
{
sizeof(DrawIndirectCommand),
@ -806,15 +815,6 @@ namespace bgfx { namespace d3d12
{ D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED, 0 },
};
struct DrawIndexedIndirectCommand
{
// D3D12_GPU_VIRTUAL_ADDRESS srv;
D3D12_GPU_VIRTUAL_ADDRESS cbv;
D3D12_VERTEX_BUFFER_VIEW vbv;
D3D12_INDEX_BUFFER_VIEW ibv;
D3D12_DRAW_INDEXED_ARGUMENTS drawIndexed;
};
D3D12_COMMAND_SIGNATURE_DESC drawIndexedCommandSignature =
{
sizeof(DrawIndexedIndirectCommand),
@ -2673,7 +2673,7 @@ data.NumQualityLevels = 0;
{ { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_FLOAT }, 16 }, // BGFX_BUFFER_COMPUTE_FORMAT_32x4
};
void BufferD3D12::create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex)
void BufferD3D12::create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride)
{
m_size = _size;
m_flags = _flags;
@ -2728,6 +2728,8 @@ data.NumQualityLevels = 0;
}
}
stride = 0 == _stride ? stride : _stride;
m_srvd.Format = format;
m_srvd.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
m_srvd.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
@ -2749,16 +2751,7 @@ data.NumQualityLevels = 0;
m_ptr = createCommittedResource(device, HeapProperty::Default, _size, flags);
if (!needUav)
{
m_staging = createCommittedResource(device, HeapProperty::Upload, _size);
}
if (m_dynamic)
{
setState(commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
}
else
if (!m_dynamic)
{
setState(commandList, D3D12_RESOURCE_STATE_COPY_DEST);
@ -2767,41 +2760,39 @@ data.NumQualityLevels = 0;
subresource.RowPitch = _size;
subresource.SlicePitch = subresource.RowPitch;
ID3D12Resource* staging = createCommittedResource(s_renderD3D12->m_device, HeapProperty::Upload, _size);
UpdateSubresources<1>(commandList
, m_ptr
, m_staging
, staging
, 0
, 0
, 1
, &subresource
);
s_renderD3D12->m_cmd.release(staging);
}
setState(commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
}
}
void BufferD3D12::update(ID3D12GraphicsCommandList* _commandList, uint32_t /*_offset*/, uint32_t _size, void* _data, bool /*_discard*/)
void BufferD3D12::update(ID3D12GraphicsCommandList* _commandList, uint32_t _offset, uint32_t _size, void* _data, bool /*_discard*/)
{
setState(_commandList, D3D12_RESOURCE_STATE_COPY_DEST);
ID3D12Resource* staging = createCommittedResource(s_renderD3D12->m_device, HeapProperty::Upload, _size);
uint8_t* data;
DX_CHECK(staging->Map(0, nullptr, (void**)&data) );
memcpy(data, _data, _size);
staging->Unmap(0, NULL);
D3D12_SUBRESOURCE_DATA subresource;
subresource.pData = _data;
subresource.RowPitch = _size;
subresource.SlicePitch = subresource.RowPitch;
D3D12_RESOURCE_STATES state = setState(_commandList, D3D12_RESOURCE_STATE_COPY_DEST);
_commandList->CopyBufferRegion(m_ptr, _offset, staging, _offset, _size);
setState(_commandList, state);
UpdateSubresources<1>(_commandList
, m_ptr
, m_staging
, 0
, 0
, 1
, &subresource
);
setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ);
s_renderD3D12->m_cmd.release(staging);
}
void BufferD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state)
D3D12_RESOURCE_STATES BufferD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state)
{
if (m_state != _state)
{
@ -2811,8 +2802,10 @@ data.NumQualityLevels = 0;
, _state
);
m_state = _state;
bx::xchg(m_state, _state);
}
return _state;
}
void VertexBufferD3D12::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags)
@ -3267,13 +3260,13 @@ data.NumQualityLevels = 0;
if (kk != 0)
{
m_staging = createCommittedResource(device, HeapProperty::Upload, totalSize);
ID3D12Resource* staging = createCommittedResource(s_renderD3D12->m_device, HeapProperty::Upload, totalSize);
setState(commandList,D3D12_RESOURCE_STATE_COPY_DEST);
uint64_t result = UpdateSubresources(commandList
, m_ptr
, m_staging
, staging
, 0
, 0
, numSrd
@ -3283,11 +3276,11 @@ data.NumQualityLevels = 0;
BX_TRACE("Update subresource %" PRId64, result);
setState(commandList, state);
s_renderD3D12->m_cmd.release(staging);
}
else
{
m_staging = NULL;
setState(commandList, state);
}
@ -3312,9 +3305,6 @@ data.NumQualityLevels = 0;
{
DX_RELEASE(m_ptr, 0);
m_ptr = NULL;
DX_RELEASE(m_staging, 0);
m_staging = NULL;
}
}
@ -3327,12 +3317,6 @@ data.NumQualityLevels = 0;
const uint32_t rectpitch = _rect.m_width*bpp/8;
const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch;
s_renderD3D12->m_cmd.finish(s_renderD3D12->m_cmd.kick() );
s_renderD3D12->m_commandList = s_renderD3D12->m_cmd.alloc();
_commandList = s_renderD3D12->m_commandList;
DX_RELEASE(m_staging, 0);
D3D12_RESOURCE_DESC desc = m_ptr->GetDesc();
desc.Height = _rect.m_height;
@ -3351,17 +3335,16 @@ data.NumQualityLevels = 0;
, &totalBytes
);
m_staging = createCommittedResource(s_renderD3D12->m_device, HeapProperty::Upload, totalBytes);
DX_NAME(m_staging, "texture %4d: staging, update", this - s_renderD3D12->m_textures);
ID3D12Resource* staging = createCommittedResource(s_renderD3D12->m_device, HeapProperty::Upload, totalBytes);
uint8_t* data;
DX_CHECK(m_staging->Map(0, NULL, (void**)&data) );
DX_CHECK(staging->Map(0, NULL, (void**)&data) );
for (uint32_t ii = 0, height = _rect.m_height; ii < height; ++ii)
{
memcpy(&data[ii*rowPitch], &_mem->data[ii*srcpitch], srcpitch);
}
m_staging->Unmap(0, NULL);
staging->Unmap(0, NULL);
D3D12_BOX box;
box.left = 0;
@ -3372,10 +3355,12 @@ data.NumQualityLevels = 0;
box.back = _z+_depth;
D3D12_TEXTURE_COPY_LOCATION dst = { m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { subres } };
D3D12_TEXTURE_COPY_LOCATION src = { m_staging, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, layout };
D3D12_TEXTURE_COPY_LOCATION src = { staging, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, layout };
_commandList->CopyTextureRegion(&dst, _rect.m_x, _rect.m_y, 0, &src, &box);
setState(_commandList, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
s_renderD3D12->m_cmd.release(staging);
}
void TextureD3D12::commit(uint8_t _stage, uint32_t _flags)
@ -3387,7 +3372,7 @@ data.NumQualityLevels = 0;
{
}
void TextureD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state)
D3D12_RESOURCE_STATES TextureD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state)
{
if (m_state != _state)
{
@ -3397,8 +3382,10 @@ data.NumQualityLevels = 0;
, _state
);
m_state = _state;
bx::xchg(m_state, _state);
}
return _state;
}
void FrameBufferD3D12::create(uint8_t _num, const TextureHandle* _handles)

View file

@ -107,7 +107,6 @@ namespace bgfx { namespace d3d12
{
BufferD3D12()
: m_ptr(NULL)
, m_staging(NULL)
, m_state(D3D12_RESOURCE_STATE_COMMON)
, m_size(0)
, m_flags(BGFX_BUFFER_NONE)
@ -115,7 +114,7 @@ namespace bgfx { namespace d3d12
{
}
void create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex);
void create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride = 0);
void update(ID3D12GraphicsCommandList* _commandList, uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
void destroy()
@ -123,17 +122,15 @@ namespace bgfx { namespace d3d12
if (NULL != m_ptr)
{
DX_RELEASE(m_ptr, 0);
DX_RELEASE(m_staging, 0);
m_dynamic = false;
}
}
void setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd;
D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd;
ID3D12Resource* m_ptr;
ID3D12Resource* m_staging;
D3D12_RESOURCE_STATES m_state;
uint32_t m_size;
uint16_t m_flags;
@ -240,7 +237,6 @@ namespace bgfx { namespace d3d12
TextureD3D12()
: m_ptr(NULL)
, m_staging(NULL)
, m_state(D3D12_RESOURCE_STATE_COMMON)
, m_numMips(0)
{
@ -251,12 +247,11 @@ namespace bgfx { namespace d3d12
void update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
void commit(uint8_t _stage, uint32_t _flags = BGFX_SAMPLER_DEFAULT_FLAGS);
void resolve();
void setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
D3D12_RESOURCE_STATES setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state);
D3D12_SHADER_RESOURCE_VIEW_DESC m_srvd;
D3D12_UNORDERED_ACCESS_VIEW_DESC m_uavd;
ID3D12Resource* m_ptr;
ID3D12Resource* m_staging;
D3D12_RESOURCE_STATES m_state;
uint32_t m_flags;
uint16_t m_samplerIdx;
@ -358,11 +353,7 @@ namespace bgfx { namespace d3d12
{
while (0 == m_control.reserve(1) )
{
CommandList& commandList = m_commandList[m_control.m_read];
WaitForSingleObject(commandList.m_event, INFINITE);
CloseHandle(commandList.m_event);
m_control.consume(1);
consume();
}
CommandList& commandList = m_commandList[m_control.m_current];
@ -393,14 +384,7 @@ namespace bgfx { namespace d3d12
{
while (0 < m_control.available() )
{
CommandList& commandList = m_commandList[m_control.m_read];
WaitForSingleObject(commandList.m_event, INFINITE);
CloseHandle(commandList.m_event);
commandList.m_event = NULL;
m_completedFence = m_fence->GetCompletedValue();
m_commandQueue->Wait(m_fence, m_completedFence);
m_control.consume(1);
consume();
if (!_finishAll
&& _waitFence <= m_completedFence)
@ -412,6 +396,30 @@ namespace bgfx { namespace d3d12
BX_CHECK(0 == m_control.available(), "");
}
void release(ID3D12Resource* _ptr)
{
m_release[m_control.m_current].push_back(_ptr);
}
void consume()
{
CommandList& commandList = m_commandList[m_control.m_read];
WaitForSingleObject(commandList.m_event, INFINITE);
CloseHandle(commandList.m_event);
commandList.m_event = NULL;
m_completedFence = m_fence->GetCompletedValue();
m_commandQueue->Wait(m_fence, m_completedFence);
ResourceArray& ra = m_release[m_control.m_read];
for (ResourceArray::iterator it = ra.begin(), itEnd = ra.end(); it != itEnd; ++it)
{
DX_RELEASE(*it, 0);
}
ra.clear();
m_control.consume(1);
}
struct CommandList
{
ID3D12GraphicsCommandList* m_commandList;
@ -424,6 +432,8 @@ namespace bgfx { namespace d3d12
uint64_t m_completedFence;
ID3D12Fence* m_fence;
CommandList m_commandList[4];
typedef stl::vector<ID3D12Resource*> ResourceArray;
ResourceArray m_release[4];
bx::RingBufferControl m_control;
};