blob: 2120b8c6cf56b64c282123e22ef35fa0d8500e45 [file] [log] [blame]
/* Copyright (c) 2015-2024 The Khronos Group Inc.
* Copyright (c) 2015-2024 Valve Corporation
* Copyright (c) 2015-2024 LunarG, Inc.
* Copyright (C) 2015-2024 Google Inc.
* Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
* Modifications Copyright (C) 2022 RasterGrid Kft.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <unordered_map>
#include <vector>
#include "state_tracker/shader_module.h"
namespace vvl {
class Pipeline;
} // namespace vvl
// These structure are here as a way to bridge information down the chassis.
// This allows the 4 different calls (PreCallValidate, PreCallRecord, Dispatch, PostCallRecord) to share information
namespace chassis {
struct CreateShaderModule {
// allows PreCallRecord to return a value like PreCallValidate
bool skip = false;
// We build a spirv::Module at PreCallRecord time were we can do basic validation of the SPIR-V (which can crash drivers
// if passed in the Dispatch). It is then passed to PostCallRecord to save in state tracking so it can be used at Pipeline
// creation time where the rest of the information is needed to do the remaining SPIR-V validation.
std::shared_ptr<spirv::Module> module_state; // contains SPIR-V to validate
spirv::StatelessData stateless_data;
uint32_t unique_shader_id = 0;
// Pass the instrumented SPIR-V info from PreCallRecord to Dispatch (so GPU-AV logic can run with it)
VkShaderModuleCreateInfo instrumented_create_info;
std::vector<uint32_t> instrumented_spirv;
};
// VkShaderEXT (VK_EXT_shader_object)
struct ShaderObject {
// allows PreCallRecord to return a value like PreCallValidate
bool skip = false;
std::vector<std::shared_ptr<spirv::Module>> module_states; // contains SPIR-V to validate
std::vector<spirv::StatelessData> stateless_data;
std::vector<uint32_t> unique_shader_ids;
// Pass the instrumented SPIR-V info from PreCallRecord to Dispatch (so GPU-AV logic can run with it)
VkShaderCreateInfoEXT* instrumented_create_info;
std::vector<std::vector<uint32_t>> instrumented_spirv;
std::vector<VkDescriptorSetLayout> new_layouts;
ShaderObject(uint32_t createInfoCount, const VkShaderCreateInfoEXT* pCreateInfos) {
instrumented_create_info = const_cast<VkShaderCreateInfoEXT*>(pCreateInfos);
module_states.resize(createInfoCount);
stateless_data.resize(createInfoCount);
unique_shader_ids.resize(createInfoCount);
instrumented_spirv.resize(createInfoCount);
}
};
// We hold one slot for each potential graphics stage
// This is used to pass the unique_shader_id around for GPL
// Tried to use `vvl::unordered_map` but caused compiler errors
using ShaderModuleUniqueIds = std::unordered_map<VkShaderStageFlagBits, uint32_t>;
struct CreateGraphicsPipelines {
std::vector<vku::safe_VkGraphicsPipelineCreateInfo> modified_create_infos;
std::vector<ShaderModuleUniqueIds> shader_unique_id_maps;
const VkGraphicsPipelineCreateInfo* pCreateInfos;
// Used to know if VkShaderModuleCreateInfo is passed down VkPipelineShaderStageCreateInfo
bool passed_in_shader_stage_ci = false;
spirv::StatelessData stateless_data[kCommonMaxGraphicsShaderStages];
CreateGraphicsPipelines(const VkGraphicsPipelineCreateInfo* create_info) { pCreateInfos = create_info; }
};
struct CreateComputePipelines {
std::vector<vku::safe_VkComputePipelineCreateInfo> modified_create_infos;
std::vector<ShaderModuleUniqueIds> shader_unique_id_maps; // not used, here for template function
const VkComputePipelineCreateInfo* pCreateInfos;
// Used to know if VkShaderModuleCreateInfo is passed down VkPipelineShaderStageCreateInfo
bool passed_in_shader_stage_ci = false;
spirv::StatelessData stateless_data;
CreateComputePipelines(const VkComputePipelineCreateInfo* create_info) { pCreateInfos = create_info; }
};
struct CreateRayTracingPipelinesNV {
std::vector<vku::safe_VkRayTracingPipelineCreateInfoCommon> modified_create_infos;
std::vector<ShaderModuleUniqueIds> shader_unique_id_maps; // not used, here for template function
const VkRayTracingPipelineCreateInfoNV* pCreateInfos;
bool passed_in_shader_stage_ci = false;
CreateRayTracingPipelinesNV(const VkRayTracingPipelineCreateInfoNV* create_info) { pCreateInfos = create_info; }
};
struct CreateRayTracingPipelinesKHR {
std::vector<vku::safe_VkRayTracingPipelineCreateInfoCommon> modified_create_infos;
std::vector<ShaderModuleUniqueIds> shader_unique_id_maps; // not used, here for template function
const VkRayTracingPipelineCreateInfoKHR* pCreateInfos;
bool passed_in_shader_stage_ci = false;
CreateRayTracingPipelinesKHR(const VkRayTracingPipelineCreateInfoKHR* create_info) { pCreateInfos = create_info; }
};
struct CreatePipelineLayout {
// This currently only works because GPU-AV is the only layer who creates this state
// If a 2nd layer starts to use it, can have conflicting values
std::vector<VkDescriptorSetLayout> new_layouts;
VkPipelineLayoutCreateInfo modified_create_info;
};
struct CreateBuffer {
VkBufferCreateInfo modified_create_info;
};
} // namespace chassis