layers: Move validation of CreateShaderModule
authorChris Forbes <chrisforbes@google.com>
Fri, 9 Jun 2017 21:42:56 +0000 (14:42 -0700)
committerChris Forbes <chrisf@ijw.co.nz>
Fri, 9 Jun 2017 23:04:13 +0000 (16:04 -0700)
Now we have no spirv details left in core_validation.cpp

layers/core_validation.cpp
layers/shader_validation.cpp
layers/shader_validation.h

index 23f9e8c73bdd09e7394374bd1d8b153c05227f90..2e31419d7be6ed3536a06fadca836c4cde581a96 100644 (file)
@@ -36,7 +36,6 @@
 // Allow use of STL min and max functions in Windows
 #define NOMINMAX
 
-#include <SPIRV/spirv.hpp>
 #include <algorithm>
 #include <assert.h>
 #include <iostream>
@@ -50,7 +49,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <string>
-#include <tuple>
 #include <inttypes.h>
 
 #include "vk_loader_platform.h"
@@ -69,7 +67,6 @@
 #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>
@@ -7240,44 +7237,17 @@ static bool CreatePassDAG(const layer_data *dev_data, const VkRenderPassCreateIn
 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;
 }
index fc44d41b179a46130e9e5167902c35c9b0e4645d..b95c55e13c6b886e819bf212c4b6d048141a4b73 100644 (file)
@@ -34,6 +34,7 @@
 #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
@@ -1509,3 +1510,43 @@ bool validate_compute_pipeline(layer_data *dev_data, PIPELINE_STATE *pPipeline)
 
     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;
+}
index 3d1c69eb6f35c981c157f24ba597bdcedd5b8edd..a6eecff4b2238c9f57b4e16d991304c15d9a2d07 100644 (file)
@@ -103,5 +103,6 @@ struct shader_module {
 bool validate_and_capture_pipeline_shader_state(layer_data *dev_data, PIPELINE_STATE *pPipeline);
 bool validate_compute_pipeline(layer_data *dev_data, PIPELINE_STATE *pPipeline);
 typedef std::pair<unsigned, unsigned> descriptor_slot_t;
+bool PreCallValidateCreateShaderModule(layer_data *dev_data, VkShaderModuleCreateInfo const *pCreateInfo, bool *spirv_valid);
 
 #endif //VULKAN_SHADER_VALIDATION_H