Merge pull request #891 from billhollings/master

Ensure vkGetPhysicalDeviceFormatProperties() are zerod for unsupported VkFormats.
This commit is contained in:
Bill Hollings 2020-05-28 12:25:04 -04:00 committed by GitHub
commit 064a45b6a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 17 deletions

View File

@ -271,7 +271,7 @@ void MVKPhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties*
void MVKPhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties2KHR* pFormatProperties) {
pFormatProperties->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR;
pFormatProperties->formatProperties = _pixelFormats.getVkFormatProperties(format);
getFormatProperties(format, &pFormatProperties->formatProperties);
}
VkResult MVKPhysicalDevice::getImageFormatProperties(VkFormat format,
@ -1307,7 +1307,7 @@ void MVKPhysicalDevice::initProperties() {
} else {
alignment = [_mtlDevice minimumLinearTextureAlignmentForPixelFormat: mtlFmt];
}
VkFormatProperties props = _pixelFormats.getVkFormatProperties(vk);
VkFormatProperties& props = _pixelFormats.getVkFormatProperties(vk);
// For uncompressed formats, this is the size of a single texel.
// Note that no implementations of Metal support compressed formats
// in a linear texture (including texture buffers). It's likely that even

View File

@ -31,7 +31,8 @@ class MVKPhysicalDevice;
// Validate these values periodically as new formats are added over time.
static const uint32_t _vkFormatCount = 256;
static const uint32_t _vkFormatCoreCount = VK_FORMAT_ASTC_12x12_SRGB_BLOCK + 1;
static const uint32_t _mtlPixelFormatCount = MTLPixelFormatX32_Stencil8 + 2; // The actual last enum value is not available on iOS
static const uint32_t _mtlPixelFormatCount = 128;
static const uint32_t _mtlPixelFormatCoreCount = MTLPixelFormatX32_Stencil8 + 2; // The actual last enum value is not available on iOS
static const uint32_t _mtlVertexFormatCount = MTLVertexFormatHalf + 1;
@ -233,7 +234,7 @@ public:
size_t getBytesPerLayer(MTLPixelFormat mtlFormat, size_t bytesPerRow, uint32_t texelRowsPerLayer);
/** Returns the default properties for the specified Vulkan format. */
VkFormatProperties getVkFormatProperties(VkFormat vkFormat);
VkFormatProperties& getVkFormatProperties(VkFormat vkFormat);
/** Returns the Metal format capabilities supported by the specified Vulkan format. */
MVKMTLFmtCaps getCapabilities(VkFormat vkFormat);
@ -323,7 +324,10 @@ protected:
uint16_t _vkFormatDescIndicesByVkFormatsCore[_vkFormatCoreCount];
std::unordered_map<uint32_t, uint32_t> _vkFormatDescIndicesByVkFormatsExt;
// Metal formats have small values and are mapped by simple lookup array.
uint16_t _mtlFormatDescIndicesByMTLPixelFormats[_mtlPixelFormatCount];
// Most Metal formats have small values and are mapped by simple lookup array.
// Outliers are mapped by a map.
uint16_t _mtlFormatDescIndicesByMTLPixelFormatsCore[_mtlPixelFormatCoreCount];
std::unordered_map<NSUInteger, uint32_t> _mtlFormatDescIndicesByMTLPixelFormatsExt;
uint16_t _mtlFormatDescIndicesByMTLVertexFormats[_mtlVertexFormatCount];
};

View File

