Skip to content

Commit 91c1947

Browse files
authored
Merge pull request #303 from cdavis5e/component-swizzle
Support arbitrary swizzles of image data.
2 parents 7dd1434 + 082d282 commit 91c1947

File tree

13 files changed

+256
-41
lines changed

13 files changed

+256
-41
lines changed

Diff for: ExternalRevisions/SPIRV-Cross_repo_revision

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c9210427b9ab547d41f1af804dedae581b382965
1+
cc5c0204d8bcdadbb4add03e53346df98bf27fa4

Diff for: MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extern "C" {
4848
*/
4949
#define MVK_VERSION_MAJOR 1
5050
#define MVK_VERSION_MINOR 0
51-
#define MVK_VERSION_PATCH 23
51+
#define MVK_VERSION_PATCH 24
5252

5353
#define MVK_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + (patch))
5454
#define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)

Diff for: MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h

+20
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
class MVKCommandEncoder;
2626
class MVKOcclusionQueryPool;
2727

28+
struct MVKShaderAuxBufferBinding;
29+
2830

2931
#pragma mark -
3032
#pragma mark MVKCommandEncoderState
@@ -388,6 +390,16 @@ class MVKResourcesCommandEncoderState : public MVKCommandEncoderState {
388390
}
389391
}
390392
}
393+
394+
struct AuxBuffer {
395+
uint32_t swizzleConst[1];
396+
};
397+
398+
// Updates the swizzle for an image in the given buffer.
399+
void updateSwizzle(id<MTLBuffer> buffer, uint32_t index, uint32_t swizzle) {
400+
auto* aux = (AuxBuffer*)buffer.contents;
401+
aux->swizzleConst[index] = swizzle;
402+
}
391403
};
392404

393405

@@ -425,6 +437,9 @@ class MVKGraphicsResourcesCommandEncoderState : public MVKResourcesCommandEncode
425437
_mtlIndexBufferBinding = binding; // No need to track dirty state
426438
}
427439

440+
/** Sets the current auxiliary buffer state. */
441+
void bindAuxBuffer(id<MTLBuffer> buffer, const MVKShaderAuxBufferBinding& binding, bool needVertexAuxBuffer, bool needFragmentAuxBuffer);
442+
428443

429444
#pragma mark Construction
430445

@@ -442,6 +457,8 @@ class MVKGraphicsResourcesCommandEncoderState : public MVKResourcesCommandEncode
442457
std::vector<MVKMTLTextureBinding> _fragmentTextureBindings;
443458
std::vector<MVKMTLSamplerStateBinding> _vertexSamplerStateBindings;
444459
std::vector<MVKMTLSamplerStateBinding> _fragmentSamplerStateBindings;
460+
MVKMTLBufferBinding _vertexAuxBufferBinding;
461+
MVKMTLBufferBinding _fragmentAuxBufferBinding;
445462

446463
bool _areVertexBufferBindingsDirty = false;
447464
bool _areFragmentBufferBindingsDirty = false;
@@ -469,6 +486,8 @@ class MVKComputeResourcesCommandEncoderState : public MVKResourcesCommandEncoder
469486
/** Binds the specified sampler state. */
470487
void bindSamplerState(const MVKMTLSamplerStateBinding& binding);
471488

489+
/** Sets the current auxiliary buffer state. */
490+
void bindAuxBuffer(id<MTLBuffer> buffer, const MVKShaderAuxBufferBinding& binding);
472491

473492
#pragma mark Construction
474493

@@ -483,6 +502,7 @@ class MVKComputeResourcesCommandEncoderState : public MVKResourcesCommandEncoder
483502
std::vector<MVKMTLBufferBinding> _bufferBindings;
484503
std::vector<MVKMTLTextureBinding> _textureBindings;
485504
std::vector<MVKMTLSamplerStateBinding> _samplerStateBindings;
505+
MVKMTLBufferBinding _auxBufferBinding;
486506

487507
bool _areBufferBindingsDirty = false;
488508
bool _areTextureBindingsDirty = false;

Diff for: MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.mm

+66
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,15 @@
425425
bind(binding, _fragmentSamplerStateBindings, _areFragmentSamplerStateBindingsDirty);
426426
}
427427

