1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-31 18:41:20 +00:00

Use re-spirv in the Vulkan driver to optimize shaders.

Includes contributions by Rémi to unify usage of SPIR-V Headers across the dependencies.

Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
This commit is contained in:
Dario
2024-11-14 13:46:57 -03:00
parent 5f12ada7a4
commit cf00643565
18 changed files with 9022 additions and 7724 deletions

21
thirdparty/re-spirv/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 renderbag and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

3183
thirdparty/re-spirv/re-spirv.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

213
thirdparty/re-spirv/re-spirv.h vendored Normal file
View File

@@ -0,0 +1,213 @@
//
// 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());
};
};