@ -198,7 +198,7 @@ MTLPixelFormat MVKPixelFormats::getMTLPixelFormat(VkFormat vkFormat) {
if ( !mtlPixFmt || !vkDesc.hasReportedSubstitution ) {
string errMsg;
errMsg += "VkFormat ";
errMsg += (vkDesc.name) ? vkDesc.name : to_string(vkDesc.vkFormat);
errMsg += vkDesc.name;
errMsg += " is not supported on this device.";
if (mtlPixFmt) {
@ -206,7 +206,7 @@ MTLPixelFormat MVKPixelFormats::getMTLPixelFormat(VkFormat vkFormat) {
auto& vkDescSubs = getVkFormatDesc(mtlPixFmt);
errMsg += " Using VkFormat ";
errMsg += (vkDescSubs.name) ? vkDescSubs.name : to_string(vkDescSubs.vkFormat);
errMsg += vkDescSubs.name;
errMsg += " instead.";
}
MVKBaseObject::reportError(_physicalDevice, VK_ERROR_FORMAT_NOT_SUPPORTED, "%s", errMsg.c_str());
@ -262,8 +262,13 @@ size_t MVKPixelFormats::getBytesPerLayer(MTLPixelFormat mtlFormat, size_t bytesP
return mvkCeilingDivide(texelRowsPerLayer, getVkFormatDesc(mtlFormat).blockTexelSize.height) * bytesPerRow;
}
VkFormatProperties MVKPixelFormats::getVkFormatProperties(VkFormat vkFormat) {
return getVkFormatDesc(vkFormat).properties;
VkFormatProperties& MVKPixelFormats::getVkFormatProperties(VkFormat vkFormat) {
auto& vkDesc = getVkFormatDesc(vkFormat);
if ( !vkDesc.isSupported() ) {
MVKBaseObject::reportError(_physicalDevice, VK_ERROR_FORMAT_NOT_SUPPORTED,
"VkFormat %s is not supported on this device.", vkDesc.name);
}
return vkDesc.properties;
}
MVKMTLFmtCaps MVKPixelFormats::getCapabilities(VkFormat vkFormat) {
@ -311,7 +316,7 @@ MTLVertexFormat MVKPixelFormats::getMTLVertexFormat(VkFormat vkFormat) {
if ( !mtlVtxFmt && vkFormat ) {
string errMsg;
errMsg += "VkFormat ";
errMsg += (vkDesc.name) ? vkDesc.name : to_string(vkDesc.vkFormat);
errMsg += vkDesc.name;
errMsg += " is not supported for vertex buffers on this device.";
if (vkDesc.vertexIsSupportedOrSubstitutable()) {
@ -319,7 +324,7 @@ MTLVertexFormat MVKPixelFormats::getMTLVertexFormat(VkFormat vkFormat) {
auto& vkDescSubs = getVkFormatDesc(getMTLVertexFormatDesc(mtlVtxFmt).vkFormat);
errMsg += " Using VkFormat ";
errMsg += (vkDescSubs.name) ? vkDescSubs.name : to_string(vkDescSubs.vkFormat);
errMsg += vkDescSubs.name;
errMsg += " instead.";
}
MVKBaseObject::reportError(_physicalDevice, VK_ERROR_FORMAT_NOT_SUPPORTED, "%s", errMsg.c_str());
@ -449,7 +454,9 @@ MTLTextureUsage MVKPixelFormats::getMTLTextureUsage(VkImageUsageFlags vkImageUsa
// Return a reference to the Vulkan format descriptor corresponding to the VkFormat.
MVKVkFormatDesc& MVKPixelFormats::getVkFormatDesc(VkFormat vkFormat) {
uint16_t fmtIdx = (vkFormat < _vkFormatCoreCount) ? _vkFormatDescIndicesByVkFormatsCore[vkFormat] : _vkFormatDescIndicesByVkFormatsExt[vkFormat];
uint16_t fmtIdx = ((vkFormat < _vkFormatCoreCount)
? _vkFormatDescIndicesByVkFormatsCore[vkFormat]
: _vkFormatDescIndicesByVkFormatsExt[vkFormat]);
return _vkFormatDescriptions[fmtIdx];
}
@ -465,7 +472,9 @@ MVKMTLFormatDesc& MVKPixelFormats::getMTLPixelFormatDesc(VkFormat vkFormat) {
// Return a reference to the Metal format descriptor corresponding to the MTLPixelFormat.
MVKMTLFormatDesc& MVKPixelFormats::getMTLPixelFormatDesc(MTLPixelFormat mtlFormat) {
uint16_t fmtIdx = (mtlFormat < _mtlPixelFormatCount) ? _mtlFormatDescIndicesByMTLPixelFormats[mtlFormat] : 0;
uint16_t fmtIdx = ((mtlFormat < _mtlPixelFormatCoreCount)
? _mtlFormatDescIndicesByMTLPixelFormatsCore[mtlFormat]
: _mtlFormatDescIndicesByMTLPixelFormatsExt[mtlFormat]);
return _mtlPixelFormatDescriptions[fmtIdx];
}
@ -510,6 +519,7 @@ void MVKPixelFormats::initVkFormatCapabilities() {
uint32_t fmtIdx = 0;
// When adding to this list, be sure to ensure _vkFormatCount is large enough for the format count
// UNDEFINED must come first.
addVkFormatDesc( UNDEFINED, Invalid, Invalid, Invalid, Invalid, 1, 1, 0, None );
@ -939,6 +949,7 @@ void MVKPixelFormats::initMTLVertexFormatCapabilities() {
uint32_t fmtIdx = 0;
// When adding to this list, be sure to ensure _mtlVertexFormatCount is large enough for the format count
// MTLVertexFormatInvalid must come first.
addMTLVertexFormatDesc( Invalid, None, None );
@ -1014,13 +1025,21 @@ void MVKPixelFormats::initMTLVertexFormatCapabilities() {
void MVKPixelFormats::buildMTLFormatMaps() {
// Set all MTLPixelFormats and MTLVertexFormats to undefined/invalid
mvkClear(_mtlFormatDescIndicesByMTLPixelFormats, _mtlPixelFormatCount);
mvkClear(_mtlFormatDescIndicesByMTLPixelFormatsCore, _mtlPixelFormatCoreCount);
mvkClear(_mtlFormatDescIndicesByMTLVertexFormats, _mtlVertexFormatCount);
// Build lookup table for MTLPixelFormat specs
// Build lookup table for MTLPixelFormat specs.
// For most Metal format values, which are small and consecutive, use a simple lookup array.
// For outlier format values, which can be large, use a map.
for (uint32_t fmtIdx = 0; fmtIdx < _mtlPixelFormatCount; fmtIdx++) {
MTLPixelFormat fmt = _mtlPixelFormatDescriptions[fmtIdx].mtlPixelFormat;
if (fmt) { _mtlFormatDescIndicesByMTLPixelFormats[fmt] = fmtIdx; }
if (fmt) {
if (fmt < _mtlPixelFormatCoreCount) {
_mtlFormatDescIndicesByMTLPixelFormatsCore[fmt] = fmtIdx;
} else {
_mtlFormatDescIndicesByMTLPixelFormatsExt[fmt] = fmtIdx;
}
}
}
// Build lookup table for MTLVertexFormat specs