mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
261 lines
10 KiB
C++
261 lines
10 KiB
C++
// Copyright (c) 2025 The Khronos Group Inc.
|
|
// Copyright (c) 2025 Google LLC
|
|
//
|
|
// 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.
|
|
|
|
#ifndef SOURCE_TABLE2_H_
|
|
#define SOURCE_TABLE2_H_
|
|
|
|
#include "source/latest_version_spirv_header.h"
|
|
#include "source/util/index_range.h"
|
|
#include "spirv-tools/libspirv.hpp"
|
|
|
|
// Define the objects that describe the grammatical structure of SPIR-V
|
|
// instructions and their operands. The objects are owned by static
|
|
// tables populated at C++ build time from the grammar files from SPIRV-Headers.
|
|
//
|
|
// Clients use freestanding methods to lookup an opcode or an operand, either
|
|
// by numeric value (in the binary), or by name.
|
|
//
|
|
// For historical reasons, the opcode lookup can also use a target enviroment
|
|
// enum to filter for opcodes supported in that environment.
|
|
//
|
|
// It should be very fast for the system loader to load (and possibly relocate)
|
|
// the static tables. In particular, there should be very few global symbols
|
|
// with independent addresses. Prefer a very few large tables of items rather
|
|
// than dozens or hundreds of global symbols.
|
|
//
|
|
// The overall structure among containers (i.e. skipping scalar data members)
|
|
// is as follows:
|
|
//
|
|
// An OperandDesc describes an operand.
|
|
// An InstructionDesc desribes an instruction.
|
|
// An ExtInstDesc describes an extended intruction.
|
|
//
|
|
// Both OperandDesc and InstructionDesc have members:
|
|
// - a name string
|
|
// - array of alias strings
|
|
// - array of spv::Capability (as an enum)
|
|
// - array of spv_operand_type_t (as an enum)
|
|
// - array of spvtools::Extension (as an enum)
|
|
// - a minVersion
|
|
// - a lastVersion
|
|
//
|
|
// An OperandDesc also has:
|
|
// - a uint32_t value.
|
|
//
|
|
// An InstructionDesc also has:
|
|
// - a spv::Op opcode
|
|
// - a bool hasResult
|
|
// - a bool hasType
|
|
// - a printing class
|
|
//
|
|
// An ExtInstDesc has:
|
|
// - a name
|
|
// - array of spv::Capability (as an enum)
|
|
// - array of spv_operand_type_t (as an enum)
|
|
//
|
|
// The arrays are represented by spans into a global static array, with one
|
|
// array for each of:
|
|
// - null-terminated strings, for names
|
|
// - arrays of null-terminated strings, for alias lists
|
|
// - spv_operand_type_t
|
|
// - spv::Capability
|
|
// - spvtools::Extension
|
|
//
|
|
// Note: Currently alias lists never have more than one element.
|
|
// The data structures and code do not assume this.
|
|
|
|
// TODO(dneto): convert the tables for extended instructions
|
|
// Currently (as defined in table.h):
|
|
// An spv_ext_inst_group_t has:
|
|
// - array of spv_ext_inst_desc_t
|
|
//
|
|
// An spv_ext_inst_desc_t has:
|
|
// - a name string
|
|
// - array of spv::Capability
|
|
// - array of spv_operand_type_t
|
|
|
|
namespace spvtools {
|
|
|
|
#include "core_tables_header.inc"
|
|
|
|
using IndexRange = utils::IndexRange<uint32_t, uint32_t>;
|
|
|
|
// Describes a SPIR-V operand.
|
|
struct OperandDesc {
|
|
const uint32_t value;
|
|
|
|
const IndexRange operands_range; // Indexes kOperandSpans
|
|
const IndexRange name_range; // Indexes kStrings
|
|
const IndexRange aliases_range; // Indexes kAliasSpans
|
|
const IndexRange capabilities_range; // Indexes kCapabilitySpans
|
|
// A set of extensions that enable this feature. If empty then this operand
|
|
// value is in core and its availability is subject to minVersion. The
|
|
// assembler, binary parser, and disassembler ignore this rule, so you can
|
|
// freely process invalid modules.
|
|
const IndexRange extensions_range; // Indexes kExtensionSpans
|
|
// Minimal core SPIR-V version required for this feature, if without
|
|
// extensions. ~0u means reserved for future use. ~0u and non-empty
|
|
// extension lists means only available in extensions.
|
|
const uint32_t minVersion = 0xFFFFFFFFu;
|
|
const uint32_t lastVersion = 0xFFFFFFFFu;
|
|
utils::Span<const spv_operand_type_t> operands() const;
|
|
utils::Span<const char> name() const;
|
|
utils::Span<const IndexRange> aliases() const;
|
|
utils::Span<const spv::Capability> capabilities() const;
|
|
utils::Span<const spvtools::Extension> extensions() const;
|
|
|
|
constexpr OperandDesc(uint32_t v, IndexRange o, IndexRange n, IndexRange a,
|
|
IndexRange c, IndexRange e, uint32_t mv, uint32_t lv)
|
|
: value(v),
|
|
operands_range(o),
|
|
name_range(n),
|
|
aliases_range(a),
|
|
capabilities_range(c),
|
|
extensions_range(e),
|
|
minVersion(mv),
|
|
lastVersion(lv) {}
|
|
|
|
constexpr OperandDesc(uint32_t v) : value(v) {}
|
|
|
|
OperandDesc(const OperandDesc&) = delete;
|
|
OperandDesc(OperandDesc&&) = delete;
|
|
};
|
|
|
|
// Describes an Instruction
|
|
struct InstructionDesc {
|
|
const spv::Op opcode;
|
|
const bool hasResult = false;
|
|
const bool hasType = false;
|
|
|
|
const IndexRange operands_range; // Indexes kOperandSpans
|
|
const IndexRange name_range; // Indexes kStrings
|
|
const IndexRange aliases_range; // Indexes kAliasSpans
|
|
const IndexRange capabilities_range; // Indexes kCapbilitySpans
|
|
// A set of extensions that enable this feature. If empty then this operand
|
|
// value is in core and its availability is subject to minVersion. The
|
|
// assembler, binary parser, and disassembler ignore this rule, so you can
|
|
// freely process invalid modules.
|
|
const IndexRange extensions_range; // Indexes kExtensionSpans
|
|
// Minimal core SPIR-V version required for this feature, if without
|
|
// extensions. ~0u means reserved for future use. ~0u and non-empty
|
|
// extension lists means only available in extensions.
|
|
const uint32_t minVersion = 0xFFFFFFFFu;
|
|
const uint32_t lastVersion = 0xFFFFFFFFu;
|
|
// The printing class specifies what kind of instruction it is, e.g. what
|
|
// section of the SPIR-V spec. E.g. kImage, kComposite
|
|
const PrintingClass printingClass = PrintingClass::kReserved;
|
|
// Returns the span of elements in the global grammar tables corresponding
|
|
// to the privately-stored index ranges
|
|
utils::Span<const spv_operand_type_t> operands() const;
|
|
utils::Span<const char> name() const;
|
|
utils::Span<const IndexRange> aliases() const;
|
|
utils::Span<const spv::Capability> capabilities() const;
|
|
utils::Span<const spvtools::Extension> extensions() const;
|
|
|
|
constexpr InstructionDesc(spv::Op oc, bool hr, bool ht, IndexRange o,
|
|
IndexRange n, IndexRange a, IndexRange c,
|
|
IndexRange e, uint32_t mv, uint32_t lv,
|
|
PrintingClass pc)
|
|
: opcode(oc),
|
|
hasResult(hr),
|
|
hasType(ht),
|
|
operands_range(o),
|
|
name_range(n),
|
|
aliases_range(a),
|
|
capabilities_range(c),
|
|
extensions_range(e),
|
|
minVersion(mv),
|
|
lastVersion(lv),
|
|
printingClass(pc) {}
|
|
|
|
constexpr InstructionDesc(spv::Op oc) : opcode(oc) {}
|
|
|
|
InstructionDesc(const InstructionDesc&) = delete;
|
|
InstructionDesc(InstructionDesc&&) = delete;
|
|
};
|
|
|
|
// Describes an extended instruction
|
|
struct ExtInstDesc {
|
|
const uint32_t value;
|
|
const IndexRange operands_range; // Indexes kOperandSpans
|
|
const IndexRange name_range; // Indexes kStrings
|
|
const IndexRange capabilities_range; // Indexes kCapbilitySpans
|
|
// Returns the span of elements in the global grammar tables corresponding
|
|
// to the privately-stored index ranges
|
|
utils::Span<const spv_operand_type_t> operands() const;
|
|
utils::Span<const char> name() const;
|
|
utils::Span<const spv::Capability> capabilities() const;
|
|
|
|
constexpr ExtInstDesc(uint32_t v, IndexRange o, IndexRange n, IndexRange c)
|
|
: value(v), operands_range(o), name_range(n), capabilities_range(c) {}
|
|
|
|
constexpr ExtInstDesc(uint32_t v) : value(v) {}
|
|
|
|
ExtInstDesc(const ExtInstDesc&) = delete;
|
|
ExtInstDesc(ExtInstDesc&&) = delete;
|
|
};
|
|
|
|
// Finds the instruction description by opcode name. The name should not
|
|
// have the "Op" prefix. On success, returns SPV_SUCCESS and updates *desc.
|
|
spv_result_t LookupOpcode(const char* name, const InstructionDesc** desc);
|
|
// Finds the instruction description by opcode value.
|
|
// On success, returns SPV_SUCCESS and updates *desc.
|
|
spv_result_t LookupOpcode(spv::Op opcode, const InstructionDesc** desc);
|
|
|
|
// Finds the instruction description by opcode name, without the "Op" prefix.
|
|
// A lookup will succeed if:
|
|
// - The instruction exists, and
|
|
// - Either the target environment supports the SPIR-V version of the
|
|
// instruction,
|
|
// or the instruction is enabled by at least one extension,
|
|
// or the instruction is enabled by at least one capability.,
|
|
// On success, returns SPV_SUCCESS and updates *desc.
|
|
spv_result_t LookupOpcodeForEnv(spv_target_env env, const char* name,
|
|
const InstructionDesc** desc);
|
|
|
|
// Finds the instruction description by opcode value.
|
|
// A lookup will succeed if:
|
|
// - The instruction exists, and
|
|
// - Either the target environment supports the SPIR-V version of the
|
|
// instruction,
|
|
// or the instruction is enabled by at least one extension,
|
|
// or the instruction is enabled by at least one capability.,
|
|
// On success, returns SPV_SUCCESS and updates *desc.
|
|
spv_result_t LookupOpcodeForEnv(spv_target_env env, spv::Op,
|
|
const InstructionDesc** desc);
|
|
|
|
spv_result_t LookupOperand(spv_operand_type_t type, const char* name,
|
|
size_t name_len, const OperandDesc** desc);
|
|
spv_result_t LookupOperand(spv_operand_type_t type, uint32_t operand,
|
|
const OperandDesc** desc);
|
|
|
|
// Finds the extended instruction description by opcode name.
|
|
// On success, returns SPV_SUCCESS and updates *desc.
|
|
spv_result_t LookupExtInst(spv_ext_inst_type_t type, const char* name,
|
|
const ExtInstDesc** desc);
|
|
// Finds the extended instruction description by opcode value.
|
|
// On success, returns SPV_SUCCESS and updates *desc.
|
|
spv_result_t LookupExtInst(spv_ext_inst_type_t type, uint32_t value,
|
|
const ExtInstDesc** desc);
|
|
|
|
// Finds Extension enum corresponding to |str|. Returns false if not found.
|
|
bool GetExtensionFromString(const char* str, Extension* extension);
|
|
|
|
// Returns text string corresponding to |extension|.
|
|
const char* ExtensionToString(Extension extension);
|
|
|
|
} // namespace spvtools
|
|
#endif // SOURCE_TABLE2_H_
|