[d3d11] Record commands into a CS chunk

This commit is contained in:
Philip Rebohle 2018-01-20 22:52:18 +01:00
parent aaf7b05625
commit 7d7cc1ceda
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 43 additions and 16 deletions

View File

@ -12,10 +12,10 @@ namespace dxvk {
D3D11DeviceContext::D3D11DeviceContext(
D3D11Device* parent,
Rc<DxvkDevice> device)
: m_parent(parent),
m_device(device) {
m_context = m_device->createContext();
: m_parent (parent),
m_device (device),
m_context (m_device->createContext()),
m_csChunk (new DxvkCsChunk()) {
// Create default state objects. We won't ever return them
// to the application, but we'll use them to apply state.
Com<ID3D11BlendState> defaultBlendState;

View File

@ -519,6 +519,7 @@ namespace dxvk {
Rc<DxvkDevice> m_device;
Rc<DxvkContext> m_context;
Rc<DxvkCsChunk> m_csChunk;
Rc<DxvkSampler> m_defaultSampler;
Com<D3D11BlendState> m_defaultBlendState;
@ -567,10 +568,14 @@ namespace dxvk {
template<typename Cmd>
void EmitCs(Cmd&& command) {
// TODO push to CS chunk
command(m_context.ptr());
if (!m_csChunk->push(command)) {
EmitCsChunk();
m_csChunk->push(command);
}
}
virtual void EmitCsChunk() = 0;
};
}

View File

@ -38,6 +38,8 @@ namespace dxvk {
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() {
EmitCsChunk();
m_parent->FlushInitContext();
m_drawCount = 0;
@ -88,13 +90,11 @@ namespace dxvk {
if (pMappedResource == nullptr)
return S_FALSE;
DxvkPhysicalBufferSlice physicalSlice;
if (MapType == D3D11_MAP_WRITE_DISCARD) {
// Allocate a new backing slice for the buffer and set
// it as the 'new' mapped slice. This assumes that the
// only way to invalidate a buffer is by mapping it.
physicalSlice = buffer->allocPhysicalSlice();
auto physicalSlice = buffer->allocPhysicalSlice();
resource->GetBufferInfo()->mappedSlice = physicalSlice;
EmitCs([
@ -103,14 +103,10 @@ namespace dxvk {
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cPhysicalSlice);
});
} else if (MapType == D3D11_MAP_WRITE_NO_OVERWRITE) {
// Use map pointer from previous map operation. This
// way we don't have to synchronize with the CS thread.
physicalSlice = resource->GetBufferInfo()->mappedSlice;
} else {
} else if (MapType != D3D11_MAP_WRITE_NO_OVERWRITE) {
// Synchronize with CS thread so that we know whether
// the buffer is currently in use by the GPU or not
// TODO implement
SynchronizeCs();
if (buffer->isInUse()) {
if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT)
@ -121,6 +117,12 @@ namespace dxvk {
}
}
// Use map pointer from previous map operation. This
// way we don't have to synchronize with the CS thread
// if the map mode is D3D11_MAP_WRITE_NO_OVERWRITE.
const DxvkPhysicalBufferSlice physicalSlice
= resource->GetBufferInfo()->mappedSlice;
pMappedResource->pData = physicalSlice.mapPtr(0);
pMappedResource->RowPitch = physicalSlice.length();
pMappedResource->DepthPitch = physicalSlice.length();
@ -243,4 +245,20 @@ namespace dxvk {
m_device->waitForIdle();
}
void D3D11ImmediateContext::SynchronizeCs() {
// Dispatch recorded commands first,
EmitCsChunk();
// TODO synchronize with CS thread
}
void D3D11ImmediateContext::EmitCsChunk() {
if (m_csChunk->commandCount() > 0) {
m_csChunk->executeAll(m_context.ptr());
m_csChunk = new DxvkCsChunk();
}
}
}

View File

@ -42,10 +42,14 @@ namespace dxvk {
ID3D11Resource* pResource,
UINT Subresource) final;
void Synchronize();
private:
void Synchronize();
void SynchronizeCs();
void EmitCsChunk();
};
}