summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-10-09 21:31:33 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-10-11 10:58:47 +0200
commitb540c783557808f778f8afd332b33aa81f7e5ec6 (patch)
treeeee26950a67782c3bc740db8d5f43adc61bfb978 /src/gui/rhi
parentf26e329c473fb0e9357bdbc4329a36d1204c40c5 (diff)
rhi: gl: d3d: Reduce the size of the Command struct
Copied by value so the size matters. Change-Id: I17eae99212801a4fb390a0e298b361123644d17d Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi')
-rw-r--r--src/gui/rhi/qrhi.cpp6
-rw-r--r--src/gui/rhi/qrhid3d11.cpp32
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h12
-rw-r--r--src/gui/rhi/qrhigles2.cpp4
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h5
5 files changed, 36 insertions, 23 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index ead50628f6..c67659478a 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -5275,6 +5275,9 @@ void QRhiCommandBuffer::setGraphicsPipeline(QRhiGraphicsPipeline *ps)
\note All offsets in \a dynamicOffsets must be byte aligned to the value
returned from QRhi::ubufAlignment().
+ \note Some backends may limit the number of supported dynamic offsets.
+ Avoid using a \a dynamicOffsetCount larger than 8.
+
\note QRhi will optimize out unnecessary invocations within a pass (taking
the conditions described above into account), so therefore overoptimizing
to avoid calls to this function is not necessary on the applications' side.
@@ -5303,6 +5306,9 @@ void QRhiCommandBuffer::setShaderResources(QRhiShaderResourceBindings *srb,
in \a bindings. Each element in \a bindings specifies a QRhiBuffer and an
offset.
+ \note Some backends may limit the number of vertex buffer bindings. Avoid
+ using a \a bindingCount larger than 8.
+
Superfluous vertex input and index changes in the same pass are ignored
automatically with most backends and therefore applications do not need to
overoptimize to avoid calls to this function.
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 7d8339252b..dc4f6b1f01 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -788,7 +788,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
cmd.args.bindShaderResources.offsetOnlyChange = !srbChanged && !srbRebuilt && !srbUpdate && hasDynamicOffsetInSrb;
cmd.args.bindShaderResources.dynamicOffsetCount = 0;
if (hasDynamicOffsetInSrb) {
- if (dynamicOffsetCount < QD3D11CommandBuffer::Command::MAX_UBUF_BINDINGS) {
+ if (dynamicOffsetCount < QD3D11CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT) {
cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
@@ -801,7 +801,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
}
} else {
qWarning("Too many dynamic offsets (%d, max is %d)",
- dynamicOffsetCount, QD3D11CommandBuffer::Command::MAX_UBUF_BINDINGS);
+ dynamicOffsetCount, QD3D11CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT);
}
}
@@ -837,6 +837,11 @@ void QRhiD3D11::setVertexInput(QRhiCommandBuffer *cb,
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::BindVertexBuffers;
cmd.args.bindVertexBuffers.startSlot = startBinding;
+ if (bindingCount > QD3D11CommandBuffer::Command::MAX_VERTEX_BUFFER_BINDING_COUNT) {
+ qWarning("Too many vertex buffer bindings (%d, max is %d)",
+ bindingCount, QD3D11CommandBuffer::Command::MAX_VERTEX_BUFFER_BINDING_COUNT);
+ bindingCount = QD3D11CommandBuffer::Command::MAX_VERTEX_BUFFER_BINDING_COUNT;
+ }
cmd.args.bindVertexBuffers.slotCount = bindingCount;
QD3D11GraphicsPipeline *psD = QRHI_RES(QD3D11GraphicsPipeline, cbD->currentGraphicsPipeline);
const QRhiVertexInputLayout &inputLayout(psD->m_vertexInputLayout);
@@ -2173,7 +2178,7 @@ void QRhiD3D11::executeBufferHostWrites(QD3D11Buffer *bufD)
}
}
-static void applyDynamicOffsets(QVarLengthArray<UINT, 4> *offsets,
+static void applyDynamicOffsets(UINT *offsets,
int batchIndex,
QRhiBatchedBindings<UINT> *originalBindings,
QRhiBatchedBindings<UINT> *staticOffsets,
@@ -2182,15 +2187,15 @@ static void applyDynamicOffsets(QVarLengthArray<UINT, 4> *offsets,
const int count = staticOffsets->batches[batchIndex].resources.count();
// Make a copy of the offset list, the entries that have no corresponding
// dynamic offset will continue to use the existing offset value.
- *offsets = staticOffsets->batches[batchIndex].resources;
for (int b = 0; b < count; ++b) {
+ offsets[b] = staticOffsets->batches[batchIndex].resources[b];
for (int di = 0; di < dynOfsPairCount; ++di) {
const uint binding = dynOfsPairs[2 * di];
// binding is the SPIR-V style binding point here, nothing to do
// with the native one.
if (binding == originalBindings->batches[batchIndex].resources[b]) {
const uint offsetInConstants = dynOfsPairs[2 * di + 1];
- (*offsets)[b] = offsetInConstants;
+ offsets[b] = offsetInConstants;
break;
}
}
@@ -2264,6 +2269,8 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
}
}
+ UINT offsets[QD3D11CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT];
+
for (int i = 0, ie = srbD->vsubufs.batches.count(); i != ie; ++i) {
const uint count = clampedResourceCount(srbD->vsubufs.batches[i].startBinding,
srbD->vsubufs.batches[i].resources.count(),
@@ -2277,13 +2284,12 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
srbD->vsubufoffsets.batches[i].resources.constData(),
srbD->vsubufsizes.batches[i].resources.constData());
} else {
- QVarLengthArray<UINT, 4> offsets;
- applyDynamicOffsets(&offsets, i, &srbD->vsubuforigbindings, &srbD->vsubufoffsets,
+ applyDynamicOffsets(offsets, i, &srbD->vsubuforigbindings, &srbD->vsubufoffsets,
dynOfsPairs, dynOfsPairCount);
context->VSSetConstantBuffers1(srbD->vsubufs.batches[i].startBinding,
count,
srbD->vsubufs.batches[i].resources.constData(),
- offsets.constData(),
+ offsets,
srbD->vsubufsizes.batches[i].resources.constData());
}
}
@@ -2302,13 +2308,12 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
srbD->fsubufoffsets.batches[i].resources.constData(),
srbD->fsubufsizes.batches[i].resources.constData());
} else {
- QVarLengthArray<UINT, 4> offsets;
- applyDynamicOffsets(&offsets, i, &srbD->fsubuforigbindings, &srbD->fsubufoffsets,
+ applyDynamicOffsets(offsets, i, &srbD->fsubuforigbindings, &srbD->fsubufoffsets,
dynOfsPairs, dynOfsPairCount);
context->PSSetConstantBuffers1(srbD->fsubufs.batches[i].startBinding,
count,
srbD->fsubufs.batches[i].resources.constData(),
- offsets.constData(),
+ offsets,
srbD->fsubufsizes.batches[i].resources.constData());
}
}
@@ -2327,13 +2332,12 @@ void QRhiD3D11::bindShaderResources(QD3D11ShaderResourceBindings *srbD,
srbD->csubufoffsets.batches[i].resources.constData(),
srbD->csubufsizes.batches[i].resources.constData());
} else {
- QVarLengthArray<UINT, 4> offsets;
- applyDynamicOffsets(&offsets, i, &srbD->csubuforigbindings, &srbD->csubufoffsets,
+ applyDynamicOffsets(offsets, i, &srbD->csubuforigbindings, &srbD->csubufoffsets,
dynOfsPairs, dynOfsPairCount);
context->CSSetConstantBuffers1(srbD->csubufs.batches[i].startBinding,
count,
srbD->csubufs.batches[i].resources.constData(),
- offsets.constData(),
+ offsets,
srbD->csubufsizes.batches[i].resources.constData());
}
}
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 4de193530a..b2ff0f77f7 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -345,7 +345,9 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
enum ClearFlag { Color = 1, Depth = 2, Stencil = 4 };
Cmd cmd;
- static const int MAX_UBUF_BINDINGS = 32; // should be D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT but 128 is a waste of space for our purposes
+ // these must be kept at a reasonably low value otherwise sizeof Command explodes
+ static const int MAX_DYNAMIC_OFFSET_COUNT = 8;
+ static const int MAX_VERTEX_BUFFER_BINDING_COUNT = 8;
// QRhi*/QD3D11* references should be kept at minimum (so no
// QRhiTexture/Buffer/etc. pointers).
@@ -370,9 +372,9 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
struct {
int startSlot;
int slotCount;
- ID3D11Buffer *buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
- UINT offsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
- UINT strides[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
+ ID3D11Buffer *buffers[MAX_VERTEX_BUFFER_BINDING_COUNT];
+ UINT offsets[MAX_VERTEX_BUFFER_BINDING_COUNT];
+ UINT strides[MAX_VERTEX_BUFFER_BINDING_COUNT];
} bindVertexBuffers;
struct {
ID3D11Buffer *buffer;
@@ -386,7 +388,7 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
QD3D11ShaderResourceBindings *srb;
bool offsetOnlyChange;
int dynamicOffsetCount;
- uint dynamicOffsetPairs[MAX_UBUF_BINDINGS * 2]; // binding, offsetInConstants
+ uint dynamicOffsetPairs[MAX_DYNAMIC_OFFSET_COUNT * 2]; // binding, offsetInConstants
} bindShaderResources;
struct {
QD3D11GraphicsPipeline *ps;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 1ea116d78c..63f419da94 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -1169,7 +1169,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
cmd.args.bindShaderResources.srb = srb;
cmd.args.bindShaderResources.dynamicOffsetCount = 0;
if (hasDynamicOffsetInSrb) {
- if (dynamicOffsetCount < QGles2CommandBuffer::Command::MAX_UBUF_BINDINGS) {
+ if (dynamicOffsetCount < QGles2CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT) {
cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
for (int i = 0; i < dynamicOffsetCount; ++i) {
@@ -1179,7 +1179,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
}
} else {
qWarning("Too many dynamic offsets (%d, max is %d)",
- dynamicOffsetCount, QGles2CommandBuffer::Command::MAX_UBUF_BINDINGS);
+ dynamicOffsetCount, QGles2CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT);
}
}
cbD->commands.append(cmd);
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 2023585b6b..d037bbc4f6 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -345,7 +345,8 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
};
Cmd cmd;
- static const int MAX_UBUF_BINDINGS = 32; // should be more than enough
+ // keep at a reasonably low value otherwise sizeof Command explodes
+ static const int MAX_DYNAMIC_OFFSET_COUNT = 8;
// QRhi*/QGles2* references should be kept at minimum (so no
// QRhiTexture/Buffer/etc. pointers).
@@ -398,7 +399,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
QRhiComputePipeline *maybeComputePs;
QRhiShaderResourceBindings *srb;
int dynamicOffsetCount;
- uint dynamicOffsetPairs[MAX_UBUF_BINDINGS * 2]; // binding, offset
+ uint dynamicOffsetPairs[MAX_DYNAMIC_OFFSET_COUNT * 2]; // binding, offset
} bindShaderResources;
struct {
GLbitfield mask;