From 0a35dcdff977a6665e1ea0d38ab11a4fa4a46cfd Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Sun, 28 Jun 2015 13:01:17 -0600 Subject: bug 14014: Fill out support for VkShaderModule Updated tests and demos to properly use VkShaderModule. Add support to shader_checker for shader module. Doesn't do anything with the pName parameter. --- demos/tri.c | 55 ++++++++++++++++------------ include/vkLayer.h | 1 - include/vulkan.h | 4 +-- layers/draw_state.cpp | 2 +- layers/layer_logging.h | 7 +++- layers/layers_table.cpp | 1 - layers/param_checker.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++---- layers/shader_checker.cpp | 63 +++++++++++++++++++++++--------- loader/table_ops.h | 1 - vk-layer-generate.py | 1 + 10 files changed, 173 insertions(+), 54 deletions(-) diff --git a/demos/tri.c b/demos/tri.c index 9a3c5f5f..6e291a2c 100644 --- a/demos/tri.c +++ b/demos/tri.c @@ -827,42 +827,53 @@ static VkShader demo_prepare_shader(struct demo *demo, const void *code, size_t size) { - VkShaderCreateInfo createInfo; + VkShaderModuleCreateInfo moduleCreateInfo; + VkShaderCreateInfo shaderCreateInfo; + VkShaderModule shaderModule; VkShader shader; VkResult err; - createInfo.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO; - createInfo.pNext = NULL; + + moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleCreateInfo.pNext = NULL; + + shaderCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO; + shaderCreateInfo.pNext = NULL; if (!demo->use_glsl) { - createInfo.codeSize = size; - createInfo.pCode = code; - createInfo.flags = 0; - - err = vkCreateShader(demo->device, &createInfo, &shader); - if (err) { - free((void *)createInfo.pCode); - } + moduleCreateInfo.codeSize = size; + moduleCreateInfo.pCode = code; + moduleCreateInfo.flags = 0; + err = vkCreateShaderModule(demo->device, &moduleCreateInfo, &shaderModule); + if (err) { + free((void *) moduleCreateInfo.pCode); + } + + shaderCreateInfo.flags = 0; + shaderCreateInfo.module = shaderModule; + err = vkCreateShader(demo->device, &shaderCreateInfo, &shader); } else { // Create fake SPV structure to feed GLSL // to the driver "under the covers" - createInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; - createInfo.pCode = malloc(createInfo.codeSize); - createInfo.flags = 0; + moduleCreateInfo.codeSize = 3 * sizeof(uint32_t) + size + 1; + moduleCreateInfo.pCode = malloc(moduleCreateInfo.codeSize); + moduleCreateInfo.flags = 0; /* try version 0 first: VkShaderStage followed by GLSL */ - ((uint32_t *) createInfo.pCode)[0] = ICD_SPV_MAGIC; - ((uint32_t *) createInfo.pCode)[1] = 0; - ((uint32_t *) createInfo.pCode)[2] = stage; - memcpy(((uint32_t *) createInfo.pCode + 3), code, size + 1); + ((uint32_t *) moduleCreateInfo.pCode)[0] = ICD_SPV_MAGIC; + ((uint32_t *) moduleCreateInfo.pCode)[1] = 0; + ((uint32_t *) moduleCreateInfo.pCode)[2] = stage; + memcpy(((uint32_t *) moduleCreateInfo.pCode + 3), code, size + 1); - err = vkCreateShader(demo->device, &createInfo, &shader); + err = vkCreateShaderModule(demo->device, &moduleCreateInfo, &shaderModule); if (err) { - free((void *) createInfo.pCode); - return VK_NULL_HANDLE; + free((void *) moduleCreateInfo.pCode); } - } + shaderCreateInfo.flags = 0; + shaderCreateInfo.module = shaderModule; + err = vkCreateShader(demo->device, &shaderCreateInfo, &shader); + } return shader; } diff --git a/include/vkLayer.h b/include/vkLayer.h index e456a9cb..154472c1 100644 --- a/include/vkLayer.h +++ b/include/vkLayer.h @@ -141,7 +141,6 @@ typedef struct VkLayerInstanceDispatchTable_ PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkCreateInstance CreateInstance; PFN_vkDestroyInstance DestroyInstance; - PFN_vkCreateDevice CreateDevice; PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices; PFN_vkGetPhysicalDeviceFeatures GetPhysicalDeviceFeatures; PFN_vkGetPhysicalDeviceFormatInfo GetPhysicalDeviceFormatInfo; diff --git a/include/vulkan.h b/include/vulkan.h index bf721bda..874caf42 100644 --- a/include/vulkan.h +++ b/include/vulkan.h @@ -1593,9 +1593,7 @@ typedef struct VkShaderCreateInfo_ VkStructureType sType; // Must be VK_STRUCTURE_TYPE_SHADER_CREATE_INFO const void* pNext; // Pointer to next structure VkShaderModule module; // Module containing entry point - const char* name; // Null-terminate entry point name - size_t codeSize; // Specified in bytes - const void* pCode; + const char* pName; // Null-terminate entry point name VkShaderCreateFlags flags; // Reserved } VkShaderCreateInfo; diff --git a/layers/draw_state.cpp b/layers/draw_state.cpp index ee891d62..48b65391 100644 --- a/layers/draw_state.cpp +++ b/layers/draw_state.cpp @@ -1556,7 +1556,7 @@ VK_LAYER_EXPORT VkResult VKAPI vkDestroyInstance(VkInstance instance) layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback); } - layer_debug_report_destroy_instance(mid(instance)); + layer_debug_report_destroy_instance(my_data->report_data); layer_data_map.erase(pTable); draw_state_instance_table_map.erase(key); diff --git a/layers/layer_logging.h b/layers/layer_logging.h index bcae4d90..68f5f89b 100644 --- a/layers/layer_logging.h +++ b/layers/layer_logging.h @@ -99,9 +99,14 @@ static inline debug_report_data *debug_report_create_instance( static inline void layer_debug_report_destroy_instance(debug_report_data *debug_data) { - VkLayerDbgFunctionNode *pTrav = debug_data->g_pDbgFunctionHead; + VkLayerDbgFunctionNode *pTrav; VkLayerDbgFunctionNode *pTravNext; + if (!debug_data) { + return; + } + + pTrav = debug_data->g_pDbgFunctionHead; /* Clear out any leftover callbacks */ while (pTrav) { pTravNext = pTrav->pNext; diff --git a/layers/layers_table.cpp b/layers/layers_table.cpp index 51baf2eb..5d1b9cf9 100644 --- a/layers/layers_table.cpp +++ b/layers/layers_table.cpp @@ -95,7 +95,6 @@ void destroy_instance_dispatch_table(dispatch_key key) VkLayerDispatchTable *get_dispatch_table(device_table_map &map, VkObject object) { -// VkLayerDispatchTable *pDisp = *(VkLayerDispatchTable **) object; dispatch_key key = get_dispatch_key(object); device_table_map::const_iterator it = map.find((void *) key); #if DISPATCH_MAP_DEBUG diff --git a/layers/param_checker.cpp b/layers/param_checker.cpp index 22ca3e08..8fa33ceb 100644 --- a/layers/param_checker.cpp +++ b/layers/param_checker.cpp @@ -4538,6 +4538,90 @@ VK_LAYER_EXPORT VkResult VKAPI vkCreateDepthStencilView( return result; } +void PreCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo) +{ + if(device == nullptr) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, VkDevice device, is null pointer"); + return; + } + + if(pCreateInfo == nullptr) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, const VkShaderCreateInfo* pCreateInfo, is null pointer"); + return; + } + if(pCreateInfo->sType < VK_STRUCTURE_TYPE_BEGIN_RANGE || + pCreateInfo->sType > VK_STRUCTURE_TYPE_END_RANGE) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, VkStructureType pCreateInfo->sType, is unrecognized enumerator"); + return; + } + if(pCreateInfo->pCode == nullptr) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, const void* pCreateInfo->pCode, is null pointer"); + return; + } + if(pCreateInfo->codeSize == 0) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, size_t pCreateInfo->codeSize, is zero"); + return; + } +} + +void PostCreateShaderModule( + VkDevice device, + VkShaderModule* pShaderModule, + VkResult result) +{ + if(device == nullptr) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, VkDevice device, is null pointer"); + return; + } + + if(pShaderModule == nullptr) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, VkShader* pShader, is null pointer"); + return; + } + if((*pShaderModule) == nullptr) + { + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", + "vkCreateShaderModule parameter, VkShader* pShader, is null pointer"); + return; + } + + if(result != VK_SUCCESS) + { + std::string reason = "vkCreateShaderModule parameter, VkResult result, is " + EnumeratorString(result); + log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", reason.c_str()); + return; + } +} + +VK_LAYER_EXPORT VkResult VKAPI vkCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + VkShaderModule* pShaderModule) +{ + PreCreateShaderModule(device, pCreateInfo); + VkResult result = get_dispatch_table(pc_device_table_map, device)->CreateShaderModule(device, pCreateInfo, pShaderModule); + + PostCreateShaderModule(device, pShaderModule, result); + + return result; +} + void PreCreateShader( VkDevice device, const VkShaderCreateInfo* pCreateInfo) @@ -4568,18 +4652,12 @@ void PreCreateShader( "vkCreateShader parameter, VkShaderModule pCreateInfo->module, is null pointer"); return; } - if(pCreateInfo->name == nullptr) + if(pCreateInfo->pName == nullptr) { log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", "vkCreateShader parameter, const char* pCreateInfo->name, is null pointer"); return; } - if(pCreateInfo->pCode == nullptr) - { - log_msg(mdd(device), VK_DBG_REPORT_WARN_BIT, (VkObjectType)0, NULL, 0, 1, "PARAMCHECK", - "vkCreateShader parameter, const void* pCreateInfo->pCode, is null pointer"); - return; - } } void PostCreateShader( diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index 62511227..df89d3c1 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "loader_platform.h" #include "vk_dispatch_table_helper.h" #include "vkLayer.h" @@ -92,7 +93,7 @@ build_type_def_index(std::vector const &words, std::unordered_map words; /* a mapping of to the first word of its def. this is useful because walking type @@ -101,7 +102,7 @@ struct shader_source { std::unordered_map type_def_index; bool is_spirv; - shader_source(VkShaderCreateInfo const *pCreateInfo) : + shader_module(VkShaderModuleCreateInfo const *pCreateInfo) : words((uint32_t *)pCreateInfo->pCode, (uint32_t *)pCreateInfo->pCode + pCreateInfo->codeSize / sizeof(uint32_t)), type_def_index(), is_spirv(true) { @@ -119,7 +120,19 @@ struct shader_source { }; -static std::unordered_map shader_map; +static std::unordered_map shader_module_map; + +struct shader_object { + std::string name; + struct shader_module *module; + + shader_object(VkShaderCreateInfo const *pCreateInfo) + { + module = shader_module_map[pCreateInfo->module]; + name = pCreateInfo->pName; + } +}; +static std::unordered_map shader_object_map; static void @@ -221,7 +234,7 @@ storage_class_name(unsigned sc) /* returns ptr to null terminator */ static char * -describe_type(char *dst, shader_source const *src, unsigned type) +describe_type(char *dst, shader_module const *src, unsigned type) { auto type_def_it = src->type_def_index.find(type); @@ -267,7 +280,7 @@ describe_type(char *dst, shader_source const *src, unsigned type) static bool -types_match(shader_source const *a, shader_source const *b, unsigned a_type, unsigned b_type, bool b_arrayed) +types_match(shader_module const *a, shader_module const *b, unsigned a_type, unsigned b_type, bool b_arrayed) { auto a_type_def_it = a->type_def_index.find(a_type); auto b_type_def_it = b->type_def_index.find(b_type); @@ -368,7 +381,7 @@ struct interface_var { static void -collect_interface_by_location(shader_source const *src, spv::StorageClass sinterface, +collect_interface_by_location(shader_module const *src, spv::StorageClass sinterface, std::map &out, std::map &builtins_out) { @@ -436,21 +449,35 @@ collect_interface_by_location(shader_source const *src, spv::StorageClass sinter } -VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(VkDevice device, const VkShaderCreateInfo *pCreateInfo, - VkShader *pShader) +VK_LAYER_EXPORT VkResult VKAPI vkCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo *pCreateInfo, + VkShaderModule *pShaderModule) { loader_platform_thread_lock_mutex(&globalLock); - VkResult res = device_dispatch_table(device)->CreateShader(device, pCreateInfo, pShader); + VkResult res = device_dispatch_table(device)->CreateShaderModule(device, pCreateInfo, pShaderModule); - shader_map[(VkBaseLayerObject *) *pShader] = new shader_source(pCreateInfo); + shader_module_map[(VkBaseLayerObject *) *pShaderModule] = new shader_module(pCreateInfo); loader_platform_thread_unlock_mutex(&globalLock); return res; } +VK_LAYER_EXPORT VkResult VKAPI vkCreateShader( + VkDevice device, + const VkShaderCreateInfo *pCreateInfo, + VkShader *pShader) +{ + loader_platform_thread_lock_mutex(&globalLock); + VkResult res = device_dispatch_table(device)->CreateShader(device, pCreateInfo, pShader); + + shader_object_map[(VkBaseLayerObject *) *pShader] = new shader_object(pCreateInfo); + loader_platform_thread_unlock_mutex(&globalLock); + return res; +} static bool -validate_interface_between_stages(shader_source const *producer, char const *producer_name, - shader_source const *consumer, char const *consumer_name, +validate_interface_between_stages(shader_module const *producer, char const *producer_name, + shader_module const *consumer, char const *consumer_name, bool consumer_arrayed_input) { std::map outputs; @@ -568,7 +595,7 @@ get_format_type(VkFormat fmt) { /* characterizes a SPIR-V type appearing in an interface to a FF stage, * for comparison to a VkFormat's characterization above. */ static unsigned -get_fundamental_type(shader_source const *src, unsigned type) +get_fundamental_type(shader_module const *src, unsigned type) { auto type_def_it = src->type_def_index.find(type); @@ -625,7 +652,7 @@ validate_vi_consistency(VkPipelineVertexInputStateCreateInfo const *vi) static bool -validate_vi_against_vs_inputs(VkPipelineVertexInputStateCreateInfo const *vi, shader_source const *vs) +validate_vi_against_vs_inputs(VkPipelineVertexInputStateCreateInfo const *vi, shader_module const *vs) { std::map inputs; /* we collect builtin inputs, but they will never appear in the VI state -- @@ -688,7 +715,7 @@ validate_vi_against_vs_inputs(VkPipelineVertexInputStateCreateInfo const *vi, sh static bool -validate_fs_outputs_against_cb(shader_source const *fs, VkPipelineCbStateCreateInfo const *cb) +validate_fs_outputs_against_cb(shader_module const *fs, VkPipelineCbStateCreateInfo const *cb) { std::map outputs; std::map builtin_outputs; @@ -786,7 +813,7 @@ validate_graphics_pipeline(VkGraphicsPipelineCreateInfo const *pCreateInfo) /* We seem to allow pipeline stages to be specified out of order, so collect and identify them * before trying to do anything more: */ - shader_source const *shaders[VK_SHADER_STAGE_FRAGMENT + 1]; /* exclude CS */ + shader_module const *shaders[VK_SHADER_STAGE_FRAGMENT + 1]; /* exclude CS */ memset(shaders, 0, sizeof(shaders)); VkPipelineCbStateCreateInfo const *cb = 0; VkPipelineVertexInputStateCreateInfo const *vi = 0; @@ -804,7 +831,8 @@ validate_graphics_pipeline(VkGraphicsPipelineCreateInfo const *pCreateInfo) layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_UNKNOWN_STAGE, "SC", str); } else { - shaders[pStage->stage] = shader_map[(void *)(pStage->shader)]; + struct shader_object *shader = shader_object_map[(void *) pStage->shader]; + shaders[pStage->stage] = shader->module; } } } @@ -969,6 +997,7 @@ VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pN if (!strncmp(#fn, pName, sizeof(#fn))) \ return (void *) fn + ADD_HOOK(vkCreateShaderModule); ADD_HOOK(vkCreateShader); ADD_HOOK(vkDestroyDevice); ADD_HOOK(vkCreateGraphicsPipeline); diff --git a/loader/table_ops.h b/loader/table_ops.h index a29324fd..be5f691f 100644 --- a/loader/table_ops.h +++ b/loader/table_ops.h @@ -362,7 +362,6 @@ static inline void loader_init_instance_core_dispatch_table(VkLayerInstanceDispa table->CreateInstance = (PFN_vkCreateInstance) gpa(inst, "vkCreateInstance"); table->DestroyInstance = (PFN_vkDestroyInstance) gpa(inst, "vkDestroyInstance"); - table->CreateDevice = (PFN_vkCreateDevice) gpa(inst, "vkCreateDevice"); table->EnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices) gpa(inst, "vkEnumeratePhysicalDevices"); table->GetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures) gpa(inst, "vkGetPhysicalDeviceFeatures"); table->GetPhysicalDeviceFormatInfo = (PFN_vkGetPhysicalDeviceFormatInfo) gpa(inst, "vkGetPhysicalDeviceFormatInfo"); diff --git a/vk-layer-generate.py b/vk-layer-generate.py index 34340b55..f2804f65 100755 --- a/vk-layer-generate.py +++ b/vk-layer-generate.py @@ -1102,6 +1102,7 @@ class ObjectTrackerSubcommand(Subcommand): obj_type_mapping[objectName] = ucc_to_U_C_C(objectTypeEnum); # Command Buffer Object doesn't follow the rule. obj_type_mapping['VkCmdBuffer'] = "VK_OBJECT_TYPE_COMMAND_BUFFER" + obj_type_mapping['VkShaderModule'] = "VK_OBJECT_TYPE_SHADER_MODULE" explicit_object_tracker_functions = [ "CreateInstance", -- cgit v1.2.3