Use MVKSmallVector in command encoder states.

MVKResourcesCommandEncoderState functions use MVKArrayRef to pass fixed content,
and template functions to pass various dynamic vector types.
This commit is contained in:
Bill Hollings 2020-05-22 18:39:43 -04:00
parent 2e91df7b21
commit a6deef8df9
2 changed files with 60 additions and 60 deletions

View File

@ -21,7 +21,7 @@
#include "MVKMTLResourceBindings.h"
#include "MVKCommandResourceFactory.h"
#include "MVKDevice.h"
#include "MVKVector.h"
#include "MVKSmallVector.h"
#include <unordered_map>
class MVKCommandEncoder;
@ -152,7 +152,7 @@ protected:
void encodeImpl(uint32_t stage) override;
void resetImpl() override;
MVKVectorInline<VkViewport, kMVKCachedViewportScissorCount> _viewports, _dynamicViewports;
MVKSmallVector<VkViewport, kMVKCachedViewportScissorCount> _viewports, _dynamicViewports;
};
@ -181,7 +181,7 @@ protected:
void encodeImpl(uint32_t stage) override;
void resetImpl() override;
MVKVectorInline<VkRect2D, kMVKCachedViewportScissorCount> _scissors, _dynamicScissors;
MVKSmallVector<VkRect2D, kMVKCachedViewportScissorCount> _scissors, _dynamicScissors;
};
@ -209,7 +209,7 @@ protected:
void resetImpl() override;
bool isTessellating();
MVKVectorInline<char, 128> _pushConstants;
MVKSmallVector<char, 128> _pushConstants;
VkShaderStageFlagBits _shaderStage;
uint32_t _mtlBufferIndex = 0;
};
@ -365,8 +365,8 @@ protected:
// Template function that updates an existing binding or adds a new binding to a vector
// of bindings, and marks the binding, the vector, and this instance as dirty
template<class T, class U>
void bind(const T& b, U& bindings, bool& bindingsDirtyFlag) {
template<class T, class V>
void bind(const T& b, V& bindings, bool& bindingsDirtyFlag) {
if ( !b.mtlResource ) { return; }
@ -385,31 +385,37 @@ protected:
}
// For texture bindings, we also keep track of whether any bindings need a texture swizzle
void bind(const MVKMTLTextureBinding& tb, MVKVector<MVKMTLTextureBinding>& texBindings,
bool& bindingsDirtyFlag, bool& needsSwizzleFlag) {
template<class V>
void bind(const MVKMTLTextureBinding& tb, V& texBindings, bool& bindingsDirtyFlag, bool& needsSwizzleFlag) {
bind(tb, texBindings, bindingsDirtyFlag);
if (tb.swizzle != 0) { needsSwizzleFlag = true; }
}
// Template function that executes a lambda expression on each dirty element of
// a vector of bindings, and marks the bindings and the vector as no longer dirty.
template<class T>
void encodeBinding(MVKVector<T>& bindings,
bool& bindingsDirtyFlag,
std::function<void(MVKCommandEncoder* cmdEncoder, T& b)> mtlOperation) {
if (bindingsDirtyFlag) {
bindingsDirtyFlag = false;
for (auto& b : bindings) {
if (b.isDirty) {
mtlOperation(_cmdEncoder, b);
b.isDirty = false;
}
}
}
}
template<class T, class V>
void encodeBinding(V& bindings,
bool& bindingsDirtyFlag,
std::function<void(MVKCommandEncoder* cmdEncoder, T& b)> mtlOperation) {
if (bindingsDirtyFlag) {
bindingsDirtyFlag = false;
for (auto& b : bindings) {
if (b.isDirty) {
mtlOperation(_cmdEncoder, b);
b.isDirty = false;
}
}
}
}
void updateImplicitBuffer(MVKVector<uint32_t> &contents, uint32_t index, uint32_t value);
void assertMissingSwizzles(bool needsSwizzle, const char* stageName, MVKVector<MVKMTLTextureBinding>& texBindings);
// Updates a value at the given index in the given vector, resizing if needed.
template<class V>
void updateImplicitBuffer(V &contents, uint32_t index, uint32_t value) {
if (index >= contents.size()) { contents.resize(index + 1); }
contents[index] = value;
}
void assertMissingSwizzles(bool needsSwizzle, const char* stageName, const MVKArrayRef<MVKMTLTextureBinding>& texBindings);
};
@ -457,7 +463,7 @@ public:
const char* pStageName,
bool fullImageViewSwizzle,
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&)> bindBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&, MVKVector<uint32_t>&)> bindImplicitBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&, const MVKArrayRef<uint32_t>&)> bindImplicitBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLTextureBinding&)> bindTexture,
std::function<void(MVKCommandEncoder*, MVKMTLSamplerStateBinding&)> bindSampler);
@ -472,11 +478,11 @@ protected:
void markDirty() override;
struct ShaderStage {
MVKVectorInline<MVKMTLBufferBinding, 8> bufferBindings;
MVKVectorInline<MVKMTLTextureBinding, 8> textureBindings;
MVKVectorInline<MVKMTLSamplerStateBinding, 8> samplerStateBindings;
MVKVectorInline<uint32_t, 8> swizzleConstants;
MVKVectorInline<uint32_t, 8> bufferSizes;
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;
@ -525,11 +531,11 @@ protected:
void encodeImpl(uint32_t) override;
void resetImpl() override;
MVKVectorInline<MVKMTLBufferBinding, 4> _bufferBindings;
MVKVectorInline<MVKMTLTextureBinding, 4> _textureBindings;
MVKVectorInline<MVKMTLSamplerStateBinding, 4> _samplerStateBindings;
MVKVectorInline<uint32_t, 4> _swizzleConstants;
MVKVectorInline<uint32_t, 4> _bufferSizes;
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;

View File

@ -491,16 +491,10 @@ void MVKBlendColorCommandEncoderState::resetImpl() {
#pragma mark -
#pragma mark MVKResourcesCommandEncoderState
// Updates a value at the given index in the given vector.
void MVKResourcesCommandEncoderState::updateImplicitBuffer(MVKVector<uint32_t> &contents, uint32_t index, uint32_t value) {
if (index >= contents.size()) { contents.resize(index + 1); }
contents[index] = value;
}
// If a swizzle is needed for this stage, iterates all the bindings and logs errors for those that need texture swizzling.
void MVKResourcesCommandEncoderState::assertMissingSwizzles(bool needsSwizzle, const char* stageName, MVKVector<MVKMTLTextureBinding>& texBindings) {
void MVKResourcesCommandEncoderState::assertMissingSwizzles(bool needsSwizzle, const char* stageName, const MVKArrayRef<MVKMTLTextureBinding>& texBindings) {
if (needsSwizzle) {
for (MVKMTLTextureBinding& tb : texBindings) {
for (auto& tb : texBindings) {
VkComponentMapping vkcm = mvkUnpackSwizzle(tb.swizzle);
if (!mvkVkComponentMappingsMatch(vkcm, {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A})) {
MVKLogError("Pipeline does not support component swizzle (%s, %s, %s, %s) required by a VkImageView used in the %s shader."
@ -562,7 +556,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeBindings(MVKShaderStage stag
const char* pStageName,
bool fullImageViewSwizzle,
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&)> bindBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&, MVKVector<uint32_t>&)> bindImplicitBuffer,
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];
@ -574,10 +568,10 @@ void MVKGraphicsResourcesCommandEncoderState::encodeBindings(MVKShaderStage stag
if (b.isDirty) { updateImplicitBuffer(shaderStage.swizzleConstants, b.index, b.swizzle); }
}
bindImplicitBuffer(_cmdEncoder, shaderStage.swizzleBufferBinding, shaderStage.swizzleConstants);
bindImplicitBuffer(_cmdEncoder, shaderStage.swizzleBufferBinding, shaderStage.swizzleConstants.contents());
} else {
assertMissingSwizzles(shaderStage.needsSwizzle && !fullImageViewSwizzle, pStageName, shaderStage.textureBindings);
assertMissingSwizzles(shaderStage.needsSwizzle && !fullImageViewSwizzle, pStageName, shaderStage.textureBindings.contents());
}
if (shaderStage.bufferSizeBufferBinding.isDirty) {
@ -585,7 +579,7 @@ void MVKGraphicsResourcesCommandEncoderState::encodeBindings(MVKShaderStage stag
if (b.isDirty) { updateImplicitBuffer(shaderStage.bufferSizes, b.index, b.size); }
}
bindImplicitBuffer(_cmdEncoder, shaderStage.bufferSizeBufferBinding, shaderStage.bufferSizes);
bindImplicitBuffer(_cmdEncoder, shaderStage.bufferSizeBufferBinding, shaderStage.bufferSizes.contents());
}
encodeBinding<MVKMTLTextureBinding>(shaderStage.textureBindings, shaderStage.areTextureBindingsDirty, bindTexture);
@ -621,10 +615,10 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef<uint32_t>& s)->void {
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
s.data(),
s.size() * sizeof(uint32_t),
s.data,
s.size * sizeof(uint32_t),
b.index);
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void {
@ -651,10 +645,10 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef<uint32_t>& s)->void {
cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationControl),
s.data(),
s.size() * sizeof(uint32_t),
s.data,
s.size * sizeof(uint32_t),
b.index);
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void {
@ -681,10 +675,10 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef<uint32_t>& s)->void {
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
s.data(),
s.size() * sizeof(uint32_t),
s.data,
s.size * sizeof(uint32_t),
b.index);
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void {
@ -711,10 +705,10 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, const MVKArrayRef<uint32_t>& s)->void {
cmdEncoder->setFragmentBytes(cmdEncoder->_mtlRenderEncoder,
s.data(),
s.size() * sizeof(uint32_t),
s.data,
s.size * sizeof(uint32_t),
b.index);
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void {
@ -814,7 +808,7 @@ void MVKComputeResourcesCommandEncoderState::encodeImpl(uint32_t) {
_swizzleBufferBinding.index);
} else {
assertMissingSwizzles(_needsSwizzle && !fullImageViewSwizzle, "compute", _textureBindings);
assertMissingSwizzles(_needsSwizzle && !fullImageViewSwizzle, "compute", _textureBindings.contents());
}
if (_bufferSizeBufferBinding.isDirty) {