chromium/third_party/vulkan-validation-layers/src/layers/state_tracker/shader_module.h

/* Copyright (c) 2021-2024 The Khronos Group Inc.
 *
 * 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.
 *
 * The Shader Module file is in charge of all things around creating and parsing an internal representation of a shader module
 */

#pragma once

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <vector>

#include "state_tracker/shader_instruction.h"
#include "state_tracker/state_object.h"
#include "state_tracker/sampler_state.h"
#include <spirv/unified1/spirv.hpp>

namespace vvl {
class Pipeline;
}  // namespace vvl

namespace spirv {
struct EntryPoint;
struct Module;

static constexpr uint32_t kInvalidValue =;

// Need to find a way to know if actually array lenght of zero, or a runtime array.
static constexpr uint32_t kRuntimeArray =;

// This is the common info for both OpDecorate and OpMemberDecorate
// Used to keep track of all decorations applied to any instruction
struct DecorationBase {};

// subset only for OpDecorate
// Can't have nested structs with OpMemberDecorate, this class prevents accidently creating a 2nd level of member decorations,
struct DecorationSet : public DecorationBase {};

// Tracking of OpExecutionMode / OpExecutionModeId values
struct ExecutionModeSet {};

struct AtomicInstructionInfo {};

// This info *could* be found/saved in TypeStructInfo, but since
//  - Only a few places (Push Constants, workgroup size) use this
//  - It is only good when you know there are no nested strcuts
// we only get this info when needed, not for every struct
struct TypeStructSize {};

// Contains all the details for a OpTypeStruct
struct TypeStructInfo {};

namespace AccessBit {
const uint32_t empty =;
const uint32_t read =;
const uint32_t write =;
const uint32_t atomic_read =;
const uint32_t atomic_write =;
const uint32_t image_read =;
const uint32_t image_write =;

constexpr uint32_t atomic_mask =;
constexpr uint32_t image_mask =;
constexpr uint32_t read_mask =;
constexpr uint32_t write_mask =;
}  // namespace AccessBit

// Mapping of < variable ID, AccessBit >
VariableAccessMap;

// Track all paths from %param to %arg so can walk back functions
//
// %arg   = OpVariable
// %call  = OpFunctionCall %result %func %arg
// %param = OpFunctionParameter
//
// < %param, vector<%arg> >
FuncParameterMap;

// Represents the OpImage* instructions and how it maps to the variable
// This is created in the Module but then used with VariableBase objects
struct ImageAccess {};

// <Image OpVariable Result ID, [ImageAccess, ImageAccess, etc] > - used for faster lookup
// Many ImageAccess can point to a single Image Variable
ImageAccessMap;
// < Variable ID, [ OpAccessChain ] >
// Allows for grouping the access chains by which variables they are actually accessing
AccessChainVariableMap;
// Mapping of OpName instructions
DebugNameMap;

// A slot is a <Location, Component> mapping
struct InterfaceSlot {};

// Represents the Image formats that can map to a SPIR-V format
enum NumericType {};
uint32_t GetFormatType(VkFormat format);
char const *string_NumericType(uint32_t type);

// Common info needed for all OpVariable
struct VariableBase {};

// These are Input/Output OpVariable that go in-between stages
// (also for example the input to a Vertex and output of the Fragment).
// These are always ints/floats (not images or samplers).
// Besides the input vertex binding, all of these are fully known at pipeline creation time
//
// These include both BuiltIns and User Defined, while there are difference in member variables, the variables are needed for the
// common logic so its easier using the same object in the end
struct StageInterfaceVariable : public VariableBase {};

// vkspec.html#interfaces-resources describes 'Shader Resource Interface'
// These are the OpVariable attached to descriptors.
// The slots are known at Pipeline creation time, but the type images/sampler/etc is
// not known until the descriptors are bound.
// The main purpose of this struct is to track what operations are statically done so
// at draw/submit time we can cross reference with the last bound descriptor.
struct ResourceInterfaceVariable : public VariableBase {};

// Used to help detect if different variable is being used
inline bool operator==(const ResourceInterfaceVariable &a, const ResourceInterfaceVariable &b) noexcept {}
inline bool operator<(const ResourceInterfaceVariable &a, const ResourceInterfaceVariable &b) noexcept {}

// vkspec.html#interfaces-resources-pushconst
// Push constants need to be statically used in shader
// Push constants are always OpTypeStruct and Block decorated
struct PushConstantVariable : public VariableBase {};

// Represents a single Entrypoint into a Shader Module
struct EntryPoint {};

// Info to capture while parsing the SPIR-V, but will only be used by ValidateSpirvStateless and don't need to save after
struct StatelessData {};

// Represents a SPIR-V Module
// This holds the SPIR-V source and parse it
struct Module {};

}  // namespace spirv

// Represents a VkShaderModule handle
namespace vvl {
struct ShaderModule : public StateObject {};
}  // namespace vvl