428+
void MVKGraphicsResourcesCommandEncoderState::bindAuxBuffer(id<MTLBuffer> buffer, const MVKShaderAuxBufferBinding& binding, bool needVertexAuxBuffer, bool needFragmentAuxBuffer) {
429+
_vertexAuxBufferBinding.mtlBuffer = needVertexAuxBuffer ? buffer : nil;
430+
_vertexAuxBufferBinding.index = binding.vertex;
431+
_vertexAuxBufferBinding.isDirty = needVertexAuxBuffer;
432+
_fragmentAuxBufferBinding.mtlBuffer = needFragmentAuxBuffer ? buffer : nil;
433+
_fragmentAuxBufferBinding.index = binding.fragment;
434+
_fragmentAuxBufferBinding.isDirty = needFragmentAuxBuffer;
435+
}
436+
428437
// Mark everything as dirty
429438
void MVKGraphicsResourcesCommandEncoderState::markDirty() {
430439
MVKCommandEncoderState::markDirty();
@@ -434,10 +443,26 @@
434443
MVKResourcesCommandEncoderState::markDirty(_fragmentTextureBindings, _areFragmentTextureBindingsDirty);
435444
MVKResourcesCommandEncoderState::markDirty(_vertexSamplerStateBindings, _areVertexSamplerStateBindingsDirty);
436445
MVKResourcesCommandEncoderState::markDirty(_fragmentSamplerStateBindings, _areFragmentSamplerStateBindingsDirty);
446+
_vertexAuxBufferBinding.isDirty = true;
447+
_fragmentAuxBufferBinding.isDirty = true;
437448
}
438449

439450
void MVKGraphicsResourcesCommandEncoderState::encodeImpl() {
440451

452+
if (_vertexAuxBufferBinding.mtlBuffer) {
453+
for (auto& b : _vertexTextureBindings) {
454+
if (b.isDirty)
455+
updateSwizzle(_vertexAuxBufferBinding.mtlBuffer, b.index, b.swizzle);
456+
}
457+
}
458+
459+
if (_fragmentAuxBufferBinding.mtlBuffer) {
460+
for (auto& b : _fragmentTextureBindings) {
461+
if (b.isDirty)
462+
updateSwizzle(_fragmentAuxBufferBinding.mtlBuffer, b.index, b.swizzle);
463+
}
464+
}
465+
441466
encodeBinding<MVKMTLBufferBinding>(_vertexBufferBindings, _areVertexBufferBindingsDirty,
442467
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
443468
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
@@ -452,6 +477,20 @@
452477
atIndex: b.index];
453478
});
454479

