Consolidate tracking of resource bindings in MVKResourcesCommandEncoderState subclasses.
Redefine MVKGraphicsResourcesCommandEncoderState::ShaderStage
as MVKResourcesCommandEncoderState::ResourceBindings.
Add ResourceBindings::reset() function.
MVKComputeResourcesCommandEncoderState replace discrete member variables
with a single ResourceBindings member variable.
Rename MVKGraphicsResourcesCommandEncoderState::_shaderStage
member variable to _shaderStageResourceBindings.
In stage iterations, replace < kMVKShaderStageCompute with <= kMVKShaderStageFragment.
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
index 5ae018b..660c74e 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
@@ -417,6 +417,40 @@
void assertMissingSwizzles(bool needsSwizzle, const char* stageName, const MVKArrayRef<MVKMTLTextureBinding>& texBindings);
+ template<size_t N>
+ struct ResourceBindings {
+ MVKSmallVector<MVKMTLBufferBinding, N> bufferBindings;
+ MVKSmallVector<MVKMTLTextureBinding, N> textureBindings;
+ MVKSmallVector<MVKMTLSamplerStateBinding, N> samplerStateBindings;
+ MVKSmallVector<uint32_t, N> swizzleConstants;
+ MVKSmallVector<uint32_t, N> bufferSizes;
+
+ MVKMTLBufferBinding swizzleBufferBinding;
+ MVKMTLBufferBinding bufferSizeBufferBinding;
+
+ bool areBufferBindingsDirty = false;
+ bool areTextureBindingsDirty = false;
+ bool areSamplerStateBindingsDirty = false;
+
+ bool needsSwizzle = false;
+
+ void reset() {
+ bufferBindings.clear();
+ textureBindings.clear();
+ samplerStateBindings.clear();
+ swizzleConstants.clear();
+ bufferSizes.clear();
+
+ areBufferBindingsDirty = false;
+ areTextureBindingsDirty = false;
+ areSamplerStateBindingsDirty = false;
+ swizzleBufferBinding.isDirty = false;
+ bufferSizeBufferBinding.isDirty = false;
+
+ needsSwizzle = false;
+ }
+ };
+
};
@@ -477,23 +511,7 @@
void resetImpl() override;
void markDirty() override;
- struct ShaderStage {
- MVKSmallVector<MVKMTLBufferBinding, 8> bufferBindings;
- MVKSmallVector<MVKMTLTextureBinding, 8> textureBindings;
- MVKSmallVector<MVKMTLSamplerStateBinding, 8> samplerStateBindings;
- MVKSmallVector<uint32_t, 8> swizzleConstants;
- MVKSmallVector<uint32_t, 8> bufferSizes;
- MVKMTLBufferBinding swizzleBufferBinding;
- MVKMTLBufferBinding bufferSizeBufferBinding;
-
- bool areBufferBindingsDirty = false;
- bool areTextureBindingsDirty = false;
- bool areSamplerStateBindingsDirty = false;
-
- bool needsSwizzle = false;
- };
-
- ShaderStage _shaderStages[4];
+ ResourceBindings<8> _shaderStageResourceBindings[4];
};
@@ -531,19 +549,7 @@
void encodeImpl(uint32_t) override;
void resetImpl() override;
- MVKSmallVector<MVKMTLBufferBinding, 4> _bufferBindings;
- MVKSmallVector<MVKMTLTextureBinding, 4> _textureBindings;
- MVKSmallVector<MVKMTLSamplerStateBinding, 4> _samplerStateBindings;
- MVKSmallVector<uint32_t, 4> _swizzleConstants;
- MVKSmallVector<uint32_t, 4> _bufferSizes;
- MVKMTLBufferBinding _swizzleBufferBinding;
- MVKMTLBufferBinding _bufferSizeBufferBinding;
-
- bool _areBufferBindingsDirty = false;
- bool _areTextureBindingsDirty = false;
- bool _areSamplerStateBindingsDirty = false;
-
- bool _needsSwizzle = false;
+ ResourceBindings<4> _resourceBindings;
};
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
index 691303b..d63ba37 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm
@@ -513,15 +513,15 @@
#pragma mark MVKGraphicsResourcesCommandEncoderState
void MVKGraphicsResourcesCommandEncoderState::bindBuffer(MVKShaderStage stage, const MVKMTLBufferBinding& binding) {
- bind(binding, _shaderStages[stage].bufferBindings, _shaderStages[stage].areBufferBindingsDirty);
+ bind(binding, _shaderStageResourceBindings[stage].bufferBindings, _shaderStageResourceBindings[stage].areBufferBindingsDirty);
}
void MVKGraphicsResourcesCommandEncoderState::bindTexture(MVKShaderStage stage, const MVKMTLTextureBinding& binding) {
- bind(binding, _shaderStages[stage].textureBindings, _shaderStages[stage].areTextureBindingsDirty, _shaderStages[stage].needsSwizzle);
+ bind(binding, _shaderStageResourceBindings[stage].textureBindings, _shaderStageResourceBindings[stage].areTextureBindingsDirty, _shaderStageResourceBindings[stage].needsSwizzle);
}
void MVKGraphicsResourcesCommandEncoderState::bindSamplerState(MVKShaderStage stage, const MVKMTLSamplerStateBinding& binding) {
- bind(binding, _shaderStages[stage].samplerStateBindings, _shaderStages[stage].areSamplerStateBindingsDirty);
+ bind(binding, _shaderStageResourceBindings[stage].samplerStateBindings, _shaderStageResourceBindings[stage].areSamplerStateBindingsDirty);
}
void MVKGraphicsResourcesCommandEncoderState::bindSwizzleBuffer(const MVKShaderImplicitRezBinding& binding,
@@ -529,13 +529,13 @@
bool needTessCtlSwizzleBuffer,
bool needTessEvalSwizzleBuffer,
bool needFragmentSwizzleBuffer) {
- for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageCompute; i++) {
- _shaderStages[i].swizzleBufferBinding.index = binding.stages[i];
+ for (uint32_t i = kMVKShaderStageVertex; i <= kMVKShaderStageFragment; i++) {
+ _shaderStageResourceBindings[i].swizzleBufferBinding.index = binding.stages[i];
}
- _shaderStages[kMVKShaderStageVertex].swizzleBufferBinding.isDirty = needVertexSwizzleBuffer;
- _shaderStages[kMVKShaderStageTessCtl].swizzleBufferBinding.isDirty = needTessCtlSwizzleBuffer;
- _shaderStages[kMVKShaderStageTessEval].swizzleBufferBinding.isDirty = needTessEvalSwizzleBuffer;
- _shaderStages[kMVKShaderStageFragment].swizzleBufferBinding.isDirty = needFragmentSwizzleBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageVertex].swizzleBufferBinding.isDirty = needVertexSwizzleBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageTessCtl].swizzleBufferBinding.isDirty = needTessCtlSwizzleBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageTessEval].swizzleBufferBinding.isDirty = needTessEvalSwizzleBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageFragment].swizzleBufferBinding.isDirty = needFragmentSwizzleBuffer;
}
void MVKGraphicsResourcesCommandEncoderState::bindBufferSizeBuffer(const MVKShaderImplicitRezBinding& binding,
@@ -543,13 +543,13 @@
bool needTessCtlSizeBuffer,
bool needTessEvalSizeBuffer,
bool needFragmentSizeBuffer) {
- for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageCompute; i++) {
- _shaderStages[i].bufferSizeBufferBinding.index = binding.stages[i];
+ for (uint32_t i = kMVKShaderStageVertex; i <= kMVKShaderStageFragment; i++) {
+ _shaderStageResourceBindings[i].bufferSizeBufferBinding.index = binding.stages[i];
}
- _shaderStages[kMVKShaderStageVertex].bufferSizeBufferBinding.isDirty = needVertexSizeBuffer;
- _shaderStages[kMVKShaderStageTessCtl].bufferSizeBufferBinding.isDirty = needTessCtlSizeBuffer;
- _shaderStages[kMVKShaderStageTessEval].bufferSizeBufferBinding.isDirty = needTessEvalSizeBuffer;
- _shaderStages[kMVKShaderStageFragment].bufferSizeBufferBinding.isDirty = needFragmentSizeBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageVertex].bufferSizeBufferBinding.isDirty = needVertexSizeBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageTessCtl].bufferSizeBufferBinding.isDirty = needTessCtlSizeBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageTessEval].bufferSizeBufferBinding.isDirty = needTessEvalSizeBuffer;
+ _shaderStageResourceBindings[kMVKShaderStageFragment].bufferSizeBufferBinding.isDirty = needFragmentSizeBuffer;
}
void MVKGraphicsResourcesCommandEncoderState::encodeBindings(MVKShaderStage stage,
@@ -559,7 +559,7 @@
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&, const MVKArrayRef<uint32_t>&)> bindImplicitBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLTextureBinding&)> bindTexture,
std::function<void(MVKCommandEncoder*, MVKMTLSamplerStateBinding&)> bindSampler) {
- auto& shaderStage = _shaderStages[stage];
+ auto& shaderStage = _shaderStageResourceBindings[stage];
encodeBinding<MVKMTLBufferBinding>(shaderStage.bufferBindings, shaderStage.areBufferBindingsDirty, bindBuffer);
if (shaderStage.swizzleBufferBinding.isDirty) {
@@ -589,10 +589,10 @@
// Mark everything as dirty
void MVKGraphicsResourcesCommandEncoderState::markDirty() {
MVKCommandEncoderState::markDirty();
- for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageCompute; i++) {
- MVKResourcesCommandEncoderState::markDirty(_shaderStages[i].bufferBindings, _shaderStages[i].areBufferBindingsDirty);
- MVKResourcesCommandEncoderState::markDirty(_shaderStages[i].textureBindings, _shaderStages[i].areTextureBindingsDirty);
- MVKResourcesCommandEncoderState::markDirty(_shaderStages[i].samplerStateBindings, _shaderStages[i].areSamplerStateBindingsDirty);
+ for (uint32_t i = kMVKShaderStageVertex; i <= kMVKShaderStageFragment; i++) {
+ MVKResourcesCommandEncoderState::markDirty(_shaderStageResourceBindings[i].bufferBindings, _shaderStageResourceBindings[i].areBufferBindingsDirty);
+ MVKResourcesCommandEncoderState::markDirty(_shaderStageResourceBindings[i].textureBindings, _shaderStageResourceBindings[i].areTextureBindingsDirty);
+ MVKResourcesCommandEncoderState::markDirty(_shaderStageResourceBindings[i].samplerStateBindings, _shaderStageResourceBindings[i].areSamplerStateBindingsDirty);
}
}
@@ -723,21 +723,9 @@
}
void MVKGraphicsResourcesCommandEncoderState::resetImpl() {
- for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageCompute; i++) {
- _shaderStages[i].bufferBindings.clear();
- _shaderStages[i].textureBindings.clear();
- _shaderStages[i].samplerStateBindings.clear();
- _shaderStages[i].swizzleConstants.clear();
- _shaderStages[i].bufferSizes.clear();
-
- _shaderStages[i].areBufferBindingsDirty = false;
- _shaderStages[i].areTextureBindingsDirty = false;
- _shaderStages[i].areSamplerStateBindingsDirty = false;
- _shaderStages[i].swizzleBufferBinding.isDirty = false;
- _shaderStages[i].bufferSizeBufferBinding.isDirty = false;
-
- _shaderStages[i].needsSwizzle = false;
- }
+ for (uint32_t i = kMVKShaderStageVertex; i <= kMVKShaderStageFragment; i++) {
+ _shaderStageResourceBindings[i].reset();
+ }
}
@@ -745,35 +733,35 @@
#pragma mark MVKComputeResourcesCommandEncoderState
void MVKComputeResourcesCommandEncoderState::bindBuffer(const MVKMTLBufferBinding& binding) {
- bind(binding, _bufferBindings, _areBufferBindingsDirty);
+ bind(binding, _resourceBindings.bufferBindings, _resourceBindings.areBufferBindingsDirty);
}
void MVKComputeResourcesCommandEncoderState::bindTexture(const MVKMTLTextureBinding& binding) {
- bind(binding, _textureBindings, _areTextureBindingsDirty, _needsSwizzle);
+ bind(binding, _resourceBindings.textureBindings, _resourceBindings.areTextureBindingsDirty, _resourceBindings.needsSwizzle);
}
void MVKComputeResourcesCommandEncoderState::bindSamplerState(const MVKMTLSamplerStateBinding& binding) {
- bind(binding, _samplerStateBindings, _areSamplerStateBindingsDirty);
+ bind(binding, _resourceBindings.samplerStateBindings, _resourceBindings.areSamplerStateBindingsDirty);
}
void MVKComputeResourcesCommandEncoderState::bindSwizzleBuffer(const MVKShaderImplicitRezBinding& binding,
bool needSwizzleBuffer) {
- _swizzleBufferBinding.index = binding.stages[kMVKShaderStageCompute];
- _swizzleBufferBinding.isDirty = needSwizzleBuffer;
+ _resourceBindings.swizzleBufferBinding.index = binding.stages[kMVKShaderStageCompute];
+ _resourceBindings.swizzleBufferBinding.isDirty = needSwizzleBuffer;
}
void MVKComputeResourcesCommandEncoderState::bindBufferSizeBuffer(const MVKShaderImplicitRezBinding& binding,
bool needBufferSizeBuffer) {
- _bufferSizeBufferBinding.index = binding.stages[kMVKShaderStageCompute];
- _bufferSizeBufferBinding.isDirty = needBufferSizeBuffer;
+ _resourceBindings.bufferSizeBufferBinding.index = binding.stages[kMVKShaderStageCompute];
+ _resourceBindings.bufferSizeBufferBinding.isDirty = needBufferSizeBuffer;
}
// Mark everything as dirty
void MVKComputeResourcesCommandEncoderState::markDirty() {
MVKCommandEncoderState::markDirty();
- MVKResourcesCommandEncoderState::markDirty(_bufferBindings, _areBufferBindingsDirty);
- MVKResourcesCommandEncoderState::markDirty(_textureBindings, _areTextureBindingsDirty);
- MVKResourcesCommandEncoderState::markDirty(_samplerStateBindings, _areSamplerStateBindingsDirty);
+ MVKResourcesCommandEncoderState::markDirty(_resourceBindings.bufferBindings, _resourceBindings.areBufferBindingsDirty);
+ MVKResourcesCommandEncoderState::markDirty(_resourceBindings.textureBindings, _resourceBindings.areTextureBindingsDirty);
+ MVKResourcesCommandEncoderState::markDirty(_resourceBindings.samplerStateBindings, _resourceBindings.areSamplerStateBindingsDirty);
}
void MVKComputeResourcesCommandEncoderState::encodeImpl(uint32_t) {
@@ -783,7 +771,7 @@
if (pipeline)
fullImageViewSwizzle = pipeline->fullImageViewSwizzle();
- encodeBinding<MVKMTLBufferBinding>(_bufferBindings, _areBufferBindingsDirty,
+ encodeBinding<MVKMTLBufferBinding>(_resourceBindings.bufferBindings, _resourceBindings.areBufferBindingsDirty,
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
if (b.isInline)
cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch),
@@ -796,40 +784,40 @@
atIndex: b.index];
});
- if (_swizzleBufferBinding.isDirty) {
+ if (_resourceBindings.swizzleBufferBinding.isDirty) {
- for (auto& b : _textureBindings) {
- if (b.isDirty) { updateImplicitBuffer(_swizzleConstants, b.index, b.swizzle); }
+ for (auto& b : _resourceBindings.textureBindings) {
+ if (b.isDirty) { updateImplicitBuffer(_resourceBindings.swizzleConstants, b.index, b.swizzle); }
}
_cmdEncoder->setComputeBytes(_cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch),
- _swizzleConstants.data(),
- _swizzleConstants.size() * sizeof(uint32_t),
- _swizzleBufferBinding.index);
+ _resourceBindings.swizzleConstants.data(),
+ _resourceBindings.swizzleConstants.size() * sizeof(uint32_t),
+ _resourceBindings.swizzleBufferBinding.index);
} else {
- assertMissingSwizzles(_needsSwizzle && !fullImageViewSwizzle, "compute", _textureBindings.contents());
+ assertMissingSwizzles(_resourceBindings.needsSwizzle && !fullImageViewSwizzle, "compute", _resourceBindings.textureBindings.contents());
}
- if (_bufferSizeBufferBinding.isDirty) {
- for (auto& b : _bufferBindings) {
- if (b.isDirty) { updateImplicitBuffer(_bufferSizes, b.index, b.size); }
+ if (_resourceBindings.bufferSizeBufferBinding.isDirty) {
+ for (auto& b : _resourceBindings.bufferBindings) {
+ if (b.isDirty) { updateImplicitBuffer(_resourceBindings.bufferSizes, b.index, b.size); }
}
_cmdEncoder->setComputeBytes(_cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch),
- _bufferSizes.data(),
- _bufferSizes.size() * sizeof(uint32_t),
- _bufferSizeBufferBinding.index);
+ _resourceBindings.bufferSizes.data(),
+ _resourceBindings.bufferSizes.size() * sizeof(uint32_t),
+ _resourceBindings.bufferSizeBufferBinding.index);
}
- encodeBinding<MVKMTLTextureBinding>(_textureBindings, _areTextureBindingsDirty,
+ encodeBinding<MVKMTLTextureBinding>(_resourceBindings.textureBindings, _resourceBindings.areTextureBindingsDirty,
[](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void {
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setTexture: b.mtlTexture
atIndex: b.index];
});
- encodeBinding<MVKMTLSamplerStateBinding>(_samplerStateBindings, _areSamplerStateBindingsDirty,
+ encodeBinding<MVKMTLSamplerStateBinding>(_resourceBindings.samplerStateBindings, _resourceBindings.areSamplerStateBindingsDirty,
[](MVKCommandEncoder* cmdEncoder, MVKMTLSamplerStateBinding& b)->void {
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setSamplerState: b.mtlSamplerState
atIndex: b.index];
@@ -837,19 +825,7 @@
}
void MVKComputeResourcesCommandEncoderState::resetImpl() {
- _bufferBindings.clear();
- _textureBindings.clear();
- _samplerStateBindings.clear();
- _swizzleConstants.clear();
- _bufferSizes.clear();
-
- _areBufferBindingsDirty = false;
- _areTextureBindingsDirty = false;
- _areSamplerStateBindingsDirty = false;
- _swizzleBufferBinding.isDirty = false;
- _bufferSizeBufferBinding.isDirty = false;
-
- _needsSwizzle = false;
+ _resourceBindings.reset();
}