Log error and assertion if ImageView swizzling is disabled but needed.
MVKConfiguration::fullTextureSwizzle renamed to fullImageViewSwizzle. Env var MVK_CONFIG_FULL_TEXTURE_SWIZZLE renamed to MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE. Refactor MVKResourcesCommandEncoderState swizzle updates. Add mvkPackSwizzle(), mvkUnpackSwizzle() & mvkVkComponentSwizzleName() and remove from MVKImage. Refactor mvkVkResultName() to use literal strings.
This commit is contained in:
parent
0f9aabfc7b
commit
a7ab108166
@ -16,10 +16,10 @@ For best results, use a Markdown reader.*
|
||||
MoltenVK 1.0.31
|
||||
---------------
|
||||
|
||||
Released 2018/01/12
|
||||
Released 2018/01/15
|
||||
|
||||
- Support runtime config via runtime environment variables
|
||||
- Add full texture swizzling to config, and disable it by default.
|
||||
- Add full ImageView swizzling to config, and disable it by default.
|
||||
- Add GPU switching to config, and enable it by default.
|
||||
- Add queue family specialization to config, and disable it by default.
|
||||
- Enable synchronous queue submits as config default.
|
||||
|
@ -375,15 +375,17 @@ typedef struct {
|
||||
VkBool32 switchSystemGPU;
|
||||
|
||||
/**
|
||||
* If enabled, arbitrary per-texture swizzles are supported, as defined in
|
||||
* VkImageViewCreateInfo::components when creating a VkImageView.
|
||||
* If enabled, arbitrary ImageView component swizzles are supported, as defined
|
||||
* in VkImageViewCreateInfo::components when creating a VkImageView.
|
||||
*
|
||||
* If disabled, a very limited set of per-texture swizzles are supported
|
||||
* If disabled, a very limited set of ImageView component swizzles are supported
|
||||
* via format substitutions.
|
||||
*
|
||||
* Metal does not natively support per-texture swizzling. If this parameter is enabled,
|
||||
* per-texture swizzling is performed in shader code during textures sampling and reading,
|
||||
* regardless of whether a swizzle has been specified, which may result in reduced performance.
|
||||
* Metal does not natively support per-texture swizzling. If this parameter is enabled
|
||||
* when a pipeline is compiled, ImageView swizzling is automatically performed in the
|
||||
* converted Metal shader code during all texture sampling and reading operations,
|
||||
* regardless of whether a swizzle has been specified for the ImageView associated
|
||||
* with the Metal texture. This may result in reduced performance.
|
||||
*
|
||||
* The value of this parameter may be changed at any time during application runtime,
|
||||
* and the changed value will immediately effect subsequent MoltenVK behaviour.
|
||||
@ -391,7 +393,7 @@ typedef struct {
|
||||
* and disabled when compiling others. Existing pipelines are not automatically
|
||||
* re-compiled when this parameter is changed.
|
||||
*
|
||||
* If this parameter is disabled, the following limited set of per-texture swizzles
|
||||
* If this parameter is disabled, the following limited set of ImageView swizzles
|
||||
* are supported by MoltenVK, via automatic format substitution:
|
||||
*
|
||||
* Texture format Swizzle
|
||||
@ -406,11 +408,11 @@ typedef struct {
|
||||
* VK_FORMAT_D24_UNORM_S8_UINT RED, ANY, ANY, ANY (stencil only)
|
||||
*
|
||||
* The initial value or this parameter is set by the
|
||||
* MVK_CONFIG_FULL_TEXTURE_SWIZZLE
|
||||
* MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE
|
||||
* runtime environment variable or MoltenVK compile-time build setting.
|
||||
* If neither is set, the value of this parameter defaults to false.
|
||||
*/
|
||||
VkBool32 fullTextureSwizzle;
|
||||
VkBool32 fullImageViewSwizzle;
|
||||
|
||||
} MVKConfiguration;
|
||||
|
||||
|
@ -351,7 +351,7 @@ void MVKCommandEncoder::clearRenderArea() {
|
||||
}
|
||||
|
||||
void MVKCommandEncoder::finalizeDispatchState() {
|
||||
_computePipelineState.encode();
|
||||
_computePipelineState.encode(); // Must do first..it sets others
|
||||
_computeResourcesState.encode();
|
||||
_computePushConstants.encode();
|
||||
}
|
||||
|
@ -374,6 +374,13 @@ protected:
|
||||
bindings.push_back(db);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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>
|
||||
@ -391,11 +398,6 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the swizzle for an image in the given vector.
|
||||
void updateSwizzle(MVKVector<uint32_t> &constants, uint32_t index, uint32_t swizzle) {
|
||||
if (index >= constants.size()) { constants.resize(index + 1); }
|
||||
constants[index] = swizzle;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -466,6 +468,9 @@ protected:
|
||||
bool _areFragmentTextureBindingsDirty = false;
|
||||
bool _areVertexSamplerStateBindingsDirty = false;
|
||||
bool _areFragmentSamplerStateBindingsDirty = false;
|
||||
|
||||
bool _needsVertexSwizzle = false;
|
||||
bool _needsFragmentSwizzle = false;
|
||||
};
|
||||
|
||||
|
||||
@ -508,6 +513,8 @@ protected:
|
||||
bool _areBufferBindingsDirty = false;
|
||||
bool _areTextureBindingsDirty = false;
|
||||
bool _areSamplerStateBindingsDirty = false;
|
||||
|
||||
bool _needsSwizzle = false;
|
||||
};
|
||||
|
||||
|
||||
|
@ -398,6 +398,31 @@ void MVKBlendColorCommandEncoderState::resetImpl() {
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKResourcesCommandEncoderState
|
||||
|
||||
// Updates the swizzle for an image in the given vector.
|
||||
static void updateSwizzle(MVKVector<uint32_t> &constants, uint32_t index, uint32_t swizzle) {
|
||||
if (index >= constants.size()) { constants.resize(index + 1); }
|
||||
constants[index] = swizzle;
|
||||
}
|
||||
|
||||
// If a swizzle is needed for this stage, iterates all the bindings and logs errors for those that need texture swizzling.
|
||||
static void assertMissingSwizzles(bool needsSwizzle, const char* stageName, MVKVector<MVKMTLTextureBinding>& texBindings) {
|
||||
if (needsSwizzle) {
|
||||
for (MVKMTLTextureBinding& tb : texBindings) {
|
||||
VkComponentMapping vkcm = mvkUnpackSwizzle(tb.swizzle);
|
||||
MVKLogError("Pipeline does not support component swizzle (%s, %s, %s, %s) required by a VkImageView used in the %s shader."
|
||||
" Full VkImageView component swizzling will be supported by a pipeline if the MVKConfiguration::fullImageViewSwizzle"
|
||||
" config parameter or MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE environment variable was enabled when the pipeline is compiled.",
|
||||
mvkVkComponentSwizzleName(vkcm.r), mvkVkComponentSwizzleName(vkcm.g),
|
||||
mvkVkComponentSwizzleName(vkcm.b), mvkVkComponentSwizzleName(vkcm.a), stageName);
|
||||
MVKAssert(false, "See previous logged error.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark MVKGraphicsResourcesCommandEncoderState
|
||||
|
||||
@ -410,11 +435,11 @@ void MVKGraphicsResourcesCommandEncoderState::bindFragmentBuffer(const MVKMTLBuf
|
||||
}
|
||||
|
||||
void MVKGraphicsResourcesCommandEncoderState::bindVertexTexture(const MVKMTLTextureBinding& binding) {
|
||||
bind(binding, _vertexTextureBindings, _areVertexTextureBindingsDirty);
|
||||
bind(binding, _vertexTextureBindings, _areVertexTextureBindingsDirty, _needsVertexSwizzle);
|
||||
}
|
||||
|
||||
void MVKGraphicsResourcesCommandEncoderState::bindFragmentTexture(const MVKMTLTextureBinding& binding) {
|
||||
bind(binding, _fragmentTextureBindings, _areFragmentTextureBindingsDirty);
|
||||
bind(binding, _fragmentTextureBindings, _areFragmentTextureBindingsDirty, _needsFragmentSwizzle);
|
||||
}
|
||||
|
||||
void MVKGraphicsResourcesCommandEncoderState::bindVertexSamplerState(const MVKMTLSamplerStateBinding& binding) {
|
||||
@ -447,20 +472,6 @@ void MVKGraphicsResourcesCommandEncoderState::markDirty() {
|
||||
|
||||
void MVKGraphicsResourcesCommandEncoderState::encodeImpl() {
|
||||
|
||||
if (_vertexAuxBufferBinding.isDirty) {
|
||||
for (auto& b : _vertexTextureBindings) {
|
||||
if (b.isDirty)
|
||||
updateSwizzle(_vertexSwizzleConstants, b.index, b.swizzle);
|
||||
}
|
||||
}
|
||||
|
||||
if (_fragmentAuxBufferBinding.isDirty) {
|
||||
for (auto& b : _fragmentTextureBindings) {
|
||||
if (b.isDirty)
|
||||
updateSwizzle(_fragmentSwizzleConstants, b.index, b.swizzle);
|
||||
}
|
||||
}
|
||||
|
||||
encodeBinding<MVKMTLBufferBinding>(_vertexBufferBindings, _areVertexBufferBindingsDirty,
|
||||
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
|
||||
[cmdEncoder->_mtlRenderEncoder setVertexBuffer: b.mtlBuffer
|
||||
@ -476,17 +487,33 @@ void MVKGraphicsResourcesCommandEncoderState::encodeImpl() {
|
||||
});
|
||||
|
||||
if (_vertexAuxBufferBinding.isDirty) {
|
||||
|
||||
for (auto& b : _vertexTextureBindings) {
|
||||
if (b.isDirty) { updateSwizzle(_vertexSwizzleConstants, b.index, b.swizzle); }
|
||||
}
|
||||
|
||||
_cmdEncoder->setVertexBytes(_cmdEncoder->_mtlRenderEncoder,
|
||||
_vertexSwizzleConstants.data(),
|
||||
_vertexSwizzleConstants.size() * sizeof(uint32_t),
|
||||
_vertexAuxBufferBinding.index);
|
||||
|
||||
} else {
|
||||
assertMissingSwizzles(_needsVertexSwizzle, "vertex", _vertexTextureBindings);
|
||||
}
|
||||
|
||||
if (_fragmentAuxBufferBinding.isDirty) {
|
||||
|
||||
for (auto& b : _fragmentTextureBindings) {
|
||||
if (b.isDirty) { updateSwizzle(_fragmentSwizzleConstants, b.index, b.swizzle); }
|
||||
}
|
||||
|
||||
_cmdEncoder->setFragmentBytes(_cmdEncoder->_mtlRenderEncoder,
|
||||
_fragmentSwizzleConstants.data(),
|
||||
_fragmentSwizzleConstants.size() * sizeof(uint32_t),
|
||||
_fragmentAuxBufferBinding.index);
|
||||
|
||||
} else {
|
||||
assertMissingSwizzles(_needsFragmentSwizzle, "fragment", _fragmentTextureBindings);
|
||||
}
|
||||
|
||||
encodeBinding<MVKMTLTextureBinding>(_vertexTextureBindings, _areVertexTextureBindingsDirty,
|
||||
@ -532,6 +559,9 @@ void MVKGraphicsResourcesCommandEncoderState::resetImpl() {
|
||||
_areFragmentSamplerStateBindingsDirty = false;
|
||||
_vertexAuxBufferBinding.isDirty = false;
|
||||
_fragmentAuxBufferBinding.isDirty = false;
|
||||
|
||||
_needsVertexSwizzle = false;
|
||||
_needsFragmentSwizzle = false;
|
||||
}
|
||||
|
||||
|
||||
@ -543,7 +573,7 @@ void MVKComputeResourcesCommandEncoderState::bindBuffer(const MVKMTLBufferBindin
|
||||
}
|
||||
|
||||
void MVKComputeResourcesCommandEncoderState::bindTexture(const MVKMTLTextureBinding& binding) {
|
||||
bind(binding, _textureBindings, _areTextureBindingsDirty);
|
||||
bind(binding, _textureBindings, _areTextureBindingsDirty, _needsSwizzle);
|
||||
}
|
||||
|
||||
void MVKComputeResourcesCommandEncoderState::bindSamplerState(const MVKMTLSamplerStateBinding& binding) {
|
||||
@ -566,13 +596,6 @@ void MVKComputeResourcesCommandEncoderState::markDirty() {
|
||||
|
||||
void MVKComputeResourcesCommandEncoderState::encodeImpl() {
|
||||
|
||||
if (_auxBufferBinding.isDirty) {
|
||||
for (auto& b : _textureBindings) {
|
||||
if (b.isDirty)
|
||||
updateSwizzle(_swizzleConstants, b.index, b.swizzle);
|
||||
}
|
||||
}
|
||||
|
||||
encodeBinding<MVKMTLBufferBinding>(_bufferBindings, _areBufferBindingsDirty,
|
||||
[](MVKCommandEncoder* cmdEncoder, MVKMTLBufferBinding& b)->void {
|
||||
[cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch) setBuffer: b.mtlBuffer
|
||||
@ -581,10 +604,18 @@ void MVKComputeResourcesCommandEncoderState::encodeImpl() {
|
||||
});
|
||||
|
||||
if (_auxBufferBinding.isDirty) {
|
||||
|
||||
for (auto& b : _textureBindings) {
|
||||
if (b.isDirty) { updateSwizzle(_swizzleConstants, b.index, b.swizzle); }
|
||||
}
|
||||
|
||||
_cmdEncoder->setComputeBytes(_cmdEncoder->getMTLComputeEncoder(kMVKCommandUseDispatch),
|
||||
_swizzleConstants.data(),
|
||||
_swizzleConstants.size() * sizeof(uint32_t),
|
||||
_auxBufferBinding.index);
|
||||
|
||||
} else {
|
||||
assertMissingSwizzles(_needsSwizzle, "compute", _textureBindings);
|
||||
}
|
||||
|
||||
encodeBinding<MVKMTLTextureBinding>(_textureBindings, _areTextureBindingsDirty,
|
||||
@ -610,6 +641,8 @@ void MVKComputeResourcesCommandEncoderState::resetImpl() {
|
||||
_areTextureBindingsDirty = false;
|
||||
_areSamplerStateBindingsDirty = false;
|
||||
_auxBufferBinding.isDirty = false;
|
||||
|
||||
_needsSwizzle = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -289,8 +289,6 @@ protected:
|
||||
void initMTLTextureViewSupport();
|
||||
MTLPixelFormat getSwizzledMTLPixelFormat(VkFormat format, VkComponentMapping components, bool& useSwizzle);
|
||||
bool matchesSwizzle(VkComponentMapping components, VkComponentMapping pattern);
|
||||
const char* getSwizzleName(VkComponentSwizzle swizzle);
|
||||
uint32_t packSwizzle(VkComponentMapping components);
|
||||
void validateImageViewConfig(const VkImageViewCreateInfo* pCreateInfo);
|
||||
|
||||
MVKImage* _image;
|
||||
|
@ -798,7 +798,7 @@ MVKImageView::MVKImageView(MVKDevice* device, const VkImageViewCreateInfo* pCrea
|
||||
_mtlPixelFormat = getSwizzledMTLPixelFormat(pCreateInfo->format, pCreateInfo->components, useSwizzle);
|
||||
_mtlTextureType = mvkMTLTextureTypeFromVkImageViewType(pCreateInfo->viewType, (_image->getSampleCount() != VK_SAMPLE_COUNT_1_BIT));
|
||||
initMTLTextureViewSupport();
|
||||
_packedSwizzle = useSwizzle ? packSwizzle(pCreateInfo->components) : 0;
|
||||
_packedSwizzle = useSwizzle ? mvkPackSwizzle(pCreateInfo->components) : 0;
|
||||
}
|
||||
|
||||
// Validate whether the image view configuration can be supported
|
||||
@ -896,19 +896,6 @@ MTLPixelFormat MVKImageView::getSwizzledMTLPixelFormat(VkFormat format, VkCompon
|
||||
return mtlPF;
|
||||
}
|
||||
|
||||
const char* MVKImageView::getSwizzleName(VkComponentSwizzle swizzle) {
|
||||
switch (swizzle) {
|
||||
case VK_COMPONENT_SWIZZLE_IDENTITY: return "VK_COMPONENT_SWIZZLE_IDENTITY";
|
||||
case VK_COMPONENT_SWIZZLE_ZERO: return "VK_COMPONENT_SWIZZLE_ZERO";
|
||||
case VK_COMPONENT_SWIZZLE_ONE: return "VK_COMPONENT_SWIZZLE_ONE";
|
||||
case VK_COMPONENT_SWIZZLE_R: return "VK_COMPONENT_SWIZZLE_R";
|
||||
case VK_COMPONENT_SWIZZLE_G: return "VK_COMPONENT_SWIZZLE_G";
|
||||
case VK_COMPONENT_SWIZZLE_B: return "VK_COMPONENT_SWIZZLE_B";
|
||||
case VK_COMPONENT_SWIZZLE_A: return "VK_COMPONENT_SWIZZLE_A";
|
||||
default: return "VK_COMPONENT_SWIZZLE_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
// Returns whether the swizzle components of the internal VkComponentMapping matches the
|
||||
// swizzle pattern, by comparing corresponding elements of the two structures. The pattern
|
||||
// supports wildcards, in that any element of pattern can be set to VK_COMPONENT_SWIZZLE_MAX_ENUM
|
||||
@ -926,12 +913,6 @@ bool MVKImageView::matchesSwizzle(VkComponentMapping components, VkComponentMapp
|
||||
return true;
|
||||
}
|
||||
|
||||
// Packs a VkComponentMapping structure into a single 32-bit word.
|
||||
uint32_t MVKImageView::packSwizzle(VkComponentMapping components) {
|
||||
return ((components.r & 0xFF) << 0) | ((components.g & 0xFF) << 8) |
|
||||
((components.b & 0xFF) << 16) | ((components.a & 0xFF) << 24);
|
||||
}
|
||||
|
||||
// Determine whether this image view should use a Metal texture view,
|
||||
// and set the _useMTLTextureView variable appropriately.
|
||||
void MVKImageView::initMTLTextureViewSupport() {
|
||||
|
@ -366,7 +366,7 @@ void MVKInstance::initConfig() {
|
||||
MVK_SET_FROM_ENV_OR_BUILD_BOOL( _mvkConfig.displayWatermark, MVK_CONFIG_DISPLAY_WATERMARK);
|
||||
MVK_SET_FROM_ENV_OR_BUILD_BOOL( _mvkConfig.specializedQueueFamilies, MVK_CONFIG_SPECIALIZED_QUEUE_FAMILIES);
|
||||
MVK_SET_FROM_ENV_OR_BUILD_BOOL( _mvkConfig.switchSystemGPU, MVK_CONFIG_SWITCH_SYSTEM_GPU);
|
||||
MVK_SET_FROM_ENV_OR_BUILD_BOOL( _mvkConfig.fullTextureSwizzle, MVK_CONFIG_FULL_TEXTURE_SWIZZLE);
|
||||
MVK_SET_FROM_ENV_OR_BUILD_BOOL( _mvkConfig.fullImageViewSwizzle, MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE);
|
||||
}
|
||||
|
||||
VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {
|
||||
|
@ -324,7 +324,7 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLRenderPipelineDescriptor
|
||||
shaderContext.options.entryPointName = pSS->pName;
|
||||
id<MTLFunction> mtlFunction = ((MVKShaderModule*)pSS->module)->getMTLFunction(&shaderContext, pSS->pSpecializationInfo, _pipelineCache).mtlFunction;
|
||||
if ( !mtlFunction ) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Vertex shader function could not be compiled into pipeline. See previous error."));
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Vertex shader function could not be compiled into pipeline. See previous logged error."));
|
||||
return nil;
|
||||
}
|
||||
plDesc.vertexFunction = mtlFunction;
|
||||
@ -347,7 +347,7 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLRenderPipelineDescriptor
|
||||
shaderContext.options.entryPointName = pSS->pName;
|
||||
id<MTLFunction> mtlFunction = ((MVKShaderModule*)pSS->module)->getMTLFunction(&shaderContext, pSS->pSpecializationInfo, _pipelineCache).mtlFunction;
|
||||
if ( !mtlFunction ) {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Fragment shader function could not be compiled into pipeline. See previous error."));
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Fragment shader function could not be compiled into pipeline. See previous logged error."));
|
||||
}
|
||||
plDesc.fragmentFunction = mtlFunction;
|
||||
_needsFragmentAuxBuffer = shaderContext.options.needsAuxBuffer;
|
||||
@ -484,7 +484,7 @@ void MVKGraphicsPipeline::initMVKShaderConverterContext(SPIRVToMSLConverterConte
|
||||
shaderContext.options.isRenderingPoints = isRenderingPoints(pCreateInfo);
|
||||
shaderContext.options.isRasterizationDisabled = (pCreateInfo->pRasterizationState && (pCreateInfo->pRasterizationState->rasterizerDiscardEnable));
|
||||
shaderContext.options.shouldFlipVertexY = _device->_pMVKConfig->shaderConversionFlipVertexY;
|
||||
shaderContext.options.shouldSwizzleTextureSamples = _device->_pMVKConfig->fullTextureSwizzle;
|
||||
shaderContext.options.shouldSwizzleTextureSamples = _device->_pMVKConfig->fullImageViewSwizzle;
|
||||
|
||||
// Set the shader context vertex attribute information
|
||||
shaderContext.vertexAttributes.clear();
|
||||
@ -581,7 +581,7 @@ MVKComputePipeline::MVKComputePipeline(MVKDevice* device,
|
||||
setConfigurationResult(plc->getConfigurationResult());
|
||||
plc->destroy();
|
||||
} else {
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Compute shader function could not be compiled into pipeline. See previous error."));
|
||||
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "Compute shader function could not be compiled into pipeline. See previous logged error."));
|
||||
}
|
||||
|
||||
if (_needsAuxBuffer && _auxBufferIndex.compute == ~0u) {
|
||||
@ -599,7 +599,7 @@ MVKMTLFunction MVKComputePipeline::getMTLFunction(const VkComputePipelineCreateI
|
||||
shaderContext.options.entryPointName = pCreateInfo->stage.pName;
|
||||
shaderContext.options.entryPointStage = spv::ExecutionModelGLCompute;
|
||||
shaderContext.options.mslVersion = _device->_pMetalFeatures->mslVersion;
|
||||
shaderContext.options.shouldSwizzleTextureSamples = _device->_pMVKConfig->fullTextureSwizzle;
|
||||
shaderContext.options.shouldSwizzleTextureSamples = _device->_pMVKConfig->fullImageViewSwizzle;
|
||||
|
||||
MVKPipelineLayout* layout = (MVKPipelineLayout*)pCreateInfo->layout;
|
||||
layout->populateShaderConverterContext(shaderContext);
|
||||
|
@ -107,9 +107,9 @@
|
||||
# define MVK_CONFIG_SWITCH_SYSTEM_GPU 1
|
||||
#endif
|
||||
|
||||
/** Support full per-texture swizzles. Disabled by default. */
|
||||
#ifndef MVK_CONFIG_FULL_TEXTURE_SWIZZLE
|
||||
# define MVK_CONFIG_FULL_TEXTURE_SWIZZLE 0
|
||||
/** Support full ImageView swizzles. Disabled by default. */
|
||||
#ifndef MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE
|
||||
# define MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE 0
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -19,45 +19,59 @@
|
||||
#include "MVKFoundation.h"
|
||||
#include "MVKLogging.h"
|
||||
|
||||
#define CASE_RESULT(R) case R: return strcpy(name, #R);
|
||||
|
||||
char* mvkResultName(VkResult vkResult, char* name) {
|
||||
#define CASE_STRINGIFY(V) case V: return #V
|
||||
|
||||
const char* mvkVkResultName(VkResult vkResult) {
|
||||
switch (vkResult) {
|
||||
CASE_RESULT(VK_SUCCESS)
|
||||
CASE_RESULT(VK_NOT_READY)
|
||||
CASE_RESULT(VK_TIMEOUT)
|
||||
CASE_RESULT(VK_EVENT_SET)
|
||||
CASE_RESULT(VK_EVENT_RESET)
|
||||
CASE_RESULT(VK_INCOMPLETE)
|
||||
|
||||
CASE_RESULT(VK_ERROR_OUT_OF_HOST_MEMORY)
|
||||
CASE_RESULT(VK_ERROR_OUT_OF_DEVICE_MEMORY)
|
||||
CASE_RESULT(VK_ERROR_INITIALIZATION_FAILED)
|
||||
CASE_RESULT(VK_ERROR_DEVICE_LOST)
|
||||
CASE_RESULT(VK_ERROR_MEMORY_MAP_FAILED)
|
||||
CASE_RESULT(VK_ERROR_LAYER_NOT_PRESENT)
|
||||
CASE_RESULT(VK_ERROR_EXTENSION_NOT_PRESENT)
|
||||
CASE_RESULT(VK_ERROR_FEATURE_NOT_PRESENT)
|
||||
CASE_RESULT(VK_ERROR_INCOMPATIBLE_DRIVER)
|
||||
CASE_RESULT(VK_ERROR_TOO_MANY_OBJECTS)
|
||||
CASE_RESULT(VK_ERROR_FORMAT_NOT_SUPPORTED)
|
||||
CASE_RESULT(VK_ERROR_FRAGMENTED_POOL)
|
||||
CASE_STRINGIFY(VK_SUCCESS);
|
||||
CASE_STRINGIFY(VK_NOT_READY);
|
||||
CASE_STRINGIFY(VK_TIMEOUT);
|
||||
CASE_STRINGIFY(VK_EVENT_SET);
|
||||
CASE_STRINGIFY(VK_EVENT_RESET);
|
||||
CASE_STRINGIFY(VK_INCOMPLETE);
|
||||
|
||||
CASE_RESULT(VK_ERROR_SURFACE_LOST_KHR)
|
||||
CASE_RESULT(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR)
|
||||
CASE_RESULT(VK_SUBOPTIMAL_KHR)
|
||||
CASE_RESULT(VK_ERROR_OUT_OF_DATE_KHR)
|
||||
CASE_RESULT(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR)
|
||||
CASE_STRINGIFY(VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
CASE_STRINGIFY(VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
CASE_STRINGIFY(VK_ERROR_INITIALIZATION_FAILED);
|
||||
CASE_STRINGIFY(VK_ERROR_DEVICE_LOST);
|
||||
CASE_STRINGIFY(VK_ERROR_MEMORY_MAP_FAILED);
|
||||
CASE_STRINGIFY(VK_ERROR_LAYER_NOT_PRESENT);
|
||||
CASE_STRINGIFY(VK_ERROR_EXTENSION_NOT_PRESENT);
|
||||
CASE_STRINGIFY(VK_ERROR_FEATURE_NOT_PRESENT);
|
||||
CASE_STRINGIFY(VK_ERROR_INCOMPATIBLE_DRIVER);
|
||||
CASE_STRINGIFY(VK_ERROR_TOO_MANY_OBJECTS);
|
||||
CASE_STRINGIFY(VK_ERROR_FORMAT_NOT_SUPPORTED);
|
||||
CASE_STRINGIFY(VK_ERROR_FRAGMENTED_POOL);
|
||||
|
||||
CASE_RESULT(VK_ERROR_VALIDATION_FAILED_EXT)
|
||||
CASE_RESULT(VK_ERROR_INVALID_SHADER_NV)
|
||||
CASE_STRINGIFY(VK_ERROR_SURFACE_LOST_KHR);
|
||||
CASE_STRINGIFY(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR);
|
||||
CASE_STRINGIFY(VK_SUBOPTIMAL_KHR);
|
||||
CASE_STRINGIFY(VK_ERROR_OUT_OF_DATE_KHR);
|
||||
CASE_STRINGIFY(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR);
|
||||
|
||||
CASE_RESULT(VK_ERROR_OUT_OF_POOL_MEMORY)
|
||||
CASE_RESULT(VK_ERROR_INVALID_EXTERNAL_HANDLE)
|
||||
CASE_STRINGIFY(VK_ERROR_VALIDATION_FAILED_EXT);
|
||||
CASE_STRINGIFY(VK_ERROR_INVALID_SHADER_NV);
|
||||
|
||||
default:
|
||||
sprintf(name, "UNKNOWN_VkResult(%d)", vkResult);
|
||||
return name;
|
||||
CASE_STRINGIFY(VK_ERROR_OUT_OF_POOL_MEMORY);
|
||||
CASE_STRINGIFY(VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
|
||||
default: return "VK_UNKNOWN_VK_Result";
|
||||
}
|
||||
}
|
||||
|
||||
const char* mvkVkComponentSwizzleName(VkComponentSwizzle swizzle) {
|
||||
switch (swizzle) {
|
||||
CASE_STRINGIFY(VK_COMPONENT_SWIZZLE_IDENTITY);
|
||||
CASE_STRINGIFY(VK_COMPONENT_SWIZZLE_ZERO);
|
||||
CASE_STRINGIFY(VK_COMPONENT_SWIZZLE_ONE);
|
||||
CASE_STRINGIFY(VK_COMPONENT_SWIZZLE_R);
|
||||
CASE_STRINGIFY(VK_COMPONENT_SWIZZLE_G);
|
||||
CASE_STRINGIFY(VK_COMPONENT_SWIZZLE_B);
|
||||
CASE_STRINGIFY(VK_COMPONENT_SWIZZLE_A);
|
||||
|
||||
default: return "VK_UNKNOWN_VKComponentSwizzle";
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,10 +79,8 @@ VkResult mvkNotifyErrorWithText(VkResult vkErr, const char* errFmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, errFmt);
|
||||
|
||||
char vkRsltName[MVKResultNameMaxLen];
|
||||
mvkResultName(vkErr, vkRsltName);
|
||||
|
||||
// Prepend the error code to the format string
|
||||
const char* vkRsltName = mvkVkResultName(vkErr);
|
||||
char fmtStr[strlen(vkRsltName) + strlen(errFmt) + 4];
|
||||
sprintf(fmtStr, "%s: %s", vkRsltName, errFmt);
|
||||
|
||||
|
@ -100,13 +100,11 @@ typedef enum {
|
||||
kMVKCommandUseDispatch, /**< vkCmdDispatch. */
|
||||
} MVKCommandUse;
|
||||
|
||||
/**
|
||||
* Copies the name of the specified VkResult code to the specified string.
|
||||
*
|
||||
* Returns a pointer to that string.
|
||||
*/
|
||||
#define MVKResultNameMaxLen 64
|
||||
char* mvkResultName(VkResult vkResult, char* name);
|
||||
/** Returns the name of the result value. */
|
||||
const char* mvkVkResultName(VkResult vkResult);
|
||||
|
||||
/** Returns the name of the component swizzle. */
|
||||
const char* mvkVkComponentSwizzleName(VkComponentSwizzle swizzle);
|
||||
|
||||
/**
|
||||
* Notifies the app of an error code and error message, via the following methods:
|
||||
@ -260,6 +258,22 @@ static inline VkOffset3D mvkVkOffset3DDifference(VkOffset3D minuend, VkOffset3D
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/** Packs the four swizzle components into a single 32-bit word. */
|
||||
static inline uint32_t mvkPackSwizzle(VkComponentMapping components) {
|
||||
return ((components.r & 0xFF) << 0) | ((components.g & 0xFF) << 8) |
|
||||
((components.b & 0xFF) << 16) | ((components.a & 0xFF) << 24);
|
||||
}
|
||||
|
||||
/** Unpacks a single 32-bit word containing four swizzle components. */
|
||||
static inline VkComponentMapping mvkUnpackSwizzle(uint32_t packed) {
|
||||
VkComponentMapping components;
|
||||
components.r = (VkComponentSwizzle)((packed >> 0) & 0xFF);
|
||||
components.g = (VkComponentSwizzle)((packed >> 8) & 0xFF);
|
||||
components.b = (VkComponentSwizzle)((packed >> 16) & 0xFF);
|
||||
components.a = (VkComponentSwizzle)((packed >> 24) & 0xFF);
|
||||
return components;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Template functions
|
||||
|
Loading…
x
Reference in New Issue
Block a user