Merge buffer and inline unions to fix issue where binding inline descriptor would interfere with future binds on the same set index in the same command buffer (now only used in push case anyway)

This commit is contained in:
Michael Barriault 2019-12-26 14:07:51 -03:30
parent 78ca4655ab
commit c3d8d4e159
4 changed files with 56 additions and 97 deletions

View File

@ -424,9 +424,6 @@ public:
/** Binds the specified buffer for the specified shader stage. */
void bindBuffer(MVKShaderStage stage, const MVKMTLBufferBinding& binding);
/** Binds the specified buffer for the specified shader stage. */
void bindInline(MVKShaderStage stage, const MVKMTLInlineBinding& binding);
/** Binds the specified texture for the specified shader stage. */
void bindTexture(MVKShaderStage stage, const MVKMTLTextureBinding& binding);
@ -461,8 +458,7 @@ public:
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&)> bindBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&, MVKVector<uint32_t>&)> bindImplicitBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLTextureBinding&)> bindTexture,
std::function<void(MVKCommandEncoder*, MVKMTLSamplerStateBinding&)> bindSampler,
std::function<void(MVKCommandEncoder*, MVKMTLInlineBinding&)> bindInline);
std::function<void(MVKCommandEncoder*, MVKMTLSamplerStateBinding&)> bindSampler);
#pragma mark Construction
@ -478,7 +474,6 @@ protected:
MVKVectorInline<MVKMTLBufferBinding, 8> bufferBindings;
MVKVectorInline<MVKMTLTextureBinding, 8> textureBindings;
MVKVectorInline<MVKMTLSamplerStateBinding, 8> samplerStateBindings;
MVKVectorInline<MVKMTLInlineBinding, 8> inlineBindings;
MVKVectorInline<uint32_t, 8> swizzleConstants;
MVKVectorInline<uint32_t, 8> bufferSizes;
MVKMTLBufferBinding swizzleBufferBinding;
@ -487,7 +482,6 @@ protected:
bool areBufferBindingsDirty = false;
bool areTextureBindingsDirty = false;
bool areSamplerStateBindingsDirty = false;
bool areInlineBindingsDirty = false;
bool needsSwizzle = false;
};
@ -507,9 +501,6 @@ public:
/** Binds the specified buffer. */
void bindBuffer(const MVKMTLBufferBinding& binding);
/** Binds the specified buffer. */
void bindInline(const MVKMTLInlineBinding& binding);
/** Binds the specified texture. */
void bindTexture(const MVKMTLTextureBinding& binding);
@ -535,7 +526,6 @@ protected:
MVKVectorInline<MVKMTLBufferBinding, 4> _bufferBindings;
MVKVectorInline<MVKMTLTextureBinding, 4> _textureBindings;
MVKVectorInline<MVKMTLSamplerStateBinding, 4> _samplerStateBindings;
MVKVectorInline<MVKMTLInlineBinding, 4> _inlineBindings;
MVKVectorInline<uint32_t, 4> _swizzleConstants;
MVKVectorInline<uint32_t, 4> _bufferSizes;
MVKMTLBufferBinding _swizzleBufferBinding;
@ -544,7 +534,6 @@ protected:
bool _areBufferBindingsDirty = false;
bool _areTextureBindingsDirty = false;
bool _areSamplerStateBindingsDirty = false;
bool _areInlineBindingsDirty = false;
bool _needsSwizzle = false;
};

View File

