layers: Update ShaderChecker to use new logging mechanism
V2: Rebase, fix issues with log_msg args, delete more old junk.
Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp
index aa0153f..170b96e 100644
--- a/layers/shader_checker.cpp
+++ b/layers/shader_checker.cpp
@@ -35,6 +35,7 @@
#include "vk_layer_config.h"
#include "vk_layer_msg.h"
#include "vk_layer_table.h"
+#include "vk_layer_logging.h"
#include "vk_enum_string_helper.h"
#include "shader_checker.h"
// The following is #included again to catch certain OS-specific functions
@@ -45,6 +46,41 @@
#include "spirv/spirv.h"
+typedef struct _layer_data {
+ debug_report_data *report_data;
+ // TODO: put instance data here
+ VkDbgMsgCallback logging_callback;
+} layer_data;
+
+static std::unordered_map<void *, layer_data *> layer_data_map;
+static device_table_map shader_checker_device_table_map;
+static instance_table_map shader_checker_instance_table_map;
+
+
+template layer_data *get_my_data_ptr<layer_data>(
+ void *data_key,
+ std::unordered_map<void *, layer_data *> &data_map);
+
+debug_report_data *mdd(VkObject object)
+{
+ dispatch_key key = get_dispatch_key(object);
+ layer_data *my_data = get_my_data_ptr(key, layer_data_map);
+#if DISPATCH_MAP_DEBUG
+ fprintf(stderr, "MDD: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
+#endif
+ return my_data->report_data;
+}
+
+debug_report_data *mid(VkInstance object)
+{
+ dispatch_key key = get_dispatch_key(object);
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(object), layer_data_map);
+#if DISPATCH_MAP_DEBUG
+ fprintf(stderr, "MID: map: %p, object: %p, key: %p, data: %p\n", &layer_data_map, object, key, my_data);
+#endif
+ return my_data->report_data;
+}
+
static LOADER_PLATFORM_THREAD_ONCE_DECLARATION(g_initOnce);
// TODO : This can be much smarter, using separate locks for separate global data
static int globalLockInitialized = 0;
@@ -103,14 +139,14 @@
std::unordered_map<unsigned, unsigned> type_def_index;
bool is_spirv;
- shader_module(VkShaderModuleCreateInfo const *pCreateInfo) :
+ shader_module(VkDevice dev, VkShaderModuleCreateInfo const *pCreateInfo) :
words((uint32_t *)pCreateInfo->pCode, (uint32_t *)pCreateInfo->pCode + pCreateInfo->codeSize / sizeof(uint32_t)),
type_def_index(),
is_spirv(true) {
if (words.size() < 5 || words[0] != spv::MagicNumber || words[1] != spv::Version) {
- layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_NON_SPIRV_SHADER, "SC",
- "Shader is not SPIR-V, most checks will not be possible");
+ log_msg(mdd(dev), VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_NON_SPIRV_SHADER, "SC",
+ "Shader is not SPIR-V, most checks will not be possible");
is_spirv = false;
return;
}
@@ -137,22 +173,38 @@
static void
-initLayer()
+init_shader_checker(layer_data *my_data)
{
- const char *strOpt;
+ uint32_t report_flags = 0;
+ uint32_t debug_action = 0;
+ FILE *log_output = NULL;
+ const char *option_str;
// initialize ShaderChecker options
- getLayerOptionEnum("ShaderCheckerReportLevel", (uint32_t *) &g_reportFlags);
- g_actionIsDefault = getLayerOptionEnum("ShaderCheckerDebugAction", (uint32_t *) &g_debugAction);
+ report_flags = getLayerOptionFlags("ShaderCheckerReportFlags", 0);
+ getLayerOptionEnum("ShaderCheckerDebugAction", (uint32_t *) &debug_action);
- if (g_debugAction & VK_DBG_LAYER_ACTION_LOG_MSG)
+ if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG)
{
- strOpt = getLayerOption("ShaderCheckerLogFilename");
- if (strOpt)
+ option_str = getLayerOption("ShaderCheckerLogFilename");
+ if (option_str)
{
- g_logFile = fopen(strOpt, "w");
+ log_output = fopen(option_str, "w");
}
- if (g_logFile == NULL)
- g_logFile = stdout;
+ if (log_output == NULL)
+ log_output = stdout;
+
+ layer_create_msg_callback(my_data->report_data, report_flags, log_callback, (void *) log_output, &my_data->logging_callback);
+ }
+
+ if (!globalLockInitialized)
+ {
+ // TODO/TBD: Need to delete this mutex sometime. How??? One
+ // suggestion is to call this during vkCreateInstance(), and then we
+ // can clean it up during vkDestroyInstance(). However, that requires
+ // that the layer have per-instance locks. We need to come back and
+ // address this soon.
+ loader_platform_thread_create_mutex(&globalLock);
+ globalLockInitialized = 1;
}
}
@@ -373,7 +425,8 @@
static void
-collect_interface_by_location(shader_module const *src, spv::StorageClass sinterface,
+collect_interface_by_location(VkDevice dev,
+ shader_module const *src, spv::StorageClass sinterface,
std::map<uint32_t, interface_var> &out,
std::map<uint32_t, interface_var> &builtins_out)
{
@@ -415,10 +468,9 @@
* The spec says nothing about how this case works (or doesn't)
* for interface matching.
*/
- char str[1024];
- sprintf(str, "var %d (type %d) in %s interface has no Location or Builtin decoration\n",
- code[word+2], code[word+1], storage_class_name(sinterface));
- layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC",
+ "var %d (type %d) in %s interface has no Location or Builtin decoration",
+ code[word+2], code[word+1], storage_class_name(sinterface));
}
else if (location != -1) {
/* A user-defined interface variable, with a location. */
@@ -447,9 +499,9 @@
VkShaderModule *pShaderModule)
{
loader_platform_thread_lock_mutex(&globalLock);
- VkResult res = device_dispatch_table(device)->CreateShaderModule(device, pCreateInfo, pShaderModule);
+ VkResult res = get_dispatch_table(shader_checker_device_table_map, device)->CreateShaderModule(device, pCreateInfo, pShaderModule);
- shader_module_map[(VkBaseLayerObject *) *pShaderModule] = new shader_module(pCreateInfo);
+ shader_module_map[(VkBaseLayerObject *) *pShaderModule] = new shader_module(device, pCreateInfo);
loader_platform_thread_unlock_mutex(&globalLock);
return res;
}
@@ -460,7 +512,7 @@
VkShader *pShader)
{
loader_platform_thread_lock_mutex(&globalLock);
- VkResult res = device_dispatch_table(device)->CreateShader(device, pCreateInfo, pShader);
+ VkResult res = get_dispatch_table(shader_checker_device_table_map, device)->CreateShader(device, pCreateInfo, pShader);
shader_object_map[(VkBaseLayerObject *) *pShader] = new shader_object(pCreateInfo);
loader_platform_thread_unlock_mutex(&globalLock);
@@ -468,7 +520,8 @@
}
static bool
-validate_interface_between_stages(shader_module const *producer, char const *producer_name,
+validate_interface_between_stages(VkDevice dev,
+ shader_module const *producer, char const *producer_name,
shader_module const *consumer, char const *consumer_name,
bool consumer_arrayed_input)
{
@@ -481,8 +534,8 @@
char str[1024];
bool pass = true;
- collect_interface_by_location(producer, spv::StorageClassOutput, outputs, builtin_outputs);
- collect_interface_by_location(consumer, spv::StorageClassInput, inputs, builtin_inputs);
+ collect_interface_by_location(dev, producer, spv::StorageClassOutput, outputs, builtin_outputs);
+ collect_interface_by_location(dev, consumer, spv::StorageClassInput, inputs, builtin_inputs);
auto a_it = outputs.begin();
auto b_it = inputs.begin();
@@ -495,15 +548,13 @@
auto b_first = b_at_end ? 0 : b_it->first;
if (b_at_end || a_first < b_first) {
- sprintf(str, "%s writes to output location %d which is not consumed by %s\n",
- producer_name, a_first, consumer_name);
- layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC",
+ "%s writes to output location %d which is not consumed by %s", producer_name, a_first, consumer_name);
a_it++;
}
else if (a_at_end || a_first > b_first) {
- sprintf(str, "%s consumes input location %d which is not written by %s\n",
- consumer_name, b_first, producer_name);
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC",
+ "%s consumes input location %d which is not written by %s", consumer_name, b_first, producer_name);
pass = false;
b_it++;
}
@@ -517,9 +568,8 @@
describe_type(producer_type, producer, a_it->second.type_id);
describe_type(consumer_type, consumer, b_it->second.type_id);
- sprintf(str, "Type mismatch on location %d: '%s' vs '%s'\n", a_it->first,
- producer_type, consumer_type);
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
+ "Type mismatch on location %d: '%s' vs '%s'", a_it->first, producer_type, consumer_type);
pass = false;
}
a_it++;
@@ -617,21 +667,20 @@
static bool
-validate_vi_consistency(VkPipelineVertexInputStateCreateInfo const *vi)
+validate_vi_consistency(VkDevice dev, VkPipelineVertexInputStateCreateInfo const *vi)
{
/* walk the binding descriptions, which describe the step rate and stride of each vertex buffer.
* each binding should be specified only once.
*/
std::unordered_map<uint32_t, VkVertexInputBindingDescription const *> bindings;
- char str[1024];
bool pass = true;
for (unsigned i = 0; i < vi->bindingCount; i++) {
auto desc = &vi->pVertexBindingDescriptions[i];
auto & binding = bindings[desc->binding];
if (binding) {
- sprintf(str, "Duplicate vertex input binding descriptions for binding %d", desc->binding);
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INCONSISTENT_VI, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INCONSISTENT_VI, "SC",
+ "Duplicate vertex input binding descriptions for binding %d", desc->binding);
pass = false;
}
else {
@@ -644,17 +693,16 @@
static bool
-validate_vi_against_vs_inputs(VkPipelineVertexInputStateCreateInfo const *vi, shader_module const *vs)
+validate_vi_against_vs_inputs(VkDevice dev, VkPipelineVertexInputStateCreateInfo const *vi, shader_module const *vs)
{
std::map<uint32_t, interface_var> inputs;
/* we collect builtin inputs, but they will never appear in the VI state --
* the vs builtin inputs are generated in the pipeline, not sourced from buffers (VertexID, etc)
*/
std::map<uint32_t, interface_var> builtin_inputs;
- char str[1024];
bool pass = true;
- collect_interface_by_location(vs, spv::StorageClassInput, inputs, builtin_inputs);
+ collect_interface_by_location(dev, vs, spv::StorageClassInput, inputs, builtin_inputs);
/* Build index by location */
std::map<uint32_t, VkVertexInputAttributeDescription const *> attribs;
@@ -672,13 +720,13 @@
auto a_first = a_at_end ? 0 : it_a->first;
auto b_first = b_at_end ? 0 : it_b->first;
if (b_at_end || a_first < b_first) {
- sprintf(str, "Vertex attribute at location %d not consumed by VS", a_first);
- layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC",
+ "Vertex attribute at location %d not consumed by VS", a_first);
it_a++;
}
else if (a_at_end || b_first < a_first) {
- sprintf(str, "VS consumes input at location %d but not provided", b_first);
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC",
+ "VS consumes input at location %d but not provided", b_first);
pass = false;
it_b++;
}
@@ -690,9 +738,9 @@
if (attrib_type != FORMAT_TYPE_UNDEFINED && input_type != FORMAT_TYPE_UNDEFINED && attrib_type != input_type) {
char vs_type[1024];
describe_type(vs_type, vs, it_b->second.type_id);
- sprintf(str, "Attribute type of `%s` at location %d does not match VS input type of `%s`",
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
+ "Attribute type of `%s` at location %d does not match VS input type of `%s`",
string_VkFormat(it_a->second->format), a_first, vs_type);
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
pass = false;
}
@@ -707,32 +755,31 @@
static bool
-validate_fs_outputs_against_cb(shader_module const *fs, VkPipelineCbStateCreateInfo const *cb)
+validate_fs_outputs_against_cb(VkDevice dev, shader_module const *fs, VkPipelineCbStateCreateInfo const *cb)
{
std::map<uint32_t, interface_var> outputs;
std::map<uint32_t, interface_var> builtin_outputs;
- char str[1024];
bool pass = true;
/* TODO: dual source blend index (spv::DecIndex, zero if not provided) */
- collect_interface_by_location(fs, spv::StorageClassOutput, outputs, builtin_outputs);
+ collect_interface_by_location(dev, fs, spv::StorageClassOutput, outputs, builtin_outputs);
/* Check for legacy gl_FragColor broadcast: In this case, we should have no user-defined outputs,
* and all color attachment should be UNORM/SNORM/FLOAT.
*/
if (builtin_outputs.find(spv::BuiltInFragColor) != builtin_outputs.end()) {
if (outputs.size()) {
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_FS_MIXED_BROADCAST, "SC",
- "Should not have user-defined FS outputs when using broadcast");
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_FS_MIXED_BROADCAST, "SC",
+ "Should not have user-defined FS outputs when using broadcast");
pass = false;
}
for (unsigned i = 0; i < cb->attachmentCount; i++) {
unsigned attachmentType = get_format_type(cb->pAttachments[i].format);
if (attachmentType == FORMAT_TYPE_SINT || attachmentType == FORMAT_TYPE_UINT) {
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
- "CB format should not be SINT or UINT when using broadcast");
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
+ "CB format should not be SINT or UINT when using broadcast");
pass = false;
}
}
@@ -749,13 +796,13 @@
while ((outputs.size() > 0 && it != outputs.end()) || attachment < cb->attachmentCount) {
if (attachment == cb->attachmentCount || ( it != outputs.end() && it->first < attachment)) {
- sprintf(str, "FS writes to output location %d with no matching attachment", it->first);
- layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC",
+ "FS writes to output location %d with no matching attachment", it->first);
it++;
}
else if (it == outputs.end() || it->first > attachment) {
- sprintf(str, "Attachment %d not written by FS", attachment);
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC",
+ "Attachment %d not written by FS", attachment);
attachment++;
pass = false;
}
@@ -767,9 +814,9 @@
if (att_type != FORMAT_TYPE_UNDEFINED && output_type != FORMAT_TYPE_UNDEFINED && att_type != output_type) {
char fs_type[1024];
describe_type(fs_type, fs, it->second.type_id);
- sprintf(str, "Attachment %d of type `%s` does not match FS output type of `%s`",
+ log_msg(mdd(dev), VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
+ "Attachment %d of type `%s` does not match FS output type of `%s`",
attachment, string_VkFormat(cb->pAttachments[attachment].format), fs_type);
- layerCbMsg(VK_DBG_REPORT_ERROR_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC", str);
pass = false;
}
@@ -800,7 +847,7 @@
static bool
-validate_graphics_pipeline(VkGraphicsPipelineCreateInfo const *pCreateInfo)
+validate_graphics_pipeline(VkDevice dev, 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: */
@@ -809,7 +856,6 @@
memset(shaders, 0, sizeof(shaders));
VkPipelineCbStateCreateInfo const *cb = 0;
VkPipelineVertexInputStateCreateInfo const *vi = 0;
- char str[1024];
bool pass = true;
loader_platform_thread_lock_mutex(&globalLock);
@@ -819,8 +865,8 @@
if (pStage->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO) {
if (pStage->stage < VK_SHADER_STAGE_VERTEX || pStage->stage > VK_SHADER_STAGE_FRAGMENT) {
- sprintf(str, "Unknown shader stage %d\n", pStage->stage);
- layerCbMsg(VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_UNKNOWN_STAGE, "SC", str);
+ log_msg(mdd(dev), VK_DBG_REPORT_WARN_BIT, (VkObjectType) 0, NULL, 0, SHADER_CHECKER_UNKNOWN_STAGE, "SC",
+ "Unknown shader stage %d", pStage->stage);
}
else {
struct shader_object *shader = shader_object_map[(void *) pStage->shader];
@@ -833,11 +879,11 @@
vi = pCreateInfo->pVertexInputState;
if (vi) {
- pass = validate_vi_consistency(vi) && pass;
+ pass = validate_vi_consistency(dev, vi) && pass;
}
if (shaders[VK_SHADER_STAGE_VERTEX] && shaders[VK_SHADER_STAGE_VERTEX]->is_spirv) {
- pass = validate_vi_against_vs_inputs(vi, shaders[VK_SHADER_STAGE_VERTEX]) && pass;
+ pass = validate_vi_against_vs_inputs(dev, vi, shaders[VK_SHADER_STAGE_VERTEX]) && pass;
}
/* TODO: enforce rules about present combinations of shaders */
@@ -853,7 +899,8 @@
assert(shaders[producer]);
if (shaders[consumer]) {
if (shaders[producer]->is_spirv && shaders[consumer]->is_spirv) {
- pass = validate_interface_between_stages(shaders[producer], shader_stage_attribs[producer].name,
+ pass = validate_interface_between_stages(dev,
+ shaders[producer], shader_stage_attribs[producer].name,
shaders[consumer], shader_stage_attribs[consumer].name,
shader_stage_attribs[consumer].arrayed_input) && pass;
}
@@ -863,7 +910,7 @@
}
if (shaders[VK_SHADER_STAGE_FRAGMENT] && shaders[VK_SHADER_STAGE_FRAGMENT]->is_spirv && cb) {
- pass = validate_fs_outputs_against_cb(shaders[VK_SHADER_STAGE_FRAGMENT], cb) && pass;
+ pass = validate_fs_outputs_against_cb(dev, shaders[VK_SHADER_STAGE_FRAGMENT], cb) && pass;
}
loader_platform_thread_unlock_mutex(&globalLock);
@@ -876,13 +923,13 @@
const VkGraphicsPipelineCreateInfo *pCreateInfo,
VkPipeline *pPipeline)
{
- bool pass = validate_graphics_pipeline(pCreateInfo);
+ bool pass = validate_graphics_pipeline(device, pCreateInfo);
if (pass) {
/* The driver is allowed to crash if passed junk. Only actually create the
* pipeline if we didn't run into any showstoppers above.
*/
- return device_dispatch_table(device)->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
+ return get_dispatch_table(shader_checker_device_table_map, device)->CreateGraphicsPipeline(device, pCreateInfo, pPipeline);
}
else {
return VK_ERROR_UNKNOWN;
@@ -896,50 +943,58 @@
VkPipeline basePipeline,
VkPipeline *pPipeline)
{
- bool pass = validate_graphics_pipeline(pCreateInfo);
+ bool pass = validate_graphics_pipeline(device, pCreateInfo);
if (pass) {
/* The driver is allowed to crash if passed junk. Only actually create the
* pipeline if we didn't run into any showstoppers above.
*/
- return device_dispatch_table(device)->CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
+ return get_dispatch_table(shader_checker_device_table_map, device)->CreateGraphicsPipelineDerivative(device, pCreateInfo, basePipeline, pPipeline);
}
else {
return VK_ERROR_UNKNOWN;
}
}
+VK_LAYER_EXPORT VkResult VKAPI vkCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice)
+{
+ VkLayerDispatchTable *pDeviceTable = get_dispatch_table(shader_checker_device_table_map, *pDevice);
+ VkResult result = pDeviceTable->CreateDevice(gpu, pCreateInfo, pDevice);
+ if (result == VK_SUCCESS) {
+ layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+ VkLayerDispatchTable *pTable = get_dispatch_table(shader_checker_device_table_map, *pDevice);
+ layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+ my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ }
+ return result;
+}
/* hook DextroyDevice to remove tableMap entry */
VK_LAYER_EXPORT VkResult VKAPI vkDestroyDevice(VkDevice device)
{
dispatch_key key = get_dispatch_key(device);
- VkResult res = device_dispatch_table(device)->DestroyDevice(device);
- destroy_device_dispatch_table(key);
- return res;
+ VkLayerDispatchTable *pDisp = get_dispatch_table(shader_checker_device_table_map, device);
+ VkResult result = pDisp->DestroyDevice(device);
+ shader_checker_device_table_map.erase(key);
+ return result;
}
VkResult VKAPI vkCreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
VkInstance* pInstance)
{
-
- loader_platform_thread_once(&g_initOnce, initLayer);
- /*
- * For layers, the pInstance has already been filled out
- * by the loader so that dispatch table is available.
- */
- VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(*pInstance);
-
+ VkLayerInstanceDispatchTable *pTable = get_dispatch_table(shader_checker_instance_table_map,*pInstance);
VkResult result = pTable->CreateInstance(pCreateInfo, pInstance);
if (result == VK_SUCCESS) {
- enable_debug_report(pCreateInfo->extensionCount, pCreateInfo->ppEnabledExtensionNames);
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+ my_data->report_data = debug_report_create_instance(
+ pTable,
+ *pInstance,
+ pCreateInfo->extensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
- debug_report_init_instance_extension_dispatch_table(
- pTable,
- pTable->GetInstanceProcAddr,
- *pInstance);
+ init_shader_checker(my_data);
}
return result;
}
@@ -948,74 +1003,93 @@
VK_LAYER_EXPORT VkResult VKAPI vkDestroyInstance(VkInstance instance)
{
dispatch_key key = get_dispatch_key(instance);
- VkResult res = instance_dispatch_table(instance)->DestroyInstance(instance);
- destroy_instance_dispatch_table(key);
+ VkLayerInstanceDispatchTable *pTable = get_dispatch_table(shader_checker_instance_table_map, instance);
+ VkResult res = pTable->DestroyInstance(instance);
+
+ // Clean up logging callback, if any
+ layer_data *my_data = get_my_data_ptr(key, layer_data_map);
+ if (my_data->logging_callback) {
+ layer_destroy_msg_callback(my_data->report_data, my_data->logging_callback);
+ }
+
+ layer_debug_report_destroy_instance(my_data->report_data);
+ layer_data_map.erase(pTable);
+
+ shader_checker_instance_table_map.erase(key);
return res;
}
VK_LAYER_EXPORT VkResult VKAPI vkDbgCreateMsgCallback(
- VkInstance instance,
- VkFlags msgFlags,
- const PFN_vkDbgMsgCallback pfnMsgCallback,
- void* pUserData,
- VkDbgMsgCallback* pMsgCallback)
+ VkInstance instance,
+ VkFlags msgFlags,
+ const PFN_vkDbgMsgCallback pfnMsgCallback,
+ void* pUserData,
+ VkDbgMsgCallback* pMsgCallback)
{
- VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(instance);
- return layer_create_msg_callback(instance, pTable, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+ VkLayerInstanceDispatchTable *pTable = get_dispatch_table(shader_checker_instance_table_map, instance);
+ VkResult res = pTable->DbgCreateMsgCallback(instance, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+ if (VK_SUCCESS == res) {
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+ res = layer_create_msg_callback(my_data->report_data, msgFlags, pfnMsgCallback, pUserData, pMsgCallback);
+ }
+ return res;
}
VK_LAYER_EXPORT VkResult VKAPI vkDbgDestroyMsgCallback(
- VkInstance instance,
- VkDbgMsgCallback msgCallback)
+ VkInstance instance,
+ VkDbgMsgCallback msgCallback)
{
- VkLayerInstanceDispatchTable *pTable = instance_dispatch_table(instance);
- return layer_destroy_msg_callback(instance, pTable, msgCallback);
+ VkLayerInstanceDispatchTable *pTable = get_dispatch_table(shader_checker_instance_table_map, instance);
+ VkResult res = pTable->DbgDestroyMsgCallback(instance, msgCallback);
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+ layer_destroy_msg_callback(my_data->report_data, msgCallback);
+ return res;
}
-VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice device, const char* pName)
+VK_LAYER_EXPORT void * VKAPI vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
{
- if (device == NULL)
+ if (dev == NULL)
return NULL;
- loader_platform_thread_once(&g_initOnce, initLayer);
-
/* loader uses this to force layer initialization; device object is wrapped */
- if (!strcmp("vkGetDeviceProcAddr", pName)) {
- initDeviceTable((const VkBaseLayerObject *) device);
+ if (!strcmp("vkGetDeviceProcAddr", funcName)) {
+ initDeviceTable(shader_checker_device_table_map, (const VkBaseLayerObject *) dev);
return (void *) vkGetDeviceProcAddr;
}
#define ADD_HOOK(fn) \
- if (!strncmp(#fn, pName, sizeof(#fn))) \
+ if (!strncmp(#fn, funcName, sizeof(#fn))) \
return (void *) fn
+ ADD_HOOK(vkCreateDevice);
ADD_HOOK(vkCreateShaderModule);
ADD_HOOK(vkCreateShader);
ADD_HOOK(vkDestroyDevice);
ADD_HOOK(vkCreateGraphicsPipeline);
ADD_HOOK(vkCreateGraphicsPipelineDerivative);
#undef ADD_HOOK
- VkLayerDispatchTable* pTable = device_dispatch_table(device);
- if (pTable->GetDeviceProcAddr == NULL)
- return NULL;
- return pTable->GetDeviceProcAddr(device, pName);
+
+ VkLayerDispatchTable* pTable = get_dispatch_table(shader_checker_device_table_map, dev);
+ {
+ if (pTable->GetDeviceProcAddr == NULL)
+ return NULL;
+ return pTable->GetDeviceProcAddr(dev, funcName);
+ }
}
-VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance inst, const char* pName)
+VK_LAYER_EXPORT void * VKAPI vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
{
void *fptr;
- if (inst == NULL)
+ if (instance == NULL)
return NULL;
- loader_platform_thread_once(&g_initOnce, initLayer);
-
- if (!strcmp("vkGetInstanceProcAddr", pName)) {
- initInstanceTable((const VkBaseLayerObject *) inst);
+ if (!strcmp("vkGetInstanceProcAddr", funcName)) {
+ initInstanceTable(shader_checker_instance_table_map, (const VkBaseLayerObject *) instance);
return (void *) vkGetInstanceProcAddr;
}
#define ADD_HOOK(fn) \
- if (!strncmp(#fn, pName, sizeof(#fn))) \
+ if (!strncmp(#fn, funcName, sizeof(#fn))) \
return (void *) fn
ADD_HOOK(vkCreateInstance);
@@ -1026,12 +1100,16 @@
ADD_HOOK(vkGetPhysicalDeviceLayerProperties);
#undef ADD_HOOK
- fptr = msg_callback_get_proc_addr(pName);
+
+ layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+ fptr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
if (fptr)
return fptr;
- VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(inst);
- if (pTable->GetInstanceProcAddr == NULL)
- return NULL;
- return pTable->GetInstanceProcAddr(inst, pName);
+ {
+ VkLayerInstanceDispatchTable* pTable = get_dispatch_table(shader_checker_instance_table_map, instance);
+ if (pTable->GetInstanceProcAddr == NULL)
+ return NULL;
+ return pTable->GetInstanceProcAddr(instance, funcName);
+ }
}