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>
This commit is contained in:
Laszlo Agocs 2020-10-09 21:31:33 +02:00
parent f26e329c47
commit b540c78355
5 changed files with 36 additions and 23 deletions

View File

@ -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.

View File

@ -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());
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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;