@ -516,10 +516,6 @@ void MVKGraphicsResourcesCommandEncoderState::bindSamplerState(MVKShaderStage st
bind(binding, _shaderStages[stage].samplerStateBindings, _shaderStages[stage].areSamplerStateBindingsDirty);
}
void MVKGraphicsResourcesCommandEncoderState::bindInline(MVKShaderStage stage, const MVKMTLInlineBinding& binding) {
bind(binding, _shaderStages[stage].inlineBindings, _shaderStages[stage].areInlineBindingsDirty);
}
void MVKGraphicsResourcesCommandEncoderState::bindSwizzleBuffer(const MVKShaderImplicitRezBinding& binding,
bool needVertexSwizzleBuffer,
bool needTessCtlSwizzleBuffer,
@ -554,11 +550,9 @@ void MVKGraphicsResourcesCommandEncoderState::encodeBindings(MVKShaderStage stag
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&)> bindBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLBufferBinding&, MVKVector<uint32_t>&)> bindImplicitBuffer,
std::function<void(MVKCommandEncoder*, MVKMTLTextureBinding&)> bindTexture,
std::function<void(MVKCommandEncoder*, MVKMTLSamplerStateBinding&)> bindSampler,
std::function<void(MVKCommandEncoder*, MVKMTLInlineBinding&)> bindInline) {
std::function<void(MVKCommandEncoder*, MVKMTLSamplerStateBinding&)> bindSampler) {
auto& shaderStage = _shaderStages[stage];
encodeBinding<MVKMTLBufferBinding>(shaderStage.bufferBindings, shaderStage.areBufferBindingsDirty, bindBuffer);
encodeBinding<MVKMTLInlineBinding>(shaderStage.inlineBindings, shaderStage.areInlineBindingsDirty, bindInline);
if (shaderStage.swizzleBufferBinding.isDirty) {
@ -591,7 +585,6 @@ void MVKGraphicsResourcesCommandEncoderState::markDirty() {
MVKResourcesCommandEncoderState::markDirty(_shaderStages[i].bufferBindings, _shaderStages[i].areBufferBindingsDirty);
MVKResourcesCommandEncoderState::markDirty(_shaderStages[i].textureBindings, _shaderStages[i].areTextureBindingsDirty);
MVKResourcesCommandEncoderState::markDirty(_shaderStages[i].samplerStateBindings, _shaderStages[i].areSamplerStateBindingsDirty);
MVKResourcesCommandEncoderState::markDirty(_shaderStages[i].inlineBindings, _shaderStages[i].areInlineBindingsDirty);
}
}
@ -604,9 +597,15 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
if (stage == (forTessellation ? kMVKGraphicsStageVertex : kMVKGraphicsStageRasterization)) {
encodeBindings(kMVKShaderStageVertex, "vertex", fullImageViewSwizzle,
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
if (b.isInline)
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
b.mtlBytes,
b.size,
b.index);
else
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
@ -621,12 +620,6 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
[](MVKCommandEncoder* cmdEncoder, MVKMTLSamplerStateBinding& b)->void {
[cmdEncoder->_mtlRenderEncoder setVertexSamplerState: b.mtlSamplerState
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLInlineBinding& b)->void {
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
b.mtlBytes,
b.size,
b.index);
});
}
@ -634,9 +627,15 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
if (stage == kMVKGraphicsStageTessControl) {
encodeBindings(kMVKShaderStageTessCtl, "tessellation control", fullImageViewSwizzle,
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationControl) setBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
if (b.isInline)
cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationControl),
b.mtlBytes,
b.size,
b.index);
else
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationControl) setBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationControl),
@ -651,12 +650,6 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
[](MVKCommandEncoder* cmdEncoder, MVKMTLSamplerStateBinding& b)->void {
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationControl) setSamplerState: b.mtlSamplerState
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLInlineBinding& b)->void {
cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseTessellationControl),
b.mtlBytes,
b.size,
b.index);
});
}
@ -664,9 +657,15 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
if (forTessellation && stage == kMVKGraphicsStageRasterization) {
encodeBindings(kMVKShaderStageTessEval, "tessellation evaluation", fullImageViewSwizzle,
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
if (b.isInline)
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
b.mtlBytes,
b.size,
b.index);
else
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
@ -681,12 +680,6 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
[](MVKCommandEncoder* cmdEncoder, MVKMTLSamplerStateBinding& b)->void {
[cmdEncoder->_mtlRenderEncoder setVertexSamplerState: b.mtlSamplerState
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLInlineBinding& b)->void {
cmdEncoder->setVertexBytes(cmdEncoder->_mtlRenderEncoder,
b.mtlBytes,
b.size,
b.index);
});
}
@ -694,9 +687,15 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
if (stage == kMVKGraphicsStageRasterization) {
encodeBindings(kMVKShaderStageFragment, "fragment", fullImageViewSwizzle,
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
[cmdEncoder->_mtlRenderEncoder setFragmentBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
if (b.isInline)
cmdEncoder->setFragmentBytes(cmdEncoder->_mtlRenderEncoder,
b.mtlBytes,
b.size,
b.index);
else
[cmdEncoder->_mtlRenderEncoder setFragmentBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b, MVKVector<uint32_t>& s)->void {
cmdEncoder->setFragmentBytes(cmdEncoder->_mtlRenderEncoder,
@ -711,12 +710,6 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl(uint32_t stage) {
[](MVKCommandEncoder* cmdEncoder, MVKMTLSamplerStateBinding& b)->void {
[cmdEncoder->_mtlRenderEncoder setFragmentSamplerState: b.mtlSamplerState
atIndex: b.index];
},
[](MVKCommandEncoder* cmdEncoder, MVKMTLInlineBinding& b)->void {
cmdEncoder->setFragmentBytes(cmdEncoder->_mtlRenderEncoder,
b.mtlBytes,
b.size,
b.index);
});
}
}
@ -726,14 +719,12 @@ void MVKGraphicsResourcesCommandEncoderState::resetImpl() {
_shaderStages[i].bufferBindings.clear();
_shaderStages[i].textureBindings.clear();
_shaderStages[i].samplerStateBindings.clear();
_shaderStages[i].inlineBindings.clear();
_shaderStages[i].swizzleConstants.clear();
_shaderStages[i].bufferSizes.clear();
_shaderStages[i].areBufferBindingsDirty = false;
_shaderStages[i].areTextureBindingsDirty = false;
_shaderStages[i].areSamplerStateBindingsDirty = false;
_shaderStages[i].areInlineBindingsDirty = false;
_shaderStages[i].swizzleBufferBinding.isDirty = false;
_shaderStages[i].bufferSizeBufferBinding.isDirty = false;
@ -757,10 +748,6 @@ void MVKComputeResourcesCommandEncoderState::bindSamplerState(const MVKMTLSample
bind(binding, _samplerStateBindings, _areSamplerStateBindingsDirty);
}
void MVKComputeResourcesCommandEncoderState::bindInline(const MVKMTLInlineBinding& binding) {
bind(binding, _inlineBindings, _areInlineBindingsDirty);
}
void MVKComputeResourcesCommandEncoderState::bindSwizzleBuffer(const MVKShaderImplicitRezBinding& binding,
bool needSwizzleBuffer) {
_swizzleBufferBinding.index = binding.stages[kMVKShaderStageCompute];
@ -779,7 +766,6 @@ void MVKComputeResourcesCommandEncoderState::markDirty() {
MVKResourcesCommandEncoderState::markDirty(_bufferBindings, _areBufferBindingsDirty);
MVKResourcesCommandEncoderState::markDirty(_textureBindings, _areTextureBindingsDirty);
MVKResourcesCommandEncoderState::markDirty(_samplerStateBindings, _areSamplerStateBindingsDirty);
MVKResourcesCommandEncoderState::markDirty(_inlineBindings, _areInlineBindingsDirty);
}
void MVKComputeResourcesCommandEncoderState::encodeImpl(uint32_t) {
@ -790,20 +776,18 @@ void MVKComputeResourcesCommandEncoderState::encodeImpl(uint32_t) {
fullImageViewSwizzle = pipeline->fullImageViewSwizzle();
encodeBinding<MVKMTLBufferBinding>(_bufferBindings, _areBufferBindingsDirty,
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
if (b.isInline)
cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch),
b.mtlBytes,
b.size,
b.index);
else
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setBuffer: b.mtlBuffer
offset: b.offset
atIndex: b.index];
});
encodeBinding<MVKMTLInlineBinding>(_inlineBindings, _areInlineBindingsDirty,
[](MVKCommandEncoder* cmdEncoder, MVKMTLInlineBinding& b)->void {
cmdEncoder->setComputeBytes(cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch),
b.mtlBytes,
b.size,
b.index);
});
if (_swizzleBufferBinding.isDirty) {
for (auto& b : _textureBindings) {
@ -848,7 +832,6 @@ void MVKComputeResourcesCommandEncoderState::resetImpl() {
_bufferBindings.clear();
_textureBindings.clear();
_samplerStateBindings.clear();
_inlineBindings.clear();
_swizzleConstants.clear();
_bufferSizes.clear();

View File

@ -37,11 +37,12 @@ typedef struct {
/** Describes a MTLBuffer resource binding. */
typedef struct {
union { id<MTLBuffer> mtlBuffer = nil; id<MTLBuffer> mtlResource; }; // aliases
union { id<MTLBuffer> mtlBuffer = nil; id<MTLBuffer> mtlResource; const void* mtlBytes; }; // aliases
NSUInteger offset = 0;
uint32_t index = 0;
uint32_t size = 0;
bool isDirty = true;
bool isInline = false;
} MVKMTLBufferBinding;
/** Describes a MTLBuffer resource binding as used for an index buffer. */
@ -51,12 +52,3 @@ typedef struct {
MTLIndexType mtlIndexType;
bool isDirty = true;
} MVKIndexMTLBufferBinding;
/** Describes host bytes resource binding. */
typedef struct {
union { const void* mtlBytes = nil; const void* mtlResource; }; // aliases
uint32_t index = 0;
uint32_t size = 0;
bool isDirty = true;
} MVKMTLInlineBinding;

View File

@ -225,7 +225,6 @@ void MVKDescriptorSetLayoutBinding::push(MVKCommandEncoder* cmdEncoder,
MVKMTLBufferBinding bb;
MVKMTLTextureBinding tb;
MVKMTLSamplerStateBinding sb;
MVKMTLInlineBinding ib;
if (dstArrayElement >= _info.descriptorCount) {
dstArrayElement -= _info.descriptorCount;
@ -275,15 +274,16 @@ void MVKDescriptorSetLayoutBinding::push(MVKCommandEncoder* cmdEncoder,
case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: {
const auto& inlineUniformBlock = get<VkWriteDescriptorSetInlineUniformBlockEXT>(pData, stride, rezIdx - dstArrayElement);
ib.mtlBytes = inlineUniformBlock.pData;
ib.size = inlineUniformBlock.dataSize;
bb.mtlBytes = inlineUniformBlock.pData;
bb.size = inlineUniformBlock.dataSize;
bb.isInline = true;
for (uint32_t i = kMVKShaderStageVertex; i < kMVKShaderStageMax; i++) {
if (_applyToStage[i]) {
ib.index = mtlIdxs.stages[i].bufferIndex + rezIdx;
bb.index = mtlIdxs.stages[i].bufferIndex + rezIdx;
if (i == kMVKShaderStageCompute) {
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindInline(ib); }
if (cmdEncoder) { cmdEncoder->_computeResourcesState.bindBuffer(bb); }
} else {
if (cmdEncoder) { cmdEncoder->_graphicsResourcesState.bindInline(MVKShaderStage(i), ib); }
if (cmdEncoder) { cmdEncoder->_graphicsResourcesState.bindBuffer(MVKShaderStage(i), bb); }
}
}
}
@ -1002,11 +1002,6 @@ MVKDescriptorBinding::~MVKDescriptorBinding() {
((MVKBufferView*)buffView)->release();
}
}
for (VkWriteDescriptorSetInlineUniformBlockEXT& inlineUniformBlock : _inlineBindings) {
if (inlineUniformBlock.pData) {
delete [] reinterpret_cast<const uint8_t*>(inlineUniformBlock.pData);
}
}
}
/**