480+
if (_vertexAuxBufferBinding.isDirty) {
481+
_vertexAuxBufferBinding.isDirty = false;
482+
[_cmdEncoder->_mtlRenderEncoder setVertexBuffer: _vertexAuxBufferBinding.mtlBuffer
483+
offset: 0
484+
atIndex: _vertexAuxBufferBinding.index];
485+
}
486+
487+
if (_fragmentAuxBufferBinding.isDirty) {
488+
_fragmentAuxBufferBinding.isDirty = false;
489+
[_cmdEncoder->_mtlRenderEncoder setFragmentBuffer: _fragmentAuxBufferBinding.mtlBuffer
490+
offset: 0
491+
atIndex: _fragmentAuxBufferBinding.index];
492+
}
493+
455494
encodeBinding<MVKMTLTextureBinding>(_vertexTextureBindings, _areVertexTextureBindingsDirty,
456495
[](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void {
457496
[cmdEncoder->_mtlRenderEncoder setVertexTexture: b.mtlTexture
@@ -484,13 +523,17 @@
484523
_fragmentTextureBindings.clear();
485524
_vertexSamplerStateBindings.clear();
486525
_fragmentSamplerStateBindings.clear();
526+
_vertexAuxBufferBinding.mtlBuffer = nil;
527+
_fragmentAuxBufferBinding.mtlBuffer = nil;
487528

488529
_areVertexBufferBindingsDirty = false;
489530
_areFragmentBufferBindingsDirty = false;
490531
_areVertexTextureBindingsDirty = false;
491532
_areFragmentTextureBindingsDirty = false;
492533
_areVertexSamplerStateBindingsDirty = false;
493534
_areFragmentSamplerStateBindingsDirty = false;
535+
_vertexAuxBufferBinding.isDirty = false;
536+
_fragmentAuxBufferBinding.isDirty = false;
494537
}
495538

496539

@@ -509,23 +552,44 @@
509552
bind(binding, _samplerStateBindings, _areSamplerStateBindingsDirty);
510553
}
511554

555+
void MVKComputeResourcesCommandEncoderState::bindAuxBuffer(id<MTLBuffer> buffer, const MVKShaderAuxBufferBinding& binding) {
556+
_auxBufferBinding.mtlBuffer = buffer;
557+
_auxBufferBinding.index = binding.compute;
558+
_auxBufferBinding.isDirty = buffer != nil;
559+
}
560+
512561
// Mark everything as dirty
513562
void MVKComputeResourcesCommandEncoderState::markDirty() {
514563
MVKCommandEncoderState::markDirty();
515564
MVKResourcesCommandEncoderState::markDirty(_bufferBindings, _areBufferBindingsDirty);
516565
MVKResourcesCommandEncoderState::markDirty(_textureBindings, _areTextureBindingsDirty);
517566
MVKResourcesCommandEncoderState::markDirty(_samplerStateBindings, _areSamplerStateBindingsDirty);
567+
_auxBufferBinding.isDirty = true;
518568
}
519569

520570
void MVKComputeResourcesCommandEncoderState::encodeImpl() {
521571

572+
if (_auxBufferBinding.mtlBuffer) {
573+
for (auto& b : _textureBindings) {
574+
if (b.isDirty)
575+
updateSwizzle(_auxBufferBinding.mtlBuffer, b.index, b.swizzle);
576+
}
577+
}
578+
522579
encodeBinding<MVKMTLBufferBinding>(_bufferBindings, _areBufferBindingsDirty,
523580
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
524581
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setBuffer: b.mtlBuffer
525582
offset: b.offset
526583
atIndex: b.index];
527584
});
528585

586+
if (_auxBufferBinding.isDirty) {
587+
_auxBufferBinding.isDirty = false;
588+
[_cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setBuffer: _auxBufferBinding.mtlBuffer
589+
offset: 0
590+
atIndex: _auxBufferBinding.index];
591+
}
592+
529593
encodeBinding<MVKMTLTextureBinding>(_textureBindings, _areTextureBindingsDirty,
530594
[](MVKCommandEncoder* cmdEncoder, MVKMTLTextureBinding& b)->void {
531595
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setTexture: b.mtlTexture
@@ -543,10 +607,12 @@
543607
_bufferBindings.clear();
544608
_textureBindings.clear();
545609
_samplerStateBindings.clear();
610+
_auxBufferBinding.mtlBuffer = nil;
546611

547612
_areBufferBindingsDirty = false;
548613
_areTextureBindingsDirty = false;
549614
_areSamplerStateBindingsDirty = false;
615+
_auxBufferBinding.isDirty = false;
550616
}
551617

552618

Diff for: MoltenVK/MoltenVK/Commands/MVKMTLResourceBindings.h

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
typedef struct {
2525
union { id<MTLTexture> mtlTexture = nil; id<MTLTexture> mtlResource; }; // aliases
2626
uint32_t index = 0;
27+
uint32_t swizzle = 0;
2728
bool isDirty = true;
2829
} MVKMTLTextureBinding;
2930

Diff for: MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ class MVKDescriptorSetLayoutBinding : public MVKConfigurableObject {
100100

101101
protected:
102102
friend class MVKDescriptorBinding;
103+
friend class MVKPipelineLayout;
103104

104105
VkResult initMetalResourceIndexOffsets(MVKShaderStageResourceBinding* pBindingIndexes,
105106
MVKShaderStageResourceBinding* pDescSetCounts,

Diff for: MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm

+21
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@
111111
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
112112
case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
113113
tb.mtlTexture = descBinding._mtlTextures[rezIdx];
114+
if (_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE && tb.mtlTexture) {
115+
tb.swizzle = ((MVKImageView*)descBinding._imageBindings[rezIdx].imageView)->getPackedSwizzle();
116+
} else {
117+
tb.swizzle = 0;
118+
}
114119
if (_applyToVertexStage) {
115120
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;
116121
cmdEncoder->_graphicsResourcesState.bindVertexTexture(tb);
@@ -145,6 +150,11 @@
145150

146151
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
147152
tb.mtlTexture = descBinding._mtlTextures[rezIdx];
153+
if (tb.mtlTexture) {
154+
tb.swizzle = ((MVKImageView*)descBinding._imageBindings[rezIdx].imageView)->getPackedSwizzle();
155+
} else {
156+
tb.swizzle = 0;
157+
}
148158
sb.mtlSamplerState = descBinding._mtlSamplers[rezIdx];
149159
if (_applyToVertexStage) {
150160
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;
@@ -243,6 +253,11 @@
243253
const auto& imageInfo = get<VkDescriptorImageInfo>(pData, stride, rezIdx - dstArrayElement);
244254
MVKImageView* imageView = (MVKImageView*)imageInfo.imageView;
245255
tb.mtlTexture = imageView->getMTLTexture();
256+
if (_info.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE && imageView) {
257+
tb.swizzle = imageView->getPackedSwizzle();
258+
} else {
259+
tb.swizzle = 0;
260+
}
246261
if (_applyToVertexStage) {
247262
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;
248263
cmdEncoder->_graphicsResourcesState.bindVertexTexture(tb);
@@ -262,6 +277,7 @@
262277
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
263278
auto* bufferView = get<MVKBufferView*>(pData, stride, rezIdx - dstArrayElement);
264279
tb.mtlTexture = bufferView->getMTLTexture();
280+
tb.swizzle = 0;
265281
if (_applyToVertexStage) {
266282
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;
267283
cmdEncoder->_graphicsResourcesState.bindVertexTexture(tb);
@@ -304,6 +320,11 @@
304320
MVKImageView* imageView = (MVKImageView*)imageInfo.imageView;
305321
MVKSampler* sampler = _immutableSamplers.empty() ? (MVKSampler*)imageInfo.sampler : _immutableSamplers[rezIdx];
306322
tb.mtlTexture = imageView->getMTLTexture();
323+
if (imageView) {
324+
tb.swizzle = imageView->getPackedSwizzle();
325+
} else {
326+
tb.swizzle = 0;
327+
}
307328
sb.mtlSamplerState = sampler->getMTLSamplerState();
308329
if (_applyToVertexStage) {
309330
tb.index = mtlIdxs.vertexStage.textureIndex + rezIdx;

Diff for: MoltenVK/MoltenVK/GPUObjects/MVKImage.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ class MVKImageView : public MVKBaseDeviceObject {
261261
/** Returns the Metal texture type of this image view. */
262262
inline MTLTextureType getMTLTextureType() { return _mtlTextureType; }
263263

264+
/** Returns the packed component swizzle of this image view. */
265+
inline uint32_t getPackedSwizzle() { return _packedSwizzle; }
266+
264267
/**
265268
* Populates the texture of the specified render pass descriptor
266269
* with the Metal texture underlying this image.
@@ -283,10 +286,10 @@ class MVKImageView : public MVKBaseDeviceObject {
283286
protected:
284287
id<MTLTexture> newMTLTexture();
285288
void initMTLTextureViewSupport();
286-
MTLPixelFormat getSwizzledMTLPixelFormat(VkFormat format, VkComponentMapping components);
289+
MTLPixelFormat getSwizzledMTLPixelFormat(VkFormat format, VkComponentMapping components, bool& useSwizzle);
287290
bool matchesSwizzle(VkComponentMapping components, VkComponentMapping pattern);
288291
const char* getSwizzleName(VkComponentSwizzle swizzle);
289-
void setSwizzleFormatError(VkFormat format, VkComponentMapping components);
292+
uint32_t packSwizzle(VkComponentMapping components);
290293
void validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo);
291294

292295
MVKImage* _image;
@@ -296,6 +299,7 @@ class MVKImageView : public MVKBaseDeviceObject {
296299
std::mutex _lock;
297300
MTLPixelFormat _mtlPixelFormat;
298301
MTLTextureType _mtlTextureType;
302+
uint32_t _packedSwizzle;
299303
bool _useMTLTextureView;
300304
};
301305

0 commit comments

Comments
 (0)