// Allow use of STL min and max functions in Windows
#define NOMINMAX
-#include <SPIRV/spirv.hpp>
#include <algorithm>
#include <assert.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
-#include <tuple>
#include <inttypes.h>
#include "vk_loader_platform.h"
#include "vk_layer_data.h"
#include "vk_layer_extension_utils.h"
#include "vk_layer_utils.h"
-#include "spirv-tools/libspirv.h"
#if defined __ANDROID__
#include <android/log.h>
VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule) {
layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
- bool skip = false;
- spv_result_t spv_valid = SPV_SUCCESS;
-
- if (!GetDisables(dev_data)->shader_validation) {
- if (!dev_data->extensions.vk_nv_glsl_shader && (pCreateInfo->codeSize % 4)) {
- skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
- __LINE__, VALIDATION_ERROR_12a00ac0, "SC",
- "SPIR-V module not valid: Codesize must be a multiple of 4 but is " PRINTF_SIZE_T_SPECIFIER ". %s",
- pCreateInfo->codeSize, validation_error_map[VALIDATION_ERROR_12a00ac0]);
- } else {
- // Use SPIRV-Tools validator to try and catch any issues with the module itself
- spv_context ctx = spvContextCreate(SPV_ENV_VULKAN_1_0);
- spv_const_binary_t binary{ pCreateInfo->pCode, pCreateInfo->codeSize / sizeof(uint32_t) };
- spv_diagnostic diag = nullptr;
-
- spv_valid = spvValidate(ctx, &binary, &diag);
- if (spv_valid != SPV_SUCCESS) {
- if (!dev_data->extensions.vk_nv_glsl_shader || (pCreateInfo->pCode[0] == spv::MagicNumber)) {
- skip |= log_msg(dev_data->report_data,
- spv_valid == SPV_WARNING ? VK_DEBUG_REPORT_WARNING_BIT_EXT : VK_DEBUG_REPORT_ERROR_BIT_EXT,
- VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC",
- "SPIR-V module not valid: %s", diag && diag->error ? diag->error : "(no error text)");
- }
- }
-
- spvDiagnosticDestroy(diag);
- spvContextDestroy(ctx);
- }
+ bool spirv_valid;
- if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
- }
+ if (PreCallValidateCreateShaderModule(dev_data, pCreateInfo, &spirv_valid))
+ return VK_ERROR_VALIDATION_FAILED_EXT;
VkResult res = dev_data->dispatch_table.CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
if (res == VK_SUCCESS) {
std::lock_guard<std::mutex> lock(global_lock);
- const auto new_shader_module = (SPV_SUCCESS == spv_valid ? new shader_module(pCreateInfo) : new shader_module());
- dev_data->shaderModuleMap[*pShaderModule] = unique_ptr<shader_module>(new_shader_module);
+ unique_ptr<shader_module> new_shader_module(spirv_valid ? new shader_module(pCreateInfo) : new shader_module());
+ dev_data->shaderModuleMap[*pShaderModule] = std::move(new_shader_module);
}
return res;
}
#include "core_validation.h"
#include "core_validation_types.h"
#include "shader_validation.h"
+#include "spirv-tools/libspirv.h"
enum FORMAT_TYPE {
FORMAT_TYPE_FLOAT = 1, // UNORM, SNORM, FLOAT, USCALED, SSCALED, SRGB -- anything we consider float in the shader
return validate_pipeline_shader_stage(dev_data, &pCreateInfo->stage, pPipeline, &module, &entrypoint);
}
+
+bool PreCallValidateCreateShaderModule(layer_data *dev_data, VkShaderModuleCreateInfo const *pCreateInfo, bool *spirv_valid) {
+ bool skip = false;
+ spv_result_t spv_valid = SPV_SUCCESS;
+ auto report_data = GetReportData(dev_data);
+
+ if (GetDisables(dev_data)->shader_validation) {
+ return false;
+ }
+
+ auto have_glsl_shader = GetEnabledExtensions(dev_data)->vk_nv_glsl_shader;
+
+ if (!have_glsl_shader && (pCreateInfo->codeSize % 4)) {
+ skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+ __LINE__, VALIDATION_ERROR_12a00ac0, "SC",
+ "SPIR-V module not valid: Codesize must be a multiple of 4 but is " PRINTF_SIZE_T_SPECIFIER ". %s",
+ pCreateInfo->codeSize, validation_error_map[VALIDATION_ERROR_12a00ac0]);
+ } else {
+ // Use SPIRV-Tools validator to try and catch any issues with the module itself
+ spv_context ctx = spvContextCreate(SPV_ENV_VULKAN_1_0);
+ spv_const_binary_t binary{ pCreateInfo->pCode, pCreateInfo->codeSize / sizeof(uint32_t) };
+ spv_diagnostic diag = nullptr;
+
+ spv_valid = spvValidate(ctx, &binary, &diag);
+ if (spv_valid != SPV_SUCCESS) {
+ if (!have_glsl_shader || (pCreateInfo->pCode[0] == spv::MagicNumber)) {
+ skip |= log_msg(report_data,
+ spv_valid == SPV_WARNING ? VK_DEBUG_REPORT_WARNING_BIT_EXT : VK_DEBUG_REPORT_ERROR_BIT_EXT,
+ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC",
+ "SPIR-V module not valid: %s", diag && diag->error ? diag->error : "(no error text)");
+ }
+ }
+
+ spvDiagnosticDestroy(diag);
+ spvContextDestroy(ctx);
+ }
+
+ *spirv_valid = (spv_valid == SPV_SUCCESS);
+ return skip;
+}