mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[d3d11] Record commands into a CS chunk
This commit is contained in:
parent
aaf7b05625
commit
7d7cc1ceda
@ -12,10 +12,10 @@ namespace dxvk {
|
|||||||
D3D11DeviceContext::D3D11DeviceContext(
|
D3D11DeviceContext::D3D11DeviceContext(
|
||||||
D3D11Device* parent,
|
D3D11Device* parent,
|
||||||
Rc<DxvkDevice> device)
|
Rc<DxvkDevice> device)
|
||||||
: m_parent(parent),
|
: m_parent (parent),
|
||||||
m_device(device) {
|
m_device (device),
|
||||||
m_context = m_device->createContext();
|
m_context (m_device->createContext()),
|
||||||
|
m_csChunk (new DxvkCsChunk()) {
|
||||||
// Create default state objects. We won't ever return them
|
// Create default state objects. We won't ever return them
|
||||||
// to the application, but we'll use them to apply state.
|
// to the application, but we'll use them to apply state.
|
||||||
Com<ID3D11BlendState> defaultBlendState;
|
Com<ID3D11BlendState> defaultBlendState;
|
||||||
|
@ -519,6 +519,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkDevice> m_device;
|
Rc<DxvkDevice> m_device;
|
||||||
Rc<DxvkContext> m_context;
|
Rc<DxvkContext> m_context;
|
||||||
|
Rc<DxvkCsChunk> m_csChunk;
|
||||||
Rc<DxvkSampler> m_defaultSampler;
|
Rc<DxvkSampler> m_defaultSampler;
|
||||||
|
|
||||||
Com<D3D11BlendState> m_defaultBlendState;
|
Com<D3D11BlendState> m_defaultBlendState;
|
||||||
@ -567,10 +568,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
template<typename Cmd>
|
template<typename Cmd>
|
||||||
void EmitCs(Cmd&& command) {
|
void EmitCs(Cmd&& command) {
|
||||||
// TODO push to CS chunk
|
if (!m_csChunk->push(command)) {
|
||||||
command(m_context.ptr());
|
EmitCsChunk();
|
||||||
|
m_csChunk->push(command);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void EmitCsChunk() = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() {
|
void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() {
|
||||||
|
EmitCsChunk();
|
||||||
|
|
||||||
m_parent->FlushInitContext();
|
m_parent->FlushInitContext();
|
||||||
m_drawCount = 0;
|
m_drawCount = 0;
|
||||||
|
|
||||||
@ -88,13 +90,11 @@ namespace dxvk {
|
|||||||
if (pMappedResource == nullptr)
|
if (pMappedResource == nullptr)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
DxvkPhysicalBufferSlice physicalSlice;
|
|
||||||
|
|
||||||
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
||||||
// Allocate a new backing slice for the buffer and set
|
// Allocate a new backing slice for the buffer and set
|
||||||
// it as the 'new' mapped slice. This assumes that the
|
// it as the 'new' mapped slice. This assumes that the
|
||||||
// only way to invalidate a buffer is by mapping it.
|
// only way to invalidate a buffer is by mapping it.
|
||||||
physicalSlice = buffer->allocPhysicalSlice();
|
auto physicalSlice = buffer->allocPhysicalSlice();
|
||||||
resource->GetBufferInfo()->mappedSlice = physicalSlice;
|
resource->GetBufferInfo()->mappedSlice = physicalSlice;
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
@ -103,14 +103,10 @@ namespace dxvk {
|
|||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->invalidateBuffer(cBuffer, cPhysicalSlice);
|
ctx->invalidateBuffer(cBuffer, cPhysicalSlice);
|
||||||
});
|
});
|
||||||
} else if (MapType == D3D11_MAP_WRITE_NO_OVERWRITE) {
|
} 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 {
|
|
||||||
// Synchronize with CS thread so that we know whether
|
// Synchronize with CS thread so that we know whether
|
||||||
// the buffer is currently in use by the GPU or not
|
// the buffer is currently in use by the GPU or not
|
||||||
// TODO implement
|
SynchronizeCs();
|
||||||
|
|
||||||
if (buffer->isInUse()) {
|
if (buffer->isInUse()) {
|
||||||
if (MapFlags & D3D11_MAP_FLAG_DO_NOT_WAIT)
|
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->pData = physicalSlice.mapPtr(0);
|
||||||
pMappedResource->RowPitch = physicalSlice.length();
|
pMappedResource->RowPitch = physicalSlice.length();
|
||||||
pMappedResource->DepthPitch = physicalSlice.length();
|
pMappedResource->DepthPitch = physicalSlice.length();
|
||||||
@ -243,4 +245,20 @@ namespace dxvk {
|
|||||||
m_device->waitForIdle();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -42,10 +42,14 @@ namespace dxvk {
|
|||||||
ID3D11Resource* pResource,
|
ID3D11Resource* pResource,
|
||||||
UINT Subresource) final;
|
UINT Subresource) final;
|
||||||
|
|
||||||
void Synchronize();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void Synchronize();
|
||||||
|
void SynchronizeCs();
|
||||||
|
|
||||||
|
void EmitCsChunk();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user