Skip to content

Commit

Permalink
rhi: gl: d3d: Reduce the size of the Command struct
Browse files Browse the repository at this point in the history
Copied by value so the size matters.

Change-Id: I17eae99212801a4fb390a0e298b361123644d17d
Reviewed-by: Andy Nichols <[email protected]>
  • Loading branch information
alpqr committed Oct 11, 2020
1 parent f26e329 commit b540c78
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 23 deletions.
6 changes: 6 additions & 0 deletions src/gui/rhi/qrhi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
32 changes: 18 additions & 14 deletions src/gui/rhi/qrhid3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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(),
Expand All @@ -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());
}
}
Expand All @@ -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());
}
}
Expand All @@ -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());
}
}
Expand Down
12 changes: 7 additions & 5 deletions src/gui/rhi/qrhid3d11_p_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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;
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/gui/rhi/qrhigles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions src/gui/rhi/qrhigles2_p_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit b540c78

Please sign in to comment.