Commit ccb04e70 authored by Laszlo Agocs's avatar Laszlo Agocs

d3d: move host writes where they belong

There was a reason for defering (two passes update the same dyn.buffer
in the same frame, those can be accumulated instead of doing a full
DISCARD write twice) but the logic was broken due to optimizing out the
BindGraphicsPipeline in some cases. So keep it simple for now, the
multi-update in same frame case is discouraged anyway.
parent 382fcf12
...@@ -1059,9 +1059,16 @@ public: ...@@ -1059,9 +1059,16 @@ public:
// beginPass(). (nb the one we merged from must be release()'d manually) // beginPass(). (nb the one we merged from must be release()'d manually)
void merge(QRhiResourceUpdateBatch *other); void merge(QRhiResourceUpdateBatch *other);
// None of these execute anything. Deferred to // None of these execute anything, processing is deferred. What exactly
// beginPass/endPass/resourceUpdate. What exactly then happens underneath // then happens underneath is hidden from the applications. The caller is
// is hidden from the applications. // free to destroy or reuse the data or image right after returning from
// the functions.
//
// Note: Updates involving host writes - typically the dynamic buffer
// updates - may accumulate within a frame. Thus pass 1 reading a region
// changed by a batch passed to pass 2 may see the changes specified in
// pass 2's update batch.
//
void updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data); void updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data);
void uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data); void uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data);
void uploadStaticBuffer(QRhiBuffer *buf, const void *data); void uploadStaticBuffer(QRhiBuffer *buf, const void *data);
......
...@@ -337,38 +337,48 @@ void QRhiD3D11::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline ...@@ -337,38 +337,48 @@ void QRhiD3D11::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
QD3D11ShaderResourceBindings *srbD = QRHI_RES(QD3D11ShaderResourceBindings, srb); QD3D11ShaderResourceBindings *srbD = QRHI_RES(QD3D11ShaderResourceBindings, srb);
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb); QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
bool resChanged = false; bool srbUpdate = false;
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) { for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
const QRhiShaderResourceBinding &b(srbD->sortedBindings[i]); const QRhiShaderResourceBinding &b(srbD->sortedBindings[i]);
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]); QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
switch (b.type) { switch (b.type) {
case QRhiShaderResourceBinding::UniformBuffer: case QRhiShaderResourceBinding::UniformBuffer:
if (QRHI_RES(QD3D11Buffer, b.ubuf.buf)->generation != bd.ubuf.generation) { {
resChanged = true; QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, b.ubuf.buf);
bd.ubuf.generation = QRHI_RES(QD3D11Buffer, b.ubuf.buf)->generation; if (bufD->m_type == QRhiBuffer::Dynamic)
executeBufferHostWritesForCurrentFrame(bufD);
if (bufD->generation != bd.ubuf.generation) {
srbUpdate = true;
bd.ubuf.generation = bufD->generation;
} }
}
break; break;
case QRhiShaderResourceBinding::SampledTexture: case QRhiShaderResourceBinding::SampledTexture:
if (QRHI_RES(QD3D11Texture, b.stex.tex)->generation != bd.stex.texGeneration {
|| QRHI_RES(QD3D11Sampler, b.stex.sampler)->generation != bd.stex.samplerGeneration) QD3D11Texture *texD = QRHI_RES(QD3D11Texture, b.stex.tex);
QD3D11Sampler *samplerD = QRHI_RES(QD3D11Sampler, b.stex.sampler);
if (texD->generation != bd.stex.texGeneration
|| samplerD->generation != bd.stex.samplerGeneration)
{ {
resChanged = true; srbUpdate = true;
bd.stex.texGeneration = QRHI_RES(QD3D11Texture, b.stex.tex)->generation; bd.stex.texGeneration = texD->generation;
bd.stex.samplerGeneration = QRHI_RES(QD3D11Sampler, b.stex.sampler)->generation; bd.stex.samplerGeneration = samplerD->generation;
} }
}
break; break;
default: default:
Q_UNREACHABLE(); Q_UNREACHABLE();
break; break;
} }
} }
if (resChanged) if (srbUpdate)
updateShaderResourceBindings(srbD); updateShaderResourceBindings(srbD);
const bool pipelineChanged = cbD->currentPipeline != ps || cbD->currentPipelineGeneration != psD->generation; const bool pipelineChanged = cbD->currentPipeline != ps || cbD->currentPipelineGeneration != psD->generation;
const bool srbChanged = cbD->currentSrb != srb || cbD->currentSrbGeneration != srbD->generation; const bool srbChanged = cbD->currentSrb != srb || cbD->currentSrbGeneration != srbD->generation;
if (pipelineChanged || srbChanged || resChanged) { if (pipelineChanged || srbChanged || srbUpdate) {
cbD->currentPipeline = ps; cbD->currentPipeline = ps;
cbD->currentPipelineGeneration = psD->generation; cbD->currentPipelineGeneration = psD->generation;
cbD->currentSrb = srb; cbD->currentSrb = srb;
...@@ -378,7 +388,7 @@ void QRhiD3D11::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline ...@@ -378,7 +388,7 @@ void QRhiD3D11::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
cmd.cmd = QD3D11CommandBuffer::Command::BindGraphicsPipeline; cmd.cmd = QD3D11CommandBuffer::Command::BindGraphicsPipeline;
cmd.args.bindGraphicsPipeline.ps = psD; cmd.args.bindGraphicsPipeline.ps = psD;
cmd.args.bindGraphicsPipeline.srb = srbD; cmd.args.bindGraphicsPipeline.srb = srbD;
cmd.args.bindGraphicsPipeline.resOnlyChange = !pipelineChanged && !srbChanged && resChanged; cmd.args.bindGraphicsPipeline.srbOnlyChange = !pipelineChanged && !srbChanged && srbUpdate;
cbD->commands.append(cmd); cbD->commands.append(cmd);
} }
} }
...@@ -1287,6 +1297,7 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD) ...@@ -1287,6 +1297,7 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
if (!bufD->hasPendingDynamicUpdates) if (!bufD->hasPendingDynamicUpdates)
return; return;
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
bufD->hasPendingDynamicUpdates = false; bufD->hasPendingDynamicUpdates = false;
D3D11_MAPPED_SUBRESOURCE mp; D3D11_MAPPED_SUBRESOURCE mp;
HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp); HRESULT hr = context->Map(bufD->buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mp);
...@@ -1300,24 +1311,6 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD) ...@@ -1300,24 +1311,6 @@ void QRhiD3D11::executeBufferHostWritesForCurrentFrame(QD3D11Buffer *bufD)
void QRhiD3D11::setShaderResources(QD3D11ShaderResourceBindings *srbD) void QRhiD3D11::setShaderResources(QD3D11ShaderResourceBindings *srbD)
{ {
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
const QRhiShaderResourceBinding &b(srbD->sortedBindings[i]);
switch (b.type) {
case QRhiShaderResourceBinding::UniformBuffer:
{
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, b.ubuf.buf);
if (bufD->m_type == QRhiBuffer::Dynamic)
executeBufferHostWritesForCurrentFrame(bufD);
}
break;
case QRhiShaderResourceBinding::SampledTexture:
break;
default:
Q_UNREACHABLE();
break;
}
}
for (const auto &batch : srbD->vssamplers.batches) for (const auto &batch : srbD->vssamplers.batches)
context->VSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData()); context->VSSetSamplers(batch.startBinding, batch.resources.count(), batch.resources.constData());
...@@ -1446,7 +1439,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain * ...@@ -1446,7 +1439,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
{ {
QD3D11GraphicsPipeline *psD = cmd.args.bindGraphicsPipeline.ps; QD3D11GraphicsPipeline *psD = cmd.args.bindGraphicsPipeline.ps;
QD3D11ShaderResourceBindings *srbD = cmd.args.bindGraphicsPipeline.srb; QD3D11ShaderResourceBindings *srbD = cmd.args.bindGraphicsPipeline.srb;
if (!cmd.args.bindGraphicsPipeline.resOnlyChange) { if (!cmd.args.bindGraphicsPipeline.srbOnlyChange) {
context->VSSetShader(psD->vs, nullptr, 0); context->VSSetShader(psD->vs, nullptr, 0);
context->PSSetShader(psD->fs, nullptr, 0); context->PSSetShader(psD->fs, nullptr, 0);
context->IASetPrimitiveTopology(psD->d3dTopology); context->IASetPrimitiveTopology(psD->d3dTopology);
......
...@@ -299,7 +299,7 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer ...@@ -299,7 +299,7 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
struct { struct {
QD3D11GraphicsPipeline *ps; QD3D11GraphicsPipeline *ps;
QD3D11ShaderResourceBindings *srb; QD3D11ShaderResourceBindings *srb;
bool resOnlyChange; bool srbOnlyChange;
} bindGraphicsPipeline; } bindGraphicsPipeline;
struct { struct {
QD3D11GraphicsPipeline *ps; QD3D11GraphicsPipeline *ps;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment