mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
Includes contributions by Rémi to unify usage of SPIR-V Headers across the dependencies. Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
213 lines
5.9 KiB
C++
213 lines
5.9 KiB
C++
//
|
|
// re-spirv
|
|
//
|
|
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file for details.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace respv {
|
|
struct SpecConstant {
|
|
uint32_t specId = 0;
|
|
std::vector<uint32_t> values;
|
|
|
|
SpecConstant() {
|
|
// Empty constructor.
|
|
}
|
|
|
|
SpecConstant(uint32_t pSpecId, const std::vector<uint32_t> &pValues) {
|
|
specId = pSpecId;
|
|
values = pValues;
|
|
}
|
|
};
|
|
|
|
struct Instruction {
|
|
uint32_t wordIndex = UINT32_MAX;
|
|
uint32_t blockIndex = UINT32_MAX;
|
|
|
|
Instruction(uint32_t pWordIndex, uint32_t pBlockIndex) {
|
|
wordIndex = pWordIndex;
|
|
blockIndex = pBlockIndex;
|
|
}
|
|
};
|
|
|
|
struct Block {
|
|
uint32_t labelInstructionIndex = UINT32_MAX;
|
|
uint32_t terminatorInstructionIndex = UINT32_MAX;
|
|
|
|
Block() {
|
|
// Empty.
|
|
}
|
|
|
|
Block(uint32_t pLabelInstructionIndex, uint32_t pTerminatorInstructionIndex) {
|
|
labelInstructionIndex = pLabelInstructionIndex;
|
|
terminatorInstructionIndex = pTerminatorInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct Function {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
uint32_t labelInstructionIndex = UINT32_MAX;
|
|
|
|
Function() {
|
|
// Empty.
|
|
}
|
|
|
|
Function(uint32_t pInstructionIndex, uint32_t pLabelInstructionIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
labelInstructionIndex = pLabelInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct Result {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
|
|
Result() {
|
|
// Empty.
|
|
}
|
|
|
|
Result(uint32_t pInstructionIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct Specialization {
|
|
uint32_t constantInstructionIndex = UINT32_MAX;
|
|
uint32_t decorationInstructionIndex = UINT32_MAX;
|
|
|
|
Specialization() {
|
|
// Empty.
|
|
}
|
|
|
|
Specialization(uint32_t pConstantInstructionIndex, uint32_t pDecorationInstructionIndex) {
|
|
constantInstructionIndex = pConstantInstructionIndex;
|
|
decorationInstructionIndex = pDecorationInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct Decoration {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
|
|
Decoration() {
|
|
// Empty.
|
|
}
|
|
|
|
Decoration(uint32_t pInstructionIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct Variable {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
|
|
Variable() {
|
|
// Empty.
|
|
}
|
|
|
|
Variable(uint32_t pInstructionIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct AccessChain {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
|
|
AccessChain() {
|
|
// Empty.
|
|
}
|
|
|
|
AccessChain(uint32_t pInstructionIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct Phi {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
|
|
Phi() {
|
|
// Empty.
|
|
}
|
|
|
|
Phi(uint32_t pInstructionIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct LoopHeader {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
uint32_t blockInstructionIndex = UINT32_MAX;
|
|
|
|
LoopHeader() {
|
|
// Empty.
|
|
}
|
|
|
|
LoopHeader(uint32_t pInstructionIndex, uint32_t pBlockInstructionIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
blockInstructionIndex = pBlockInstructionIndex;
|
|
}
|
|
};
|
|
|
|
struct ListNode {
|
|
uint32_t instructionIndex = UINT32_MAX;
|
|
uint32_t nextListIndex = UINT32_MAX;
|
|
|
|
ListNode() {
|
|
// Empty.
|
|
}
|
|
|
|
ListNode(uint32_t pInstructionIndex, uint32_t pNextListIndex) {
|
|
instructionIndex = pInstructionIndex;
|
|
nextListIndex = pNextListIndex;
|
|
}
|
|
};
|
|
|
|
struct Shader {
|
|
const uint32_t *extSpirvWords = nullptr;
|
|
size_t extSpirvWordCount = 0;
|
|
std::vector<uint32_t> inlinedSpirvWords;
|
|
std::vector<Instruction> instructions;
|
|
std::vector<uint32_t> instructionAdjacentListIndices;
|
|
std::vector<uint32_t> instructionInDegrees;
|
|
std::vector<uint32_t> instructionOutDegrees;
|
|
std::vector<uint32_t> instructionOrder;
|
|
std::vector<Block> blocks;
|
|
std::vector<uint32_t> blockPreOrderIndices;
|
|
std::vector<uint32_t> blockPostOrderIndices;
|
|
std::vector<Function> functions;
|
|
std::vector<uint32_t> variableOrder;
|
|
std::vector<Result> results;
|
|
std::vector<Specialization> specializations;
|
|
std::vector<Decoration> decorations;
|
|
std::vector<Phi> phis;
|
|
std::vector<LoopHeader> loopHeaders;
|
|
std::vector<ListNode> listNodes;
|
|
uint32_t defaultSwitchOpConstantInt = UINT32_MAX;
|
|
|
|
Shader();
|
|
|
|
// Data is only copied if pInlineFunctions is true. An extra processing pass is required if inlining is enabled.
|
|
// This step is usually not required unless the shader compiler has disabled optimizations.
|
|
Shader(const void *pData, size_t pSize, bool pInlineFunctions);
|
|
void clear();
|
|
bool checkData(const void *pData, size_t pSize);
|
|
bool inlineData(const void *pData, size_t pSize);
|
|
bool parseData(const void *pData, size_t pSize);
|
|
bool parse(const void *pData, size_t pSize, bool pInlineFunctions);
|
|
bool process(const void *pData, size_t pSize);
|
|
bool sort(const void *pData, size_t pSize);
|
|
bool empty() const;
|
|
};
|
|
|
|
struct Options {
|
|
bool removeDeadCode = true;
|
|
};
|
|
|
|
struct Optimizer {
|
|
static bool run(const Shader &pShader, const SpecConstant *pNewSpecConstants, uint32_t pNewSpecConstantCount, std::vector<uint8_t> &pOptimizedData, Options pOptions = Options());
|
|
};
|
|
};
|