diff options
| author | Chris Forbes <chrisf@ijw.co.nz> | 2015-04-08 10:19:16 +1200 |
|---|---|---|
| committer | Chris Forbes <chrisf@ijw.co.nz> | 2015-04-17 10:13:59 +1200 |
| commit | e9bc1232e05e7d6cc528be380169eadee5ce5590 (patch) | |
| tree | 24f5cbbb1fde140e0fcb7ce462dd25541a220387 /layers | |
| parent | ac467fe5a180b209a8c01be2681afc873e06319e (diff) | |
| download | usermoji-e9bc1232e05e7d6cc528be380169eadee5ce5590.tar.xz | |
shader_checker: add validation of interface between vs and fs
Diffstat (limited to 'layers')
| -rw-r--r-- | layers/shader_checker.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/layers/shader_checker.cpp b/layers/shader_checker.cpp index 6d88b233..ad375dfa 100644 --- a/layers/shader_checker.cpp +++ b/layers/shader_checker.cpp @@ -26,6 +26,7 @@ #include <assert.h> #include <map> #include <unordered_map> +#include <map> #include <vector> #include "loader_platform.h" #include "vk_dispatch_table_helper.h" @@ -250,6 +251,50 @@ VK_LAYER_EXPORT VkResult VKAPI vkCreateShader(VkDevice device, const VkShaderCre } +static void +validate_interface_between_stages(shader_source const *producer, char const *producer_name, + shader_source const *consumer, char const *consumer_name) +{ + std::map<uint32_t, interface_var> outputs; + std::map<uint32_t, interface_var> inputs; + + std::map<uint32_t, interface_var> builtin_outputs; + std::map<uint32_t, interface_var> builtin_inputs; + + printf("Begin validate_interface_between_stages %s -> %s\n", + producer_name, consumer_name); + + collect_interface_by_location(producer, spv::StorageOutput, outputs, builtin_outputs); + collect_interface_by_location(consumer, spv::StorageInput, inputs, builtin_inputs); + + auto a_it = outputs.begin(); + auto b_it = inputs.begin(); + + /* maps sorted by key (location); walk them together to find mismatches */ + while (a_it != outputs.end() || b_it != inputs.end()) { + if (b_it == inputs.end() || a_it->first < b_it->first) { + printf(" WARN: %s writes to output location %d which is not consumed by %s\n", + producer_name, a_it->first, consumer_name); + a_it++; + } + else if (a_it == outputs.end() || a_it->first > b_it->first) { + printf(" ERR: %s consumes input location %d which is not written by %s\n", + consumer_name, b_it->first, producer_name); + b_it++; + } + else { + printf(" OK: match on location %d\n", + a_it->first); + /* TODO: typecheck */ + a_it++; + b_it++; + } + } + + printf("End validate_interface_between_stages\n"); +} + + VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(VkDevice device, const VkGraphicsPipelineCreateInfo *pCreateInfo, VkPipeline *pPipeline) @@ -288,6 +333,11 @@ VK_LAYER_EXPORT VkResult VKAPI vkCreateGraphicsPipeline(VkDevice device, printf("Pipeline: vi=%p vs=%p fs=%p cb=%p\n", vi, vs_source, fs_source, cb); + if (vs_source && fs_source) { + validate_interface_between_stages(vs_source, "vertex shader", + fs_source, "fragment shader"); + } + VkLayerDispatchTable *pTable = tableMap[(VkBaseLayerObject *)device]; VkResult res = pTable->CreateGraphicsPipeline(device, pCreateInfo, pPipeline); return res; |
