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:
parent
2e91df7b21
commit
a6deef8df9
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user