Commit f8f6103e by Alexis Hetu Committed by Alexis Hétu

VK_EXT_provoking_vertex support

Adding an new extension, which is not present in the Vulkan headers, in order for ANGLE to be able to specify to SwiftShader which provoking vertex convention to use, in order to properly emulate OpenGL ES on top of Vulkan, since OpenGL ES uses the last vertex convention and Vulkan uses the first vertex convention. Bug: angleproject:3677, angleproject:3430 Change-Id: If4e6539d48bc282af8ed6f2a9db6b2fc9d0dbe2d Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/37248 Presubmit-Ready: Alexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com>
parent 6623ca14
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "vulkan.h"
// THIS FILE SHOULD BE DELETED IF VK_EXT_provoking_vertex IS EVER ADDED TO THE VULKAN HEADERS
#ifdef VK_EXT_provoking_vertex
#error "VK_EXT_provoking_vertex is already defined in the Vulkan headers, you can delete this file"
#endif
static constexpr VkStructureType VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = static_cast<VkStructureType>(1000254000);
static constexpr VkStructureType VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = static_cast<VkStructureType>(1000254001);
static constexpr VkStructureType VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = static_cast<VkStructureType>(1000254002);
#define VK_EXT_provoking_vertex 1
#define VK_EXT_PROVOKING_VERTEX_SPEC_VERSION 1
#define VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME "VK_EXT_provoking_vertex"
typedef enum VkProvokingVertexModeEXT {
VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT = 0,
VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT = 1,
VK_PROVOKING_VERTEX_MODE_BEGIN_RANGE_EXT = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT,
VK_PROVOKING_VERTEX_MODE_END_RANGE_EXT = VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT,
VK_PROVOKING_VERTEX_MODE_RANGE_SIZE_EXT = (VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT - VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT + 1),
VK_PROVOKING_VERTEX_MODE_MAX_ENUM_EXT = 0x7FFFFFFF
} VkProvokingVertexModeEXT;
typedef struct VkPhysicalDeviceProvokingVertexFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 provokingVertexLast;
} VkPhysicalDeviceProvokingVertexFeaturesEXT;
typedef struct VkPhysicalDeviceProvokingVertexPropertiesEXT {
VkStructureType sType;
void* pNext;
VkBool32 provokingVertexModePerPipeline;
} VkPhysicalDeviceProvokingVertexPropertiesEXT;
typedef struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkProvokingVertexModeEXT provokingVertexMode;
} VkPipelineRasterizationProvokingVertexStateCreateInfoEXT;
...@@ -110,6 +110,7 @@ namespace sw ...@@ -110,6 +110,7 @@ namespace sw
cullMode = VK_CULL_MODE_FRONT_BIT; cullMode = VK_CULL_MODE_FRONT_BIT;
frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT; lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
depthBias = 0.0f; depthBias = 0.0f;
......
...@@ -88,6 +88,7 @@ namespace sw ...@@ -88,6 +88,7 @@ namespace sw
BlendState getBlendState(int index) const; BlendState getBlendState(int index) const;
VkPrimitiveTopology topology; VkPrimitiveTopology topology;
VkProvokingVertexModeEXT provokingVertexMode;
bool stencilEnable; bool stencilEnable;
VkStencilOpState frontStencil; VkStencilOpState frontStencil;
......
...@@ -46,8 +46,10 @@ unsigned int maxPrimitives = 1 << 21; ...@@ -46,8 +46,10 @@ unsigned int maxPrimitives = 1 << 21;
namespace sw namespace sw
{ {
template<typename T> template<typename T>
inline bool setBatchIndices(unsigned int batch[128][3], VkPrimitiveTopology topology, T indices, unsigned int start, unsigned int triangleCount) inline bool setBatchIndices(unsigned int batch[128][3], VkPrimitiveTopology topology, VkProvokingVertexModeEXT provokingVertexMode, T indices, unsigned int start, unsigned int triangleCount)
{ {
bool provokeFirst = (provokingVertexMode == VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT);
switch(topology) switch(topology)
{ {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
...@@ -72,8 +74,8 @@ namespace sw ...@@ -72,8 +74,8 @@ namespace sw
auto index = 2 * start; auto index = 2 * start;
for(unsigned int i = 0; i < triangleCount; i++) for(unsigned int i = 0; i < triangleCount; i++)
{ {
batch[i][0] = indices[index + 0]; batch[i][0] = indices[index + (provokeFirst ? 0 : 1)];
batch[i][1] = indices[index + 1]; batch[i][1] = indices[index + (provokeFirst ? 1 : 0)];
batch[i][2] = indices[index + 1]; batch[i][2] = indices[index + 1];
index += 2; index += 2;
...@@ -85,8 +87,8 @@ namespace sw ...@@ -85,8 +87,8 @@ namespace sw
auto index = start; auto index = start;
for(unsigned int i = 0; i < triangleCount; i++) for(unsigned int i = 0; i < triangleCount; i++)
{ {
batch[i][0] = indices[index + 0]; batch[i][0] = indices[index + (provokeFirst ? 0 : 1)];
batch[i][1] = indices[index + 1]; batch[i][1] = indices[index + (provokeFirst ? 1 : 0)];
batch[i][2] = indices[index + 1]; batch[i][2] = indices[index + 1];
index += 1; index += 1;
...@@ -98,9 +100,9 @@ namespace sw ...@@ -98,9 +100,9 @@ namespace sw
auto index = 3 * start; auto index = 3 * start;
for(unsigned int i = 0; i < triangleCount; i++) for(unsigned int i = 0; i < triangleCount; i++)
{ {
batch[i][0] = indices[index + 0]; batch[i][0] = indices[index + (provokeFirst ? 0 : 2)];
batch[i][1] = indices[index + 1]; batch[i][1] = indices[index + (provokeFirst ? 1 : 0)];
batch[i][2] = indices[index + 2]; batch[i][2] = indices[index + (provokeFirst ? 2 : 1)];
index += 3; index += 3;
} }
...@@ -111,9 +113,9 @@ namespace sw ...@@ -111,9 +113,9 @@ namespace sw
auto index = start; auto index = start;
for(unsigned int i = 0; i < triangleCount; i++) for(unsigned int i = 0; i < triangleCount; i++)
{ {
batch[i][0] = indices[index + 0]; batch[i][0] = indices[index + (provokeFirst ? 0 : 2)];
batch[i][1] = indices[index + ((start + i) & 1) + 1]; batch[i][1] = indices[index + ((start + i) & 1) + (provokeFirst ? 1 : 0)];
batch[i][2] = indices[index + (~(start + i) & 1) + 1]; batch[i][2] = indices[index + (~(start + i) & 1) + (provokeFirst ? 1 : 0)];
index += 1; index += 1;
} }
...@@ -124,9 +126,9 @@ namespace sw ...@@ -124,9 +126,9 @@ namespace sw
auto index = start + 1; auto index = start + 1;
for(unsigned int i = 0; i < triangleCount; i++) for(unsigned int i = 0; i < triangleCount; i++)
{ {
batch[i][0] = indices[index + 0]; batch[i][provokeFirst ? 0 : 2] = indices[index + 0];
batch[i][1] = indices[index + 1]; batch[i][provokeFirst ? 1 : 0] = indices[index + 1];
batch[i][2] = indices[0]; batch[i][provokeFirst ? 2 : 1] = indices[0];
index += 1; index += 1;
} }
...@@ -260,6 +262,7 @@ namespace sw ...@@ -260,6 +262,7 @@ namespace sw
draw->numPrimitivesPerBatch = numPrimitivesPerBatch; draw->numPrimitivesPerBatch = numPrimitivesPerBatch;
draw->numBatches = (count + draw->numPrimitivesPerBatch - 1) / draw->numPrimitivesPerBatch; draw->numBatches = (count + draw->numPrimitivesPerBatch - 1) / draw->numPrimitivesPerBatch;
draw->topology = context->topology; draw->topology = context->topology;
draw->provokingVertexMode = context->provokingVertexMode;
draw->indexType = indexType; draw->indexType = indexType;
draw->lineRasterizationMode = context->lineRasterizationMode; draw->lineRasterizationMode = context->lineRasterizationMode;
...@@ -498,7 +501,8 @@ namespace sw ...@@ -498,7 +501,8 @@ namespace sw
draw->indexType, draw->indexType,
batch->firstPrimitive, batch->firstPrimitive,
batch->numPrimitives, batch->numPrimitives,
draw->topology); draw->topology,
draw->provokingVertexMode);
} }
auto& vertexTask = batch->vertexTask; auto& vertexTask = batch->vertexTask;
...@@ -561,7 +565,8 @@ namespace sw ...@@ -561,7 +565,8 @@ namespace sw
VkIndexType indexType, VkIndexType indexType,
unsigned int start, unsigned int start,
unsigned int triangleCount, unsigned int triangleCount,
VkPrimitiveTopology topology) VkPrimitiveTopology topology,
VkProvokingVertexModeEXT provokingVertexMode)
{ {
if(!primitiveIndices) if(!primitiveIndices)
{ {
...@@ -570,7 +575,7 @@ namespace sw ...@@ -570,7 +575,7 @@ namespace sw
unsigned int operator[](unsigned int i) { return i; } unsigned int operator[](unsigned int i) { return i; }
}; };
if(!setBatchIndices(triangleIndicesOut, topology, LinearIndex(), start, triangleCount)) if(!setBatchIndices(triangleIndicesOut, topology, provokingVertexMode, LinearIndex(), start, triangleCount))
{ {
return; return;
} }
...@@ -580,13 +585,13 @@ namespace sw ...@@ -580,13 +585,13 @@ namespace sw
switch(indexType) switch(indexType)
{ {
case VK_INDEX_TYPE_UINT16: case VK_INDEX_TYPE_UINT16:
if(!setBatchIndices(triangleIndicesOut, topology, static_cast<const uint16_t*>(primitiveIndices), start, triangleCount)) if(!setBatchIndices(triangleIndicesOut, topology, provokingVertexMode, static_cast<const uint16_t*>(primitiveIndices), start, triangleCount))
{ {
return; return;
} }
break; break;
case VK_INDEX_TYPE_UINT32: case VK_INDEX_TYPE_UINT32:
if(!setBatchIndices(triangleIndicesOut, topology, static_cast<const uint32_t*>(primitiveIndices), start, triangleCount)) if(!setBatchIndices(triangleIndicesOut, topology, provokingVertexMode, static_cast<const uint32_t*>(primitiveIndices), start, triangleCount))
{ {
return; return;
} }
......
...@@ -150,6 +150,7 @@ namespace sw ...@@ -150,6 +150,7 @@ namespace sw
unsigned int numBatches; unsigned int numBatches;
VkPrimitiveTopology topology; VkPrimitiveTopology topology;
VkProvokingVertexModeEXT provokingVertexMode;
VkIndexType indexType; VkIndexType indexType;
VkLineRasterizationModeEXT lineRasterizationMode; VkLineRasterizationModeEXT lineRasterizationMode;
...@@ -179,7 +180,8 @@ namespace sw ...@@ -179,7 +180,8 @@ namespace sw
VkIndexType indexType, VkIndexType indexType,
unsigned int start, unsigned int start,
unsigned int triangleCount, unsigned int triangleCount,
VkPrimitiveTopology topology); VkPrimitiveTopology topology,
VkProvokingVertexModeEXT provokingVertexMode);
static int setupSolidTriangles(Triangle* triangles, Primitive* primitives, const DrawCall* drawCall, int count); static int setupSolidTriangles(Triangle* triangles, Primitive* primitives, const DrawCall* drawCall, int count);
static int setupWireframeTriangles(Triangle* triangles, Primitive* primitives, const DrawCall* drawCall, int count); static int setupWireframeTriangles(Triangle* triangles, Primitive* primitives, const DrawCall* drawCall, int count);
......
...@@ -394,6 +394,11 @@ void PhysicalDevice::getProperties(VkPhysicalDeviceLineRasterizationPropertiesEX ...@@ -394,6 +394,11 @@ void PhysicalDevice::getProperties(VkPhysicalDeviceLineRasterizationPropertiesEX
properties->lineSubPixelPrecisionBits = vk::SUBPIXEL_PRECISION_BITS; properties->lineSubPixelPrecisionBits = vk::SUBPIXEL_PRECISION_BITS;
} }
void PhysicalDevice::getProperties(VkPhysicalDeviceProvokingVertexPropertiesEXT* properties) const
{
properties->provokingVertexModePerPipeline = VK_TRUE;
}
bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const
{ {
const VkPhysicalDeviceFeatures& supportedFeatures = getFeatures(); const VkPhysicalDeviceFeatures& supportedFeatures = getFeatures();
......
...@@ -63,6 +63,7 @@ public: ...@@ -63,6 +63,7 @@ public:
void getProperties(const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties) const; void getProperties(const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties) const;
void getProperties(VkPhysicalDeviceDriverPropertiesKHR* properties) const; void getProperties(VkPhysicalDeviceDriverPropertiesKHR* properties) const;
void getProperties(VkPhysicalDeviceLineRasterizationPropertiesEXT* properties) const; void getProperties(VkPhysicalDeviceLineRasterizationPropertiesEXT* properties) const;
void getProperties(VkPhysicalDeviceProvokingVertexPropertiesEXT* properties) const;
void getFormatProperties(Format format, VkFormatProperties* pFormatProperties) const; void getFormatProperties(Format format, VkFormatProperties* pFormatProperties) const;
void getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling, void getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
......
...@@ -390,6 +390,31 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn ...@@ -390,6 +390,31 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn
UNIMPLEMENTED("pCreateInfo->pRasterizationState settings"); UNIMPLEMENTED("pCreateInfo->pRasterizationState settings");
} }
if(rasterizationState->pNext)
{
const VkBaseInStructure* extensionCreateInfo = reinterpret_cast<const VkBaseInStructure*>(rasterizationState->pNext);
while(extensionCreateInfo)
{
// Casting to a long since some structures, such as
// VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT
// are not enumerated in the official Vulkan header
switch((long)(extensionCreateInfo->sType))
{
case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT:
{
const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT* provokingVertexModeCreateInfo =
reinterpret_cast<const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT*>(extensionCreateInfo);
context.provokingVertexMode = provokingVertexModeCreateInfo->provokingVertexMode;
}
break;
default:
UNIMPLEMENTED("extensionCreateInfo->pNext");
}
extensionCreateInfo = extensionCreateInfo->pNext;
}
}
context.rasterizerDiscard = (rasterizationState->rasterizerDiscardEnable == VK_TRUE); context.rasterizerDiscard = (rasterizationState->rasterizerDiscardEnable == VK_TRUE);
context.cullMode = rasterizationState->cullMode; context.cullMode = rasterizationState->cullMode;
context.frontFace = rasterizationState->frontFace; context.frontFace = rasterizationState->frontFace;
......
...@@ -49,6 +49,7 @@ public: ...@@ -49,6 +49,7 @@ public:
template class VkNonDispatchableHandle<object##Ptr>; template class VkNonDispatchableHandle<object##Ptr>;
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <vulkan/vk_ext_provoking_vertex.h>
#ifdef Bool #ifdef Bool
#undef Bool // b/127920555 #undef Bool // b/127920555
......
...@@ -233,6 +233,7 @@ static const VkExtensionProperties deviceExtensionProperties[] = ...@@ -233,6 +233,7 @@ static const VkExtensionProperties deviceExtensionProperties[] =
#if SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD #if SWIFTSHADER_EXTERNAL_SEMAPHORE_LINUX_MEMFD
{ VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION }, { VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION },
#endif #endif
{ VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, VK_EXT_PROVOKING_VERTEX_SPEC_VERSION },
}; };
VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
...@@ -500,7 +501,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c ...@@ -500,7 +501,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c
while(extensionCreateInfo) while(extensionCreateInfo)
{ {
switch(extensionCreateInfo->sType) // Casting to a long since some structures, such as
// VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT
// are not enumerated in the official Vulkan header
switch((long)(extensionCreateInfo->sType))
{ {
case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO: case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO:
// According to the Vulkan spec, section 2.7.2. Implicit Valid Usage: // According to the Vulkan spec, section 2.7.2. Implicit Valid Usage:
...@@ -597,6 +601,16 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c ...@@ -597,6 +601,16 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c
} }
} }
break; break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT:
{
const VkPhysicalDeviceProvokingVertexFeaturesEXT* provokingVertexFeatures = reinterpret_cast<const VkPhysicalDeviceProvokingVertexFeaturesEXT*>(extensionCreateInfo);
// Provoking vertex is supported.
// provokingVertexFeatures->provokingVertexLast can be VK_TRUE or VK_FALSE.
// No action needs to be taken on our end in either case; it's the apps responsibility to check
// that the provokingVertexLast feature is enabled before using the provoking vertex convention.
(void)provokingVertexFeatures->provokingVertexLast;
}
default: default:
// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]" // "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType)); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here. UNIMPLEMENTED("extensionCreateInfo->sType %d", int(extensionCreateInfo->sType)); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
...@@ -2434,7 +2448,9 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physi ...@@ -2434,7 +2448,9 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physi
VkBaseOutStructure* extensionProperties = reinterpret_cast<VkBaseOutStructure*>(pProperties->pNext); VkBaseOutStructure* extensionProperties = reinterpret_cast<VkBaseOutStructure*>(pProperties->pNext);
while(extensionProperties) while(extensionProperties)
{ {
// Casting to a long since some structures, such as VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID // Casting to a long since some structures, such as
// VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID and
// VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT
// are not enumerated in the official Vulkan header // are not enumerated in the official Vulkan header
switch((long)(extensionProperties->sType)) switch((long)(extensionProperties->sType))
{ {
...@@ -2503,6 +2519,12 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physi ...@@ -2503,6 +2519,12 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physi
vk::Cast(physicalDevice)->getProperties(&properties); vk::Cast(physicalDevice)->getProperties(&properties);
} }
break; break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT:
{
auto& properties = *reinterpret_cast<VkPhysicalDeviceProvokingVertexPropertiesEXT*>(extensionProperties);
vk::Cast(physicalDevice)->getProperties(&properties);
}
break;
default: default:
// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]" // "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
UNIMPLEMENTED("extensionProperties->sType"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here. UNIMPLEMENTED("extensionProperties->sType"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment