[cmake] refactor: Use CPM over submodules #143
39 changed files with 22 additions and 3470 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -22,6 +22,3 @@
|
||||||
[submodule "externals/nx_tzdb/tzdb_to_nx/externals/tz/tz"]
|
[submodule "externals/nx_tzdb/tzdb_to_nx/externals/tz/tz"]
|
||||||
path = externals/nx_tzdb/tzdb_to_nx/externals/tz/tz
|
path = externals/nx_tzdb/tzdb_to_nx/externals/tz/tz
|
||||||
url = https://github.com/eggert/tz.git
|
url = https://github.com/eggert/tz.git
|
||||||
[submodule "externals/sirit/externals/SPIRV-Headers"]
|
|
||||||
path = externals/sirit/externals/SPIRV-Headers
|
|
||||||
url = https://github.com/KhronosGroup/SPIRV-Headers.git
|
|
||||||
|
|
19
externals/CMakeLists.txt
vendored
19
externals/CMakeLists.txt
vendored
|
@ -176,7 +176,24 @@ if (USE_DISCORD_PRESENCE AND NOT TARGET DiscordRPC::discord-rpc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Sirit
|
# Sirit
|
||||||
add_subdirectory(sirit)
|
# TODO(crueter): spirv-tools doesn't work w/ system
|
||||||
|
set(CPM_USE_LOCAL_PACKAGES OFF)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME SPIRV-Headers
|
||||||
|
URL "https://github.com/KhronosGroup/SPIRV-Headers/archive/4e209d3d7e.zip"
|
||||||
|
URL_HASH SHA512=f48bbe18341ed55ea0fe280dbbbc0a44bf222278de6e716e143ca1e95ca320b06d4d23d6583fbf8d03e1428f3dac8fa00e5b82ddcd6b425e6236d85af09550a4
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CPM_USE_LOCAL_PACKAGES ON)
|
||||||
|
|
||||||
|
CPMAddPackage(
|
||||||
|
NAME sirit
|
||||||
|
URL "https://github.com/raphaelthegreat/sirit/archive/51fcf9720f.zip"
|
||||||
|
URL_HASH SHA512=a8f98ea0c51763b89924d836ad482ebdfe9130251cf4e14733ccaacc885ae8cc4c8b03d1dc43e8861609e5f7929c16f935879c1f6bf61866fd75077954774394
|
||||||
|
OPTIONS
|
||||||
|
"SIRIT_USE_SYSTEM_SPIRV_HEADERS ON"
|
||||||
|
)
|
||||||
|
|
||||||
# httplib
|
# httplib
|
||||||
if ((ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER) AND NOT TARGET httplib::httplib)
|
if ((ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER) AND NOT TARGET httplib::httplib)
|
||||||
|
|
88
externals/sirit/.clang-format
vendored
88
externals/sirit/.clang-format
vendored
|
@ -1,88 +0,0 @@
|
||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
# BasedOnStyle: LLVM
|
|
||||||
AccessModifierOffset: -4
|
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
AlignEscapedNewlinesLeft: false
|
|
||||||
AlignOperands: true
|
|
||||||
AlignTrailingComments: true
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
|
||||||
AllowShortBlocksOnASingleLine: false
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortFunctionsOnASingleLine: Empty
|
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
|
||||||
AlwaysBreakTemplateDeclarations: true
|
|
||||||
BinPackArguments: true
|
|
||||||
BinPackParameters: true
|
|
||||||
BraceWrapping:
|
|
||||||
AfterClass: false
|
|
||||||
AfterControlStatement: false
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: false
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterObjCDeclaration: false
|
|
||||||
AfterStruct: false
|
|
||||||
AfterUnion: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: false
|
|
||||||
IndentBraces: false
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeBraces: Attach
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializersBeforeComma: false
|
|
||||||
ColumnLimit: 100
|
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
|
||||||
ConstructorInitializerIndentWidth: 4
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
Cpp11BracedListStyle: true
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
DisableFormat: false
|
|
||||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^\<[^Q][^/.>]*\>'
|
|
||||||
Priority: -2
|
|
||||||
- Regex: '^\<'
|
|
||||||
Priority: -1
|
|
||||||
- Regex: '^\"'
|
|
||||||
Priority: 0
|
|
||||||
IndentCaseLabels: false
|
|
||||||
IndentWidth: 4
|
|
||||||
IndentWrappedFunctionNames: false
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
|
||||||
MacroBlockBegin: ''
|
|
||||||
MacroBlockEnd: ''
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: None
|
|
||||||
ObjCBlockIndentWidth: 2
|
|
||||||
ObjCSpaceAfterProperty: false
|
|
||||||
ObjCSpaceBeforeProtocolList: true
|
|
||||||
PenaltyBreakBeforeFirstCallParameter: 19
|
|
||||||
PenaltyBreakComment: 300
|
|
||||||
PenaltyBreakFirstLessLess: 120
|
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyExcessCharacter: 1000000
|
|
||||||
PenaltyReturnTypeOnItsOwnLine: 150
|
|
||||||
PointerAlignment: Left
|
|
||||||
ReflowComments: true
|
|
||||||
SortIncludes: true
|
|
||||||
SpaceAfterCStyleCast: false
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 1
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInSquareBrackets: false
|
|
||||||
Standard: Cpp11
|
|
||||||
TabWidth: 4
|
|
||||||
UseTab: Never
|
|
||||||
...
|
|
2
externals/sirit/.gitignore
vendored
2
externals/sirit/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
build
|
|
||||||
*.o
|
|
3
externals/sirit/.gitmodules
vendored
3
externals/sirit/.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
||||||
[submodule "externals/SPIRV-Headers"]
|
|
||||||
path = externals/SPIRV-Headers
|
|
||||||
url = https://github.com/KhronosGroup/SPIRV-Headers
|
|
103
externals/sirit/CMakeLists.txt
vendored
103
externals/sirit/CMakeLists.txt
vendored
|
@ -1,103 +0,0 @@
|
||||||
# This file has been adapted from dynarmic
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.12)
|
|
||||||
project(sirit CXX)
|
|
||||||
|
|
||||||
# Determine if we're built as a subproject (using add_subdirectory)
|
|
||||||
# or if this is the master project.
|
|
||||||
set(MASTER_PROJECT OFF)
|
|
||||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
|
||||||
set(MASTER_PROJECT ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Sirit project options
|
|
||||||
option(SIRIT_TESTS "Build tests" OFF)
|
|
||||||
option(SIRIT_USE_SYSTEM_SPIRV_HEADERS "Use system SPIR-V headers" OFF)
|
|
||||||
|
|
||||||
# Default to a Release build
|
|
||||||
if (NOT CMAKE_BUILD_TYPE)
|
|
||||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
|
||||||
message(STATUS "Defaulting to a Release build")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set hard requirements for C++
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
||||||
|
|
||||||
# Warn on CMake API deprecations
|
|
||||||
set(CMAKE_WARN_DEPRECATED ON)
|
|
||||||
|
|
||||||
# Disable in-source builds
|
|
||||||
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
|
||||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
|
||||||
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
|
||||||
message(SEND_ERROR "In-source builds are not allowed.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Add the module directory to the list of paths
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules")
|
|
||||||
|
|
||||||
# Compiler flags
|
|
||||||
if (MSVC)
|
|
||||||
set(SIRIT_CXX_FLAGS
|
|
||||||
/std:c++latest # CMAKE_CXX_STANDARD as no effect on MSVC until CMake 3.10.
|
|
||||||
/W4
|
|
||||||
/w34263 # Non-virtual member function hides base class virtual function
|
|
||||||
/w44265 # Class has virtual functions, but destructor is not virtual
|
|
||||||
/w34456 # Declaration of 'var' hides previous local declaration
|
|
||||||
/w34457 # Declaration of 'var' hides function parameter
|
|
||||||
/w34458 # Declaration of 'var' hides class member
|
|
||||||
/w34459 # Declaration of 'var' hides global definition
|
|
||||||
/w34946 # Reinterpret-cast between related types
|
|
||||||
/wd4592 # Symbol will be dynamically initialized (implementation limitation)
|
|
||||||
/permissive- # Stricter C++ standards conformance
|
|
||||||
/MP
|
|
||||||
/Zi
|
|
||||||
/Zo
|
|
||||||
/EHsc
|
|
||||||
/Zc:throwingNew # Assumes new never returns null
|
|
||||||
/Zc:inline # Omits inline functions from object-file output
|
|
||||||
/DNOMINMAX
|
|
||||||
/WX)
|
|
||||||
|
|
||||||
if (CMAKE_VS_PLATFORM_TOOLSET MATCHES "LLVM-vs[0-9]+")
|
|
||||||
list(APPEND SIRIT_CXX_FLAGS
|
|
||||||
-Qunused-arguments
|
|
||||||
-Wno-missing-braces)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(SIRIT_CXX_FLAGS
|
|
||||||
-Wall
|
|
||||||
-Wextra
|
|
||||||
-Wcast-qual
|
|
||||||
-pedantic
|
|
||||||
-pedantic-errors
|
|
||||||
-Wfatal-errors
|
|
||||||
-Wno-missing-braces
|
|
||||||
-Wconversion
|
|
||||||
-Wsign-conversion
|
|
||||||
-Wshadow
|
|
||||||
-Werror)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Enable unit-testing.
|
|
||||||
enable_testing(true)
|
|
||||||
|
|
||||||
# SPIR-V headers
|
|
||||||
if (SIRIT_USE_SYSTEM_SPIRV_HEADERS)
|
|
||||||
find_package(SPIRV-Headers REQUIRED)
|
|
||||||
else()
|
|
||||||
add_subdirectory(externals/SPIRV-Headers EXCLUDE_FROM_ALL)
|
|
||||||
|
|
||||||
if (NOT TARGET SPIRV-Headers::SPIRV-Headers)
|
|
||||||
add_library(SPIRV-Headers::SPIRV-Headers ALIAS SPIRV-Headers)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# Sirit project files
|
|
||||||
add_subdirectory(src)
|
|
||||||
if (SIRIT_TESTS)
|
|
||||||
add_subdirectory(tests)
|
|
||||||
endif()
|
|
24
externals/sirit/LICENSE.txt
vendored
24
externals/sirit/LICENSE.txt
vendored
|
@ -1,24 +0,0 @@
|
||||||
Copyright (c) 2019, sirit
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the <organization> nor the
|
|
||||||
names of its contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
53
externals/sirit/README.md
vendored
53
externals/sirit/README.md
vendored
|
@ -1,53 +0,0 @@
|
||||||
Sirit
|
|
||||||
=====
|
|
||||||
A runtime SPIR-V assembler. It aims to ease dynamic SPIR-V code generation
|
|
||||||
without calling external applications (like Khronos' `spirv-as`)
|
|
||||||
|
|
||||||
Its design aims to move code that does not belong in the application to the
|
|
||||||
library, without limiting its functionality.
|
|
||||||
|
|
||||||
What Sirit does for you:
|
|
||||||
* Sort declaration opcodes
|
|
||||||
* Handle types and constant duplicates
|
|
||||||
* Emit SPIR-V opcodes
|
|
||||||
|
|
||||||
What Sirit won't do for you:
|
|
||||||
* Avoid ID duplicates (e.g. emitting the same label twice)
|
|
||||||
* Dump code to disk
|
|
||||||
* Handle control flow
|
|
||||||
* Compile from a higher level language
|
|
||||||
|
|
||||||
|
|
||||||
It's in early stages of development, many instructions are missing since
|
|
||||||
they are written manually instead of being generated from a file.
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
class MyModule : public Sirit::Module {
|
|
||||||
public:
|
|
||||||
MyModule() {}
|
|
||||||
~MyModule() = default;
|
|
||||||
|
|
||||||
void Generate() {
|
|
||||||
AddCapability(spv::Capability::Shader);
|
|
||||||
SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450);
|
|
||||||
|
|
||||||
auto main_type{TypeFunction(TypeVoid())};
|
|
||||||
auto main_func{OpFunction(TypeVoid(), spv::FunctionControlMask::MaskNone, main_type)};
|
|
||||||
AddLabel(OpLabel());
|
|
||||||
OpReturn();
|
|
||||||
OpFunctionEnd();
|
|
||||||
|
|
||||||
AddEntryPoint(spv::ExecutionModel::Vertex, main_func, "main");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Then...
|
|
||||||
|
|
||||||
MyModule module;
|
|
||||||
module.Generate();
|
|
||||||
|
|
||||||
std::vector<std::uint32_t> code{module.Assemble()};
|
|
||||||
```
|
|
1
externals/sirit/externals/SPIRV-Headers
vendored
1
externals/sirit/externals/SPIRV-Headers
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 04b76709bf40a7ce8df3382060ef3620f19de566
|
|
1365
externals/sirit/include/sirit/sirit.h
vendored
1365
externals/sirit/include/sirit/sirit.h
vendored
File diff suppressed because it is too large
Load diff
1
externals/sirit/src/.gitignore
vendored
1
externals/sirit/src/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
sirit.h
|
|
32
externals/sirit/src/CMakeLists.txt
vendored
32
externals/sirit/src/CMakeLists.txt
vendored
|
@ -1,32 +0,0 @@
|
||||||
add_library(sirit
|
|
||||||
../include/sirit/sirit.h
|
|
||||||
sirit.cpp
|
|
||||||
stream.h
|
|
||||||
common_types.h
|
|
||||||
instructions/type.cpp
|
|
||||||
instructions/constant.cpp
|
|
||||||
instructions/function.cpp
|
|
||||||
instructions/flow.cpp
|
|
||||||
instructions/debug.cpp
|
|
||||||
instructions/derivatives.cpp
|
|
||||||
instructions/memory.cpp
|
|
||||||
instructions/annotation.cpp
|
|
||||||
instructions/misc.cpp
|
|
||||||
instructions/logical.cpp
|
|
||||||
instructions/conversion.cpp
|
|
||||||
instructions/bit.cpp
|
|
||||||
instructions/arithmetic.cpp
|
|
||||||
instructions/extension.cpp
|
|
||||||
instructions/image.cpp
|
|
||||||
instructions/group.cpp
|
|
||||||
instructions/barrier.cpp
|
|
||||||
instructions/atomic.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_options(sirit PRIVATE ${SIRIT_CXX_FLAGS})
|
|
||||||
|
|
||||||
target_include_directories(sirit
|
|
||||||
PUBLIC ../include
|
|
||||||
PRIVATE .)
|
|
||||||
|
|
||||||
target_link_libraries(sirit PUBLIC SPIRV-Headers::SPIRV-Headers)
|
|
31
externals/sirit/src/common_types.h
vendored
31
externals/sirit/src/common_types.h
vendored
|
@ -1,31 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
using u8 = std::uint8_t;
|
|
||||||
using u16 = std::uint16_t;
|
|
||||||
using u32 = std::uint32_t;
|
|
||||||
using u64 = std::uint64_t;
|
|
||||||
using uptr = std::uintptr_t;
|
|
||||||
|
|
||||||
using s8 = std::int8_t;
|
|
||||||
using s16 = std::int16_t;
|
|
||||||
using s32 = std::int32_t;
|
|
||||||
using s64 = std::int64_t;
|
|
||||||
using sptr = std::intptr_t;
|
|
||||||
|
|
||||||
using f32 = float;
|
|
||||||
using f64 = double;
|
|
||||||
static_assert(sizeof(f32) == sizeof(u32), "f32 must be 32 bits wide");
|
|
||||||
static_assert(sizeof(f64) == sizeof(u64), "f64 must be 64 bits wide");
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
27
externals/sirit/src/instructions/annotation.cpp
vendored
27
externals/sirit/src/instructions/annotation.cpp
vendored
|
@ -1,27 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <span>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::Decorate(Id target, spv::Decoration decoration, std::span<const Literal> literals) {
|
|
||||||
annotations->Reserve(3 + literals.size());
|
|
||||||
return *annotations << spv::Op::OpDecorate << target << decoration << literals << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::MemberDecorate(Id structure_type, Literal member, spv::Decoration decoration,
|
|
||||||
std::span<const Literal> literals) {
|
|
||||||
annotations->Reserve(4 + literals.size());
|
|
||||||
return *annotations << spv::Op::OpMemberDecorate << structure_type << member << decoration
|
|
||||||
<< literals << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
46
externals/sirit/src/instructions/arithmetic.cpp
vendored
46
externals/sirit/src/instructions/arithmetic.cpp
vendored
|
@ -1,46 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
#define DEFINE_UNARY(funcname, opcode) \
|
|
||||||
Id Module::funcname(Id result_type, Id operand) { \
|
|
||||||
code->Reserve(4); \
|
|
||||||
return *code << OpId{opcode, result_type} << operand << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_BINARY(funcname, opcode) \
|
|
||||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \
|
|
||||||
code->Reserve(5); \
|
|
||||||
return *code << OpId{opcode, result_type} << operand_1 << operand_2 << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_UNARY(OpSNegate, spv::Op::OpSNegate)
|
|
||||||
DEFINE_UNARY(OpFNegate, spv::Op::OpFNegate)
|
|
||||||
|
|
||||||
DEFINE_BINARY(OpIAdd, spv::Op::OpIAdd)
|
|
||||||
DEFINE_BINARY(OpFAdd, spv::Op::OpFAdd)
|
|
||||||
DEFINE_BINARY(OpISub, spv::Op::OpISub)
|
|
||||||
DEFINE_BINARY(OpFSub, spv::Op::OpFSub)
|
|
||||||
DEFINE_BINARY(OpIMul, spv::Op::OpIMul)
|
|
||||||
DEFINE_BINARY(OpFMul, spv::Op::OpFMul)
|
|
||||||
DEFINE_BINARY(OpUDiv, spv::Op::OpUDiv)
|
|
||||||
DEFINE_BINARY(OpSDiv, spv::Op::OpSDiv)
|
|
||||||
DEFINE_BINARY(OpFDiv, spv::Op::OpFDiv)
|
|
||||||
DEFINE_BINARY(OpUMod, spv::Op::OpUMod)
|
|
||||||
DEFINE_BINARY(OpSMod, spv::Op::OpSMod)
|
|
||||||
DEFINE_BINARY(OpFMod, spv::Op::OpFMod)
|
|
||||||
DEFINE_BINARY(OpSRem, spv::Op::OpSRem)
|
|
||||||
DEFINE_BINARY(OpFRem, spv::Op::OpFRem)
|
|
||||||
DEFINE_BINARY(OpIAddCarry, spv::Op::OpIAddCarry)
|
|
||||||
DEFINE_BINARY(OpVectorTimesScalar, spv::Op::OpVectorTimesScalar)
|
|
||||||
DEFINE_BINARY(OpDot, spv::Op::OpDot)
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
104
externals/sirit/src/instructions/atomic.cpp
vendored
104
externals/sirit/src/instructions/atomic.cpp
vendored
|
@ -1,104 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpAtomicLoad(Id result_type, Id pointer, Id memory, Id semantics) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicLoad, result_type} << pointer << memory << semantics
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicStore(Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicStore} << pointer << memory << semantics << value
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicExchange(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicExchange, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicCompareExchange(Id result_type, Id pointer, Id memory, Id equal, Id unequal,
|
|
||||||
Id value, Id comparator) {
|
|
||||||
code->Reserve(9);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicCompareExchange, result_type} << pointer << memory
|
|
||||||
<< equal << unequal << value << comparator << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicIIncrement(Id result_type, Id pointer, Id memory, Id semantics) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicIIncrement, result_type} << pointer << memory << semantics
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicIDecrement(Id result_type, Id pointer, Id memory, Id semantics) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicIDecrement, result_type} << pointer << memory << semantics
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicIAdd(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicIAdd, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicISub(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicISub, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicSMin(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicSMin, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicUMin(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicUMin, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicSMax(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicSMax, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicUMax(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicUMax, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicAnd(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicAnd, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicOr(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicOr, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAtomicXor(Id result_type, Id pointer, Id memory, Id semantics, Id value) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpAtomicXor, result_type} << pointer << memory << semantics
|
|
||||||
<< value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
23
externals/sirit/src/instructions/barrier.cpp
vendored
23
externals/sirit/src/instructions/barrier.cpp
vendored
|
@ -1,23 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpControlBarrier(Id execution, Id memory, Id semantics) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << spv::Op::OpControlBarrier << execution << memory << semantics << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpMemoryBarrier(Id scope, Id semantics) {
|
|
||||||
code->Reserve(3);
|
|
||||||
return *code << spv::Op::OpMemoryBarrier << scope << semantics << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
76
externals/sirit/src/instructions/bit.cpp
vendored
76
externals/sirit/src/instructions/bit.cpp
vendored
|
@ -1,76 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpShiftRightLogical(Id result_type, Id base, Id shift) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpShiftRightLogical, result_type} << base << shift << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpShiftRightArithmetic(Id result_type, Id base, Id shift) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpShiftRightArithmetic, result_type} << base << shift << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpShiftLeftLogical(Id result_type, Id base, Id shift) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpShiftLeftLogical, result_type} << base << shift << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitwiseOr(Id result_type, Id operand_1, Id operand_2) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpBitwiseOr, result_type} << operand_1 << operand_2 << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitwiseXor(Id result_type, Id operand_1, Id operand_2) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpBitwiseXor, result_type} << operand_1 << operand_2 << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitwiseAnd(Id result_type, Id operand_1, Id operand_2) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpBitwiseAnd, result_type} << operand_1 << operand_2 << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpNot(Id result_type, Id operand) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpNot, result_type} << operand << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitFieldInsert(Id result_type, Id base, Id insert, Id offset, Id count) {
|
|
||||||
code->Reserve(7);
|
|
||||||
return *code << OpId{spv::Op::OpBitFieldInsert, result_type} << base << insert << offset
|
|
||||||
<< count << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitFieldSExtract(Id result_type, Id base, Id offset, Id count) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpBitFieldSExtract, result_type} << base << offset << count
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitFieldUExtract(Id result_type, Id base, Id offset, Id count) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpBitFieldUExtract, result_type} << base << offset << count
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitReverse(Id result_type, Id base) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpBitReverse, result_type} << base << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBitCount(Id result_type, Id base) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpBitCount, result_type} << base << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
48
externals/sirit/src/instructions/constant.cpp
vendored
48
externals/sirit/src/instructions/constant.cpp
vendored
|
@ -1,48 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::ConstantTrue(Id result_type) {
|
|
||||||
declarations->Reserve(3);
|
|
||||||
return *declarations << OpId{spv::Op::OpConstantTrue, result_type} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::ConstantFalse(Id result_type) {
|
|
||||||
declarations->Reserve(3);
|
|
||||||
return *declarations << OpId{spv::Op::OpConstantFalse, result_type} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::Constant(Id result_type, const Literal& literal) {
|
|
||||||
declarations->Reserve(3 + 2);
|
|
||||||
return *declarations << OpId{spv::Op::OpConstant, result_type} << literal << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::ConstantComposite(Id result_type, std::span<const Id> constituents) {
|
|
||||||
declarations->Reserve(3 + constituents.size());
|
|
||||||
return *declarations << OpId{spv::Op::OpConstantComposite, result_type} << constituents
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::ConstantSampler(Id result_type, spv::SamplerAddressingMode addressing_mode,
|
|
||||||
bool normalized, spv::SamplerFilterMode filter_mode) {
|
|
||||||
declarations->Reserve(6);
|
|
||||||
return *declarations << OpId{spv::Op::OpConstantSampler, result_type} << addressing_mode
|
|
||||||
<< normalized << filter_mode << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::ConstantNull(Id result_type) {
|
|
||||||
declarations->Reserve(3);
|
|
||||||
return *declarations << OpId{spv::Op::OpConstantNull, result_type} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
29
externals/sirit/src/instructions/conversion.cpp
vendored
29
externals/sirit/src/instructions/conversion.cpp
vendored
|
@ -1,29 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
#define DEFINE_UNARY(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id operand) { \
|
|
||||||
code->Reserve(4); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << operand << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_UNARY(OpConvertFToU)
|
|
||||||
DEFINE_UNARY(OpConvertFToS)
|
|
||||||
DEFINE_UNARY(OpConvertSToF)
|
|
||||||
DEFINE_UNARY(OpConvertUToF)
|
|
||||||
DEFINE_UNARY(OpUConvert)
|
|
||||||
DEFINE_UNARY(OpSConvert)
|
|
||||||
DEFINE_UNARY(OpFConvert)
|
|
||||||
DEFINE_UNARY(OpQuantizeToF16)
|
|
||||||
DEFINE_UNARY(OpBitcast)
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
36
externals/sirit/src/instructions/debug.cpp
vendored
36
externals/sirit/src/instructions/debug.cpp
vendored
|
@ -1,36 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "common_types.h"
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::Name(Id target, std::string_view name) {
|
|
||||||
debug->Reserve(3 + WordsInString(name));
|
|
||||||
*debug << spv::Op::OpName << target << name << EndOp{};
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::MemberName(Id type, u32 member, std::string_view name) {
|
|
||||||
debug->Reserve(4 + WordsInString(name));
|
|
||||||
*debug << spv::Op::OpMemberName << type << member << name << EndOp{};
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::String(std::string_view string) {
|
|
||||||
debug->Reserve(3 + WordsInString(string));
|
|
||||||
return *debug << OpId{spv::Op::OpString} << string << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpLine(Id file, Literal line, Literal column) {
|
|
||||||
debug->Reserve(4);
|
|
||||||
return *debug << spv::Op::OpLine << file << line << column << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
29
externals/sirit/src/instructions/derivatives.cpp
vendored
29
externals/sirit/src/instructions/derivatives.cpp
vendored
|
@ -1,29 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2021 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
#define DEFINE_UNARY(funcname, opcode) \
|
|
||||||
Id Module::funcname(Id result_type, Id operand) { \
|
|
||||||
code->Reserve(4); \
|
|
||||||
return *code << OpId{opcode, result_type} << operand << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_UNARY(OpDPdx, spv::Op::OpDPdx)
|
|
||||||
DEFINE_UNARY(OpDPdy, spv::Op::OpDPdy)
|
|
||||||
DEFINE_UNARY(OpFwidth, spv::Op::OpFwidth)
|
|
||||||
DEFINE_UNARY(OpDPdxFine, spv::Op::OpDPdxFine)
|
|
||||||
DEFINE_UNARY(OpDPdyFine, spv::Op::OpDPdyFine)
|
|
||||||
DEFINE_UNARY(OpFwidthFine, spv::Op::OpFwidthFine)
|
|
||||||
DEFINE_UNARY(OpDPdxCoarse, spv::Op::OpDPdxCoarse)
|
|
||||||
DEFINE_UNARY(OpDPdyCoarse, spv::Op::OpDPdyCoarse)
|
|
||||||
DEFINE_UNARY(OpFwidthCoarse, spv::Op::OpFwidthCoarse)
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
80
externals/sirit/src/instructions/extension.cpp
vendored
80
externals/sirit/src/instructions/extension.cpp
vendored
|
@ -1,80 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <spirv/unified1/GLSL.std.450.h>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpExtInst(Id result_type, Id set, u32 instruction, std::span<const Id> operands) {
|
|
||||||
code->Reserve(5 + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpExtInst, result_type} << set << instruction << operands
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_UNARY(funcname, opcode) \
|
|
||||||
Id Module::funcname(Id result_type, Id operand) { \
|
|
||||||
return OpExtInst(result_type, GetGLSLstd450(), opcode, operand); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_BINARY(funcname, opcode) \
|
|
||||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2) { \
|
|
||||||
return OpExtInst(result_type, GetGLSLstd450(), opcode, operand_1, operand_2); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_TRINARY(funcname, opcode) \
|
|
||||||
Id Module::funcname(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \
|
|
||||||
return OpExtInst(result_type, GetGLSLstd450(), opcode, operand_1, operand_2, operand_3); \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_UNARY(OpFAbs, GLSLstd450FAbs)
|
|
||||||
DEFINE_UNARY(OpSAbs, GLSLstd450SAbs)
|
|
||||||
DEFINE_UNARY(OpRound, GLSLstd450Round)
|
|
||||||
DEFINE_UNARY(OpRoundEven, GLSLstd450RoundEven)
|
|
||||||
DEFINE_UNARY(OpTrunc, GLSLstd450Trunc)
|
|
||||||
DEFINE_UNARY(OpFSign, GLSLstd450FSign)
|
|
||||||
DEFINE_UNARY(OpSSign, GLSLstd450SSign)
|
|
||||||
DEFINE_UNARY(OpFloor, GLSLstd450Floor)
|
|
||||||
DEFINE_UNARY(OpCeil, GLSLstd450Ceil)
|
|
||||||
DEFINE_UNARY(OpFract, GLSLstd450Fract)
|
|
||||||
DEFINE_UNARY(OpSin, GLSLstd450Sin)
|
|
||||||
DEFINE_UNARY(OpCos, GLSLstd450Cos)
|
|
||||||
DEFINE_UNARY(OpAsin, GLSLstd450Asin)
|
|
||||||
DEFINE_UNARY(OpAcos, GLSLstd450Acos)
|
|
||||||
DEFINE_BINARY(OpPow, GLSLstd450Pow)
|
|
||||||
DEFINE_UNARY(OpExp, GLSLstd450Exp)
|
|
||||||
DEFINE_UNARY(OpLog, GLSLstd450Log)
|
|
||||||
DEFINE_UNARY(OpExp2, GLSLstd450Exp2)
|
|
||||||
DEFINE_UNARY(OpLog2, GLSLstd450Log2)
|
|
||||||
DEFINE_UNARY(OpSqrt, GLSLstd450Sqrt)
|
|
||||||
DEFINE_UNARY(OpInverseSqrt, GLSLstd450InverseSqrt)
|
|
||||||
DEFINE_BINARY(OpFMin, GLSLstd450FMin)
|
|
||||||
DEFINE_BINARY(OpUMin, GLSLstd450UMin)
|
|
||||||
DEFINE_BINARY(OpSMin, GLSLstd450SMin)
|
|
||||||
DEFINE_BINARY(OpFMax, GLSLstd450FMax)
|
|
||||||
DEFINE_BINARY(OpUMax, GLSLstd450UMax)
|
|
||||||
DEFINE_BINARY(OpSMax, GLSLstd450SMax)
|
|
||||||
DEFINE_TRINARY(OpFClamp, GLSLstd450FClamp)
|
|
||||||
DEFINE_TRINARY(OpUClamp, GLSLstd450UClamp)
|
|
||||||
DEFINE_TRINARY(OpSClamp, GLSLstd450SClamp)
|
|
||||||
DEFINE_TRINARY(OpFma, GLSLstd450Fma)
|
|
||||||
DEFINE_UNARY(OpPackHalf2x16, GLSLstd450PackHalf2x16)
|
|
||||||
DEFINE_UNARY(OpUnpackHalf2x16, GLSLstd450UnpackHalf2x16)
|
|
||||||
DEFINE_UNARY(OpFindILsb, GLSLstd450FindILsb)
|
|
||||||
DEFINE_UNARY(OpFindSMsb, GLSLstd450FindSMsb)
|
|
||||||
DEFINE_UNARY(OpFindUMsb, GLSLstd450FindUMsb)
|
|
||||||
DEFINE_UNARY(OpInterpolateAtCentroid, GLSLstd450InterpolateAtCentroid)
|
|
||||||
DEFINE_BINARY(OpInterpolateAtSample, GLSLstd450InterpolateAtSample)
|
|
||||||
DEFINE_BINARY(OpInterpolateAtOffset, GLSLstd450InterpolateAtOffset)
|
|
||||||
DEFINE_UNARY(OpNormalize, GLSLstd450Normalize)
|
|
||||||
DEFINE_BINARY(OpCross, GLSLstd450Cross)
|
|
||||||
DEFINE_UNARY(OpLength, GLSLstd450Length)
|
|
||||||
DEFINE_TRINARY(OpFMix, GLSLstd450FMix)
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
109
externals/sirit/src/instructions/flow.cpp
vendored
109
externals/sirit/src/instructions/flow.cpp
vendored
|
@ -1,109 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpPhi(Id result_type, std::span<const Id> operands) {
|
|
||||||
assert(operands.size() % 2 == 0);
|
|
||||||
code->Reserve(3 + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpPhi, result_type} << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::DeferredOpPhi(Id result_type, std::span<const Id> blocks) {
|
|
||||||
deferred_phi_nodes.push_back(code->LocalAddress());
|
|
||||||
code->Reserve(3 + blocks.size() * 2);
|
|
||||||
*code << OpId{spv::Op::OpPhi, result_type};
|
|
||||||
for (const Id block : blocks) {
|
|
||||||
*code << u32{0} << block;
|
|
||||||
}
|
|
||||||
return *code << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpLoopMerge(Id merge_block, Id continue_target, spv::LoopControlMask loop_control,
|
|
||||||
std::span<const Id> literals) {
|
|
||||||
code->Reserve(4 + literals.size());
|
|
||||||
return *code << spv::Op::OpLoopMerge << merge_block << continue_target << loop_control
|
|
||||||
<< literals << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpSelectionMerge(Id merge_block, spv::SelectionControlMask selection_control) {
|
|
||||||
code->Reserve(3);
|
|
||||||
return *code << spv::Op::OpSelectionMerge << merge_block << selection_control << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpLabel() {
|
|
||||||
return Id{++bound};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBranch(Id target_label) {
|
|
||||||
code->Reserve(2);
|
|
||||||
return *code << spv::Op::OpBranch << target_label << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpBranchConditional(Id condition, Id true_label, Id false_label, u32 true_weight,
|
|
||||||
u32 false_weight) {
|
|
||||||
code->Reserve(6);
|
|
||||||
*code << spv::Op::OpBranchConditional << condition << true_label << false_label;
|
|
||||||
if (true_weight != 0 || false_weight != 0) {
|
|
||||||
*code << true_weight << false_weight;
|
|
||||||
}
|
|
||||||
return *code << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpSwitch(Id selector, Id default_label, std::span<const Literal> literals,
|
|
||||||
std::span<const Id> labels) {
|
|
||||||
assert(literals.size() == labels.size());
|
|
||||||
const size_t size = literals.size();
|
|
||||||
code->Reserve(3 + size * 2);
|
|
||||||
|
|
||||||
*code << spv::Op::OpSwitch << selector << default_label;
|
|
||||||
for (std::size_t i = 0; i < size; ++i) {
|
|
||||||
*code << literals[i] << labels[i];
|
|
||||||
}
|
|
||||||
return *code << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpReturn() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpReturn << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpUnreachable() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpUnreachable << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpReturnValue(Id value) {
|
|
||||||
code->Reserve(2);
|
|
||||||
return *code << spv::Op::OpReturnValue << value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpKill() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpKill << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpDemoteToHelperInvocation() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpDemoteToHelperInvocation << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpDemoteToHelperInvocationEXT() {
|
|
||||||
OpDemoteToHelperInvocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpTerminateInvocation() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpTerminateInvocation << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
34
externals/sirit/src/instructions/function.cpp
vendored
34
externals/sirit/src/instructions/function.cpp
vendored
|
@ -1,34 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpFunction(Id result_type, spv::FunctionControlMask function_control, Id function_type) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpFunction, result_type} << function_control << function_type
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpFunctionEnd() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpFunctionEnd << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpFunctionCall(Id result_type, Id function, std::span<const Id> arguments) {
|
|
||||||
code->Reserve(4 + arguments.size());
|
|
||||||
return *code << OpId{spv::Op::OpFunctionCall, result_type} << function << arguments << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpFunctionParameter(Id result_type) {
|
|
||||||
code->Reserve(3);
|
|
||||||
return *code << OpId{spv::Op::OpFunctionParameter, result_type} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
88
externals/sirit/src/instructions/group.cpp
vendored
88
externals/sirit/src/instructions/group.cpp
vendored
|
@ -1,88 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpSubgroupBallotKHR(Id result_type, Id predicate) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpSubgroupBallotKHR, result_type} << predicate << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpSubgroupReadInvocationKHR(Id result_type, Id value, Id index) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpSubgroupReadInvocationKHR, result_type} << value << index
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpSubgroupAllKHR(Id result_type, Id predicate) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpSubgroupAllKHR, result_type} << predicate << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpSubgroupAnyKHR(Id result_type, Id predicate) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpSubgroupAnyKHR, result_type} << predicate << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpSubgroupAllEqualKHR(Id result_type, Id predicate) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpSubgroupAllEqualKHR, result_type} << predicate << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformElect(Id result_type, Id scope) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformElect, result_type} << scope << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformBroadcastFirst(Id result_type, Id scope, Id value) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformBroadcastFirst, result_type} << scope << value
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformBroadcast(Id result_type, Id scope, Id value, Id id) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformBroadcast, result_type} << scope << value
|
|
||||||
<< id << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformShuffle(Id result_type, Id scope, Id value, Id id) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformShuffle, result_type} << scope << value << id
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformShuffleXor(Id result_type, Id scope, Id value, Id mask) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformShuffleXor, result_type} << scope << value
|
|
||||||
<< mask << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformAll(Id result_type, Id scope, Id predicate) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformAll, result_type} << scope << predicate << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformAny(Id result_type, Id scope, Id predicate) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformAny, result_type} << scope << predicate << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformAllEqual(Id result_type, Id scope, Id value) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformAllEqual, result_type} << scope << value << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpGroupNonUniformBallot(Id result_type, Id scope, Id predicate) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpGroupNonUniformBallot, result_type} << scope << predicate << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
169
externals/sirit/src/instructions/image.cpp
vendored
169
externals/sirit/src/instructions/image.cpp
vendored
|
@ -1,169 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
#define DEFINE_IMAGE_OP(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands, \
|
|
||||||
std::span<const Id> operands) { \
|
|
||||||
code->Reserve(6 + operands.size()); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate \
|
|
||||||
<< image_operands << operands << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_IMAGE_EXP_OP(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, \
|
|
||||||
spv::ImageOperandsMask image_operands, std::span<const Id> operands) { \
|
|
||||||
code->Reserve(6 + operands.size()); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate \
|
|
||||||
<< image_operands << operands << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_IMAGE_EXTRA_OP(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands, \
|
|
||||||
std::span<const Id> operands) { \
|
|
||||||
code->Reserve(7 + operands.size()); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate << extra \
|
|
||||||
<< image_operands << operands << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_IMAGE_EXTRA_EXP_OP(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id sampled_image, Id coordinate, Id extra, \
|
|
||||||
spv::ImageOperandsMask image_operands, std::span<const Id> operands) { \
|
|
||||||
code->Reserve(8 + operands.size()); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << sampled_image << coordinate << extra \
|
|
||||||
<< image_operands << operands << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_IMAGE_QUERY_OP(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id image) { \
|
|
||||||
code->Reserve(5); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << image << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_IMAGE_QUERY_BIN_OP(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id image, Id extra) { \
|
|
||||||
code->Reserve(5); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << image << extra << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_IMAGE_OP(OpImageSampleImplicitLod)
|
|
||||||
DEFINE_IMAGE_EXP_OP(OpImageSampleExplicitLod)
|
|
||||||
DEFINE_IMAGE_EXTRA_OP(OpImageSampleDrefImplicitLod)
|
|
||||||
DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleDrefExplicitLod)
|
|
||||||
DEFINE_IMAGE_OP(OpImageSampleProjImplicitLod)
|
|
||||||
DEFINE_IMAGE_EXP_OP(OpImageSampleProjExplicitLod)
|
|
||||||
DEFINE_IMAGE_EXTRA_OP(OpImageSampleProjDrefImplicitLod)
|
|
||||||
DEFINE_IMAGE_EXTRA_EXP_OP(OpImageSampleProjDrefExplicitLod)
|
|
||||||
DEFINE_IMAGE_OP(OpImageFetch)
|
|
||||||
DEFINE_IMAGE_EXTRA_OP(OpImageGather)
|
|
||||||
DEFINE_IMAGE_EXTRA_OP(OpImageDrefGather)
|
|
||||||
DEFINE_IMAGE_OP(OpImageRead)
|
|
||||||
DEFINE_IMAGE_QUERY_BIN_OP(OpImageQuerySizeLod)
|
|
||||||
DEFINE_IMAGE_QUERY_OP(OpImageQuerySize)
|
|
||||||
DEFINE_IMAGE_QUERY_BIN_OP(OpImageQueryLod)
|
|
||||||
DEFINE_IMAGE_QUERY_OP(OpImageQueryLevels)
|
|
||||||
DEFINE_IMAGE_QUERY_OP(OpImageQuerySamples)
|
|
||||||
|
|
||||||
Id Module::OpSampledImage(Id result_type, Id image, Id sampler) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpSampledImage, result_type} << image << sampler << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageWrite(Id image, Id coordinate, Id texel,
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
assert(image_operands.has_value() != operands.empty());
|
|
||||||
code->Reserve(5 + operands.size());
|
|
||||||
return *code << spv::Op::OpImageWrite << image << coordinate << texel << image_operands
|
|
||||||
<< operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImage(Id result_type, Id sampled_image) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpImage, result_type} << sampled_image << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseSampleImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(5 + (image_operands.has_value() ? 1 : 0) + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseSampleImplicitLod, result_type} << sampled_image
|
|
||||||
<< coordinate << image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseSampleExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
|
||||||
spv::ImageOperandsMask image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(6 + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseSampleExplicitLod, result_type} << sampled_image
|
|
||||||
<< coordinate << image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseSampleDrefImplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
|
||||||
Id dref,
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(6 + (image_operands.has_value() ? 1 : 0) + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseSampleDrefImplicitLod, result_type} << sampled_image
|
|
||||||
<< coordinate << dref << image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseSampleDrefExplicitLod(Id result_type, Id sampled_image, Id coordinate,
|
|
||||||
Id dref, spv::ImageOperandsMask image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(7 + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseSampleDrefExplicitLod, result_type} << sampled_image
|
|
||||||
<< coordinate << dref << image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseFetch(Id result_type, Id image, Id coordinate,
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(5 + (image_operands.has_value() ? 1 : 0) + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseFetch, result_type} << image << coordinate
|
|
||||||
<< image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseGather(Id result_type, Id sampled_image, Id coordinate, Id component,
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(6 + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseGather, result_type} << sampled_image << coordinate
|
|
||||||
<< component << image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseDrefGather(Id result_type, Id sampled_image, Id coordinate, Id dref,
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(6 + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseDrefGather, result_type} << sampled_image
|
|
||||||
<< coordinate << dref << image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseTexelsResident(Id result_type, Id resident_code) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseTexelsResident, result_type} << resident_code
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpImageSparseRead(Id result_type, Id image, Id coordinate,
|
|
||||||
std::optional<spv::ImageOperandsMask> image_operands,
|
|
||||||
std::span<const Id> operands) {
|
|
||||||
code->Reserve(5 + (image_operands.has_value() ? 1 : 0) + operands.size());
|
|
||||||
return *code << OpId{spv::Op::OpImageSparseTexelsResident, result_type} << image << coordinate
|
|
||||||
<< image_operands << operands << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
65
externals/sirit/src/instructions/logical.cpp
vendored
65
externals/sirit/src/instructions/logical.cpp
vendored
|
@ -1,65 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
#define DEFINE_UNARY(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id operand) { \
|
|
||||||
code->Reserve(4); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << operand << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_BINARY(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id operand_1, Id operand_2) { \
|
|
||||||
code->Reserve(5); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << operand_1 << operand_2 << EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_TRINARY(opcode) \
|
|
||||||
Id Module::opcode(Id result_type, Id operand_1, Id operand_2, Id operand_3) { \
|
|
||||||
code->Reserve(6); \
|
|
||||||
return *code << OpId{spv::Op::opcode, result_type} << operand_1 << operand_2 << operand_3 \
|
|
||||||
<< EndOp{}; \
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_UNARY(OpAny)
|
|
||||||
DEFINE_UNARY(OpAll)
|
|
||||||
DEFINE_UNARY(OpIsNan)
|
|
||||||
DEFINE_UNARY(OpIsInf)
|
|
||||||
DEFINE_BINARY(OpLogicalEqual)
|
|
||||||
DEFINE_BINARY(OpLogicalNotEqual)
|
|
||||||
DEFINE_BINARY(OpLogicalOr)
|
|
||||||
DEFINE_BINARY(OpLogicalAnd)
|
|
||||||
DEFINE_UNARY(OpLogicalNot)
|
|
||||||
DEFINE_TRINARY(OpSelect)
|
|
||||||
DEFINE_BINARY(OpIEqual)
|
|
||||||
DEFINE_BINARY(OpINotEqual)
|
|
||||||
DEFINE_BINARY(OpUGreaterThan)
|
|
||||||
DEFINE_BINARY(OpSGreaterThan)
|
|
||||||
DEFINE_BINARY(OpUGreaterThanEqual)
|
|
||||||
DEFINE_BINARY(OpSGreaterThanEqual)
|
|
||||||
DEFINE_BINARY(OpULessThan)
|
|
||||||
DEFINE_BINARY(OpSLessThan)
|
|
||||||
DEFINE_BINARY(OpULessThanEqual)
|
|
||||||
DEFINE_BINARY(OpSLessThanEqual)
|
|
||||||
DEFINE_BINARY(OpFOrdEqual)
|
|
||||||
DEFINE_BINARY(OpFUnordEqual)
|
|
||||||
DEFINE_BINARY(OpFOrdNotEqual)
|
|
||||||
DEFINE_BINARY(OpFUnordNotEqual)
|
|
||||||
DEFINE_BINARY(OpFOrdLessThan)
|
|
||||||
DEFINE_BINARY(OpFUnordLessThan)
|
|
||||||
DEFINE_BINARY(OpFOrdGreaterThan)
|
|
||||||
DEFINE_BINARY(OpFUnordGreaterThan)
|
|
||||||
DEFINE_BINARY(OpFOrdLessThanEqual)
|
|
||||||
DEFINE_BINARY(OpFUnordLessThanEqual)
|
|
||||||
DEFINE_BINARY(OpFOrdGreaterThanEqual)
|
|
||||||
DEFINE_BINARY(OpFUnordGreaterThanEqual)
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
74
externals/sirit/src/instructions/memory.cpp
vendored
74
externals/sirit/src/instructions/memory.cpp
vendored
|
@ -1,74 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpImageTexelPointer(Id result_type, Id image, Id coordinate, Id sample) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpImageTexelPointer, result_type} << image << coordinate << sample
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpLoad(Id result_type, Id pointer, std::optional<spv::MemoryAccessMask> memory_access) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpLoad, result_type} << pointer << memory_access << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpStore(Id pointer, Id object, std::optional<spv::MemoryAccessMask> memory_access) {
|
|
||||||
code->Reserve(4);
|
|
||||||
return *code << spv::Op::OpStore << pointer << object << memory_access << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpAccessChain(Id result_type, Id base, std::span<const Id> indexes) {
|
|
||||||
assert(!indexes.empty());
|
|
||||||
code->Reserve(4 + indexes.size());
|
|
||||||
return *code << OpId{spv::Op::OpAccessChain, result_type} << base << indexes << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpVectorExtractDynamic(Id result_type, Id vector, Id index) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpVectorExtractDynamic, result_type} << vector << index
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpVectorInsertDynamic(Id result_type, Id vector, Id component, Id index) {
|
|
||||||
code->Reserve(6);
|
|
||||||
return *code << OpId{spv::Op::OpVectorInsertDynamic, result_type} << vector << component
|
|
||||||
<< index << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpVectorShuffle(Id result_type, Id vector_1, Id vector_2, std::span<const Literal> components) {
|
|
||||||
code->Reserve(5 + components.size());
|
|
||||||
return *code << OpId{spv::Op::OpVectorShuffle, result_type} << vector_1 << vector_2
|
|
||||||
<< components << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpCompositeInsert(Id result_type, Id object, Id composite,
|
|
||||||
std::span<const Literal> indexes) {
|
|
||||||
code->Reserve(5 + indexes.size());
|
|
||||||
return *code << OpId{spv::Op::OpCompositeInsert, result_type} << object << composite << indexes
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpCompositeExtract(Id result_type, Id composite, std::span<const Literal> indexes) {
|
|
||||||
code->Reserve(4 + indexes.size());
|
|
||||||
return *code << OpId{spv::Op::OpCompositeExtract, result_type} << composite << indexes
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::OpCompositeConstruct(Id result_type, std::span<const Id> ids) {
|
|
||||||
assert(ids.size() >= 1);
|
|
||||||
code->Reserve(3 + ids.size());
|
|
||||||
return *code << OpId{spv::Op::OpCompositeConstruct, result_type} << ids << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
38
externals/sirit/src/instructions/misc.cpp
vendored
38
externals/sirit/src/instructions/misc.cpp
vendored
|
@ -1,38 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::OpUndef(Id result_type) {
|
|
||||||
code->Reserve(3);
|
|
||||||
return *code << OpId{spv::Op::OpUndef, result_type} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpEmitVertex() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpEmitVertex << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpEndPrimitive() {
|
|
||||||
code->Reserve(1);
|
|
||||||
*code << spv::Op::OpEndPrimitive << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpEmitStreamVertex(Id stream) {
|
|
||||||
code->Reserve(2);
|
|
||||||
*code << spv::Op::OpEmitStreamVertex << stream << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::OpEndStreamPrimitive(Id stream) {
|
|
||||||
code->Reserve(2);
|
|
||||||
*code << spv::Op::OpEndStreamPrimitive << stream << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
130
externals/sirit/src/instructions/type.cpp
vendored
130
externals/sirit/src/instructions/type.cpp
vendored
|
@ -1,130 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
Id Module::TypeVoid() {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeVoid} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeBool() {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeBool} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeInt(int width, bool is_signed) {
|
|
||||||
declarations->Reserve(4);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeInt} << width << is_signed << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeSInt(int width) {
|
|
||||||
return TypeInt(width, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeUInt(int width) {
|
|
||||||
return TypeInt(width, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeFloat(int width) {
|
|
||||||
declarations->Reserve(3);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeFloat} << width << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeVector(Id component_type, int component_count) {
|
|
||||||
assert(component_count >= 2);
|
|
||||||
declarations->Reserve(4);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeVector} << component_type << component_count
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeMatrix(Id column_type, int column_count) {
|
|
||||||
assert(column_count >= 2);
|
|
||||||
declarations->Reserve(4);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeMatrix} << column_type << column_count << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeImage(Id sampled_type, spv::Dim dim, int depth, bool arrayed, bool ms, int sampled,
|
|
||||||
spv::ImageFormat image_format,
|
|
||||||
std::optional<spv::AccessQualifier> access_qualifier) {
|
|
||||||
declarations->Reserve(10);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeImage} << sampled_type << dim << depth << arrayed
|
|
||||||
<< ms << sampled << image_format << access_qualifier << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeSampler() {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeSampler} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeSampledImage(Id image_type) {
|
|
||||||
declarations->Reserve(3);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeSampledImage} << image_type << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeArray(Id element_type, Id length) {
|
|
||||||
declarations->Reserve(4);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeArray} << element_type << length << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeRuntimeArray(Id element_type) {
|
|
||||||
declarations->Reserve(3);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeRuntimeArray} << element_type << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeStruct(std::span<const Id> members) {
|
|
||||||
declarations->Reserve(2 + members.size());
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeStruct} << members << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeOpaque(std::string_view name) {
|
|
||||||
declarations->Reserve(3 + WordsInString(name));
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeOpaque} << name << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypePointer(spv::StorageClass storage_class, Id type) {
|
|
||||||
declarations->Reserve(4);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypePointer} << storage_class << type << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeFunction(Id return_type, std::span<const Id> arguments) {
|
|
||||||
declarations->Reserve(3 + arguments.size());
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeFunction} << return_type << arguments << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeEvent() {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeEvent} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeDeviceEvent() {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeDeviceEvent} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeReserveId() {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeReserveId} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypeQueue() {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypeQueue} << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::TypePipe(spv::AccessQualifier access_qualifier) {
|
|
||||||
declarations->Reserve(2);
|
|
||||||
return *declarations << OpId{spv::Op::OpTypePipe} << access_qualifier << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
142
externals/sirit/src/sirit.cpp
vendored
142
externals/sirit/src/sirit.cpp
vendored
|
@ -1,142 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "sirit/sirit.h"
|
|
||||||
|
|
||||||
#include "common_types.h"
|
|
||||||
#include "stream.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
constexpr u32 MakeWord0(spv::Op op, size_t word_count) {
|
|
||||||
return static_cast<u32>(op) | static_cast<u32>(word_count) << 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
Module::Module(u32 version_)
|
|
||||||
: version{version_}, ext_inst_imports{std::make_unique<Stream>(&bound)},
|
|
||||||
entry_points{std::make_unique<Stream>(&bound)},
|
|
||||||
execution_modes{std::make_unique<Stream>(&bound)}, debug{std::make_unique<Stream>(&bound)},
|
|
||||||
annotations{std::make_unique<Stream>(&bound)}, declarations{std::make_unique<Declarations>(
|
|
||||||
&bound)},
|
|
||||||
global_variables{std::make_unique<Stream>(&bound)}, code{std::make_unique<Stream>(&bound)} {}
|
|
||||||
|
|
||||||
Module::~Module() = default;
|
|
||||||
|
|
||||||
std::vector<u32> Module::Assemble() const {
|
|
||||||
std::vector<u32> words = {spv::MagicNumber, version, GENERATOR_MAGIC_NUMBER, bound + 1, 0};
|
|
||||||
const auto insert = [&words](std::span<const u32> input) {
|
|
||||||
words.insert(words.end(), input.begin(), input.end());
|
|
||||||
};
|
|
||||||
|
|
||||||
words.reserve(words.size() + capabilities.size() * 2);
|
|
||||||
for (const spv::Capability capability : capabilities) {
|
|
||||||
insert(std::array{
|
|
||||||
MakeWord0(spv::Op::OpCapability, 2),
|
|
||||||
static_cast<u32>(capability),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const std::string_view extension_name : extensions) {
|
|
||||||
size_t string_words = WordsInString(extension_name);
|
|
||||||
words.push_back(MakeWord0(spv::Op::OpExtension, string_words + 1));
|
|
||||||
size_t insert_index = words.size();
|
|
||||||
words.resize(words.size() + string_words);
|
|
||||||
InsertStringView(words, insert_index, extension_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
insert(ext_inst_imports->Words());
|
|
||||||
|
|
||||||
insert(std::array{
|
|
||||||
MakeWord0(spv::Op::OpMemoryModel, 3),
|
|
||||||
static_cast<u32>(addressing_model),
|
|
||||||
static_cast<u32>(memory_model),
|
|
||||||
});
|
|
||||||
|
|
||||||
insert(entry_points->Words());
|
|
||||||
insert(execution_modes->Words());
|
|
||||||
insert(debug->Words());
|
|
||||||
insert(annotations->Words());
|
|
||||||
insert(declarations->Words());
|
|
||||||
insert(global_variables->Words());
|
|
||||||
insert(code->Words());
|
|
||||||
|
|
||||||
return words;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::PatchDeferredPhi(const std::function<Id(std::size_t index)>& func) {
|
|
||||||
for (const u32 phi_index : deferred_phi_nodes) {
|
|
||||||
const u32 first_word = code->Value(phi_index);
|
|
||||||
[[maybe_unused]] const spv::Op op = static_cast<spv::Op>(first_word & 0xffff);
|
|
||||||
assert(op == spv::Op::OpPhi);
|
|
||||||
const u32 num_words = first_word >> 16;
|
|
||||||
const u32 num_args = (num_words - 3) / 2;
|
|
||||||
u32 cursor = phi_index + 3;
|
|
||||||
for (u32 arg = 0; arg < num_args; ++arg, cursor += 2) {
|
|
||||||
code->SetValue(cursor, func(arg).value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::AddExtension(std::string extension_name) {
|
|
||||||
extensions.insert(std::move(extension_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::AddCapability(spv::Capability capability) {
|
|
||||||
capabilities.insert(capability);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::SetMemoryModel(spv::AddressingModel addressing_model_,
|
|
||||||
spv::MemoryModel memory_model_) {
|
|
||||||
addressing_model = addressing_model_;
|
|
||||||
memory_model = memory_model_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::AddEntryPoint(spv::ExecutionModel execution_model, Id entry_point,
|
|
||||||
std::string_view name, std::span<const Id> interfaces) {
|
|
||||||
entry_points->Reserve(4 + WordsInString(name) + interfaces.size());
|
|
||||||
*entry_points << spv::Op::OpEntryPoint << execution_model << entry_point << name << interfaces
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module::AddExecutionMode(Id entry_point, spv::ExecutionMode mode,
|
|
||||||
std::span<const Literal> literals) {
|
|
||||||
execution_modes->Reserve(3 + literals.size());
|
|
||||||
*execution_modes << spv::Op::OpExecutionMode << entry_point << mode << literals << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::AddLabel(Id label) {
|
|
||||||
assert(label.value != 0);
|
|
||||||
code->Reserve(2);
|
|
||||||
*code << MakeWord0(spv::Op::OpLabel, 2) << label.value;
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::AddLocalVariable(Id result_type, spv::StorageClass storage_class,
|
|
||||||
std::optional<Id> initializer) {
|
|
||||||
code->Reserve(5);
|
|
||||||
return *code << OpId{spv::Op::OpVariable, result_type} << storage_class << initializer
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::AddGlobalVariable(Id result_type, spv::StorageClass storage_class,
|
|
||||||
std::optional<Id> initializer) {
|
|
||||||
global_variables->Reserve(5);
|
|
||||||
return *global_variables << OpId{spv::Op::OpVariable, result_type} << storage_class
|
|
||||||
<< initializer << EndOp{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Id Module::GetGLSLstd450() {
|
|
||||||
if (!glsl_std_450) {
|
|
||||||
ext_inst_imports->Reserve(3 + 4);
|
|
||||||
glsl_std_450 = *ext_inst_imports << OpId{spv::Op::OpExtInstImport} << "GLSL.std.450"
|
|
||||||
<< EndOp{};
|
|
||||||
}
|
|
||||||
return *glsl_std_450;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
0
externals/sirit/src/stream.cpp
vendored
0
externals/sirit/src/stream.cpp
vendored
267
externals/sirit/src/stream.h
vendored
267
externals/sirit/src/stream.h
vendored
|
@ -1,267 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <bit>
|
|
||||||
#include <cassert>
|
|
||||||
#include <concepts>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <functional>
|
|
||||||
#include <span>
|
|
||||||
#include <string_view>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#ifndef __cpp_lib_bit_cast
|
|
||||||
#include <cstring>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <spirv/unified1/spirv.hpp>
|
|
||||||
|
|
||||||
#include "common_types.h"
|
|
||||||
|
|
||||||
namespace Sirit {
|
|
||||||
|
|
||||||
class Declarations;
|
|
||||||
|
|
||||||
struct OpId {
|
|
||||||
OpId(spv::Op opcode_) : opcode{opcode_} {}
|
|
||||||
OpId(spv::Op opcode_, Id result_type_) : opcode{opcode_}, result_type{result_type_} {
|
|
||||||
assert(result_type.value != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
spv::Op opcode{};
|
|
||||||
Id result_type{};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EndOp {};
|
|
||||||
|
|
||||||
inline size_t WordsInString(std::string_view string) {
|
|
||||||
return string.size() / sizeof(u32) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void InsertStringView(std::vector<u32>& words, size_t& insert_index,
|
|
||||||
std::string_view string) {
|
|
||||||
const size_t size = string.size();
|
|
||||||
const auto read = [string, size](size_t offset) {
|
|
||||||
return offset < size ? static_cast<u32>(string[offset]) : 0u;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i += sizeof(u32)) {
|
|
||||||
words[insert_index++] = read(i) | read(i + 1) << 8 | read(i + 2) << 16 | read(i + 3) << 24;
|
|
||||||
}
|
|
||||||
if (size % sizeof(u32) == 0) {
|
|
||||||
words[insert_index++] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Stream {
|
|
||||||
friend Declarations;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Stream(u32* bound_) : bound{bound_} {}
|
|
||||||
|
|
||||||
void Reserve(size_t num_words) {
|
|
||||||
if (insert_index + num_words <= words.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
words.resize(insert_index + num_words);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::span<const u32> Words() const noexcept {
|
|
||||||
return std::span(words.data(), insert_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 LocalAddress() const noexcept {
|
|
||||||
return static_cast<u32>(words.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 Value(u32 index) const noexcept {
|
|
||||||
return words[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetValue(u32 index, u32 value) noexcept {
|
|
||||||
words[index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(spv::Op op) {
|
|
||||||
op_index = insert_index;
|
|
||||||
words[insert_index++] = static_cast<u32>(op);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(OpId op) {
|
|
||||||
op_index = insert_index;
|
|
||||||
words[insert_index++] = static_cast<u32>(op.opcode);
|
|
||||||
if (op.result_type.value != 0) {
|
|
||||||
words[insert_index++] = op.result_type.value;
|
|
||||||
}
|
|
||||||
words[insert_index++] = ++*bound;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Id operator<<(EndOp) {
|
|
||||||
const size_t num_words = insert_index - op_index;
|
|
||||||
words[op_index] |= static_cast<u32>(num_words) << 16;
|
|
||||||
return Id{*bound};
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(u32 value) {
|
|
||||||
words[insert_index++] = value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(s32 value) {
|
|
||||||
return *this << static_cast<u32>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(u64 value) {
|
|
||||||
return *this << static_cast<u32>(value) << static_cast<u32>(value >> 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(s64 value) {
|
|
||||||
return *this << static_cast<u64>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(float value) {
|
|
||||||
#ifdef __cpp_lib_bit_cast
|
|
||||||
return *this << std::bit_cast<u32>(value);
|
|
||||||
#else
|
|
||||||
static_assert(sizeof(float) == sizeof(u32));
|
|
||||||
u32 int_value;
|
|
||||||
std::memcpy(&int_value, &value, sizeof(int_value));
|
|
||||||
return *this << int_value;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(double value) {
|
|
||||||
#ifdef __cpp_lib_bit_cast
|
|
||||||
return *this << std::bit_cast<u64>(value);
|
|
||||||
#else
|
|
||||||
static_assert(sizeof(double) == sizeof(u64));
|
|
||||||
u64 int_value;
|
|
||||||
std::memcpy(&int_value, &value, sizeof(int_value));
|
|
||||||
return *this << int_value;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(bool value) {
|
|
||||||
return *this << static_cast<u32>(value ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(Id value) {
|
|
||||||
assert(value.value != 0);
|
|
||||||
return *this << value.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(const Literal& literal) {
|
|
||||||
std::visit([this](auto value) { *this << value; }, literal);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(std::string_view string) {
|
|
||||||
InsertStringView(words, insert_index, string);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream& operator<<(const char* string) {
|
|
||||||
return *this << std::string_view{string};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
requires std::is_enum_v<T> Stream& operator<<(T value) {
|
|
||||||
static_assert(sizeof(T) == sizeof(u32));
|
|
||||||
return *this << static_cast<u32>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Stream& operator<<(std::optional<T> value) {
|
|
||||||
if (value) {
|
|
||||||
*this << *value;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Stream& operator<<(std::span<const T> values) {
|
|
||||||
for (const auto& value : values) {
|
|
||||||
*this << value;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
u32* bound = nullptr;
|
|
||||||
std::vector<u32> words;
|
|
||||||
size_t insert_index = 0;
|
|
||||||
size_t op_index = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Declarations {
|
|
||||||
public:
|
|
||||||
explicit Declarations(u32* bound) : stream{bound} {}
|
|
||||||
|
|
||||||
void Reserve(size_t num_words) {
|
|
||||||
return stream.Reserve(num_words);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::span<const u32> Words() const noexcept {
|
|
||||||
return stream.Words();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
Declarations& operator<<(const T& value) {
|
|
||||||
stream << value;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Declarations without an id don't exist
|
|
||||||
Declarations& operator<<(spv::Op) = delete;
|
|
||||||
|
|
||||||
Declarations& operator<<(OpId op) {
|
|
||||||
id_index = op.result_type.value != 0 ? 2 : 1;
|
|
||||||
stream << op;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Id operator<<(EndOp) {
|
|
||||||
const auto begin = stream.words.data();
|
|
||||||
std::vector<u32> declarations(begin + stream.op_index, begin + stream.insert_index);
|
|
||||||
|
|
||||||
// Normalize result id for lookups
|
|
||||||
const u32 id = std::exchange(declarations[id_index], 0);
|
|
||||||
|
|
||||||
const auto [entry, inserted] = existing_declarations.emplace(declarations, id);
|
|
||||||
if (inserted) {
|
|
||||||
return stream << EndOp{};
|
|
||||||
}
|
|
||||||
// If the declaration already exists, undo the operation
|
|
||||||
stream.insert_index = stream.op_index;
|
|
||||||
--*stream.bound;
|
|
||||||
|
|
||||||
return Id{entry->second};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct HashVector {
|
|
||||||
size_t operator()(const std::vector<u32>& vector) const noexcept {
|
|
||||||
size_t hash = std::hash<size_t>{}(vector.size());
|
|
||||||
for (const u32 value : vector) {
|
|
||||||
hash ^= std::hash<u32>{}(value);
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Stream stream;
|
|
||||||
std::unordered_map<std::vector<u32>, u32, HashVector> existing_declarations;
|
|
||||||
size_t id_index = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Sirit
|
|
6
externals/sirit/tests/CMakeLists.txt
vendored
6
externals/sirit/tests/CMakeLists.txt
vendored
|
@ -1,6 +0,0 @@
|
||||||
add_executable(sirit_tests
|
|
||||||
main.cpp)
|
|
||||||
target_link_libraries(sirit_tests PRIVATE sirit)
|
|
||||||
target_include_directories(sirit_tests PRIVATE . ../include)
|
|
||||||
|
|
||||||
add_test(sirit_tests sirit_tests)
|
|
139
externals/sirit/tests/main.cpp
vendored
139
externals/sirit/tests/main.cpp
vendored
|
@ -1,139 +0,0 @@
|
||||||
/* This file is part of the sirit project.
|
|
||||||
* Copyright (c) 2019 sirit
|
|
||||||
* This software may be used and distributed according to the terms of the
|
|
||||||
* 3-Clause BSD License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <sirit/sirit.h>
|
|
||||||
|
|
||||||
class MyModule : public Sirit::Module {
|
|
||||||
public:
|
|
||||||
MyModule() : Sirit::Module{0x00010300} {}
|
|
||||||
~MyModule() = default;
|
|
||||||
|
|
||||||
void Generate() {
|
|
||||||
AddCapability(spv::Capability::Shader);
|
|
||||||
SetMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450);
|
|
||||||
|
|
||||||
const auto t_void = Name(TypeVoid(), "void");
|
|
||||||
const auto t_uint = Name(TypeInt(32, false), "uint");
|
|
||||||
const auto t_float = Name(TypeFloat(32), "float");
|
|
||||||
|
|
||||||
const auto float4 = Name(TypeVector(t_float, 4), "float4");
|
|
||||||
const auto in_float = Name(TypePointer(spv::StorageClass::Input, t_float), "in_float");
|
|
||||||
const auto in_float4 = Name(TypePointer(spv::StorageClass::Input, float4), "in_float4");
|
|
||||||
const auto out_float4 = Name(TypePointer(spv::StorageClass::Output, float4), "out_float4");
|
|
||||||
|
|
||||||
const auto gl_per_vertex = Name(TypeStruct(float4), "gl_PerVertex");
|
|
||||||
const auto gl_per_vertex_ptr =
|
|
||||||
Name(TypePointer(spv::StorageClass::Output, gl_per_vertex), "out_gl_PerVertex");
|
|
||||||
|
|
||||||
const auto in_pos = Name(AddGlobalVariable(in_float4, spv::StorageClass::Input), "in_pos");
|
|
||||||
const auto per_vertex =
|
|
||||||
Name(AddGlobalVariable(gl_per_vertex_ptr, spv::StorageClass::Output), "per_vertex");
|
|
||||||
|
|
||||||
Decorate(in_pos, spv::Decoration::Location, 0);
|
|
||||||
Decorate(gl_per_vertex, spv::Decoration::Block);
|
|
||||||
Decorate(gl_per_vertex, spv::Decoration::Block);
|
|
||||||
MemberDecorate(gl_per_vertex, 0, spv::Decoration::BuiltIn,
|
|
||||||
static_cast<std::uint32_t>(spv::BuiltIn::Position));
|
|
||||||
|
|
||||||
const auto main_func = Name(
|
|
||||||
OpFunction(t_void, spv::FunctionControlMask::MaskNone, TypeFunction(t_void)), "main");
|
|
||||||
AddLabel();
|
|
||||||
|
|
||||||
const auto ptr_pos_x = OpAccessChain(in_float, in_pos, Constant(t_uint, 0u));
|
|
||||||
const auto ptr_pos_y = OpAccessChain(in_float, in_pos, Constant(t_uint, 1u));
|
|
||||||
|
|
||||||
const auto pos_x = OpLoad(t_float, ptr_pos_x);
|
|
||||||
const auto pos_y = OpLoad(t_float, ptr_pos_y);
|
|
||||||
|
|
||||||
auto tmp_position = OpUndef(float4);
|
|
||||||
tmp_position = OpCompositeInsert(float4, pos_x, tmp_position, 0);
|
|
||||||
tmp_position = OpCompositeInsert(float4, pos_y, tmp_position, 1);
|
|
||||||
tmp_position = OpCompositeInsert(float4, Constant(t_float, 0.0f), tmp_position, 2);
|
|
||||||
tmp_position = OpCompositeInsert(float4, Constant(t_float, 1.0f), tmp_position, 3);
|
|
||||||
|
|
||||||
const auto gl_position = OpAccessChain(out_float4, per_vertex, Constant(t_uint, 0u));
|
|
||||||
OpStore(gl_position, tmp_position);
|
|
||||||
|
|
||||||
OpReturn();
|
|
||||||
OpFunctionEnd();
|
|
||||||
|
|
||||||
AddEntryPoint(spv::ExecutionModel::Vertex, main_func, "main", in_pos, per_vertex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr std::uint8_t expected_binary[] = {
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x0d, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
|
||||||
0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x76, 0x6f, 0x69, 0x64,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x75, 0x69, 0x6e, 0x74,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x6f, 0x61,
|
|
||||||
0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x6f, 0x61,
|
|
||||||
0x74, 0x34, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x5f, 0x66,
|
|
||||||
0x6c, 0x6f, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
|
|
||||||
0x69, 0x6e, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
|
|
||||||
0x07, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x00, 0x00,
|
|
||||||
0x05, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65,
|
|
||||||
0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, 0x00, 0x00,
|
|
||||||
0x6f, 0x75, 0x74, 0x5f, 0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x5f, 0x70,
|
|
||||||
0x6f, 0x73, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x70, 0x65, 0x72, 0x5f,
|
|
||||||
0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
|
||||||
0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
|
||||||
0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00,
|
|
||||||
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
|
||||||
0x48, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
|
|
||||||
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
|
|
||||||
0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
||||||
0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00,
|
|
||||||
0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
|
|
||||||
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
|
||||||
0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00,
|
|
||||||
0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
||||||
0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
||||||
0x2b, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x2b, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
||||||
0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x2b, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
|
|
||||||
0x3b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
||||||
0x3b, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
||||||
0x36, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x0c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
|
|
||||||
0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
|
|
||||||
0x41, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
|
||||||
0x11, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
|
||||||
0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
|
||||||
0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
|
|
||||||
0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
|
||||||
0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
||||||
0x17, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
||||||
0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
|
||||||
0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x52, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00,
|
|
||||||
0x1b, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
|
||||||
0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
|
|
||||||
0x0f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
|
|
||||||
0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
MyModule module;
|
|
||||||
module.Generate();
|
|
||||||
|
|
||||||
std::vector<std::uint32_t> code = module.Assemble();
|
|
||||||
if (std::size(code) * sizeof(std::uint32_t) != std::size(expected_binary)) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if (std::memcmp(std::data(code), std::data(expected_binary), std::size(expected_binary)) != 0) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
|
@ -468,7 +468,7 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
|
||||||
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
||||||
auto inst{program.blocks.front()->begin()};
|
auto inst{program.blocks.front()->begin()};
|
||||||
size_t block_index{0};
|
size_t block_index{0};
|
||||||
ctx.PatchDeferredPhi([&](size_t phi_arg) {
|
ctx.PatchDeferredPhi([&](size_t phi_arg, Id parent) -> std::pair<Id, Id> {
|
||||||
if (phi_arg == 0) {
|
if (phi_arg == 0) {
|
||||||
++inst;
|
++inst;
|
||||||
if (inst == program.blocks[block_index]->end() ||
|
if (inst == program.blocks[block_index]->end() ||
|
||||||
|
@ -479,7 +479,7 @@ void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
||||||
} while (inst->GetOpcode() != IR::Opcode::Phi);
|
} while (inst->GetOpcode() != IR::Opcode::Phi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ctx.Def(inst->Arg(phi_arg));
|
return {ctx.Def(inst->Arg(phi_arg)), parent};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
|
@ -12,7 +12,7 @@ void EmitJoin(EmitContext&) {
|
||||||
|
|
||||||
void EmitDemoteToHelperInvocation(EmitContext& ctx) {
|
void EmitDemoteToHelperInvocation(EmitContext& ctx) {
|
||||||
if (ctx.profile.support_demote_to_helper_invocation) {
|
if (ctx.profile.support_demote_to_helper_invocation) {
|
||||||
ctx.OpDemoteToHelperInvocation();
|
ctx.OpDemoteToHelperInvocationEXT();
|
||||||
} else {
|
} else {
|
||||||
const Id kill_label{ctx.OpLabel()};
|
const Id kill_label{ctx.OpLabel()};
|
||||||
const Id impossible_label{ctx.OpLabel()};
|
const Id impossible_label{ctx.OpLabel()};
|
||||||
|
|
|
@ -70,7 +70,7 @@ Id GetMaxThreadId(EmitContext& ctx, Id thread_id, Id clamp, Id segmentation_mask
|
||||||
Id SelectValue(EmitContext& ctx, Id in_range, Id value, Id src_thread_id) {
|
Id SelectValue(EmitContext& ctx, Id in_range, Id value, Id src_thread_id) {
|
||||||
return ctx.OpSelect(
|
return ctx.OpSelect(
|
||||||
ctx.U32[1], in_range,
|
ctx.U32[1], in_range,
|
||||||
ctx.OpGroupNonUniformShuffle(ctx.U32[1], SubgroupScope(ctx), value, src_thread_id), value);
|
ctx.OpGroupNonUniformShuffleXor(ctx.U32[1], SubgroupScope(ctx), value, src_thread_id), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Id AddPartitionBase(EmitContext& ctx, Id thread_id) {
|
Id AddPartitionBase(EmitContext& ctx, Id thread_id) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue