layers: Chassis custom CreateGfxPipelines handling
For the chassis to support the core_validation implementation of
CreateGraphicsPipelines, some custom local stack data is necessary
along with the modification of a parameter.
Change-Id: Iebb34aaba02d521790b62d61de37812a107393b8
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 0383eda..7334aaf 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -5217,13 +5217,12 @@
bool PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
const VkGraphicsPipelineCreateInfo *pCreateInfos,
const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
- // Default parameter
- create_graphics_pipeline_api_state *cgpl_state) {
+ void *cgpl_state_data) {
layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
bool skip = false;
+ create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
cgpl_state->pipe_state.reserve(count);
- // TODO - State changes and validation need to be untangled here -- potentially a performance issue
for (uint32_t i = 0; i < count; i++) {
cgpl_state->pipe_state.push_back(std::unique_ptr<PIPELINE_STATE>(new PIPELINE_STATE));
(cgpl_state->pipe_state)[i]->initGraphicsPipeline(&pCreateInfos[i],
@@ -5249,10 +5248,9 @@
// GPU validation may replace pCreateInfos for the down-chain call
void PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
- VkPipeline *pPipelines,
- // Default parameter
- create_graphics_pipeline_api_state *cgpl_state) {
+ VkPipeline *pPipelines, void *cgpl_state_data) {
layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
cgpl_state->pCreateInfos = pCreateInfos;
// GPU Validation may replace instrumented shaders with non-instrumented ones, so allow it to modify the createinfos.
if (GetEnables(device_data)->gpu_validation) {
@@ -5265,9 +5263,9 @@
void PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
const VkGraphicsPipelineCreateInfo *pCreateInfos,
const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines, VkResult result,
- // Default parameter
- create_graphics_pipeline_api_state *cgpl_state) {
+ void *cgpl_state_data) {
layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
// This API may create pipelines regardless of the return value
for (uint32_t i = 0; i < count; i++) {
if (pPipelines[i] != VK_NULL_HANDLE) {
diff --git a/layers/core_validation.h b/layers/core_validation.h
index f9157fb..60d3c62 100644
--- a/layers/core_validation.h
+++ b/layers/core_validation.h
@@ -1396,19 +1396,14 @@
bool PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
const VkGraphicsPipelineCreateInfo* pCreateInfos,
- const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines,
- // Default parameter
- create_graphics_pipeline_api_state* cgpl_state);
+ const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* cgpl_state);
void PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator,
- VkPipeline* pPipelines,
- // Default parameter
- create_graphics_pipeline_api_state* cgpl_state);
+ VkPipeline* pPipelines, void* cgpl_state);
void PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
const VkGraphicsPipelineCreateInfo* pCreateInfos,
const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, VkResult result,
- // Default parameter
- create_graphics_pipeline_api_state* cgpl_state);
+ void* cgpl_state);
bool PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator,
VkPipeline* pPipelines,
diff --git a/scripts/layer_chassis_generator.py b/scripts/layer_chassis_generator.py
index fc9c0bd..05fa0c3 100644
--- a/scripts/layer_chassis_generator.py
+++ b/scripts/layer_chassis_generator.py
@@ -136,6 +136,8 @@
'vkEnumerateInstanceExtensionProperties',
'vkEnumerateDeviceLayerProperties',
'vkEnumerateDeviceExtensionProperties',
+ # Functions that are handled explicitly due to chassis architecture violations
+ 'vkCreateGraphicsPipelines',
# ValidationCache functions do not get dispatched
'vkCreateValidationCacheEXT',
'vkDestroyValidationCacheEXT',
@@ -751,7 +753,45 @@
}
+// Special-case APIs for which core_validation needs custom parameter lists and/or modifies parameters
+VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines) {
+ auto layer_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ bool skip = false;
+
+#ifdef BUILD_CORE_VALIDATION
+ create_graphics_pipeline_api_state cgpl_state{};
+#else
+ struct create_graphics_pipeline_api_state {
+ const VkGraphicsPipelineCreateInfo* pCreateInfos;
+ } cgpl_state;
+ cgpl_state.pCreateInfos = pCreateInfos;
+#endif
+
+ for (auto intercept : layer_data->object_dispatch) {
+ auto lock = intercept->write_lock();
+ skip |= intercept->PreCallValidateCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, &cgpl_state);
+ if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
+ }
+ for (auto intercept : layer_data->object_dispatch) {
+ auto lock = intercept->write_lock();
+ intercept->PreCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, &cgpl_state);
+ }
+
+ VkResult result = DispatchCreateGraphicsPipelines(layer_data, device, pipelineCache, createInfoCount, cgpl_state.pCreateInfos, pAllocator, pPipelines);
+
+ for (auto intercept : layer_data->object_dispatch) {
+ auto lock = intercept->write_lock();
+ intercept->PostCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result, &cgpl_state);
+ }
+ return result;
+}
VKAPI_ATTR VkResult VKAPI_CALL CreateValidationCacheEXT(
VkDevice device,
@@ -820,6 +860,18 @@
virtual void CoreLayerDestroyValidationCacheEXT(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator) {};
virtual VkResult CoreLayerMergeValidationCachesEXT(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches) { return VK_SUCCESS; };
virtual VkResult CoreLayerGetValidationCacheDataEXT(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData) { return VK_SUCCESS; };
+
+ // Allow additional parameter for CreateGraphicsPipelines
+ virtual bool PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* cgpl_state) {
+ return PreCallValidateCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+ };
+ virtual void PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, void* cgpl_state) {
+ PreCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+ };
+ virtual void PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines, VkResult result, void* cgpl_state) {
+ PostCallRecordCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, result);
+ };
+
"""
inline_custom_source_postamble = """