From be98c28e782efe15fbf4b14577ad765028a643fa Mon Sep 17 00:00:00 2001 From: nyorain Date: Wed, 18 Dec 2024 18:55:46 +0100 Subject: [PATCH] Remove spvm & continue patching --- architecture.md | 51 +- docs/own/todo.md | 71 +- meson.build | 40 +- src/gui/command.cpp | 4 - src/gui/shader.cpp | 97 +- src/gui/shader.hpp | 110 +- src/gui/shaderEmulation.cpp | 1700 ----------------------- src/spvm/LICENSE | 21 - src/spvm/analyzer.h | 41 - src/spvm/context.c | 16 - src/spvm/context.h | 29 - src/spvm/ext/GLSL.std.450.h | 131 -- src/spvm/ext/GLSL450.c | 1367 ------------------- src/spvm/ext/GLSL450.h | 16 - src/spvm/image.c | 302 ---- src/spvm/image.h | 115 -- src/spvm/opcode.h | 11 - src/spvm/opcode_execute.c | 2486 --------------------------------- src/spvm/opcode_setup.c | 784 ----------- src/spvm/program.c | 84 -- src/spvm/program.h | 89 -- src/spvm/result.c | 204 --- src/spvm/result.h | 107 -- src/spvm/spirv.h | 2568 ----------------------------------- src/spvm/state.c | 474 ------- src/spvm/state.h | 153 --- src/spvm/types.c | 45 - src/spvm/types.h | 18 - src/spvm/value.c | 41 - src/spvm/value.h | 65 - src/util/patch.cpp | 332 +++-- 31 files changed, 319 insertions(+), 11253 deletions(-) delete mode 100644 src/gui/shaderEmulation.cpp delete mode 100644 src/spvm/LICENSE delete mode 100644 src/spvm/analyzer.h delete mode 100644 src/spvm/context.c delete mode 100644 src/spvm/context.h delete mode 100644 src/spvm/ext/GLSL.std.450.h delete mode 100644 src/spvm/ext/GLSL450.c delete mode 100644 src/spvm/ext/GLSL450.h delete mode 100644 src/spvm/image.c delete mode 100644 src/spvm/image.h delete mode 100644 src/spvm/opcode.h delete mode 100644 src/spvm/opcode_execute.c delete mode 100644 src/spvm/opcode_setup.c delete mode 100644 src/spvm/program.c delete mode 100644 src/spvm/program.h delete mode 100644 src/spvm/result.c delete mode 100644 src/spvm/result.h delete mode 100644 src/spvm/spirv.h delete mode 100644 src/spvm/state.c delete mode 100644 src/spvm/state.h delete mode 100644 src/spvm/types.c delete mode 100644 src/spvm/types.h delete mode 100644 src/spvm/value.c delete mode 100644 src/spvm/value.h diff --git a/architecture.md b/architecture.md index 047c8072..0aef3283 100644 --- a/architecture.md +++ b/architecture.md @@ -22,6 +22,12 @@ the layer works internally. Useful mainly for development on it. minimal and the overall layer lightweight. - `pml`: [pml](https://github.com/nyorain/pml) is a lightweight C posix main loop. Dependency of swa on unix. + - `spc`: Source of a custom [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross) fork. + We use it for SPIR-V reflection and patching. Our custom fork has + extended features that make patching of shaders easier without doing + a lot of duplicate work. We rely on this module instead of writing + it from scratch since it is well maintained and implements important + functionality such as evaluating specialization constants. - `src`: pretty much all source codes and non-public headers go here - `command`: for all command-related utility - `util`: utility headers that are not directly involved with the vulkan API @@ -52,17 +58,6 @@ the layer works internally. Useful mainly for development on it. We compile it directly into the layer library. - `tracy`: Source of the profiling tool we use, directly baked into the library. See [performance.md](docs/performance.md) for more details on profiling. - - `spirv-cross`: Source of [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross). - We use it for SPIR-V reflection and patching. As of may 2021, we still use - spriv-reflect in most places but this will likely be replaced with - SPIRV-Cross. We need SPIRV-cross for the xfb patching we have to do - for the vertex viewer, doing this can involve things such as evaluating - (spec-)constant shader expressions (e.g. array sizes) which isn't something - we want to implement ourselves in the layer. - - `spvm`: Contains sources for the [SPIRV-VM](https://github.com/dfranx/SPIRV-VM) - library vil uses for shader debugging. We should probably move that - to a git subproject sooner or later since we often need to change/extend/fix - it during development. - `minhook`: sources of the [minhook library](https://github.com/TsudaKageyu/minhook). Used only for the hooked win32 overlay, to grab/block input from the application. @@ -70,27 +65,27 @@ the layer works internally. Useful mainly for development on it. [backward library](https://github.com/bombela/backward-cpp) used to capture stack traces - `tao/pegtl`: We use the [tao/pegtl](https://github.com/taocpp/PEGTL) library - to parse expressions. Used for instance by the buffer viewer to convert a - glsl-like type specification to an internal type representation used to + to parse expressions. Used for instance by the buffer viewer to convert a + glsl-like type specification to an internal type representation used to format buffer content, see [src/util/bufparser.cpp](src/util/bufparser.cpp). - `test/unit`: To test the functions and classes not exported from the layer, we compile the tests directly into the shared library (when tests are enabled, they are off by default, but always run on the CI). The tests compiled into the shared library are defined in this folder. We compile them into the library itself so we can test functions that - are not exported. + are not exported. We also have a `main.cpp` here that is able to execute the tests. Unit tests are mainly for internal utility. - `test/integration`: We have some integration tests here. They just use Vulkan like any app would, with the vil layer loaded. - Preferably, and to make this work easily in CI, we use the null Vulkan + Preferably, and to make this work easily in CI, we use the null Vulkan mock_icd driver but load the validation layers *after* vil to make sure it catches our errors. - `include`: Only the public API header lives here. Future API or otherwise public headers should go here. - `docs`: Documentation, examples, pictures. The `own` subfolder contains many incredibly smart concepts, ideas and design documents disguised as - error-ridden gibberish with spelling errors, rhetorical questions and + error-ridden gibberish with spelling errors, rhetorical questions and inconsistencies. There you will also find the ever-growing todo list. ## Code organization @@ -117,15 +112,15 @@ For almost every vulkan handle, there is a representation on our side. `VkImageView` by `vil::ImageView` and so on. `vil::Device` has tables mapping the vulkan handles to their -representations inside the layer. For dispatchable handles (Instance, Device, -CommandBuffer, Queue; we also use it for VkSurfaceKHR), there is a global +representations inside the layer. For dispatchable handles (Instance, Device, +CommandBuffer, Queue; we also use it for VkSurfaceKHR), there is a global table in [src/data.hpp](src/data.hpp). The layer optionally wraps handles, see (env.md)[docs/env.md] for configuration, it's even possible to decide on a per-object-type basis whether wrapping is done. See [this post](https://renderdoc.org/vulkan-layer-guide.html) for more details on handle wrapping. -Wrapping handles allows us to bypass those (potentially large, synchronized) +Wrapping handles allows us to bypass those (potentially large, synchronized) global or per-device lookup tables and instead directly cast into our representation of the handles. But it also decreases the chance that the layer works with extensions it does not explicitly support. @@ -155,7 +150,7 @@ to a DescriptorSet to make sure we can view its state at a current point in time later on, even if the DescriptorSet was destroyed or updated. In general, we keep track of some connections between handles where -performance allows it to make it possible to view them in the gui. +performance allows it to make it possible to view them in the gui. While the gui is rendered, it will lock the device mutex in many places when accessing these connections. @@ -168,7 +163,7 @@ to call queue operations from multiple threads at the same time). API objects created by the application generally have an object counterpart inside the layer, e.g. [vil::Image](src/image.hpp), [vil::DescriptorSet](src/ds.hpp), [vil::CommandBuffer](src/cb.hpp), or [vil::Device](src/device.hpp). -They all derive from [vil::Handle](src/handle.hpp) which just knows its +They all derive from [vil::Handle](src/handle.hpp) which just knows its own debug name. Many device-level handles have an embedded, intrusive, atomic reference @@ -206,14 +201,14 @@ these objects for multiple purposes: ## CommandRecord -`vil::CommandRecord` (see [record.hpp](src/command/record.hpp)) holds all state for a +`vil::CommandRecord` (see [record.hpp](src/command/record.hpp)) holds all state for a recorded command buffer, i.e. all commands, the usage flags with which the record was begun, which handles are used. It's disconnected from the command buffer itself and can outlive it. You can imagine the CommandBuffer as a builder for CommandRecord object. -CommandRecords are used in multiple places and ownership is shared via an +CommandRecords are used in multiple places and ownership is shared via an intrusive reference count. -One speciality is its custom memory allocation mechanism, see +One speciality is its custom memory allocation mechanism, see [linalloc.hpp](src/util/linalloc.hpp) and [command/alloc.hpp](src/command/alloc.hpp). Since CommandBuffer recording can be a bottleneck and might involve many thousands commands, we don't have any time to waste there. Therefore, we always allocate larger @@ -230,8 +225,8 @@ commands into the submissions done by the application. A `CommandHook` can be installed in the `vil::Device` and will be considered every time commands are submitted to a queue of that device via `CommandHook::hook`. That function gets a submission to a queue -and can replace command buffers with internal, patched replacements. -To "insert" commands, it simply reads from the recorded command buffer +and can replace command buffers with internal, patched replacements. +To "insert" commands, it simply reads from the recorded command buffer (using our `vil::Command` objects created at recording time), records the commands into an internally created command, adding or altering commands as needed. The reason we don't already do this directly into the application's command @@ -257,7 +252,7 @@ All that state is hold in `CommandHookState`, which is directly accessed when rendering the command buffer gui. Aside from copying state at a selected command, we also use `CommandHook` -to capture bookkeeping data when needed, for instance in +to capture bookkeeping data when needed, for instance in `vkCmdBuildAccelerationStructuresKHR`. ### Render pass splitting @@ -287,7 +282,7 @@ See [src/rp.hpp](src/rp.hpp) for the details. `vil::splittable(...)` returns whether the splitting approach is possible for the given render pass description. We have a small test [rpsplit.cpp](docs/test/rpsplit.cpp) that should be extended when issues with that are found in the future. -`vil::splitIterrutable(...)` then spits out render pass create infos +`vil::splitIterrutable(...)` then spits out render pass create infos that can be used to create the new render passes. ### TODO: diff --git a/docs/own/todo.md b/docs/own/todo.md index 73f9a49a..eda4a22a 100644 --- a/docs/own/todo.md +++ b/docs/own/todo.md @@ -263,10 +263,15 @@ patch capture shader debugging: that breakpoint is not hit. - [ ] add more general widget for selecting a stage of a pipe in the debugger - [ ] add support for vertex shader debugging - - [ ] branch based on vertexID - - [ ] widget to select vertexID. See vertexViewer branch + - [x] branch based on vertexID + - [x] widget to select vertexID. See vertexViewer branch +- [ ] additional shader debug selects + - [ ] Layer + - [ ] ViewIndex + - [ ] ViewportIndex - [ ] add support for pixel shader debugging - [ ] branch based on pixel position + - [ ] allow to select sample for msaa - [ ] widget to select pixel position - [ ] allow to get there via a "debug this pixel" button in image viewer? @@ -279,65 +284,9 @@ patch capture shader debugging: on the fly where the hooked shaders are replaced? - [ ] separate function arguments and local vars in UI - [ ] toggle via UI: also capture all local named SSA IDs - -(emulate) shader debugger, low prio: -- [x] cleanup/fix freezing as described in node 2235 -- [x] implement breakpoints - - [x] issue: we currently check for equality for breakpoints. - breakpoints for lines that don't have code associated with them - in spirv won't trigger. Need to do a more proper check - - [ ] clean up breakpoint handling -- [ ] factor out retrieving descriptor from varID+indicies as used - in load/store/arrayLength callbacks. Code duplication atm. -- [ ] set spec constants for shader module in gui shader debugger. - Test with shader from tkn/iro -- [ ] detect unsupported features/capabilities (such as subgroup ops) - and display "unsupported feature: X" error message in gui -- [ ] test, fix, cleanup handling of multiple files. Broken - with breakpoints and their visualization. -- [ ] add UI for selecting workgroup/invocation -- [x] return workgroup size from shader in loadBuiltin - - [ ] TODO: test -- [x] add support for loading push constants - - [ ] TODO: test. Can we write unit tests for this? Should be possible -- [ ] support vertex shaders - - [ ] correctly wire up the vertex input. And add ui for selecting - instance/vertex id to debug. -- [ ] support fragment shaders - - [ ] figure out how to wire up input. Sketch: allow to select the - pixel, then select the primitive in the current draw call - covering the pixel (if more than one; or always use the last - one if it makes sense via vulkan drawing order guarantees?). - We then interpolate the input we got from xfb and use that - as input to the fragment shader. - - geometry and tesselation shaders can remain unsupported for now. -- [ ] support ray tracing pipelines - - [ ] as with compute shaders, we want to select the dispatch index - - [ ] add support in spvm. Not sure about callback interface, probably - just pass the parameters from TraceRay to the application callback - and then let the application return the hit? - Hm, no, it's probably better to let the application then handle - everything (i.e. invoking all the required intersection/hit/miss shaders) - and just return/modify the ray payload, right? - - [ ] aside from debugging the shaders (and the acceleration structure - hitting process), allow to visualize the rays (we can probably - just do a very small number of rays) in the acceleration - structure. - - [ ] if we are serious about it, we need to really build our own - host-side acceleration structures -- [ ] add proper stack trace (ui tab) - - [ ] allow to jump to positions in stack trace -- [ ] allow to view all sources in ui -- [ ] figure out where to put the "Debug shader" buttons -- [ ] add support for stores. And make sure reading variables later - on return the correct values. Might need changes in spvm, the - was_loaded optimization is incorrect in that case. - Maybe set was_loaded to false when the OpVariable was stored to? -- [ ] clean up implementation. How we gather/display variables - Make sure the variable display tree nodes can opened while the - state is being recreated (with "refresh" set. Should probably just - use the name, not its pointer as well. Figure out why we did - it for buffmt. arrays?) +- [ ] matrix decoration in captured output +- [ ] show global variables in captured output? + - [ ] also builtins? maybe in different tab/node? spvm: - [x] Add OpSpecConstant* support diff --git a/meson.build b/meson.build index 133f5aaf..31f22af1 100644 --- a/meson.build +++ b/meson.build @@ -79,7 +79,6 @@ args = cc.get_supported_arguments([ # for clang '-Wno-missing-braces', - '-Wno-newline-eof', # needed for spvm TODO re-enable and fix! '-Wno-nonnull-compare', # seems like clang bug # to be compatible with msvc warning level on gcc/clang @@ -184,20 +183,6 @@ elif get_option('throw-on-assert') layer_args += '-DVIL_THROW_ON_ASSERT' endif -# spvm -spvm_src = files( - 'src/spvm/context.c', - 'src/spvm/result.c', - 'src/spvm/state.c', - 'src/spvm/types.c', - 'src/spvm/value.c', - 'src/spvm/image.c', - 'src/spvm/program.c', - 'src/spvm/opcode_setup.c', - 'src/spvm/opcode_execute.c', - 'src/spvm/ext/GLSL450.c', -) - src = files( # own meta sources & util 'src/layer.cpp', @@ -255,7 +240,6 @@ src = files( 'src/gui/bufferViewer.cpp', 'src/gui/imageViewer.cpp', 'src/gui/shader.cpp', - 'src/gui/shaderEmulation.cpp', 'src/gui/blur.cpp', 'src/gui/commandSelection.cpp', # debug wip @@ -523,28 +507,6 @@ if not with_win32 or not with_tracy # pch = 'src/pch.hpp' endif -lib_spvm = static_library( - 'spvm', - spvm_src, - gnu_symbol_visibility: 'hidden', - include_directories: inc, - c_args: args + cc.get_supported_arguments([ - '-Wno-unused-parameter', - '-Wno-unused-variable', - '/wd4100', # unreferenced formal parameter. - '/wd4189', # unused local variable - '/wd4457', # declaration hides function parameter - # TODO: fix the ones below? - '-Wno-sign-compare', - # new clang warnings - '-Wno-strict-prototypes', - '-Wno-unused-but-set-parameter', - '-Wno-unused-but-set-variable', - '/wd4018', # signed/unsigned mismatch - '/wd4090', # different 'const' qualifier on free/realloc calls - ]), -) - # building as separate lib as ugly workaround for gcc pch warning issue # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64117 lib_imgui = static_library( @@ -573,7 +535,7 @@ vil_layer = shared_library( gnu_symbol_visibility: 'hidden', dependencies: deps, include_directories: inc, - link_whole: [lib_spvm, lib_imgui], + link_whole: [lib_imgui], cpp_args: args + layer_args, c_args: args, link_args: cc.get_supported_link_arguments(link_args), diff --git a/src/gui/command.cpp b/src/gui/command.cpp index 36d8b2da..9662b5f0 100644 --- a/src/gui/command.cpp +++ b/src/gui/command.cpp @@ -322,10 +322,6 @@ void CommandViewer::updateFromSelector(bool forceUpdateHook) { || stateCmd->boundPipe() != lastStateCmd->boundPipe()) { selectCommandView = true; shaderDebugger_.unselect(); - } else if(isLocalCapture && sel.completedHookState()) { - if(shaderDebugger_.emulation()) { - shaderDebugger_.emulation()->initVarMap(); - } } break; diff --git a/src/gui/shader.cpp b/src/gui/shader.cpp index d6581781..59cc34fb 100644 --- a/src/gui/shader.cpp +++ b/src/gui/shader.cpp @@ -44,11 +44,6 @@ void ShaderDebugger::init(Gui& gui) { textedit_.SetShowWhitespaces(false); textedit_.SetTabSize(4); textedit_.SetReadOnly(true); - - // emu_ = std::make_unique(*this); - if(emu_) { - emu_->init(); - } } void ShaderDebugger::select(VkShaderStageFlagBits stage, @@ -78,10 +73,6 @@ void ShaderDebugger::select(VkShaderStageFlagBits stage, currentFile_ = sourceFilesIDs_[0]; textedit_.SetText(fileContent(currentFile_)); } - - if(emu_) { - emu_->select(); - } } void ShaderDebugger::unselect() { @@ -96,10 +87,6 @@ void ShaderDebugger::unselect() { commandID_ = {}; vertexID_ = {}; instanceID_ = {}; - - if(emu_) { - emu_->unselect(); - } } void ShaderDebugger::draw() { @@ -174,35 +161,31 @@ void ShaderDebugger::draw() { // variable view if(ImGui::BeginChild("Views")) { - if(emu_) { - emu_->drawControlTabs(); - } else { - if(ImGui::BeginTabBar("Tabs")) { - if(ImGui::BeginTabItem("Inputs")) { - drawInputsTab(); - ImGui::EndTabItem(); - } - if(ImGui::BeginTabItem("Variables")) { - auto state = selection().completedHookState().get(); - if(state && state->shaderCapture.size && !patch_.current.captures.empty()) { - Type base {}; - base.type = Type::typeStruct; - base.members = patch_.current.captures; - auto data = state->shaderCapture.data(); - auto io = read(data); - - imGuiText("hitcount for {}, {}, {}: {}", - io[0], io[1], io[2], io[3]); - - if(io[3] >= 1u) { - displayTable("vars", base, data); - } + if(ImGui::BeginTabBar("Tabs")) { + if(ImGui::BeginTabItem("Inputs")) { + drawInputsTab(); + ImGui::EndTabItem(); + } + if(ImGui::BeginTabItem("Variables")) { + auto state = selection().completedHookState().get(); + if(state && state->shaderCapture.size && !patch_.current.captures.empty()) { + Type base {}; + base.type = Type::typeStruct; + base.members = patch_.current.captures; + auto data = state->shaderCapture.data(); + auto io = read(data); + + imGuiText("hitcount for {}, {}, {}: {}", + io[0], io[1], io[2], io[3]); + + if(io[3] >= 1u) { + displayTable("vars", base, data); } - ImGui::EndTabItem(); } - - ImGui::EndTabBar(); + ImGui::EndTabItem(); } + + ImGui::EndTabBar(); } } @@ -375,7 +358,41 @@ CommandSelection& ShaderDebugger::selection() const { } void ShaderDebugger::drawInputsTab() { - // TODO: decide depending on shader type + if(stage_ == VK_SHADER_STAGE_COMPUTE_BIT) { + drawInputsCompute(); + } else if(stage_ == VK_SHADER_STAGE_VERTEX_BIT) { + drawInputsVertex(); + } else { + dlg_error("Unsupported stage: {}", stage_); + imGuiText("Error: unsupported stage selected"); + } +} + +void ShaderDebugger::drawInputsVertex() { + auto [numCmds, indexed] = drawInfo(); + auto sliderFlags = ImGuiSliderFlags_AlwaysClamp; + if(numCmds > 1) { + auto v = int(commandID_); + ImGui::DragInt("Command", &v, 1.f, 0, numCmds - 1, "%d", sliderFlags); + commandID_ = v; + } + + auto drawCmd = drawCmdInfo(commandID_); + if(drawCmd.firstIni > 1) { + auto v = int(instanceID_); + ImGui::DragInt("Instance", &v, 1.f, drawCmd.firstIni, + drawCmd.firstIni + drawCmd.numInis - 1, "%d", sliderFlags); + instanceID_ = v; + } + + auto v = int(vertexID_); + ImGui::DragInt("ID", &v, 1.f, 0, drawCmd.numVerts - 1, "%d", sliderFlags); + // TODO: show popup explaining this is the vertex ID, i.e. for indexed + // drawing the index to be read. + vertexID_ = v; +} + +void ShaderDebugger::drawInputsCompute() { using nytl::vec::cw::operators::operator*; auto wgs = workgroupSize(); diff --git a/src/gui/shader.hpp b/src/gui/shader.hpp index ee98a601..4eea528f 100644 --- a/src/gui/shader.hpp +++ b/src/gui/shader.hpp @@ -5,14 +5,8 @@ #include #include #include -#include -#include -#include -#include #include #include -#include -#include #include #include @@ -21,7 +15,6 @@ namespace vil { // from buffmt struct Type; class ShaderDebugger; -struct ShaderEmulation; struct ShaderDebugPatch { u32 file {u32(-1)}; @@ -63,7 +56,6 @@ class ShaderDebugger { const auto& compiled() const { return compiled_; } const auto& globalInvocationID() const { return globalInvocationID_; } CommandSelection& selection() const; - ShaderEmulation* emulation() const { return emu_.get(); } void updateHooks(CommandHook&); private: @@ -87,6 +79,8 @@ class ShaderDebugger { const std::string& fileName(u32 fileID) const; const std::string& fileContent(u32 fileID) const; void drawInputsTab(); + void drawInputsCompute(); + void drawInputsVertex(); std::string_view fileContents(u32 fileID); @@ -122,109 +116,9 @@ class ShaderDebugger { u32 instanceID_ {0u}; u32 vertexID_ {0u}; // might also be instance id - std::unique_ptr emu_ {}; - bool livePatch_ {true}; ShaderDebugPatch patch_ {}; }; -struct ShaderEmulation { -public: - ShaderEmulation(ShaderDebugger& dbg) : dbg_(&dbg) {} - ~ShaderEmulation(); - - void init(); - void select(); - void unselect(); - - void loadVar(unsigned srcID, span indices, - span dst, u32 typeID); - void loadBuiltin(const spc::BuiltInResource& builtin, - span indices, span dst); - void storeVar(unsigned dstID, span indices, - span src, u32 typeID); - - // Returns (type, offset) tuple for accessing the sub-type - // given by the given indices (as usually defined by SPIR-V) in - // the given typeID. - // Requires the total dataSize of the original type/buffer to - // correctly handle runtime arrays. - std::pair accessBuffer(ThreadMemScope& tms, - unsigned typeID, span indices, u32 dataSize); - - spvm_vec4f readImage(spvm_image&, int x, int y, int z, int layer, int level); - void writeImage(spvm_image&, int x, int y, int z, int layer, int level, - const spvm_vec4f&); - unsigned arrayLength(unsigned varID, span indices); - - void setupMember(const Type& type, ReadBuf, spvm_member& dst); - void setupMemberArray(span arrayDims, const Type& type, ReadBuf, spvm_member& dst); - void setupVector(const Type& type, u32 stride, ReadBuf, spvm_member& dst); - void setupScalar(const Type&, ReadBuf, spvm_member& dst); - - // (Re-)Initialized the spvm state. - void initState(); - - // Converts the information of the given sampler to a spvm_sampler_desc. - static spvm_sampler_desc setupSampler(const Sampler& src); - - spvm_value_type valueType(const spvm_member& member); - - // formatting spvm_result/spvm_member for debug table - void display(const char* name, const spvm_member& members); - std::string formatScalar(const spvm_member& member); - - // executes a single opcode. Returns true if a breakpoint was hit. - bool stepOpcode(); - void stepLine(); - - // Sets the text editor to the current line of the state. - void updatePosition(bool moveCursor = true); - - void drawInputsTab(); - void drawInputsCompute(); - void drawInputsVertex(); - void drawVariablesTab(); - void drawBreakpointsTab(); - void drawCallstackTab(); - void drawControlTabs(); - - void updateHooks(CommandHook&); - void initVarMap(); - ShaderDebugger& shaderDebugger() { return *dbg_; } - - // imgui - void drawControls(); - void updateFromEditor(); - -private: - struct { - spvm_context_t context {}; - spvm_program_t program {}; - spvm_state_t state {}; - } spvm_; - - struct OurImage : spvm_image { - ReadBuf data; - VkFormat format; // of data - }; - - static const OurImage emptyImage; - static const spvm_sampler defaultSampler; - - std::deque samplers_; - std::deque images_; - - std::unordered_map varIDToDsCopyMap_; - ShaderDebugger* dbg_; - - bool rerun_ {}; - bool freezeOnBreakPoint_ {}; - - u32 currLine_ {}; - std::string currFileName_ {}; - -}; - } // namespace vil diff --git a/src/gui/shaderEmulation.cpp b/src/gui/shaderEmulation.cpp deleted file mode 100644 index 9513e26d..00000000 --- a/src/gui/shaderEmulation.cpp +++ /dev/null @@ -1,1700 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace vil { - -using nytl::read; -const ShaderEmulation::OurImage ShaderEmulation::emptyImage {}; -const spvm_sampler ShaderEmulation::defaultSampler {}; - -ShaderEmulation::~ShaderEmulation() { - if(spvm_.context) { - spvm_context_deinitialize(spvm_.context); - } -} - -void ShaderEmulation::init() { - spvm_.context = spvm_context_initialize(); -} - -void ShaderEmulation::select() { - dlg_assert(shaderDebugger().compiled()); - auto& compiled = *shaderDebugger().compiled(); - - static_assert(sizeof(spvm_word) == sizeof(u32)); - auto ptr = reinterpret_cast(compiled.get_ir().spirv.data()); - spvm_.program = spvm_program_create(spvm_.context, ptr, compiled.get_ir().spirv.size()); - initState(); -} - -void ShaderEmulation::unselect() { - currLine_ = {}; - currFileName_ = {}; - varIDToDsCopyMap_.clear(); - samplers_.clear(); - images_.clear(); - - if(spvm_.state) { - spvm_state_delete(spvm_.state); - spvm_.state = nullptr; - } - - if(spvm_.program) { - spvm_program_delete(spvm_.program); - spvm_.program = nullptr; - } - -} - -span children(spvm_member& member) { - return {member.members, std::size_t(member.member_count)}; -} - -void ShaderEmulation::initState() { - dlg_assert(spvm_.program); - dlg_assert(shaderDebugger().compiled()); - - samplers_.clear(); - images_.clear(); - - spvm_state_settings settings {}; - settings.load_variable = [](struct spvm_state* state, unsigned varID, - unsigned index_count, const spvm_word* indices, spvm_member_list list, - spvm_word typeID) { - auto* self = static_cast(state->user_data); - self->loadVar(varID, - {indices, std::size_t(index_count)}, - {list.members, std::size_t(list.member_count)}, typeID); - }; - settings.store_variable = [](struct spvm_state* state, unsigned varID, - unsigned index_count, const spvm_word* indices, spvm_member_list list, - spvm_word typeID) { - auto* self = static_cast(state->user_data); - self->storeVar(varID, - {indices, std::size_t(index_count)}, - {list.members, std::size_t(list.member_count)}, typeID); - }; - settings.log = [](struct spvm_state*, const char* fmt, va_list vargs) { - char buf[500]; - std::vsnprintf(buf, sizeof(buf), fmt, vargs); - dlg_error("spvm: {}", buf); - }; - - spvm_.state = spvm_state_create(spvm_.program, settings); - spvm_.state->user_data = this; - spvm_.state->read_image = [](spvm_state* state, spvm_image* img, - int x, int y, int z, int layer, int level) { - auto* self = static_cast(state->user_data); - return self->readImage(*img, x, y, z, layer, level); - }; - spvm_.state->write_image = [](spvm_state* state, spvm_image* img, - int x, int y, int z, int layer, int level, const spvm_vec4f* data) { - auto* self = static_cast(state->user_data); - self->writeImage(*img, x, y, z, layer, level, *data); - }; - spvm_.state->array_length = [](spvm_state* state, unsigned varID, - unsigned index_count, const spvm_word* indices) { - auto* self = static_cast(state->user_data); - return self->arrayLength(varID, {indices, std::size_t(index_count)}); - }; - - static spvm_analyzer analyzer; - analyzer.on_undefined_behavior = [](spvm_state*, spvm_word ub) { - // TODO: allow to break on UB. - dlg_trace("shader triggered undefined behavior: {}", ub); - }; - spvm_.state->analyzer = &analyzer; - - spvm_word entryPoint = -1; - auto defaultEntryPoint = shaderDebugger().compiled()->get_ir().default_entry_point; - for(auto i = 0; i < spvm_.program->entry_point_count; ++i) { - if(u32(spvm_.program->entry_points[i].id) == defaultEntryPoint) { - entryPoint = spvm_.program->entry_points[i].id; - break; - } - } - - // TODO: don't static here - static spvm_ext_opcode_func* glslExt = spvm_build_glsl450_ext(); - spvm_state_set_extension(spvm_.state, "GLSL.std.450", glslExt); - - dlg_assert(entryPoint != -1); - spvm_state_prepare(spvm_.state, entryPoint); -} - - -void ShaderEmulation::stepLine() { - auto doBreak = false; - auto line = spvm_.state->current_line; - // TODO: should probably also check for file change here, right? - // just in case we jump to a function in another file that - // happens to be at the same line - while(spvm_.state->current_line == line && spvm_.state->code_current && !doBreak) { - doBreak = stepOpcode(); - } - - updatePosition(true); -} - - -bool ShaderEmulation::stepOpcode() { - auto currLine = spvm_.state->current_line; - auto currFile = spvm_.state->current_file; - - auto posPrev = spvm_.state->code_current; - spvm_state_step_opcode(spvm_.state); - - if(spvm_.state->current_line == currLine && - spvm_.state->current_file == currFile) { - // position hasn't changed, can't be a breakpoint - return false; - } - - for(auto& bp : shaderDebugger().breakpoints()) { - // if(spvm_word(bp.lineID) == spvm_.state->current_line && - // fileName(bp.fileID) == spvm_.state->current_file) { - // return true; - // } - if(posPrev == bp.pos) { - return true; - } - } - - return false; -} - -void ShaderEmulation::writeImage(spvm_image&, int x, int y, int z, int layer, int level, - const spvm_vec4f& data) { - // TODO - // have to implement it, make sure subsequent reads return the same value - (void) x; - (void) y; - (void) z; - (void) layer; - (void) level; - (void) data; -} - -spvm_value_type ShaderEmulation::valueType(const spvm_member& member) { - auto* resType = spvm_state_get_type_info(spvm_.state->results, &spvm_.state->results[member.type]); - dlg_assert(resType); - return resType->value_type; -} - -void ShaderEmulation::display(const char* name, const spvm_member& member) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - auto id = dlg::format("{}:{}", name, (void*) name); - auto flags = ImGuiTreeNodeFlags_FramePadding; - - auto* ptype = spvm_state_get_type_info(spvm_.state->results, &spvm_.state->results[member.type]); - dlg_assert(ptype); - auto& type = *ptype; - - if(type.value_type == spvm_value_type_struct) { - if(ImGui::TreeNodeEx(id.c_str(), flags, "%s", name)) { - dlg_assert(type.member_count == member.member_count); - for(auto i = 0u; i < u32(member.member_count); ++i) { - std::string mname; - if(type.member_name && i < u32(type.member_name_count)) { - mname = type.member_name[i]; - } else { - mname = dlg::format("?{}", i); - } - - display(mname.c_str(), member.members[i]); - } - - ImGui::TreePop(); - } - - return; - } else if(type.value_type == spvm_value_type_array) { - if(ImGui::TreeNodeEx(id.c_str(), flags, "%s", name)) { - for(auto i = 0; i < member.member_count; ++i) { - auto aname = dlg::format("[{}]", i); - display(aname.c_str(), member.members[i]); - } - - ImGui::TreePop(); - } - - return; - } else if(type.value_type == spvm_value_type_matrix) { - // TODO: have to take care since they are col-major - imGuiText("TODO: matrix printing"); - return; - } - - ImGui::AlignTextToFramePadding(); - ImGui::Bullet(); - ImGui::SameLine(); - imGuiText("{}", name); - ImGui::TableNextColumn(); - - if(type.value_type == spvm_value_type_vector) { - auto str = std::string{}; - - for(auto i = 0; i < member.member_count; ++i) { - if(i != 0) { - str += ", "; - } - str += formatScalar(member.members[i]); - } - - ImGui::AlignTextToFramePadding(); - imGuiText("{}", str); - return; - } - - // Invalid types for values - dlg_assert_or(type.value_type != spvm_value_type_void, return); - dlg_assert_or(type.value_type != spvm_value_type_runtime_array, return); - - // TODO: might happen I guess - dlg_assert_or(type.value_type != spvm_value_type_sampler, return); - dlg_assert_or(type.value_type != spvm_value_type_image, return); - dlg_assert_or(type.value_type != spvm_value_type_sampled_image, return); - - // Must be scalar - auto fs = formatScalar(member); - imGuiText("{}", fs); - - // TODO: tooltip -} - -std::string ShaderEmulation::formatScalar(const spvm_member& member) { - std::string str; - auto vt = valueType(member); - if(vt == spvm_value_type_int) { - str += dlg::format("{}", member.value.s); - } else if(vt == spvm_value_type_float) { - str += dlg::format("{}", member.value.f); - } else if(vt == spvm_value_type_bool) { - str += dlg::format("{}", bool(member.value.b)); - } else { - str += dlg::format("", int(vt)); - } - - return str; -} - -void ShaderEmulation::loadBuiltin(const spc::BuiltInResource& builtin, - span indices, span dst) { - // dlg_trace("spirv OpLoad of builtin {}", builtin.builtin); - - /* - auto loadVecU = [&](const auto& vec) { - if(indices.empty()) { - dlg_assert(dst.size() == vec.size()); - for(auto i = 0u; i < vec.size(); ++i) { - dlg_assert(valueType(dst[i]) == spvm_value_type_int); - dst[i].value.u = vec[i]; - } - } else { - dlg_assert(indices.size() == 1u); - dlg_assert(dst.size() == 1u); - dlg_assert(u32(indices[0]) < vec.size()); - dlg_assert(valueType(dst[0]) == spvm_value_type_int); - dst[0].value.u = vec[indices[0]]; - } - }; - - auto loadScalarU = [&](const auto& val) { - dlg_assert(dst.size() == 1u); - dlg_assert(valueType(dst[0]) == spvm_value_type_int); - dst[0].value.u = val; - }; - - auto wgs = shaderDebugger().workgroupSize(); - auto numWGs = shaderDebugger().numWorkgroups(); - - if(stage_ == VK_SHADER_STAGE_COMPUTE_BIT) { - auto wgs = workgroupSize(); - auto numWGs = numWorkgroups(); - - switch(builtin.builtin) { - case spv::BuiltInNumSubgroups: { - // TODO: proper subgroup support - loadScalarU(1u); - return; - } - case spv::BuiltInNumWorkgroups: { - loadVecU(numWGs); - return; - } - case spv::BuiltInWorkgroupSize: { - loadVecU(wgs); - return; - } - case spv::BuiltInWorkgroupId: { - Vec3ui id {0u, 0u, 0u}; - // floor by design - id.x = globalInvocationID_.x / wgs.x; - id.y = globalInvocationID_.y / wgs.y; - id.z = globalInvocationID_.z / wgs.z; - loadVecU(id); - return; - } - case spv::BuiltInGlobalInvocationId: { - loadVecU(globalInvocationID_); - return; - } - case spv::BuiltInLocalInvocationId: { - Vec3ui id {0u, 0u, 0u}; - id.x = globalInvocationID_.x % wgs.x; - id.y = globalInvocationID_.y % wgs.y; - id.z = globalInvocationID_.z % wgs.z; - loadVecU(id); - return; - } - case spv::BuiltInLocalInvocationIndex: { - Vec3ui lid {0u, 0u, 0u}; - lid.x = globalInvocationID_.x % wgs.x; - lid.y = globalInvocationID_.y % wgs.y; - lid.z = globalInvocationID_.z % wgs.z; - auto id = - lid.z * wgs.y * wgs.x + - lid.y * wgs.x + - lid.x; - loadScalarU(id); - return; - } default: - break; - } - } else if(stage_ == VK_SHADER_STAGE_VERTEX_BIT) { - auto cmd = drawCmdInfo(commandID_); - switch(builtin.builtin) { - case spv::BuiltInVertexIndex: - loadScalarU(vertexID_); - return; - case spv::BuiltInInstanceIndex: - loadScalarU(instanceID_); - return; - case spv::BuiltInBaseVertex: - loadScalarU(cmd.vertexOffset); - return; - case spv::BuiltInBaseInstance: - loadScalarU(cmd.firstIni); - return; - default: - break; - } - } else { - dlg_error("unhandled stage {}", stage_); - } -*/ - - dlg_error("Unhandled builtin: {}", builtin.builtin); -} - -unsigned ShaderEmulation::arrayLength(unsigned varID, span indices) { - ZoneScoped; - dlg_assert(shaderDebugger().compiled()); - auto& compiled = *shaderDebugger().compiled(); - - auto res = resource(compiled, varID); - if(!res) { - dlg_error("OpArrayLength of invalid/unknown var {}", varID); - return 0; - } - - dlg_assert(compiled.has_decoration(res->id, spv::DecorationDescriptorSet) && - compiled.has_decoration(res->id, spv::DecorationBinding)); - auto& spcTypeMaybeArrayed = compiled.get_type(res->type_id); - - // Handle array bindings - auto arrayElemID = 0u; - auto spcType = spcTypeMaybeArrayed; - if(!spcTypeMaybeArrayed.array.empty()) { - // Multidimensional binding arrays not allowed I guess - dlg_assert(spcType.array.size() == 1u); - - // Loading an entire binding array is not allowed I guess, we just - // require an element to be selected here - dlg_assert(!indices.empty()); - - auto bounds = spcType.array[0]; - if(spcType.array_size_literal[0] == true) { - bounds = compiled.evaluate_constant_u32(bounds); - } - - dlg_assert(u32(indices[0]) < bounds); - - arrayElemID = indices[0]; - indices = indices.subspan(1u); - spcType.array.clear(); - spcType.array_size_literal.clear(); - } - - auto setID = compiled.get_decoration(res->id, spv::DecorationDescriptorSet); - auto bindingID = compiled.get_decoration(res->id, spv::DecorationBinding); - - auto& selection = shaderDebugger().selection(); - auto* baseCmd = selection.command().back(); - auto* cmd = deriveCast(baseCmd); - auto& dsState = selection.descriptorSnapshot(); - auto dss = cmd->boundDescriptors().descriptorSets; - - dlg_assert(setID < dss.size()); - auto& cmdDS = dss[setID]; - - auto stateIt = dsState.states.find(cmdDS.dsEntry); - dlg_assert(stateIt != dsState.states.end()); - auto [ds, lock] = access(*stateIt->second); - - // For samplers, we didn't do a copy and so have to early-out here - auto dsCopyIt = varIDToDsCopyMap_.find(varID); - if(dsCopyIt == varIDToDsCopyMap_.end()) { - dlg_error("OpArrayLength for var {} ERROR: not retrieved", varID); - return 0; - } - - auto hookState = selection.completedHookState(); - dlg_assert(hookState); - // dsCopyIt->second stores the beginning of the range we stored in the - // array elements in. So we have to offset it with the arrayElemID - dlg_assert(hookState->copiedDescriptors.size() > dsCopyIt->second + arrayElemID); - auto& copyResult = hookState->copiedDescriptors[dsCopyIt->second + arrayElemID]; - - dlg_assert(copyResult.op.set == setID); - dlg_assert(copyResult.op.binding == bindingID); - - dlg_assert_or(spcType.storage == spv::StorageClassStorageBuffer || - spcType.storage == spv::StorageClassUniform, return 0); - - auto buf = buffers(ds, bindingID)[arrayElemID]; - u32 size = 0u; - if(buf.buffer) { - size = evalRange(buf.buffer->ci.size, buf.offset, buf.range); - } else { - // NOTE: copied size will usually match the raw buffer size, - // except it was truncated for some reason (e.g. because it - // was too large). - dlg_warn("buffer was destroyed, using copied size instead"); - auto* buf = std::get_if(©Result.data); - dlg_assert(buf); - size = buf->data().size(); - } - - ThreadMemScope tms; - auto [type, off] = accessBuffer(tms, res->type_id, indices, size); - dlg_assert_or(type, return 0); - - dlg_assert(!type->array.empty()); - dlg_assert(type->array[0] == 0u); - auto subSize = type->deco.arrayStride; - for(auto dim : span(type->array).subspan(1)) { - dlg_assert(dim != 0u); // only first dimension can be runtime size - subSize *= dim; - } - - dlg_assert(size % subSize == 0u); - return size / subSize; -} - -std::pair ShaderEmulation::accessBuffer(ThreadMemScope& tms, - unsigned typeID, span indices, u32 dataSize) { - const auto* type = buildType(*shaderDebugger().compiled(), typeID, tms.customUse()); - dlg_assert(type); - - auto off = 0u; - while(!indices.empty()) { - if(!type->array.empty()) { - auto count = type->array[0]; - auto remDims = span(type->array).subspan(1); - - auto subSize = type->deco.arrayStride; - dlg_assert(subSize); - - for(auto size : remDims) { - dlg_assert(size != 0u); // only first dimension can be runtime size - subSize *= size; - } - - if(count == 0u) { // runtime array, find out size - auto remSize = dataSize - off; - // doesn't have to be like that even though it's sus if the buffer - // size isn't a multiple of the stride. - // dlg_assert(remSize % subSize == 0u); - count = remSize / subSize; // intentionally round down - } - - off += u32(indices[0]) * subSize; - indices = indices.subspan(1); - - while(!indices.empty() && !remDims.empty()) { - count = remDims[0]; - remDims = remDims.subspan(1); - - subSize /= count; - off += u32(indices[0]) * subSize; - indices = indices.subspan(1); - } - - auto& cpy = tms.construct(); - cpy = *type; - cpy.array = remDims; - type = &cpy; - } else if(type->type == Type::typeStruct) { - auto id = u32(indices[0]); - indices = indices.subspan(1); - dlg_assert(id < type->members.size()); - - auto& member = type->members[id]; - off += member.offset; - type = member.type; - } else if(type->columns > 1) { - auto id = u32(indices[0]); - indices = indices.subspan(1); - off += type->deco.matrixStride * id; - dlg_assert(id < type->columns); - - auto& cpy = tms.construct(); - cpy = *type; - cpy.columns = 1u; - type = &cpy; - } else if(type->vecsize > 1) { - auto id = u32(indices[0]); - indices = indices.subspan(1); - dlg_assert(id < type->vecsize); - - auto& cpy = tms.construct(); - cpy = *type; - cpy.vecsize = 1u; - type = &cpy; - - // buffer layout does not matter here since new type is scalar - off += id * size(*type, BufferLayout::std140); - } else { - dlg_error("Invalida type for AccessChain"); - type = nullptr; - break; - } - } - - dlg_assert(type); - return {type, u32(off)}; -} - -void ShaderEmulation::loadVar(unsigned srcID, span indices, - span dst, u32 typeID) { - ZoneScoped; - dlg_assert(shaderDebugger().compiled()); - auto& compiled = *shaderDebugger().compiled(); - - auto res = resource(compiled, srcID); - if(!res) { - auto builtin = builtinResource(compiled, srcID); - if(!builtin) { - dlg_error("OpLoad of invalid/unknown var {}", srcID); - return; - } - - loadBuiltin(*builtin, indices, dst); - return; - } - - // dlg_trace("spirv OpLoad of non-builtin var {}", srcID); - - dlg_assert(compiled.has_decoration(res->id, spv::DecorationDescriptorSet) && - compiled.has_decoration(res->id, spv::DecorationBinding)); - auto& spcTypeMaybeArrayed = compiled.get_type(res->type_id); - - // Handle array bindings - auto arrayElemID = 0u; - auto spcType = spcTypeMaybeArrayed; - if(!spcTypeMaybeArrayed.array.empty()) { - // Multidimensional binding arrays not allowed I guess - dlg_assert(spcType.array.size() == 1u); - - // Loading an entire binding array is not allowed I guess, we just - // require an element to be selected here - dlg_assert(!indices.empty()); - - auto bounds = spcType.array[0]; - if(spcType.array_size_literal[0] == true) { - bounds = compiled.evaluate_constant_u32(bounds); - } - - dlg_assert(u32(indices[0]) < bounds); - - arrayElemID = indices[0]; - indices = indices.subspan(1u); - spcType.array.clear(); - spcType.array_size_literal.clear(); - } - - auto setID = compiled.get_decoration(res->id, spv::DecorationDescriptorSet); - auto bindingID = compiled.get_decoration(res->id, spv::DecorationBinding); - - auto* baseCmd = shaderDebugger().selection().command().back(); - auto* cmd = deriveCast(baseCmd); - auto& dsState = shaderDebugger().selection().descriptorSnapshot(); - auto dss = cmd->boundDescriptors().descriptorSets; - - dlg_assert(setID < dss.size()); - auto& cmdDS = dss[setID]; - - auto stateIt = dsState.states.find(cmdDS.dsEntry); - dlg_assert(stateIt != dsState.states.end()); - auto [ds, lock] = access(*stateIt->second); - - // For samplers, we didn't do a copy and so have to early-out here - auto dsCopyIt = varIDToDsCopyMap_.find(srcID); - if(dsCopyIt == varIDToDsCopyMap_.end()) { - dlg_assert_or(spcType.basetype == spc::SPIRType::Sampler, return); - // ugh, not sure which one is right here - dlg_assert_or(spcType.storage == spv::StorageClassUniform || spcType.storage == spv::StorageClassUniformConstant, return); - dlg_assert(indices.empty()); - - // dlg_trace(" >> found sampler"); - - auto image = vil::images(ds, bindingID)[arrayElemID]; - dlg_assert(image.sampler); - - auto& sampler = samplers_.emplace_back(); - sampler.desc = setupSampler(*image.sampler); - - dlg_assert(dst.size() == 1u); - dst[0].value.sampler = &sampler; - - dlg_assert(dst[0].member_count == 0u); - return; - } - - auto hookState = shaderDebugger().selection().completedHookState(); - dlg_assert(hookState); - // dsCopyIt->second stores the beginning of the range we stored in the - // array elements in. So we have to offset it with the arrayElemID - dlg_assert(hookState->copiedDescriptors.size() > dsCopyIt->second + arrayElemID); - auto& copyResult = hookState->copiedDescriptors[dsCopyIt->second + arrayElemID]; - - dlg_assert(copyResult.op.set == setID); - dlg_assert(copyResult.op.binding == bindingID); - dlg_assert(copyResult.op.elem == 0u); - - if(spcType.storage == spv::StorageClassPushConstant) { - auto pcrData = cmd->boundPushConstants().data; - - ThreadMemScope tms; - auto [type, off] = accessBuffer(tms, res->type_id, indices, pcrData.size()); - dlg_assert(type); - - spvm_member* setupDst; - spvm_member wrapper; - if(type->type == Type::typeStruct || - type->vecsize > 1 || - type->columns > 1 || - !type->array.empty()) { - setupDst = &wrapper; - wrapper.type = typeID; - wrapper.members = dst.data(); - wrapper.member_count = dst.size(); - } else { - dlg_assert(dst.size() == 1u); - setupDst = &dst[0]; - } - - // NOTE: this can happen I guess, e.g. if not the whole range was - // bound and the shader is reading undefined data I guess? - auto typeSize = size(*type, BufferLayout::std140); - auto end = off + typeSize; - dlg_assert(end <= pcrData.size()); - if(end > pcrData.size()) { - // read undefined data... - auto undefData = tms.allocUndef(typeSize); - if(off < pcrData.size()) { - std::copy(pcrData.begin() + off, pcrData.end(), undefData.begin()); - } - pcrData = undefData; - } else { - pcrData = pcrData.subspan(off); - } - - setupMember(*type, pcrData, *setupDst); - return; - } else if(spcType.storage == spv::StorageClassInput) { - // TODO: get from vertex input? - dlg_error("TODO: loadVar input"); - return; - } else if(spcType.storage == spv::StorageClassOutput) { - // TODO: from own storage? not sure what this actually means - dlg_error("TODO: loadVar output"); - return; - } else if(spcType.storage == spv::StorageClassUniformConstant) { - // we already handled samplers above - dlg_assert(spcType.basetype != spc::SPIRType::Sampler); - - // TODO: imageView, image from descriptor might be null here. - // We should probably just encode the needed information into - // the CommandHook so we can read the data even if original - // image/view were destroyed. - if(spcType.basetype == spc::SPIRType::Image) { - dlg_assert(dst.size() == 1u); - - auto image = vil::images(ds, bindingID)[arrayElemID]; - if(!image.imageView || !image.imageView->img) { - dlg_warn("source imageView/image were destroyed"); - dst[0].value.image = const_cast(&emptyImage); - return; - } - - auto& imgView = *image.imageView; - auto& img = *imgView.img; - - auto* buf = std::get_if(©Result.data); - dlg_assert(buf); - - auto& dstImg = images_.emplace_back(); - dstImg.width = img.ci.extent.width; - dstImg.height = img.ci.extent.height; - dstImg.depth = img.ci.extent.depth; - dstImg.levels = imgView.ci.subresourceRange.levelCount; - dstImg.layers = imgView.ci.subresourceRange.layerCount; - dstImg.data = buf->buffer.data(); - dstImg.format = buf->format; - - dst[0].value.image = &dstImg; - dlg_assert(u32(dst[0].type) == res->base_type_id); - dlg_assert(dst[0].member_count == 0u); - - return; - } else if(spcType.basetype == spc::SPIRType::SampledImage) { - dlg_assert(dst.size() == 2u); - - auto image = vil::images(ds, bindingID)[arrayElemID]; - if(!image.imageView || !image.imageView->img) { - dlg_warn("source imageView/image or sampler were destroyed"); - dst[0].value.image = const_cast(&emptyImage); - dst[1].value.sampler = const_cast(&defaultSampler); - return; - } - - auto& imgView = *image.imageView; - auto& img = *imgView.img; - - auto* buf = std::get_if(©Result.data); - dlg_assert(buf); - - auto& dstImg = images_.emplace_back(); - dstImg.width = img.ci.extent.width; - dstImg.height = img.ci.extent.height; - dstImg.depth = img.ci.extent.depth; - dstImg.levels = imgView.ci.subresourceRange.levelCount; - dstImg.layers = imgView.ci.subresourceRange.layerCount; - dstImg.data = buf->buffer.data(); - dstImg.format = buf->format; - - auto& sampler = samplers_.emplace_back(); - sampler.desc = setupSampler(*image.sampler); - - auto& spvmRes = spvm_.state->results[srcID]; - auto* resType = spvm_state_get_type_info(spvm_.state->results, &spvm_.state->results[spvmRes.pointer]); - - // members[0]: image - dlg_assert(dst[0].member_count == 0u); - dlg_assert(dst[0].type == resType->pointer); - dst[0].value.image = &dstImg; - - // members[0]: sampler. We don't care about the OpTypeSampler used - dlg_assert(dst[1].member_count == 0u); - dst[1].value.sampler = &sampler; - - return; - } else { - dlg_error("Invalid/unsupported UniformConstant"); - return; - } - } else if(spcType.storage == spv::StorageClassUniform || - spcType.storage == spv::StorageClassStorageBuffer) { - if(spcType.basetype == spc::SPIRType::Struct) { - auto* copiedBuf = std::get_if(©Result.data); - dlg_assert(copiedBuf); - auto data = copiedBuf->data(); - - auto buf = buffers(ds, bindingID)[arrayElemID]; - u32 size = 0u; - if(buf.buffer) { - size = evalRange(buf.buffer->ci.size, buf.offset, buf.range); - } else { - // NOTE: copied size will usually match the raw buffer size, - // except it was truncated for some reason (e.g. because it - // was too large). - dlg_warn("buffer was destroyed, using copied size instead"); - size = data.size(); - } - - ThreadMemScope tms; - auto [type, off] = accessBuffer(tms, res->type_id, indices, size); - dlg_assert(type); - - spvm_member* setupDst; - spvm_member wrapper; - if(type->type == Type::typeStruct || - type->vecsize > 1 || - type->columns > 1 || - !type->array.empty()) { - setupDst = &wrapper; - wrapper.type = typeID; - wrapper.members = dst.data(); - wrapper.member_count = dst.size(); - } else { - dlg_assert(dst.size() == 1u); - setupDst = &dst[0]; - } - - setupMember(*type, data.subspan(off), *setupDst); - return; - } else { - dlg_error("Unsupported spc type for uniform value"); - return; - } - } - - // TODO: - // - graphic pipeline input/output vars - // - ray tracing stuff - dlg_error("Unsupported variable storage class"); - return; -} - -void ShaderEmulation::storeVar(unsigned id, span indices, - span src, u32 typeID) { - // TODO - // even if we are not interested in the results, we have to implement - // it to make sure reads of previous writes return the written values. - (void) id; - (void) indices; - (void) src; - (void) typeID; -} - -void ShaderEmulation::updateHooks(CommandHook& hook) { - dlg_assert(shaderDebugger().compiled()); - auto& compiled = *shaderDebugger().compiled(); - - CommandHookOps ops {}; - varIDToDsCopyMap_.clear(); - - auto resources = compiled.get_shader_resources(); - - auto addCopies = [&](auto& resources, bool imageAsBuffer) { - for(auto& res : resources) { - if(!compiled.has_decoration(res.id, spv::DecorationDescriptorSet) || - !compiled.has_decoration(res.id, spv::DecorationBinding)) { - dlg_warn("resource {} doesn't have set/binding decorations", res.name); - continue; - } - - auto& type = compiled.get_type_from_variable(res.id); - varIDToDsCopyMap_.insert({u32(res.id), u32(ops.descriptorCopies.size())}); - - DescriptorCopyOp dsCopy; - dsCopy.set = compiled.get_decoration(res.id, spv::DecorationDescriptorSet); - dsCopy.binding = compiled.get_decoration(res.id, spv::DecorationBinding); - dsCopy.before = true; - dsCopy.imageAsBuffer = imageAsBuffer; - - auto arraySize = 1u; - if(type.array.size() > 1) { - // TODO: support all array dimensions? - dlg_error("multi-dim arrays not supported"); - } - - for(auto i = 0u; i < arraySize; ++i) { - dsCopy.elem = i; - ops.descriptorCopies.push_back(dsCopy); - } - } - }; - - addCopies(resources.sampled_images, true); - addCopies(resources.separate_images, true); - addCopies(resources.storage_images, true); - addCopies(resources.storage_buffers, false); - addCopies(resources.uniform_buffers, false); - addCopies(resources.subpass_inputs, true); - - // for indirect dispatch, need to know the number of workgrups - // since the shader might read that var - // TODO: only do it if the shader accesses the variable? - auto* baseCmd = shaderDebugger().selection().command().back(); - if(commandCast(baseCmd) || - commandCast(baseCmd) || - commandCast(baseCmd) || - commandCast(baseCmd)) { - ops.copyIndirectCmd = true; - } - - CommandHookUpdate update; - update.invalidate = true; - update.newOps = std::move(ops); - hook.freeze.store(false); - hook.updateHook(std::move(update)); - - shaderDebugger().selection().clearState(); -} - -void ShaderEmulation::initVarMap() { - dlg_assert(shaderDebugger().selection().completedHookState()); - auto& state = *shaderDebugger().selection().completedHookState(); - - dlg_assert(shaderDebugger().compiled()); - auto& compiled = *shaderDebugger().compiled(); - - // TODO: support copied descriptor set without imageAsBuffer. - // We can still manually download the data somehow - - varIDToDsCopyMap_.clear(); - auto resources = compiled.get_shader_resources(); - - auto initVars = [&](auto& resources, bool imageAsBuffer) { - for(auto& res : resources) { - if(!compiled.has_decoration(res.id, spv::DecorationDescriptorSet) || - !compiled.has_decoration(res.id, spv::DecorationBinding)) { - dlg_warn("resource {} doesn't have set/binding decorations", res.name); - continue; - } - - auto& type = compiled.get_type_from_variable(res.id); - auto setID = compiled.get_decoration(res.id, spv::DecorationDescriptorSet); - auto bindingID = compiled.get_decoration(res.id, spv::DecorationBinding); - - // don't have to insert for *each* elemID, they are sequential - auto* copy = findDsCopy(state, setID, bindingID, 0u, - true, imageAsBuffer); - if(!copy) { - dlg_warn("shader debugger: missing var"); - continue; - } - - dlg_assert(copy >= state.copiedDescriptors.data()); - auto off = u32(copy - state.copiedDescriptors.data()); - dlg_assert(off < state.copiedDescriptors.size()); - varIDToDsCopyMap_.insert({u32(res.id), off}); - - // assert that copies are indeed sequential - dlg_check({ - auto arraySize = 1u; - if(type.array.size() > 1) { - // TODO: support all array dimensions? - dlg_error("multi-dim arrays not supported"); - } - - for(auto elemID = 0u; elemID < arraySize; ++elemID) { - auto* ecopy = findDsCopy(state, setID, bindingID, elemID, - true, imageAsBuffer); - dlg_assert(ecopy && (ecopy - copy) == i64(elemID)); - } - }); - } - }; - - initVars(resources.sampled_images, true); - initVars(resources.separate_images, true); - initVars(resources.storage_images, true); - initVars(resources.storage_buffers, false); - initVars(resources.uniform_buffers, false); - initVars(resources.subpass_inputs, true); -} - -void ShaderEmulation::setupScalar(const Type& type, ReadBuf data, spvm_member& dst) { - [[maybe_unused]] auto vt = valueType(dst); - dlg_assert(dst.member_count == 0u); - dlg_assert(vt == spvm_value_type_bool || - vt == spvm_value_type_float || - vt == spvm_value_type_int); - - if(type.type == Type::typeFloat) { - dlg_assert(vt == spvm_value_type_float); - - if(type.width == 32) { - dst.value.f = read(data); - } else if(type.width == 64) { - dst.value.d = read(data); - } else if(type.width == 16) { - dst.value.f = read(data); - } else { - dlg_error("Invalid width: float with {} bits", type.width); - } - } else if(type.type == Type::typeInt) { - dlg_assert(vt == spvm_value_type_int); - - if(type.width == 64) { - dst.value.s = read(data); - } else if(type.width == 32) { - dst.value.s = read(data); - } else if(type.width == 16) { - dst.value.s = read(data); - } else if(type.width == 8) { - dst.value.s = read(data); - } else { - dlg_error("Invalid width: int with {} bits", type.width); - } - } else if(type.type == Type::typeUint) { - dlg_assert(vt == spvm_value_type_int); - - if(type.width == 64) { - dst.value.u = read(data); - } else if(type.width == 32) { - dst.value.u = read(data); - } else if(type.width == 16) { - dst.value.u = read(data); - } else if(type.width == 8) { - dst.value.u = read(data); - } else { - dlg_error("Invalid width: uint with {} bits", type.width); - } - } else if(type.type == Type::typeBool) { - dlg_assert(vt == spvm_value_type_bool); - dlg_assert(type.width == 32); - dst.value.b = bool(read(data)); - } else { - dlg_error("Invalid scalar"); - } -} - -void ShaderEmulation::setupVector(const Type& type, u32 stride, ReadBuf data, - spvm_member& dst) { - dlg_assert(valueType(dst) == spvm_value_type_vector); - - auto nextType = type; - nextType.vecsize = 1u; - - auto elems = children(dst); - dlg_assert(elems.size() == type.vecsize); - - for(auto i = 0u; i < type.vecsize; ++i) { - setupScalar(nextType, data.subspan(i * stride), elems[i]); - } -} - -void ShaderEmulation::setupMember(const Type& type, ReadBuf data, spvm_member& dst) { - if(!type.array.empty()) { - setupMemberArray(type.array, type, data, dst); - return; - } - - if(type.type == Type::typeStruct) { - dlg_assert(valueType(dst) == spvm_value_type_struct); - - auto members = children(dst); - dlg_assert(members.size() == type.members.size()); - - for(auto [i, member] : enumerate(type.members)) { - setupMember(*member.type, data.subspan(member.offset), members[i]); - } - - return; - } - - if(type.columns > 1) { - dlg_assert(type.deco.matrixStride); - dlg_assert(valueType(dst) == spvm_value_type_matrix); - - auto nextType = type; - nextType.columns = 1u; - - auto colStride = type.deco.matrixStride; - auto rowStride = type.width / 8; - - if(type.deco.flags & Decoration::Bits::rowMajor) { - std::swap(colStride, rowStride); - } - - auto cols = children(dst); - dlg_assert(cols.size() == type.columns); - - for(auto i = 0u; i < type.columns; ++i) { - auto off = i * colStride; - setupVector(nextType, rowStride, data.subspan(off), cols[i]); - } - - return; - } else if(type.vecsize > 1) { - auto stride = type.width / 8; - return setupVector(type, stride, data, dst); - } - - setupScalar(type, data, dst); -} - -void ShaderEmulation::setupMemberArray(span arrayDims, - const Type& type, ReadBuf data, spvm_member& dst) { - dlg_assert(!type.array.empty()); - - auto count = arrayDims[0]; - arrayDims = arrayDims.subspan(1); - - auto subSize = type.deco.arrayStride; - for(auto dim : arrayDims) { - dlg_assert(dim != 0u); // only first dimension can be runtime size - subSize *= dim; - } - - if(count == 0u) { - // NOTE: this can't happen, loading a runtime_array is not allowed - // per spirv. - dlg_assert(valueType(dst) == spvm_value_type_runtime_array); - dlg_error("OpLoad on runtime array?! Not allowed!"); - return; - - /* - // runtime array, find out real size. - auto remSize = data.size(); - // doesn't have to be like that even though it's sus if the buffer - // size isn't a multiple of the stride. - // dlg_assert(remSize % subSize == 0u); - count = remSize / subSize; // intentionally round down - */ - } - - dlg_assert(valueType(dst) == spvm_value_type_array); - - auto elems = children(dst); - dlg_assert(elems.size() == count); - - for(auto i = 0u; i < count; ++i) { - auto nextData = data.subspan(i * subSize); - - if(!arrayDims.empty()) { - setupMemberArray(arrayDims, type, nextData, elems[i]); - } else { - auto nt = type; - nt.array = {}; - setupMember(nt, nextData, elems[i]); - } - } -} - -spvm_sampler_desc ShaderEmulation::setupSampler(const Sampler& src) { - spvm_sampler_desc ret {}; - ret.filter_min = spvm_sampler_filter(src.ci.minFilter); - ret.filter_mag = spvm_sampler_filter(src.ci.magFilter); - ret.mipmap_mode = spvm_sampler_filter(src.ci.mipmapMode); - ret.address_mode_u = spvm_sampler_address_mode(src.ci.addressModeU); - ret.address_mode_v = spvm_sampler_address_mode(src.ci.addressModeV); - ret.address_mode_w = spvm_sampler_address_mode(src.ci.addressModeW); - ret.mip_bias = src.ci.mipLodBias; - ret.compare_op = spvm_sampler_compare_op(src.ci.compareOp); - ret.min_lod = src.ci.minLod; - ret.max_lod = src.ci.maxLod; - return ret; -} - -spvm_vec4f ShaderEmulation::readImage(spvm_image& srcImg, int x, int y, int z, int layer, int level) { - auto& img = static_cast(srcImg); - auto off = 0u; - - Vec3ui extent = {img.width, img.height, img.depth}; - for(auto l = 0; l < level; ++l) { - extent[0] = std::max(extent[0] >> 1, 1u); - extent[1] = std::max(extent[1] >> 1, 1u); - extent[2] = std::max(extent[2] >> 1, 1u); - off += extent[0] * extent[1] * extent[2] * img.layers; - } - - auto sliceSize = extent[0] * extent[1]; - auto layerSize = extent[2] * sliceSize; - - off += layer * layerSize; - off += z * sliceSize; - off += y * extent[0]; - off += x; - - auto fmtSize = FormatElementSize(img.format); - off *= fmtSize; - if(off + fmtSize > img.data.size()) { - dlg_warn("Image read would be out of range: \n" - "\tpos ({}, {}, {}), layer {}, level {}\n" - "\timage data size in pixels: {}", - x, y, z, layer, level, img.data.size() / fmtSize); - return {}; - } - - auto texelBytes = img.data.subspan(off, fmtSize); - auto texel = read(img.format, texelBytes); - - return {float(texel[0]), float(texel[1]), float(texel[2]), float(texel[3])}; -} - -void ShaderEmulation::drawControls() { - // TODO - /* - dlg_assert(spvm_.state); - - auto isLastReturn = [this](){ // TODO: kinda hacky. I guess spvm should have a function - // like this? or we should always save the relevant information - // before stepping? not sure. - spvm_word opcode_data = *spvm_.state->code_current; - SpvOp opcode = SpvOp(opcode_data & SpvOpCodeMask); - - if((opcode == SpvOpReturn || opcode == SpvOpReturnValue) && - spvm_.state->function_stack_current == 0) { - return true; - } - - return false; - }; - - if(lastHookState_ != hookState.get()) { - rerun_ = true; - lastHookState_ = hookState.get(); - } - - if(rerun_) { - spvm_state_delete(spvm_.state); - initState(); - - // TODO: not sure how to handle divergence (i.e. when the current - // run doesn't hit the position we want to get to) - // Maybe just go to beginning again but don't overwrite currLine, - // currFileName? - // notify about it in UI? - while(spvm_.state->code_current && ( - u32(spvm_.state->current_line) != currLine_ || - !spvm_.state->current_file || - spvm_.state->current_file != currFileName_)) { - auto doBreak = stepOpcode(); - if(doBreak) { - if(freezeOnBreakPoint_) { - freezeOnBreakPoint_ = false; - gui_->cbGui().selector().freezeState = true; - } - - break; - } - } - - // We don't want to update the cursor position here since that would - // make navigation impossible when refreshing every frame. - updatePosition(false); - rerun_ = false; - } - - // Handle input - if(spvm_.state->code_current && textedit_.mFocused) { - ImGuiIO& io = ImGui::GetIO(); - auto shift = io.KeyShift; - auto ctrl = io.KeyCtrl; - auto alt = io.KeyAlt; - - auto breakKey = ImGuiKey_F9; - auto stepKey = ImGuiKey_F10; - - if(!shift && !ctrl && !alt && ImGui::IsKeyPressed(breakKey, false)) { - toggleBreakpoint(); - } else if(!shift && !ctrl && !alt && ImGui::IsKeyPressed(stepKey, false)) { - stepLine(); - } - - io.WantCaptureKeyboard = true; - } - - // Controls - if(spvm_.state->code_current) { - if(ImGui::Button("Step Opcode")) { - auto doBreak = false; - // silently execute all init instructions here first - do { - doBreak = stepOpcode(); - } while(spvm_.state->current_line < 0 && spvm_.state->code_current && !doBreak); - } - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Execute a single SPIR-V opcode"); - } - - ImGui::SameLine(); - - if(spvm_.state->code_current && ImGui::Button("Step Line")) { - stepLine(); - } - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Execute the program until the current line changes"); - } - - ImGui::SameLine(); - - if(ImGui::Button("Run")) { - auto doBreak = false; - while(spvm_.state->code_current && !doBreak) { - // TODO: really do this here? kinda hacky - if(isLastReturn()) { - break; - } - - doBreak = stepOpcode(); - } - - updatePosition(true); - } - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Execute the program until it's finished " - "or a breakpoint triggered"); - } - - - ImGui::SameLine(); - - // toggle breakpoint - if(ImGui::Button("Breakpoint")) { - toggleBreakpoint(); - } - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Toggles the breakpoint at the current file/line " - "of the code editor"); - } - - ImGui::SameLine(); - - if(ImGui::Button("Move Cursor")) { - updatePosition(true); - } - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Move the cursor in the editor to the " - "current execution position"); - } - - // TODO: execute to cursor button/functionality - } else { - ImGui::Text("Finished"); - - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Program execution has finished."); - } - } - - ImGui::SameLine(); - - if(ImGui::Button("Reset")) { - spvm_state_delete(spvm_.state); - initState(); - updatePosition(true); - } - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Reset execution to the beginning"); - } - - { - auto disable = gui_->cbGui().selector().freezeState; - if(disable) { - ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.6f); - } - - ImGui::Checkbox("Freeze on Breakpoint", &freezeOnBreakPoint_); - if(gui_->showHelp && ImGui::IsItemHovered()) { - ImGui::SetTooltip("Automatically freeze state when hitting " - "a breakpoint"); - } - - if(disable) { - ImGui::PopStyleVar(); - ImGui::PopItemFlag(); - } - } - */ -} - -void ShaderEmulation::updateFromEditor() { - // currLine_ = spvm_.state->current_line; - // if(spvm_.state->current_file) { - // currFileName_ = spvm_.state->current_file; - // } -} - -/* -void ShaderEmulation::drawVariablesTab() { - // imGuiText("Current line: {}", state->current_line); - // imGuiText("Instruction count : {}", state->instruction_count); - // imGuiText("Offset: {}", state->code_current - program->code); - - // vars_ - // for(auto [name, res] : vars_) { - // printRes(name, res); - // } - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, gui_->uiScale() * ImVec2(4.f, 2.5f)); - auto flags = ImGuiTableFlags_BordersInner | - ImGuiTableFlags_Resizable | - ImGuiTableFlags_SizingStretchSame; - if(ImGui::BeginTable("Values", 2u, flags)) { - ImGui::TableSetupColumn(nullptr, 0, 0.25f); - ImGui::TableSetupColumn(nullptr, 0, 0.75f); - - // local vars - for(auto i = 0u; i < spvm_.program->bound; ++i) { - auto& res = spvm_.state->results[i]; - if((res.type != spvm_result_type_variable && res.type != spvm_result_type_function_parameter) || - !res.name || - res.owner != spvm_.state->current_function || - // TODO: make this filter optional, via gui. - // Useful in many cases but can be annoying/incorrect when - // a variable isn't written on all branches. - // To fix this (the filter setting/checkbox is probably - // still a good idea) we could store the first OpStore - // to this variable in opcode_setup of spvm. And then - // here compare whether the current position of state - // postdominates that instruction. - !res.stored_to) { - continue; - } - - if(res.owner != spvm_.state->current_function) { - continue; - } - - // auto it = vars_.find(res.name); - // if(it != vars_.end()) { - // continue; - // } - - const spvm_member* setupDst; - spvm_member wrapper; - auto* resType = spvm_state_get_type_info(spvm_.state->results, - &spvm_.state->results[res.pointer]); - auto vt = resType->value_type; - - if(vt == spvm_value_type_matrix || - vt == spvm_value_type_vector || - vt == spvm_value_type_struct || - vt == spvm_value_type_array) { - setupDst = &wrapper; - wrapper.type = u32(resType - spvm_.state->results); // type id - wrapper.members = res.members; - wrapper.member_count = res.member_count; - } else { - dlg_assert(res.member_count == 1u); - setupDst = &res.members[0]; - } - - display(res.name, *setupDst); - } - - ImGui::EndTable(); - } - - ImGui::PopStyleVar(1); -} - -void ShaderEmulation::drawBreakpointsTab() { - for(auto& bp : breakpoints_) { - ImGui::Bullet(); - ImGui::SameLine(); - imGuiText("{}:{}", fileName(bp.fileID), bp.lineID); - } -} - -void ShaderEmulation::drawCallstackTab() { - // TODO: does not belong here. Visual representation would be useful. - imGuiText("Current line: {}", spvm_.state->current_line); - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, gui_->uiScale() * ImVec2(4.f, 2.5f)); - auto flags = ImGuiTableFlags_BordersInner | - ImGuiTableFlags_Resizable | - ImGuiTableFlags_SizingStretchSame; - if(ImGui::BeginTable("Callstack", 3u, flags)) { - // TODO: - // - allow selecting entries and then showing the respective variables from threre - // - show file, line, function (and maybe hide address by default) - auto count = spvm_.state->function_stack_current + 1; - for(auto i = 0; i < count; ++i) { - ImGui::TableNextRow(); - - // TODO: show line! - - ImGui::TableNextColumn(); - imGuiText("{}", i); - - ImGui::TableNextColumn(); - imGuiText("{}", static_cast(spvm_.state->function_stack[i])); - - ImGui::TableNextColumn(); - auto name = spvm_.state->function_stack_info[i]->name; - imGuiText("{}", name ? name : "?"); - } - - ImGui::EndTable(); - } - - ImGui::PopStyleVar(1); -} - -*/ - -void ShaderEmulation::updatePosition(bool moveCursor) { - (void) moveCursor; - /* - if(!spvm_.state->current_file) { - dlg_warn("Can't jump to debugging state, current_file is null"); - return; - } - - if(spvm_.state->current_line < 0) { - dlg_warn("Can't jump to debugging state, current_line = {}", - spvm_.state->current_line); - return; - } - - auto fileID = -1; - for(auto i = 0u; i < spvm_.state->owner->file_count; ++i) { - if(std::strcmp(spvm_.state->owner->files[i].name, spvm_.state->current_file) == 0u) { - fileID = i; - break; - } - } - - if(fileID == -1) { - dlg_warn("Can't jump to debugging state, invalid file '{}'", spvm_.state->current_file); - return; - } - - if(currFileName_ != spvm_.state->owner->files[fileID].name) { - dlg_trace("now in file {}", spvm_.state->owner->files[fileID].name); - textedit_.SetText(spvm_.state->owner->files[fileID].source); - } - - // TODO: seems to be a textedit bug - auto line = spvm_.state->current_line == 0 ? 0 : spvm_.state->current_line - 1; - textedit_.mCurrentLineNumber = {unsigned(line)}; - - if(moveCursor) { - textedit_.SetCursorPosition({line, 1}); - } - */ -} - -void ShaderEmulation::drawControlTabs() { - /* - if(ImGui::BeginTabBar("Tabs")) { - if(ImGui::BeginTabItem("Inputs")) { - drawInputsTab(); - ImGui::EndTabItem(); - } - - if(ImGui::BeginTabItem("Callstack")) { - drawCallstackTab(); - ImGui::EndTabItem(); - } - - if(ImGui::BeginTabItem("Variables")) { - drawVariablesTab(); - ImGui::EndTabItem(); - } - - if(ImGui::BeginTabItem("Breakpoints")) { - drawBreakpointsTab(); - ImGui::EndTabItem(); - } - - ImGui::EndTabBar(); - } - */ -} - - /* -void ShaderDebugger::toggleBreakpoint() { - // TODO: get current editor file - auto fileName = spvm_.state->current_file; - if(!fileName) { - dlg_assert(spvm_.state->owner->file_count > 0); - fileName = spvm_.state->owner->files[0].name; - } - - const auto fid = fileID(fileName); - const auto line = 1 + u32(textedit_.GetCursorPosition().mLine); - bool doSet = true; - - for(auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) { - auto& bp = *it; - if(bp.lineID == line && bp.fileID == fid) { - doSet = false; - breakpoints_.erase(it); - // TODO: file - textedit_.GetBreakpoints().erase(line); - break; - } - } - - if(doSet) { - // find position - auto spv = spvm_.program->code; - auto spvEnd = spvm_.program->code + spvm_.program->code_length; - - struct Find { - const spvm_source pos; - u32 line; - }; - - std::optional best; - - while(spv < spvEnd) { - auto instrBegin = spv; - spvm_word opcode_data = SPVM_READ_WORD(spv); - spvm_word word_count = ((opcode_data & (~SpvOpCodeMask)) >> SpvWordCountShift); - SpvOp opcode = SpvOp(opcode_data & SpvOpCodeMask); - - if(opcode == SpvOpLine) { - u32 opfile = SPVM_READ_WORD(spv); - u32 opline = SPVM_READ_WORD(spv); - u32 opclmn = SPVM_READ_WORD(spv); - (void) opclmn; - - auto opfileID = fileID(spvm_.state->results[opfile].name); - if(opfileID == fid && opline >= line) { - if(!best || opline < best->line) { - best.emplace(Find{instrBegin, opline}); - - if(opline == line) { - // exact - break; - } - } - } - } - - dlg_assert(word_count > 0); - spv = instrBegin + word_count; - } - - // TODO: add threshold? we currently might add a breakpoint - // somewhere else, just because it's the closest. - // Should at least be in the same function, right? - if(!best) { - dlg_error("Coun't find location for breakpoint"); - return; - } - - // TODO: move visual presentation of breakpoint to the - // exact found position? - - auto& nbp = breakpoints_.emplace_back(); - nbp.fileID = fid; - nbp.lineID = line; - nbp.pos = best->pos; - textedit_.GetBreakpoints().insert(line); - } -} - */ - -} // namespace vil diff --git a/src/spvm/LICENSE b/src/spvm/LICENSE deleted file mode 100644 index 24cafde0..00000000 --- a/src/spvm/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 dfranx - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/src/spvm/analyzer.h b/src/spvm/analyzer.h deleted file mode 100644 index e4053616..00000000 --- a/src/spvm/analyzer.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __SPIRV_VM_ANALYZER_H__ -#define __SPIRV_VM_ANALYZER_H__ - -#include - -enum spvm_undefined_behavior { - spvm_undefined_behavior_none, // not an undefined behavior - spvm_undefined_behavior_div_by_zero, // a/b when b == 0 - spvm_undefined_behavior_mod_by_zero, // a%b when b == 0 - spvm_undefined_behavior_image_read_out_of_bounds, // OpImageRead -> coords are out of bounds - spvm_undefined_behavior_image_write_out_of_bounds, // OpImageWrite-> coords are out of bounds - spvm_undefined_behavior_vector_extract_dynamic, // OpVectorExtractDynamic -> index out of bounds - spvm_undefined_behavior_vector_insert_dynamic, // OpVectorInsertDynamic -> index out of bounds - spvm_undefined_behavior_asin, // asin(x) when |x| > 1 - spvm_undefined_behavior_acos, // acos(x) when |x| > 1 - spvm_undefined_behavior_acosh, // acosh(x) when x < 1 - spvm_undefined_behavior_atanh, // atanh(x) when |x| >= 1 - spvm_undefined_behavior_atan2, // atan2(y, x) when x = y = 0 - spvm_undefined_behavior_pow, // pow(x, y) when x < 0 or when x = 0 and y <= 0 - spvm_undefined_behavior_log, // log(x) when x <= 0 - spvm_undefined_behavior_log2, // log2(x) when x <= 0 - spvm_undefined_behavior_sqrt, // sqrt(x) when x < 0 - spvm_undefined_behavior_inverse_sqrt, // invsqrt(x) when x <= 0 - spvm_undefined_behavior_fmin, // min(x, y) when x or y is NaN - spvm_undefined_behavior_fmax, // max(x, y) when x or y is NaN - spvm_undefined_behavior_clamp, // clamp(x, minVal, maxVal) when minVal > maxVal - spvm_undefined_behavior_smoothstep, // smoothstep(edge0, edge1, x) when edge0 >= edge1 - spvm_undefined_behavior_frexp, // frexp(x, out exp) when x is NaN or inf - spvm_undefined_behavior_ldexp, // ldexp(x, exp) when exp > 128 (float) or exp > 1024 (double) - spvm_undefined_behavior_image_gather_invalid_comp, // OpImageGather -> component not in {0, 1, 2, 3} - spvm_undefined_behavior_matrix_inverse, // inverse(m) -> m was singular - spvm_undefined_behavior_count -}; - -typedef struct spvm_analyzer { - void (*on_undefined_behavior)(struct spvm_state*, spvm_word ub); -} spvm_analyzer; -typedef struct spvm_analyzer* spvm_analyzer_t; - - -#endif // __SPIRV_VM_ANALYZER_H__ diff --git a/src/spvm/context.c b/src/spvm/context.c deleted file mode 100644 index 22997a9d..00000000 --- a/src/spvm/context.c +++ /dev/null @@ -1,16 +0,0 @@ -#include - - -spvm_context_t spvm_context_initialize() -{ - spvm_context_t ret = (spvm_context_t)malloc(sizeof(spvm_context)); - _spvm_context_create_execute_table(ret); - _spvm_context_create_setup_table(ret); - return ret; -} -void spvm_context_deinitialize(spvm_context_t ctx) -{ - free(ctx->opcode_execute); - free(ctx->opcode_setup); - free(ctx); -} \ No newline at end of file diff --git a/src/spvm/context.h b/src/spvm/context.h deleted file mode 100644 index c1f77b2b..00000000 --- a/src/spvm/context.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __SPIRV_VM_CONTEXT_H__ -#define __SPIRV_VM_CONTEXT_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#define SPVM_OPCODE_TABLE_LENGTH 405 - -typedef struct spvm_context { - spvm_opcode_func* opcode_execute; - spvm_opcode_func* opcode_setup; -} spvm_context; -typedef struct spvm_context* spvm_context_t; - -spvm_context_t spvm_context_initialize(); -void spvm_context_deinitialize(spvm_context_t ctx); - -/* PRIVATE FUNCTIONS */ -void _spvm_context_create_execute_table(spvm_context_t ctx); -void _spvm_context_create_setup_table(spvm_context_t ctx); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SPIRV_VM_CONTEXT_H__ diff --git a/src/spvm/ext/GLSL.std.450.h b/src/spvm/ext/GLSL.std.450.h deleted file mode 100644 index 7c884684..00000000 --- a/src/spvm/ext/GLSL.std.450.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -** Copyright (c) 2014-2016 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and/or associated documentation files (the "Materials"), -** to deal in the Materials without restriction, including without limitation -** the rights to use, copy, modify, merge, publish, distribute, sublicense, -** and/or sell copies of the Materials, and to permit persons to whom the -** Materials are furnished to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in -** all copies or substantial portions of the Materials. -** -** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -** IN THE MATERIALS. -*/ - -#ifndef GLSLstd450_H -#define GLSLstd450_H - -static const int GLSLstd450Version = 100; -static const int GLSLstd450Revision = 3; - -enum GLSLstd450 { - GLSLstd450Bad = 0, // Don't use - - GLSLstd450Round = 1, - GLSLstd450RoundEven = 2, - GLSLstd450Trunc = 3, - GLSLstd450FAbs = 4, - GLSLstd450SAbs = 5, - GLSLstd450FSign = 6, - GLSLstd450SSign = 7, - GLSLstd450Floor = 8, - GLSLstd450Ceil = 9, - GLSLstd450Fract = 10, - - GLSLstd450Radians = 11, - GLSLstd450Degrees = 12, - GLSLstd450Sin = 13, - GLSLstd450Cos = 14, - GLSLstd450Tan = 15, - GLSLstd450Asin = 16, - GLSLstd450Acos = 17, - GLSLstd450Atan = 18, - GLSLstd450Sinh = 19, - GLSLstd450Cosh = 20, - GLSLstd450Tanh = 21, - GLSLstd450Asinh = 22, - GLSLstd450Acosh = 23, - GLSLstd450Atanh = 24, - GLSLstd450Atan2 = 25, - - GLSLstd450Pow = 26, - GLSLstd450Exp = 27, - GLSLstd450Log = 28, - GLSLstd450Exp2 = 29, - GLSLstd450Log2 = 30, - GLSLstd450Sqrt = 31, - GLSLstd450InverseSqrt = 32, - - GLSLstd450Determinant = 33, - GLSLstd450MatrixInverse = 34, - - GLSLstd450Modf = 35, // second operand needs an OpVariable to write to - GLSLstd450ModfStruct = 36, // no OpVariable operand - GLSLstd450FMin = 37, - GLSLstd450UMin = 38, - GLSLstd450SMin = 39, - GLSLstd450FMax = 40, - GLSLstd450UMax = 41, - GLSLstd450SMax = 42, - GLSLstd450FClamp = 43, - GLSLstd450UClamp = 44, - GLSLstd450SClamp = 45, - GLSLstd450FMix = 46, - GLSLstd450IMix = 47, // Reserved - GLSLstd450Step = 48, - GLSLstd450SmoothStep = 49, - - GLSLstd450Fma = 50, - GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to - GLSLstd450FrexpStruct = 52, // no OpVariable operand - GLSLstd450Ldexp = 53, - - GLSLstd450PackSnorm4x8 = 54, - GLSLstd450PackUnorm4x8 = 55, - GLSLstd450PackSnorm2x16 = 56, - GLSLstd450PackUnorm2x16 = 57, - GLSLstd450PackHalf2x16 = 58, - GLSLstd450PackDouble2x32 = 59, - GLSLstd450UnpackSnorm2x16 = 60, - GLSLstd450UnpackUnorm2x16 = 61, - GLSLstd450UnpackHalf2x16 = 62, - GLSLstd450UnpackSnorm4x8 = 63, - GLSLstd450UnpackUnorm4x8 = 64, - GLSLstd450UnpackDouble2x32 = 65, - - GLSLstd450Length = 66, - GLSLstd450Distance = 67, - GLSLstd450Cross = 68, - GLSLstd450Normalize = 69, - GLSLstd450FaceForward = 70, - GLSLstd450Reflect = 71, - GLSLstd450Refract = 72, - - GLSLstd450FindILsb = 73, - GLSLstd450FindSMsb = 74, - GLSLstd450FindUMsb = 75, - - GLSLstd450InterpolateAtCentroid = 76, - GLSLstd450InterpolateAtSample = 77, - GLSLstd450InterpolateAtOffset = 78, - - GLSLstd450NMin = 79, - GLSLstd450NMax = 80, - GLSLstd450NClamp = 81, - - GLSLstd450Count -}; - -#endif // #ifndef GLSLstd450_H \ No newline at end of file diff --git a/src/spvm/ext/GLSL450.c b/src/spvm/ext/GLSL450.c deleted file mode 100644 index 99a7fc31..00000000 --- a/src/spvm/ext/GLSL450.c +++ /dev/null @@ -1,1367 +0,0 @@ -#include -#include -#include "GLSL.std.450.h" -#include -#include - -#ifndef M_PI -# define M_PI 3.14159265358979323846 -#endif - -void spvm_execute_GLSL450_Round(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = round(state->results[x].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = roundf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_RoundEven(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = round(state->results[x].members[i].value.d * 0.5) + 0.5; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = roundf(state->results[x].members[i].value.f * 0.5f) + 0.5f; -} -void spvm_execute_GLSL450_Trunc(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = trunc(state->results[x].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = truncf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_FAbs(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = fabs(state->results[x].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = fabsf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_SAbs(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = labs(state->results[x].members[i].value.s); -} -void spvm_execute_GLSL450_FSign(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - double d = state->results[x].members[i].value.d; - state->results[id].members[i].value.d = (d < 0.0) ? -1 : (d > 0.0 ? 1 : 0); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - float f = state->results[x].members[i].value.f; - state->results[id].members[i].value.f = (f < 0.0f) ? -1 : (f > 0.0f ? 1 : 0); - } -} -void spvm_execute_GLSL450_SSign(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - int s = state->results[x].members[i].value.s; - state->results[id].members[i].value.s = (s < 0) ? -1 : (s > 0 ? 1 : 0); - } -} -void spvm_execute_GLSL450_Floor(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = floor(state->results[x].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = floorf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Ceil(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = ceil(state->results[x].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = ceilf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Fract(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[x].members[i].value.d - floor(state->results[x].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[x].members[i].value.f - floorf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Radians(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[x].members[i].value.f * M_PI / 180.0f; -} -void spvm_execute_GLSL450_Degrees(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[x].members[i].value.f * 180.0f / M_PI; -} -void spvm_execute_GLSL450_Sin(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = sinf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Cos(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = cosf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Tan(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = tanf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Asin(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = asinf(state->results[x].members[i].value.f); - - if (state->analyzer && fabsf(state->results[x].members[i].value.f) > 1.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_acos); - } -} -void spvm_execute_GLSL450_Acos(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = acosf(state->results[x].members[i].value.f); - - if (state->analyzer && fabsf(state->results[x].members[i].value.f) > 1.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_acos); - } -} -void spvm_execute_GLSL450_Atan(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = atanf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Sinh(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = sinhf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Cosh(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = coshf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Tanh(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = tanhf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Asinh(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = asinhf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Acosh(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = acoshf(state->results[x].members[i].value.f); - - if (state->analyzer && state->results[x].members[i].value.f < 1.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_acosh); - } -} -void spvm_execute_GLSL450_Atanh(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = atanhf(state->results[x].members[i].value.f); - - if (state->analyzer && fabsf(state->results[x].members[i].value.f) >= 1.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_atanh); - } -} -void spvm_execute_GLSL450_Atan2(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word y = SPVM_READ_WORD(state->code_current); - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = atan2f(state->results[y].members[i].value.f, state->results[x].members[i].value.f); - - if (state->analyzer && state->results[x].members[i].value.f == 0.0f && state->results[y].members[i].value.f == 0.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_atan2); - } -} -void spvm_execute_GLSL450_Pow(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = powf(state->results[x].members[i].value.f, state->results[y].members[i].value.f); - - if (state->analyzer && (state->results[x].members[i].value.f < 0.0f || - (state->results[x].members[i].value.f == 0.0f && state->results[y].members[i].value.f <= 0.0f))) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_pow); - } -} -void spvm_execute_GLSL450_Exp(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = expf(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Log(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = logf(state->results[x].members[i].value.f); - - if (state->analyzer && state->results[x].members[i].value.f <= 0.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_log); - } -} -void spvm_execute_GLSL450_Exp2(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = exp2f(state->results[x].members[i].value.f); -} -void spvm_execute_GLSL450_Log2(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = log2f(state->results[x].members[i].value.f); - - if (state->analyzer && state->results[x].members[i].value.f <= 0.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_log2); - } -} -void spvm_execute_GLSL450_Sqrt(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.d = sqrt(state->results[x].members[i].value.d); - - if (state->analyzer && state->results[x].members[i].value.d < 0.0) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_sqrt); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = sqrtf(state->results[x].members[i].value.f); - - if (state->analyzer && state->results[x].members[i].value.f < 0.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_sqrt); - } -} -void spvm_execute_GLSL450_InverseSqrt(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.d = 1.0 / sqrt(state->results[x].members[i].value.d); - - if (state->analyzer && state->results[x].members[i].value.d <= 0.0) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_inverse_sqrt); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = 1.0f / sqrtf(state->results[x].members[i].value.f); - - if (state->analyzer && state->results[x].members[i].value.f <= 0.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_inverse_sqrt); - } -} -#define MATRIX_GET(m, c, r) *(m + c * 4 + r) -void matrix_to_array_d(double* out, spvm_byte use_d, spvm_member_t mems, spvm_word mem_count) { - if (use_d) { - for (spvm_word i = 0; i < mem_count; i++) { - assert(mems[i].member_count == mem_count); - for (spvm_word j = 0; j < mems[i].member_count; j++) { - MATRIX_GET(out, i, j) = mems[i].members[j].value.d; - } - } - } - else { - for (spvm_word i = 0; i < mem_count; i++) { - assert(mems[i].member_count == mem_count); - for (spvm_word j = 0; j < mems[i].member_count; j++) { - MATRIX_GET(out, i, j) = (double)mems[i].members[j].value.f; - } - } - } -} -double matrix_determinant(double* m, spvm_word mtype) -{ - if (mtype == 2) // 2x2 matrix - return MATRIX_GET(m,0,0) * MATRIX_GET(m, 1, 1) - MATRIX_GET(m, 1, 0) * MATRIX_GET(m, 0, 1); - else if (mtype == 3) // 3x3 matrix - return MATRIX_GET(m,0,0) * (MATRIX_GET(m,1,1) * MATRIX_GET(m,2,2) - MATRIX_GET(m,2,1) * MATRIX_GET(m,1,2)) - -MATRIX_GET(m,1,0) * (MATRIX_GET(m,0,1) * MATRIX_GET(m,2,2) - MATRIX_GET(m,2,1) * MATRIX_GET(m,0,2)) - +MATRIX_GET(m,2,0) * (MATRIX_GET(m,0,1) * MATRIX_GET(m,1,2) - MATRIX_GET(m,1,1) * MATRIX_GET(m,0,2)); - else if (mtype == 4) { - double m2233 = MATRIX_GET(m,2,2) * MATRIX_GET(m,3,3) - MATRIX_GET(m,3,2) * MATRIX_GET(m,2,3); - double m2133 = MATRIX_GET(m,2,1) * MATRIX_GET(m,3,3) - MATRIX_GET(m,3,1) * MATRIX_GET(m,2,3); - double m2132 = MATRIX_GET(m,2,1) * MATRIX_GET(m,3,2) - MATRIX_GET(m,3,1) * MATRIX_GET(m,2,2); - double m2033 = MATRIX_GET(m,2,0) * MATRIX_GET(m,3,3) - MATRIX_GET(m,3,0) * MATRIX_GET(m,2,3); - double m2032 = MATRIX_GET(m,2,0) * MATRIX_GET(m,3,2) - MATRIX_GET(m,3,0) * MATRIX_GET(m,2,2); - double m2031 = MATRIX_GET(m,2,0) * MATRIX_GET(m,3,1) - MATRIX_GET(m,3,0) * MATRIX_GET(m,2,1); - - return MATRIX_GET(m,0,0) * (MATRIX_GET(m,1,1) * m2233 - MATRIX_GET(m,1,2) * m2133 + MATRIX_GET(m,1,3) * m2132) - -MATRIX_GET(m,0,1) * (MATRIX_GET(m,1,0) * m2233 - MATRIX_GET(m,1,2) * m2033 + MATRIX_GET(m,1,3) * m2032) - +MATRIX_GET(m,0,2) * (MATRIX_GET(m,1,0) * m2133 - MATRIX_GET(m,1,1) * m2033 + MATRIX_GET(m,1,3) * m2031) - -MATRIX_GET(m,0,3) * (MATRIX_GET(m,1,0) * m2132 - MATRIX_GET(m,1,1) * m2032 + MATRIX_GET(m,1,2) * m2031); - } - - return 0.0; -} -void spvm_execute_GLSL450_Determinant(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - double m[4][4]; - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - spvm_word mtype = state->results[x].member_count; - - matrix_to_array_d(&m[0][0], type_info->value_bitcount > 32, state->results[x].members, mtype); - double res = matrix_determinant(&m[0][0], mtype); - - if (type_info->value_bitcount > 32) - state->results[id].members[0].value.d = res; - else - state->results[id].members[0].value.f = res; -} -void spvm_execute_GLSL450_MatrixInverse(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - double m[4][4]; - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - spvm_word mtype = state->results[x].member_count; - - matrix_to_array_d(&m[0][0], type_info->value_bitcount > 32, state->results[x].members, mtype); - // TODO: when the determinant here is zero, the resulting values - // are undefined per glsl spec. - // Add error code in undefined behavior analyzer - double det = matrix_determinant(&m[0][0], mtype); - if (state->analyzer && fabs(det) < 0.000001) { - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_matrix_inverse); - } - - double invdet = 1.0 / det; - - double res[4][4] = {0}; - - if (mtype == 2) { - res[0][0] = +m[1][1] * invdet; - res[0][1] = -m[0][1] * invdet; - res[1][0] = -m[1][0] * invdet; - res[1][1] = +m[0][0] * invdet; - } else if (mtype == 3) { - res[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]) * invdet; - res[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * invdet; - res[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]) * invdet; - res[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]) * invdet; - res[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]) * invdet; - res[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]) * invdet; - res[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]) * invdet; - res[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]) * invdet; - res[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]) * invdet; - } else if (mtype == 4) { - double c00 = m[2][2] * m[3][3] - m[3][2] * m[2][3]; - double c02 = m[1][2] * m[3][3] - m[3][2] * m[1][3]; - double c03 = m[1][2] * m[2][3] - m[2][2] * m[1][3]; - - double c04 = m[2][1] * m[3][3] - m[3][1] * m[2][3]; - double c06 = m[1][1] * m[3][3] - m[3][1] * m[1][3]; - double c07 = m[1][1] * m[2][3] - m[2][1] * m[1][3]; - - double c08 = m[2][1] * m[3][2] - m[3][1] * m[2][2]; - double c10 = m[1][1] * m[3][2] - m[3][1] * m[1][2]; - double c11 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; - - double c12 = m[2][0] * m[3][3] - m[3][0] * m[2][3]; - double c14 = m[1][0] * m[3][3] - m[3][0] * m[1][3]; - double c15 = m[1][0] * m[2][3] - m[2][0] * m[1][3]; - - double c16 = m[2][0] * m[3][2] - m[3][0] * m[2][2]; - double c18 = m[1][0] * m[3][2] - m[3][0] * m[1][2]; - double c19 = m[1][0] * m[2][2] - m[2][0] * m[1][2]; - - double c20 = m[2][0] * m[3][1] - m[3][0] * m[2][1]; - double c22 = m[1][0] * m[3][1] - m[3][0] * m[1][1]; - double c23 = m[1][0] * m[2][1] - m[2][0] * m[1][1]; - - res[0][0] = +(m[1][1] * c00 - m[1][2] * c04 + m[1][3] * c08) * invdet; - res[0][1] = -(m[0][1] * c00 - m[0][2] * c04 + m[0][3] * c08) * invdet; - res[0][2] = +(m[0][1] * c02 - m[0][2] * c06 + m[0][3] * c10) * invdet; - res[0][3] = -(m[0][1] * c03 - m[0][2] * c07 + m[0][3] * c11) * invdet; - - res[1][0] = -(m[1][0] * c00 - m[1][2] * c12 + m[1][3] * c16) * invdet; - res[1][1] = +(m[0][0] * c00 - m[0][2] * c12 + m[0][3] * c16) * invdet; - res[1][2] = -(m[0][0] * c02 - m[0][2] * c14 + m[0][3] * c18) * invdet; - res[1][3] = +(m[0][0] * c03 - m[0][2] * c15 + m[0][3] * c19) * invdet; - - res[2][0] = +(m[1][0] * c04 - m[1][1] * c12 + m[1][3] * c20) * invdet; - res[2][1] = -(m[0][0] * c04 - m[0][1] * c12 + m[0][3] * c20) * invdet; - res[2][2] = +(m[0][0] * c06 - m[0][1] * c14 + m[0][3] * c22) * invdet; - res[2][3] = -(m[0][0] * c07 - m[0][1] * c15 + m[0][3] * c23) * invdet; - - res[3][0] = -(m[1][0] * c08 - m[1][1] * c16 + m[1][2] * c20) * invdet; - res[3][1] = +(m[0][0] * c08 - m[0][1] * c16 + m[0][2] * c20) * invdet; - res[3][2] = -(m[0][0] * c10 - m[0][1] * c18 + m[0][2] * c22) * invdet; - res[3][3] = +(m[0][0] * c11 - m[0][1] * c19 + m[0][2] * c23) * invdet; - } - - if (type_info->value_bitcount > 32) - for (int i = 0; i < mtype; i++) - for (int j = 0; j < mtype; j++) - state->results[id].members[i].members[j].value.d = res[i][j]; - else - for (int i = 0; i < mtype; i++) - for (int j = 0; j < mtype; j++) - state->results[id].members[i].members[j].value.f = res[i][j]; -} -void spvm_execute_GLSL450_Modf(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word out = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = modf(state->results[x].members[i].value.d, &state->results[out].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = modff(state->results[x].members[i].value.f, &state->results[out].members[i].value.f); -} -void spvm_execute_GLSL450_ModfStruct(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[0].members[i].value.d = modf(state->results[x].members[i].value.d, &state->results[id].members[1].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[0].members[i].value.f = modff(state->results[x].members[i].value.f, &state->results[id].members[1].members[i].value.f); -} -void spvm_execute_GLSL450_FMin(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.d = SPVM_MIN(state->results[x].members[i].value.d, state->results[y].members[i].value.d); - - if (state->analyzer && (isnan(state->results[x].members[i].value.d) || isnan(state->results[y].members[i].value.d))) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_fmin); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = SPVM_MIN(state->results[x].members[i].value.f, state->results[y].members[i].value.f); - - if (state->analyzer && (isnan(state->results[x].members[i].value.f) || isnan(state->results[y].members[i].value.f))) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_fmin); - } -} -void spvm_execute_GLSL450_UMin(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = SPVM_MIN(state->results[x].members[i].value.u, state->results[y].members[i].value.u); -} -void spvm_execute_GLSL450_SMin(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = SPVM_MIN(state->results[x].members[i].value.s, state->results[y].members[i].value.s); -} -void spvm_execute_GLSL450_FMax(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.d = SPVM_MAX(state->results[x].members[i].value.d, state->results[y].members[i].value.d); - - if (state->analyzer && (isnan(state->results[x].members[i].value.d) || isnan(state->results[y].members[i].value.d))) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_fmax); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = SPVM_MAX(state->results[x].members[i].value.f, state->results[y].members[i].value.f); - - if (state->analyzer && (isnan(state->results[x].members[i].value.f) || isnan(state->results[y].members[i].value.f))) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_fmax); - } -} -void spvm_execute_GLSL450_UMax(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = SPVM_MAX(state->results[x].members[i].value.u, state->results[y].members[i].value.u); -} -void spvm_execute_GLSL450_SMax(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = SPVM_MAX(state->results[x].members[i].value.s, state->results[y].members[i].value.s); -} -void spvm_execute_GLSL450_FClamp(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word minVal = SPVM_READ_WORD(state->code_current); - spvm_word maxVal = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.d = SPVM_CLAMP(state->results[x].members[i].value.d, state->results[minVal].members[i].value.d, state->results[maxVal].members[i].value.d); - - if (state->analyzer && (state->results[minVal].members[i].value.d > state->results[maxVal].members[i].value.d)) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_clamp); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = SPVM_CLAMP(state->results[x].members[i].value.f, state->results[minVal].members[i].value.f, state->results[maxVal].members[i].value.f); - - if (state->analyzer && (state->results[minVal].members[i].value.f > state->results[maxVal].members[i].value.f)) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_clamp); - } -} - -void spvm_execute_GLSL450_UClamp(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word minVal = SPVM_READ_WORD(state->code_current); - spvm_word maxVal = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.u = SPVM_CLAMP(state->results[x].members[i].value.u, state->results[minVal].members[i].value.u, state->results[maxVal].members[i].value.u); - - if (state->analyzer && (state->results[minVal].members[i].value.u > state->results[maxVal].members[i].value.u)) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_clamp); - } -} -void spvm_execute_GLSL450_SClamp(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word minVal = SPVM_READ_WORD(state->code_current); - spvm_word maxVal = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.s = SPVM_CLAMP(state->results[x].members[i].value.s, state->results[minVal].members[i].value.s, state->results[maxVal].members[i].value.s); - - if (state->analyzer && (state->results[minVal].members[i].value.s > state->results[maxVal].members[i].value.s)) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_clamp); - } -} -void spvm_execute_GLSL450_FMix(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - spvm_word a = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - double aVal = state->results[a].members[i].value.d; - state->results[id].members[i].value.d = state->results[x].members[i].value.d * (1 - aVal) + state->results[y].members[i].value.d * aVal; - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - float aVal = state->results[a].members[i].value.f; - state->results[id].members[i].value.f = state->results[x].members[i].value.f * (1 - aVal) + state->results[y].members[i].value.f * aVal; - } -} -void spvm_execute_GLSL450_Step(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word edge = SPVM_READ_WORD(state->code_current); - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[x].members[i].value.d >= state->results[edge].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[x].members[i].value.f >= state->results[edge].members[i].value.f; -} -void spvm_execute_GLSL450_SmoothStep(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word edge0 = SPVM_READ_WORD(state->code_current); - spvm_word edge1 = SPVM_READ_WORD(state->code_current); - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - double xVal = state->results[x].members[i].value.d; - double edge0Val = state->results[edge0].members[i].value.d; - double edge1Val = state->results[edge1].members[i].value.d; - - if (edge0Val == edge1Val) { - state->results[id].members[i].value.d = 0.0; - } else { - xVal = SPVM_CLAMP((xVal - edge0Val) / (edge1Val - edge0Val), 0.0, 1.0); - state->results[id].members[i].value.d = xVal * xVal * (3.0 - 2.0 * xVal); - } - - - if (state->analyzer && edge0Val > edge1Val) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_smoothstep); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - float xVal = state->results[x].members[i].value.f; - float edge0Val = state->results[edge0].members[i].value.f; - float edge1Val = state->results[edge1].members[i].value.f; - - if (edge0Val == edge1Val) { - state->results[id].members[i].value.f = 0.0f; - } else { - xVal = SPVM_CLAMP((xVal - edge0Val) / (edge1Val - edge0Val), 0.0f, 1.0f); - state->results[id].members[i].value.f = xVal * xVal * (3.0f - 2.0f * xVal); - } - - if (state->analyzer && edge0Val > edge1Val) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_smoothstep); - } -} -void spvm_execute_GLSL450_Fma(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word a = SPVM_READ_WORD(state->code_current); - spvm_word b = SPVM_READ_WORD(state->code_current); - spvm_word c = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[a].members[i].value.d * state->results[b].members[i].value.d + state->results[c].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[a].members[i].value.f * state->results[b].members[i].value.f + state->results[c].members[i].value.f; -} -void spvm_execute_GLSL450_Frexp(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word out = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - int s = state->results[out].members[i].value.s; - state->results[id].members[i].value.d = frexp(state->results[x].members[i].value.d, &s); - state->results[out].members[i].value.s = s; - - if (state->analyzer && (isnan(state->results[x].members[i].value.d) || isinf(state->results[x].members[i].value.d))) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_frexp); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - int s = state->results[out].members[i].value.s; - state->results[id].members[i].value.f = frexpf(state->results[x].members[i].value.f, &s); - state->results[out].members[i].value.s = s; - - if (state->analyzer && (isnan(state->results[x].members[i].value.f) || isinf(state->results[x].members[i].value.f))) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_frexp); - } -} -void spvm_execute_GLSL450_FrexpStruct(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - int s = state->results[id].members[1].members[i].value.s; - state->results[id].members[0].members[i].value.d = frexp(state->results[x].members[i].value.d, &s); - state->results[id].members[1].members[i].value.s = s; - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - int s = state->results[id].members[1].members[i].value.s; - state->results[id].members[0].members[i].value.f = frexpf(state->results[x].members[i].value.f, &s); - state->results[id].members[1].members[i].value.s = s; - } -} -void spvm_execute_GLSL450_Ldexp(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word exp = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.d = ldexp(state->results[x].members[i].value.d, state->results[exp].members[i].value.s); - - - if (state->analyzer && state->results[exp].members[i].value.d > 1024) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_ldexp); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = ldexpf(state->results[x].members[i].value.f, state->results[exp].members[i].value.s); - - if (state->analyzer && state->results[exp].members[i].value.f > 128) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_ldexp); - } -} -void spvm_execute_GLSL450_PackSnorm4x8(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = 0; - for (spvm_word i = 0; i < 4; i++) { - char s = roundf(SPVM_CLAMP(state->results[x].members[i].value.f, -1.0f, +1.0f) * 127.0f); - res |= s << (8 * i); - } - state->results[id].members[0].value.u = res; -} -void spvm_execute_GLSL450_PackUnorm4x8(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = 0; - for (spvm_word i = 0; i < 4; i++) { - unsigned char s = roundf(SPVM_CLAMP(state->results[x].members[i].value.f, 0.0f, +1.0f) * 255.0f); - res |= s << (8 * i); - } - state->results[id].members[0].value.u = res; -} -void spvm_execute_GLSL450_PackSnorm2x16(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = 0; - for (spvm_word i = 0; i < 2; i++) { - short s = roundf(SPVM_CLAMP(state->results[x].members[i].value.f, -1.0f, +1.0f) * 32767.0f); - res |= s << (16 * i); - } - state->results[id].members[0].value.u = res; -} -void spvm_execute_GLSL450_PackUnorm2x16(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = 0; - for (spvm_word i = 0; i < 2; i++) { - unsigned short s = roundf(SPVM_CLAMP(state->results[x].members[i].value.f, 0.0f, +1.0f) * 65535.0f); - res |= s << (16 * i); - } - state->results[id].members[0].value.u = res; -} -void spvm_execute_GLSL450_PackDouble2x32(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - union { - unsigned int data[2]; - double res; - } u; - - u.data[0] = state->results[x].members[0].value.u; - u.data[1] = state->results[x].members[1].value.u; - - state->results[id].members[0].value.d = u.res; -} -typedef union { - unsigned int i; - float f; -} floatConverter; -float toFloat32(short value) -{ - /* https://github.com/g-truc/glm/blob/ddebaba03308475b1e33670267eadd596d039949/glm/detail/type_half.inl */ - int s = (value >> 15) & 0x00000001; - int e = (value >> 10) & 0x0000001f; - int m = value & 0x000003ff; - - if (e == 0) { - if (m == 0) { - floatConverter result; - result.i = s << 31; - return result.f; - } - else { - while (!(m & 0x00000400)) { - m <<= 1; - e -= 1; - } - - e += 1; - m &= ~0x00000400; - } - } - else if (e == 31) { - if (m == 0) { - floatConverter result; - result.i = (s << 31) | 0x7f800000; - return result.f; - } - else { - floatConverter result; - result.i = (s << 31) | 0x7f800000 | (m << 13); - return result.f; - } - } - - e = e + (127 - 15); - m = m << 13; - - floatConverter Result; - Result.i = (s << 31) | (e << 23) | m; - return Result.f; -} -short toFloat16(float value) -{ - /* https://github.com/g-truc/glm/blob/ddebaba03308475b1e33670267eadd596d039949/glm/detail/type_half.inl */ - floatConverter Entry; - Entry.f = value; - int i = Entry.i; - - int s = (i >> 16) & 0x00008000; - int e = ((i >> 23) & 0x000000ff) - (127 - 15); - int m = i & 0x007fffff; - - if (e <= 0) { - if (e < -10) - return s; - - m = (m | 0x00800000) >> (1 - e); - - if (m & 0x00001000) - m += 0x00002000; - - return s | (m >> 13); - } - else if (e == 0xff - (127 - 15)) { - if (m == 0) - return s | 0x7c00; - else { - m >>= 13; - return s | 0x7c00 | m | (m == 0); - } - } - - if (m & 0x00001000) { - m += 0x00002000; - if (m & 0x00800000) { - m = 0; - e += 1; - } - } - - if (e > 30) - return s | 0x7c00; - - return s | (e << 10) | (m >> 13); -} -void spvm_execute_GLSL450_PackHalf2x16(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = toFloat16(state->results[x].members[0].value.f); - res |= ((unsigned int)toFloat16(state->results[x].members[1].value.f)) << 16; - - state->results[id].members[0].value.u = res; -} -void spvm_execute_GLSL450_UnpackHalf2x16(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - state->results[id].members[0].value.f = toFloat32(state->results[x].members[0].value.u); - state->results[id].members[1].value.f = toFloat32(state->results[x].members[0].value.u >> 16); -} -void spvm_execute_GLSL450_UnpackDouble2x32(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - union { - unsigned int res[2]; - double data; - } u; - - u.data = state->results[x].members[0].value.d; - - state->results[id].members[0].value.u = u.res[0]; - state->results[id].members[1].value.u = u.res[1]; -} -void spvm_execute_GLSL450_UnpackUnorm2x16(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = state->results[x].members[0].value.u; - for (spvm_word i = 0; i < 2; i++) { - unsigned short s = res >> (16 * i); - state->results[id].members[i].value.f = SPVM_CLAMP(s / 65535.0f, 0.0f, +1.0f); - } -} -void spvm_execute_GLSL450_UnpackSnorm2x16(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = state->results[x].members[0].value.u; - for (spvm_word i = 0; i < 2; i++) { - short s = res >> (16 * i); - state->results[id].members[i].value.f = SPVM_CLAMP(s / 32767.0f, -1.0f, +1.0f); - } -} -void spvm_execute_GLSL450_UnpackUnorm4x8(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = state->results[x].members[0].value.u; - for (spvm_word i = 0; i < 4; i++) { - unsigned char s = res >> (8 * i); - state->results[id].members[i].value.f = SPVM_CLAMP(s / 255.0f, 0.0f, +1.0f); - } -} -void spvm_execute_GLSL450_UnpackSnorm4x8(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - unsigned int res = state->results[x].members[0].value.u; - for (spvm_word i = 0; i < 4; i++) { - char s = res >> (8 * i); - state->results[id].members[i].value.f = SPVM_CLAMP(s / 127.0f, -1.0f, +1.0f); - } -} -void spvm_execute_GLSL450_Length(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - double sum = 0.0; - for (spvm_word i = 0; i < state->results[x].member_count; i++) - sum += state->results[x].members[i].value.d * state->results[x].members[i].value.d; - state->results[id].members[0].value.d = sqrt(sum); - } else { - float sum = 0.0f; - for (spvm_word i = 0; i < state->results[x].member_count; i++) - sum += state->results[x].members[i].value.f * state->results[x].members[i].value.f; - state->results[id].members[0].value.f = sqrtf(sum); - } -} -void spvm_execute_GLSL450_Distance(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word p0 = SPVM_READ_WORD(state->code_current); - spvm_word p1 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - double sum = 0.0; - for (spvm_word i = 0; i < state->results[p0].member_count; i++) - sum += (state->results[p0].members[i].value.d - state->results[p1].members[i].value.d) * (state->results[p0].members[i].value.d - state->results[p1].members[i].value.d); - state->results[id].members[0].value.d = sqrt(sum); - } else { - float sum = 0.0f; - for (spvm_word i = 0; i < state->results[p0].member_count; i++) - sum += (state->results[p0].members[i].value.f - state->results[p1].members[i].value.f) * (state->results[p0].members[i].value.f - state->results[p1].members[i].value.f); - state->results[id].members[0].value.f = sqrtf(sum); - } -} -void spvm_execute_GLSL450_Cross(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - spvm_member_t xMems = state->results[x].members; - spvm_member_t yMems = state->results[y].members; - state->results[id].members[0].value.d = xMems[1].value.d * yMems[2].value.d - yMems[1].value.d * xMems[2].value.d; - state->results[id].members[1].value.d = xMems[2].value.d * yMems[0].value.d - yMems[2].value.d * xMems[0].value.d; - state->results[id].members[2].value.d = xMems[0].value.d * yMems[1].value.d - yMems[0].value.d * xMems[1].value.d; - } - else { - spvm_member_t xMems = state->results[x].members; - spvm_member_t yMems = state->results[y].members; - state->results[id].members[0].value.f = xMems[1].value.f * yMems[2].value.f - yMems[1].value.f * xMems[2].value.f; - state->results[id].members[1].value.f = xMems[2].value.f * yMems[0].value.f - yMems[2].value.f * xMems[0].value.f; - state->results[id].members[2].value.f = xMems[0].value.f * yMems[1].value.f - yMems[0].value.f * xMems[1].value.f; - } -} -void spvm_execute_GLSL450_Normalize(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - double sum = 0.0; - for (spvm_word i = 0; i < state->results[x].member_count; i++) - sum += state->results[x].members[i].value.d * state->results[x].members[i].value.d; - sum = sqrt(sum); - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[x].members[i].value.d / sum; - } - else { - float sum = 0.0; - for (spvm_word i = 0; i < state->results[x].member_count; i++) - sum += state->results[x].members[i].value.f * state->results[x].members[i].value.f; - sum = sqrtf(sum); - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[x].members[i].value.f / sum; - } -} -void spvm_execute_GLSL450_FaceForward(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word N = SPVM_READ_WORD(state->code_current); - spvm_word I = SPVM_READ_WORD(state->code_current); - spvm_word Nref = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - double dot = 0.0; - for (spvm_word i = 0; i < state->results[Nref].member_count; i++) - dot += state->results[Nref].members[i].value.d * state->results[I].members[i].value.d; - dot = (dot < 0.0) ? 1.0 : -1.0; - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = dot * state->results[N].members[i].value.d; - } - else { - float dot = 0.0; - for (spvm_word i = 0; i < state->results[Nref].member_count; i++) - dot += state->results[Nref].members[i].value.f * state->results[I].members[i].value.f; - dot = (dot < 0.0f) ? 1.0f : -1.0f; - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = dot * state->results[N].members[i].value.f; - } -} -void spvm_execute_GLSL450_Reflect(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word I = SPVM_READ_WORD(state->code_current); - spvm_word N = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - double dotNI = 0.0; - for (spvm_word i = 0; i < state->results[N].member_count; i++) - dotNI += state->results[N].members[i].value.d * state->results[I].members[i].value.d; - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[I].members[i].value.d - 2 * dotNI * state->results[N].members[i].value.d; - } - else { - float dotNI = 0.0; - for (spvm_word i = 0; i < state->results[N].member_count; i++) - dotNI += state->results[N].members[i].value.f * state->results[I].members[i].value.f; - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[I].members[i].value.f - 2 * dotNI * state->results[N].members[i].value.f; - } -} -void spvm_execute_GLSL450_Refract(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word I = SPVM_READ_WORD(state->code_current); - spvm_word N = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - double eta = state->results[SPVM_READ_WORD(state->code_current)].members[0].value.d; - - double dotNI = 0.0; - for (spvm_word i = 0; i < state->results[N].member_count; i++) - dotNI += state->results[N].members[i].value.d * state->results[I].members[i].value.d; - - double k = 1.0 - eta * eta * (1.0 - dotNI * dotNI); - - if (k < 0.0) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = 0.0; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = eta * state->results[I].members[i].value.d - (eta * dotNI + sqrt(k)) * state->results[N].members[i].value.d; - } - else { - float eta = state->results[SPVM_READ_WORD(state->code_current)].members[0].value.f; - - float dotNI = 0.0f; - for (spvm_word i = 0; i < state->results[N].member_count; i++) - dotNI += state->results[N].members[i].value.f * state->results[I].members[i].value.f; - - float k = 1.0f - eta * eta * (1.0f - dotNI * dotNI); - - if (k < 0.0) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = 0.0f; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = eta * state->results[I].members[i].value.f - (eta * dotNI + sqrtf(k)) * state->results[N].members[i].value.f; - } -} -void spvm_execute_GLSL450_FindILsb(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ -/* -TODO: - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - _BitScanForward(&state->results[id].members[0].value.u, state->results[x].members[0].value.u); -*/ -} -void spvm_execute_GLSL450_FindSMsb(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ -/* -TODO: - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - _BitScanReverse(&state->results[id].members[0].value.s, state->results[x].members[0].value.s); -*/ -} -void spvm_execute_GLSL450_FindUMsb(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ -/* -TODO: - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - _BitScanReverse(&state->results[id].members[0].value.u, state->results[x].members[0].value.u); -*/ -} -void spvm_execute_GLSL450_NMin(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = SPVM_NMIN(state->results[x].members[i].value.d, state->results[y].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = SPVM_NMIN(state->results[x].members[i].value.f, state->results[y].members[i].value.f); -} -void spvm_execute_GLSL450_NMax(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word y = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = SPVM_NMAX(state->results[x].members[i].value.d, state->results[y].members[i].value.d); - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = SPVM_NMAX(state->results[x].members[i].value.f, state->results[y].members[i].value.f); -} -void spvm_execute_GLSL450_NClamp(spvm_word type, spvm_word id, spvm_word word_count, spvm_state_t state) -{ - spvm_word x = SPVM_READ_WORD(state->code_current); - spvm_word minVal = SPVM_READ_WORD(state->code_current); - spvm_word maxVal = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.d = SPVM_NCLAMP(state->results[x].members[i].value.d, state->results[minVal].members[i].value.d, state->results[maxVal].members[i].value.d); - - if (state->analyzer && state->results[minVal].members[i].value.d > state->results[maxVal].members[i].value.d) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_clamp); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = SPVM_NCLAMP(state->results[x].members[i].value.f, state->results[minVal].members[i].value.f, state->results[maxVal].members[i].value.f); - - if (state->analyzer && state->results[minVal].members[i].value.f > state->results[maxVal].members[i].value.f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_clamp); - } -} - -spvm_ext_opcode_func* spvm_build_glsl450_ext() -{ - spvm_ext_opcode_func* ret = (spvm_ext_opcode_func*)calloc(GLSLstd450Count, sizeof(spvm_ext_opcode_func)); - - ret[GLSLstd450Round] = spvm_execute_GLSL450_Round; - ret[GLSLstd450RoundEven] = spvm_execute_GLSL450_RoundEven; - ret[GLSLstd450Trunc] = spvm_execute_GLSL450_Trunc; - ret[GLSLstd450FAbs] = spvm_execute_GLSL450_FAbs; - ret[GLSLstd450SAbs] = spvm_execute_GLSL450_SAbs; - ret[GLSLstd450FSign] = spvm_execute_GLSL450_FSign; - ret[GLSLstd450SSign] = spvm_execute_GLSL450_SSign; - ret[GLSLstd450Floor] = spvm_execute_GLSL450_Floor; - ret[GLSLstd450Ceil] = spvm_execute_GLSL450_Ceil; - ret[GLSLstd450Fract] = spvm_execute_GLSL450_Fract; - ret[GLSLstd450Radians] = spvm_execute_GLSL450_Radians; - ret[GLSLstd450Degrees] = spvm_execute_GLSL450_Degrees; - ret[GLSLstd450Sin] = spvm_execute_GLSL450_Sin; - ret[GLSLstd450Cos] = spvm_execute_GLSL450_Cos; - ret[GLSLstd450Tan] = spvm_execute_GLSL450_Tan; - ret[GLSLstd450Asin] = spvm_execute_GLSL450_Asin; - ret[GLSLstd450Acos] = spvm_execute_GLSL450_Acos; - ret[GLSLstd450Atan] = spvm_execute_GLSL450_Atan; - ret[GLSLstd450Sinh] = spvm_execute_GLSL450_Sinh; - ret[GLSLstd450Cosh] = spvm_execute_GLSL450_Cosh; - ret[GLSLstd450Tanh] = spvm_execute_GLSL450_Tanh; - ret[GLSLstd450Asinh] = spvm_execute_GLSL450_Asinh; - ret[GLSLstd450Acosh] = spvm_execute_GLSL450_Acosh; - ret[GLSLstd450Atanh] = spvm_execute_GLSL450_Atanh; - ret[GLSLstd450Atan2] = spvm_execute_GLSL450_Atan2; - ret[GLSLstd450Pow] = spvm_execute_GLSL450_Pow; - ret[GLSLstd450Exp] = spvm_execute_GLSL450_Exp; - ret[GLSLstd450Log] = spvm_execute_GLSL450_Log; - ret[GLSLstd450Exp2] = spvm_execute_GLSL450_Exp2; - ret[GLSLstd450Log2] = spvm_execute_GLSL450_Log2; - ret[GLSLstd450Sqrt] = spvm_execute_GLSL450_Sqrt; - ret[GLSLstd450InverseSqrt] = spvm_execute_GLSL450_InverseSqrt; - ret[GLSLstd450Determinant] = spvm_execute_GLSL450_Determinant; - ret[GLSLstd450MatrixInverse] = spvm_execute_GLSL450_MatrixInverse; - ret[GLSLstd450Modf] = spvm_execute_GLSL450_Modf; - ret[GLSLstd450ModfStruct] = spvm_execute_GLSL450_ModfStruct; - ret[GLSLstd450FMin] = spvm_execute_GLSL450_FMin; - ret[GLSLstd450UMin] = spvm_execute_GLSL450_UMin; - ret[GLSLstd450SMin] = spvm_execute_GLSL450_SMin; - ret[GLSLstd450FMax] = spvm_execute_GLSL450_FMax; - ret[GLSLstd450UMax] = spvm_execute_GLSL450_UMax; - ret[GLSLstd450SMax] = spvm_execute_GLSL450_SMax; - ret[GLSLstd450FClamp] = spvm_execute_GLSL450_FClamp; - ret[GLSLstd450UClamp] = spvm_execute_GLSL450_UClamp; - ret[GLSLstd450SClamp] = spvm_execute_GLSL450_SClamp; - ret[GLSLstd450FMix] = spvm_execute_GLSL450_FMix; - ret[GLSLstd450Step] = spvm_execute_GLSL450_Step; - ret[GLSLstd450SmoothStep] = spvm_execute_GLSL450_SmoothStep; - ret[GLSLstd450Fma] = spvm_execute_GLSL450_Fma; - ret[GLSLstd450Frexp] = spvm_execute_GLSL450_Frexp; - ret[GLSLstd450FrexpStruct] = spvm_execute_GLSL450_FrexpStruct; - ret[GLSLstd450Ldexp] = spvm_execute_GLSL450_Ldexp; - ret[GLSLstd450PackSnorm4x8] = spvm_execute_GLSL450_PackSnorm4x8; - ret[GLSLstd450PackUnorm4x8] = spvm_execute_GLSL450_PackUnorm4x8; - ret[GLSLstd450PackSnorm2x16] = spvm_execute_GLSL450_PackSnorm2x16; - ret[GLSLstd450PackUnorm2x16] = spvm_execute_GLSL450_PackUnorm2x16; - ret[GLSLstd450PackDouble2x32] = spvm_execute_GLSL450_PackDouble2x32; - ret[GLSLstd450PackHalf2x16] = spvm_execute_GLSL450_PackHalf2x16; - ret[GLSLstd450UnpackHalf2x16] = spvm_execute_GLSL450_UnpackHalf2x16; - ret[GLSLstd450UnpackDouble2x32] = spvm_execute_GLSL450_UnpackDouble2x32; - ret[GLSLstd450UnpackSnorm2x16] = spvm_execute_GLSL450_UnpackSnorm2x16; - ret[GLSLstd450UnpackUnorm2x16] = spvm_execute_GLSL450_UnpackUnorm2x16; - ret[GLSLstd450UnpackSnorm4x8] = spvm_execute_GLSL450_UnpackSnorm4x8; - ret[GLSLstd450UnpackUnorm4x8] = spvm_execute_GLSL450_UnpackUnorm4x8; - ret[GLSLstd450Length] = spvm_execute_GLSL450_Length; - ret[GLSLstd450Distance] = spvm_execute_GLSL450_Distance; - ret[GLSLstd450Cross] = spvm_execute_GLSL450_Cross; - ret[GLSLstd450Normalize] = spvm_execute_GLSL450_Normalize; - ret[GLSLstd450FaceForward] = spvm_execute_GLSL450_FaceForward; - ret[GLSLstd450Reflect] = spvm_execute_GLSL450_Reflect; - ret[GLSLstd450Refract] = spvm_execute_GLSL450_Refract; - ret[GLSLstd450FindILsb] = spvm_execute_GLSL450_FindILsb; - ret[GLSLstd450FindSMsb] = spvm_execute_GLSL450_FindSMsb; - ret[GLSLstd450FindUMsb] = spvm_execute_GLSL450_FindUMsb; - ret[GLSLstd450InterpolateAtCentroid] = 0; - ret[GLSLstd450InterpolateAtSample] = 0; - ret[GLSLstd450InterpolateAtOffset] = 0; - ret[GLSLstd450NMin] = spvm_execute_GLSL450_NMin; - ret[GLSLstd450NMax] = spvm_execute_GLSL450_NMax; - ret[GLSLstd450NClamp] = spvm_execute_GLSL450_NClamp; - - return ret; -} diff --git a/src/spvm/ext/GLSL450.h b/src/spvm/ext/GLSL450.h deleted file mode 100644 index 38f73ff9..00000000 --- a/src/spvm/ext/GLSL450.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __SPRIV_VM_EXT_GLSL_450_H__ -#define __SPRIV_VM_EXT_GLSL_450_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -spvm_ext_opcode_func* spvm_build_glsl450_ext(); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SPRIV_VM_EXT_GLSL_450_H__ diff --git a/src/spvm/image.c b/src/spvm/image.c deleted file mode 100644 index 375cc64c..00000000 --- a/src/spvm/image.c +++ /dev/null @@ -1,302 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -spvm_vec4f spvm_image_read(struct spvm_state* state, spvm_image* image, - int x, int y, int z, int layer, int level) -{ - assert(state->read_image); - return state->read_image(state, image, x, y, z, layer, level); -} - -void spvm_image_write(struct spvm_state* state, spvm_image* image, - int x, int y, int z, int layer, int level, const spvm_vec4f* data) -{ - assert(state->write_image); - state->write_image(state, image, x, y, z, layer, level, data); -} - -unsigned spvm_image_texel_id(struct spvm_image* image, - int x, int y, int z, int layer, int level) -{ - unsigned width = image->width; - unsigned height = image->height; - unsigned depth = image->depth; - unsigned off = 0u; - - for(int l = 0; l < level; ++l) - { - width = SPVM_MAX(width >> 1u, 1u); - height = SPVM_MAX(height >> 1u, 1u); - depth = SPVM_MAX(depth >> 1u, 1u); - off += width * height * depth * image->layers; - } - - unsigned sliceSize = width * height; - unsigned layerSize = depth * sliceSize; - - off += layer * layerSize; - off += z * sliceSize; - off += y * width; - off += x; - - return off; -} - -spvm_vec4f spvm_image_read_impl(struct spvm_state* state, struct spvm_image* image, - int x, int y, int z, int layer, int level) -{ - if (!image->user_data) - { - spvm_vec4f res = {0}; - return res; - } - - unsigned off = spvm_image_texel_id(image, x, y, z, layer, level); - const float* src = (float*) image->user_data; - - spvm_vec4f res = {0}; - memcpy(res.data, src + off, sizeof(res.data)); - return res; -} - -void spvm_image_write_impl(struct spvm_state* state, struct spvm_image* image, - int x, int y, int z, int layer, int level, const spvm_vec4f* data) -{ - if (!image->user_data) - return; - - unsigned off = spvm_image_texel_id(image, x, y, z, layer, level); - float* dst = (float*) image->user_data; - memcpy(&dst + off, data->data, sizeof(data->data)); -} - -// For the sampling implementation, see -// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap16.html#textures-texel-filtering -// There are a lot of corner cases we are not handling currently. - -int spvm_util_mirror(int n) -{ - return (n >= 0) ? n : -(1 + n); -} - -// Returns -1 for border. -int spvm_apply_address_mode(spvm_sampler_address_mode mode, int val, int size) -{ - switch(mode) - { - case spvm_sampler_address_mode_repeat: - return ((val % size) + size) % size; - case spvm_sampler_address_mode_clamp_to_edge: - return SPVM_CLAMP(val, 0.f, size - 1); - case spvm_sampler_address_mode_clamp_to_border: - return (val < 0 || val >= size) ? -1 : val; - case spvm_sampler_address_mode_mirrored_repeat: { - int t = ((val % (2 * size)) + 2 * size) % (2 * size) - size; - return (size - 1) * spvm_util_mirror(t); - } - } - - assert(0); - return -1; -} - -float spvm_frac(float val) -{ - double iptr; - return modf(val, &iptr); -} - -spvm_vec4f spvm_fetch_texel(struct spvm_state* state, - spvm_image* img, const spvm_sampler_desc* desc, int x, int y, int z, int layer, int level) -{ - layer = SPVM_CLAMP(layer, 0, img->layers - 1); - level = SPVM_CLAMP(level, 0, img->levels - 1); - - unsigned width = SPVM_MAX(img->width >> level, 1u); - unsigned height = SPVM_MAX(img->height >> level, 1u); - unsigned depth = SPVM_MAX(img->depth >> level, 1u); - - x = spvm_apply_address_mode(desc->address_mode_u, x, width); - y = spvm_apply_address_mode(desc->address_mode_v, y, height); - z = spvm_apply_address_mode(desc->address_mode_w, z, depth); - - // check for border condition - if (x < 0 || y < 0 || z < 0) { - return desc->border_color; - } - - return state->read_image(state, img, x, y, z, layer, level); -} - -spvm_vec4f spvm_sampled_image_sample(struct spvm_state* state, - spvm_image* img, spvm_sampler* sampler, - float s, float t, float r, float layer, float level) -{ - spvm_sampler_desc* desc = &sampler->desc; - - level = SPVM_CLAMP(level + desc->mip_bias, desc->min_lod, desc->max_lod); - spvm_sampler_filter filter = (level <= 0.f) ? desc->filter_mag : desc->filter_min; - - int levels[2]; - float level_weights[2]; - unsigned num_level_samples; - - if(desc->mipmap_mode == spvm_sampler_filter_nearest) - { - num_level_samples = 1u; - levels[0] = roundf(level); - levels[1] = levels[0]; - level_weights[0] = 1.f; - level_weights[1] = 0.f; - } - else - { - num_level_samples = 2u; - levels[0] = floor(level); - levels[1] = levels[0] + 1; - level_weights[0] = 1 - (level - levels[0]); - level_weights[1] = level - levels[0]; - } - - spvm_vec4f res = {0.f}; - - for(unsigned l = 0u; l < num_level_samples; ++l) - { - unsigned level = SPVM_CLAMP(levels[l], 0, img->levels - 1); - unsigned width = SPVM_MAX(img->width >> level, 1u); - unsigned height = SPVM_MAX(img->height >> level, 1u); - unsigned depth = SPVM_MAX(img->depth >> level, 1u); - - float u = width * s; - float v = height * t; - float w = depth * r; - - const float shift = 0.5f; - - if (filter == spvm_sampler_filter_nearest) - { - int i = roundf(u - shift); - int j = roundf(v - shift); - int k = roundf(w - shift); - spvm_vec4f sample = spvm_fetch_texel(state, img, desc, - i, j, k, roundf(layer), level); - - for(unsigned j = 0u; j < 4; ++j) - res.data[j] += level_weights[l] * sample.data[j]; - } - else - { - int i0 = floor(u - shift); - int j0 = floor(v - shift); - int k0 = floor(w - shift); - - int i1 = i0 + 1; - int j1 = j0 + 1; - int k1 = k0 + 1; - - float alpha = spvm_frac(u - shift); - float beta = spvm_frac(v - shift); - float gamma = spvm_frac(w - shift); - - for(unsigned s = 0u; s < 8; ++s) - { - int i = (s & 1) ? i0 : i1; - int j = (s & 2) ? j0 : j1; - int k = (s & 4) ? k0 : k1; - - float lin_weight = - ((s & 1) ? (1 - alpha) : alpha) * - ((s & 2) ? (1 - beta) : beta) * - ((s & 4) ? (1 - gamma) : gamma); - - spvm_vec4f sample = spvm_fetch_texel(state, img, desc, - i, j, k, roundf(layer), level); - - for(unsigned j = 0u; j < 4; ++j) - res.data[j] += lin_weight * level_weights[l] * sample.data[j]; - } - - } - } - - return res; -} - -struct spvm_sampled_image_lod_query spvm_sampled_image_query_lod( - struct spvm_state* state, spvm_image* image, const struct spvm_image_info* imginfo, - spvm_sampler* sampler, unsigned coord_id, float shader_lod_bias, float shader_lod_min) -{ - - // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap16.html#textures-lod-and-scale-factor - // TODO: handle proj - // TODO: handle unnormalized sampling coords - // TODO: handle cubemaps - - spvm_state_ddx(state, coord_id); - spvm_state_ddy(state, coord_id); - - return spvm_sampled_image_query_lod_from_grad(state, image, imginfo, - sampler, state->derivative_buffer_x, state->derivative_buffer_y, - shader_lod_bias, shader_lod_min); -} - -struct spvm_sampled_image_lod_query spvm_sampled_image_query_lod_from_grad( - struct spvm_state* state, spvm_image* image, const struct spvm_image_info* imginfo, - spvm_sampler* sampler, float* ddx, float* ddy, - float shader_lod_bias, float shader_lod_min) -{ - - float mx[3] = {0.f}; - float my[3] = {0.f}; - - mx[0] = ddx[0] * image->width; - my[0] = ddy[0] * image->width; - - if(imginfo->dim >= SpvDim2D) { - mx[1] = ddx[1] * image->height; - my[1] = ddy[1] * image->height; - } - - if(imginfo->dim >= SpvDim3D) { - mx[2] = ddx[2] * image->depth; - my[2] = ddy[2] * image->depth; - } - - float ro_x = sqrt(mx[0] * mx[0] + mx[1] * mx[1] + mx[2] * mx[2]); - float ro_y = sqrt(my[0] * my[0] + my[1] * my[1] + my[2] * my[2]); - - float ro_max = SPVM_MAX(ro_x, ro_y); - float ro_min = SPVM_MIN(ro_x, ro_y); - - // TODO: handle anisotropy - const float eta = 1.f; - - float lambda_base = log2(ro_max / eta); - - // NOTE: we don't clamp to any maxSamplerLodBias here - float lambda_prime = lambda_base + shader_lod_bias + sampler->desc.mip_bias; - - float lod_min = SPVM_MAX(shader_lod_min, sampler->desc.min_lod); - float lod_max = sampler->desc.max_lod; - - float lambda = SPVM_CLAMP(lambda_prime, lod_min, lod_max); - float dl = lambda; - - if (sampler->desc.mipmap_mode == spvm_sampler_filter_nearest) { - dl = round(dl); - } - - struct spvm_sampled_image_lod_query ret; - ret.dl = dl; - ret.lambda_prime = lambda_prime; - - return ret; -} - diff --git a/src/spvm/image.h b/src/spvm/image.h deleted file mode 100644 index d973b131..00000000 --- a/src/spvm/image.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef __SPIRV_VM_IMAGE_H__ -#define __SPIRV_VM_IMAGE_H__ - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -struct spvm_state; -struct spvm_image; -struct spvm_result; -struct spvm_image_info; - -typedef struct spvm_vec4f { - float data[4]; -} spvm_vec4f; - -typedef struct spvm_image { - // Size values of the first (base) mip level accessible to the shader. - // If the full image has size 1024x1024 but the imageView bound - // to the descriptor has firstLevel = 2, expects 256x256 here. - unsigned width; - unsigned height; - unsigned depth; - unsigned layers; - unsigned levels; - // TODO: support for multisampling - - void* user_data; -} spvm_image; - -// Default implementation for image sampling -// See VkSamplerCreateInfo -typedef enum spvm_sampler_filter { - spvm_sampler_filter_nearest, - spvm_sampler_filter_linear, -} spvm_sampler_filter; - -typedef enum spvm_sampler_address_mode { - spvm_sampler_address_mode_repeat, - spvm_sampler_address_mode_mirrored_repeat, - spvm_sampler_address_mode_clamp_to_edge, - spvm_sampler_address_mode_clamp_to_border, -} spvm_sampler_address_mode; - -typedef enum spvm_sampler_compare_op { - spvm_sampler_compare_op_never, - spvm_sampler_compare_op_less, - spvm_sampler_compare_op_equal, - spvm_sampler_compare_op_less_or_equal, - spvm_sampler_compare_op_greater, - spvm_sampler_compare_op_not_equal, - spvm_sampler_compare_op_greater_or_equal, - spvm_sampler_compare_op_always, -} spvm_sampler_compare_op; - -typedef struct spvm_sampler_desc { - spvm_sampler_filter filter_min; - spvm_sampler_filter filter_mag; - spvm_sampler_filter mipmap_mode; - spvm_sampler_address_mode address_mode_u; - spvm_sampler_address_mode address_mode_v; - spvm_sampler_address_mode address_mode_w; - spvm_vec4f border_color; - float mip_bias; - spvm_sampler_compare_op compare_op; - float min_lod; - float max_lod; - // TODO: no support for anisotropy yet - // TODO: no support for unnormalized coordinates yet -} spvm_sampler_desc; - -typedef struct spvm_sampler { - spvm_sampler_desc desc; -} spvm_sampler; - -spvm_vec4f spvm_image_read(struct spvm_state*, spvm_image*, - int x, int y, int z, int layer, int level); -void spvm_image_write(struct spvm_state*, spvm_image*, - int x, int y, int z, int layer, int level, const spvm_vec4f* data); -spvm_vec4f spvm_sampled_image_sample(struct spvm_state*, spvm_image*, spvm_sampler*, - float x, float y, float z, float layer, float level); - -// Applies the addressing mode from the sampler but always just -// reads a single texel. -spvm_vec4f spvm_fetch_texel(struct spvm_state* state, - spvm_image* img, const spvm_sampler_desc* desc, int x, int y, int z, int layer, int level); - -// spvm_image implementation -// Functions will interpret user_data as float* with tight layout -// and directly read/write it. -spvm_vec4f spvm_image_read_impl(struct spvm_state*, struct spvm_image*, - int x, int y, int z, int layer, int level); -void spvm_image_write_impl(struct spvm_state*, struct spvm_image*, - int x, int y, int z, int layer, int level, const spvm_vec4f* data); - -struct spvm_sampled_image_lod_query { - float lambda_prime; // the level without any clamping/rounding - float dl; // the selected level -}; - -// Expects the coords to be loaded into the derivative buffers of the given state. -struct spvm_sampled_image_lod_query spvm_sampled_image_query_lod( - struct spvm_state*, spvm_image*, const struct spvm_image_info*, spvm_sampler*, - unsigned coord_id, float shader_lod_bias, float shader_lod_min); - -// For cubemaps, ddx and ddy must already correspond to the selected face. -struct spvm_sampled_image_lod_query spvm_sampled_image_query_lod_from_grad( - struct spvm_state*, spvm_image*, const struct spvm_image_info*, spvm_sampler*, - float* ddx/*[3]*/, float* ddy/*[3]*/, float shader_lod_bias, float shader_lod_min); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SPIRV_VM_IMAGE_H__ diff --git a/src/spvm/opcode.h b/src/spvm/opcode.h deleted file mode 100644 index f1c8ce36..00000000 --- a/src/spvm/opcode.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __SPIRV_VM_OPCODE_H__ -#define __SPIRV_VM_OPCODE_H__ - -#include - -struct spvm_state; - -typedef void(*spvm_opcode_func)(spvm_word word_count, struct spvm_state* state); -typedef void(*spvm_ext_opcode_func)(spvm_word type, spvm_word id, spvm_word word_count, struct spvm_state* state); - -#endif // __SPIRV_VM_OPCODE_H__ \ No newline at end of file diff --git a/src/spvm/opcode_execute.c b/src/spvm/opcode_execute.c deleted file mode 100644 index f06ec2ec..00000000 --- a/src/spvm/opcode_execute.c +++ /dev/null @@ -1,2486 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char spvm_use_access_callback(enum spvm_result_type result_type, - SpvStorageClass storage_class) { - if (result_type != spvm_result_type_variable && - result_type != spvm_result_type_access_chain && - result_type != spvm_result_type_function_parameter) { - return 0; - } - - switch(storage_class) { - case SpvStorageClassPushConstant: - case SpvStorageClassUniform: - case SpvStorageClassStorageBuffer: - case SpvStorageClassUniformConstant: - // TODO: really always use access callback for these? - // could be set statically. Maybe leave up to the user? - case SpvStorageClassInput: - case SpvStorageClassOutput: - // TODO: workgroup? - // TODO: input, output? - // TODO: raytracing stuff? - return 1; - default: - break; - } - - return 0; -} - -/* opcodes */ -/* 3.32.2 Debug Instructions */ -void spvm_execute_OpLine(spvm_word word_count, spvm_state_t state) -{ - spvm_word file = SPVM_READ_WORD(state->code_current); - spvm_word line = SPVM_READ_WORD(state->code_current); - spvm_word clmn = SPVM_READ_WORD(state->code_current); - - state->current_file = state->results[file].name; - state->current_line = line; - state->current_column = clmn; -} -void spvm_execute_OpNoLine(spvm_word word_count, spvm_state_t state) -{ - state->current_file = NULL; - state->current_line = -1; - state->current_column = -1; -} - -/* 3.32.4 Debug Instructions */ -void spvm_execute_OpExtInst(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word set = SPVM_READ_WORD(state->code_current); - spvm_word inst = SPVM_READ_WORD(state->code_current); - - if (!state->results[set].extension) { - spvm_state_log(state, "OpExtInst for unregistered extension %d", set); - return; - } - - if (!state->results[set].extension[inst]) { - spvm_state_log(state, "Unhandled OpExtInst set = %d, inst = %d", set, inst); - return; - } - - state->results[set].extension[inst](type, id, word_count - 4, state); -} - -/* 3.32.8 Memory Instructions */ -void spvm_execute_OpStore(spvm_word word_count, spvm_state_t state) -{ - spvm_word ptr_id = SPVM_READ_WORD(state->code_current); - spvm_word val_id = SPVM_READ_WORD(state->code_current); - - spvm_result_t src = &state->results[val_id]; - spvm_result_t dst = &state->results[ptr_id]; - - char use_cb = spvm_use_access_callback(dst->type, dst->storage_class); - if(dst->type == spvm_result_type_variable && state->store_variable && use_cb) { - spvm_member_list src_mems; - src_mems.members = src->members; - src_mems.member_count = src->member_count; - - state->store_variable(state, ptr_id, 0, NULL, src_mems, src->pointer); - } else if(dst->type == spvm_result_type_access_chain && state->store_variable && use_cb) { - spvm_member_list src_mems; - src_mems.members = src->members; - src_mems.member_count = src->member_count; - - state->store_variable(state, ptr_id, dst->index_count, - dst->indices, src_mems, src->pointer); - } else { - assert(dst->index_count == 0u); - spvm_member_memcpy(dst->members, src->members, src->member_count); - - if (dst->type == spvm_result_type_variable) { - state->results[ptr_id].stored_to = 1; - } else if (dst->type == spvm_result_type_access_chain) { - state->results[dst->access_chain_ref].stored_to = 1; - } - - if (state->results[ptr_id].storage_class == SpvStorageClassWorkgroup && state->owner->write_workgroup_memory) - state->owner->write_workgroup_memory(state, ptr_id, val_id); - } -} -void spvm_execute_OpLoad(spvm_word word_count, spvm_state_t state) -{ - spvm_word type_id = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word ptr_id = SPVM_READ_WORD(state->code_current); - - spvm_result_t src = &state->results[ptr_id]; - - if(state->load_variable && spvm_use_access_callback(src->type, src->storage_class)) { - spvm_word src_id = ptr_id; - int allow_opt = 1; - - while(src->type == spvm_result_type_function_parameter) { - src_id = src->access_chain_ref; - src = &state->results[src_id]; - allow_opt = 0; // TODO: we can optimize here in most cases as well - } - - // TODO: handle access chain on function parameter - if(src->type == spvm_result_type_access_chain) { - src_id = src->access_chain_ref; - } - - if (allow_opt && state->results[id].was_loaded) { - return; - } - - spvm_member_list dst_mems; - dst_mems.members = state->results[id].members; - dst_mems.member_count = state->results[id].member_count; - - state->load_variable(state, src_id, src->index_count, src->indices, dst_mems, type_id); - state->results[id].was_loaded = 1; - } else { - assert(src->index_count == 0u); - spvm_member_memcpy(state->results[id].members, src->members, src->member_count); - } -} -void spvm_execute_OpArrayLength(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); // result type - - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word var_id = SPVM_READ_WORD(state->code_current); - spvm_word member_id = SPVM_READ_WORD(state->code_current); - - assert(state->array_length); - - spvm_result_t var = &state->results[var_id]; - - if (var->type == spvm_result_type_access_chain) { - // TODO: msvc does not support vla - // spvm_word indices[1 + var->index_count]; - assert(var->index_count < 512); - spvm_word indices[512]; - - memcpy(indices, var->indices, sizeof(spvm_word) * var->index_count); - indices[var->index_count] = member_id; - - spvm_result_t svar = &state->results[var->access_chain_ref]; - assert(svar->type == spvm_result_type_variable); - assert(svar->storage_class == SpvStorageClassStorageBuffer); - - state->results[id].members[0].value.u = state->array_length(state, - var->access_chain_ref, 1 + var->index_count, indices); - } else { - assert(var->type == spvm_result_type_variable); - assert(var->storage_class == SpvStorageClassStorageBuffer || - var->storage_class == SpvStorageClassUniform); - state->results[id].members[0].value.u = state->array_length(state, - var_id, 1, &member_id); - } -} -void spvm_execute_OpCopyMemory(spvm_word word_count, spvm_state_t state) -{ - // TODO: need to add support for new load/store variable api - assert(!"Not implemented"); - - spvm_word target = SPVM_READ_WORD(state->code_current); - spvm_word source = SPVM_READ_WORD(state->code_current); - - spvm_member_memcpy(state->results[target].members, state->results[source].members, state->results[target].member_count); -} -void spvm_execute_OpCopyMemorySized(spvm_word word_count, spvm_state_t state) -{ - // TODO: need to add support for new load/store variable api - assert(!"Not implemented"); - - spvm_word target = SPVM_READ_WORD(state->code_current); - spvm_word source = SPVM_READ_WORD(state->code_current); - spvm_word size_id = SPVM_READ_WORD(state->code_current); - - spvm_word size = state->results[size_id].members[0].value.s; - - // TODO: spvm_member_copy_sized() - memcpy(state->results[target].members, state->results[source].members, size); -} -void spvm_execute_OpAccessChain(spvm_word word_count, spvm_state_t state) -{ - spvm_source source_pointer = state->code_current; - - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word value_id = SPVM_READ_WORD(state->code_current); - - spvm_result* src = &state->results[value_id]; - - if(state->load_variable && state->store_variable && - spvm_use_access_callback(src->type, src->storage_class)) { - spvm_result* dst = &state->results[id]; - - if(src->type == spvm_result_type_variable) { - for(spvm_word i = 0; i < dst->index_count; ++i) { - spvm_word index_id = SPVM_READ_WORD(state->code_current); - spvm_word index = state->results[index_id].members[0].value.s; - dst->indices[i] = index; - } - } else if(src->type == spvm_result_type_access_chain) { - spvm_word local_index_count = word_count - 3; - memcpy(dst->indices, src->indices, src->index_count * sizeof(src->indices[0])); - - for(spvm_word i = 0; i < local_index_count; ++i) { - spvm_word index_id = SPVM_READ_WORD(state->code_current); - spvm_word index = state->results[index_id].members[0].value.s; - dst->indices[src->index_count + i] = index; - } - } - } else { - spvm_word index_count = word_count - 4; - spvm_word index_id = SPVM_READ_WORD(state->code_current); - spvm_word index = state->results[index_id].members[0].value.s; - - spvm_member_t result = src->members + SPVM_MIN(index, src->member_count - 1); - - while (index_count) { - index_id = SPVM_READ_WORD(state->code_current); - index = state->results[index_id].members[0].value.s; - - result = result->members + SPVM_MIN(index, result->member_count - 1); - - index_count--; - } - - if (result->member_count != 0) { - state->results[id].member_count = result->member_count; - state->results[id].members = result->members; - } else { - state->results[id].member_count = 1; - state->results[id].members = result; - } - } -} -void spvm_execute_OpPtrEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - // TODO: should this actually check if they point to the same value or if the values are same? - state->results[id].members[0].value.b = (state->results[op1].members == state->results[op2].members); -} -void spvm_execute_OpPtrNotEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - // TODO: should this actually check if they point to the same value or if the values are same? - state->results[id].members[0].value.b = (state->results[op1].members != state->results[op2].members); -} -void spvm_execute_OpFunctionCall(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word func = SPVM_READ_WORD(state->code_current); - - spvm_word argc = word_count - 3; - - spvm_result_t next_func = &state->results[func]; - - for (spvm_word i = 0; i < argc; i++) { - spvm_word arg_id = SPVM_READ_WORD(state->code_current); - state->results[next_func->params[i]].members = state->results[arg_id].members; - state->results[next_func->params[i]].access_chain_ref = arg_id; - } - - spvm_state_push_function_stack(state, next_func, id); -} -void spvm_execute_OpReturn(spvm_word word_count, spvm_state_t state) -{ - state->return_id = -1; - spvm_state_pop_function_stack(state); -} -void spvm_execute_OpReturnValue(spvm_word word_count, spvm_state_t state) -{ - state->return_id = SPVM_READ_WORD(state->code_current); - spvm_state_pop_function_stack(state); -} - -/* 3.32.10 Image Instruction */ -typedef struct { - spvm_word bits; - - float bias; - float lod; - float dx[3]; - float dy[3]; - char uses_offsets; - int offsets[4][3]; - int sample; - float min_lod; -} spvm_image_operands; -void spvm_image_operands_parse(spvm_image_operands* info, spvm_state_t state) -{ - spvm_word bits = info->bits = SPVM_READ_WORD(state->code_current); - if (bits & SpvImageOperandsBiasMask) - info->bias = state->results[SPVM_READ_WORD(state->code_current)].members[0].value.f; - if (bits & SpvImageOperandsLodMask) - info->lod = state->results[SPVM_READ_WORD(state->code_current)].members[0].value.f; - if (bits & SpvImageOperandsGradMask) { - spvm_result_t dx = &state->results[SPVM_READ_WORD(state->code_current)]; - spvm_result_t dy = &state->results[SPVM_READ_WORD(state->code_current)]; - for (spvm_word i = 0; i < dx->member_count; i++) - info->dx[i] = dx->members[i].value.f; - for (spvm_word i = 0; i < dy->member_count; i++) - info->dy[i] = dy->members[i].value.f; - } - if (bits & SpvImageOperandsConstOffsetMask) { - spvm_result_t offs = &state->results[SPVM_READ_WORD(state->code_current)]; - for (spvm_word i = 0; i < offs->member_count; i++) - info->offsets[0][i] = offs->members[i].value.s; - } - if (bits & SpvImageOperandsOffsetMask) { - spvm_result_t offs = &state->results[SPVM_READ_WORD(state->code_current)]; - for (spvm_word i = 0; i < offs->member_count; i++) - info->offsets[0][i] = offs->members[i].value.s; - } - if (bits & SpvImageOperandsConstOffsetsMask) { - spvm_result_t offs = &state->results[SPVM_READ_WORD(state->code_current)]; - for (spvm_word i = 0; i < offs->member_count; i++) - for (spvm_word j = 0; j < offs->member_count; j++) - info->offsets[i][j] = offs->members[i].members[j].value.s; - info->uses_offsets = 1; - } - if (bits & SpvImageOperandsSampleMask) - info->sample = state->results[SPVM_READ_WORD(state->code_current)].members[0].value.s; - if (bits & SpvImageOperandsMinLodMask) - info->min_lod = state->results[SPVM_READ_WORD(state->code_current)].members[0].value.f; -} - -// Returns the layer to be sampled -float process_cubemap_normal(float* nrml) -{ - /* https://github.com/zauonlok/renderer/blob/a6b50f06e85659edbc8ee18c674e6f781aacfd84/renderer/core/texture.c#L210 */ - /* https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/chap16.html#_cube_map_face_selection */ - float absX = (float)fabs(nrml[0]); - float absY = (float)fabs(nrml[1]); - float absZ = (float)fabs(nrml[2]); - float ma, layer; - - if (absX > absY && absX > absZ) { - ma = absX; - if (nrml[0] > 0) { - nrml[0] = -nrml[2]; - nrml[1] = -nrml[1]; - layer = 0.0f; - } else { - nrml[0] = +nrml[2]; - nrml[1] = -nrml[1]; - layer = 1.0f; - } - } else if (absY > absZ) { - ma = absY; - if (nrml[1] > 0) { - nrml[0] = +nrml[0]; - nrml[1] = +nrml[2]; - layer = 2.0f; - } else { - nrml[0] = +nrml[0]; - nrml[1] = -nrml[2]; - layer = 3.0f; - } - } else { - ma = absZ; - if (nrml[2] > 0) { - nrml[0] = +nrml[0]; - nrml[1] = -nrml[1]; - layer = 4.0f; - } else { - nrml[0] = -nrml[0]; - nrml[1] = -nrml[1]; - layer = 5.0f; - } - } - - nrml[0] = (nrml[0] / ma + 1) / 2; - nrml[1] = (nrml[1] / ma + 1) / 2; - return layer; -} - -float spvm_execute_compare(float val, float ref, spvm_sampler_compare_op op) { - switch(op) { - case spvm_sampler_compare_op_never: return 0.f; - case spvm_sampler_compare_op_always: return 1.f; - case spvm_sampler_compare_op_equal: - return (ref == val) ? 1.f : 0.f; - case spvm_sampler_compare_op_not_equal: - return (ref != val) ? 1.f : 0.f; - case spvm_sampler_compare_op_greater: - return (ref > val) ? 1.f : 0.f; - case spvm_sampler_compare_op_less: - return (ref < val) ? 1.f : 0.f; - case spvm_sampler_compare_op_greater_or_equal: - return (ref >= val) ? 1.f : 0.f; - case spvm_sampler_compare_op_less_or_equal: - return (ref <= val) ? 1.f : 0.f; - default: - assert(!"Invalid sampler compare op"); - return 0.f; - } -} - -static spvm_vec4f spvm_op_image_sample(spvm_state_t state, - spvm_word sampled_image_id, spvm_word coord_id, - spvm_image_operands* operands, const float* dref, bool proj) -{ - spvm_result_t coord = &state->results[coord_id]; - - spvm_result_t container = &state->results[sampled_image_id]; - assert(container->member_count == 2u); - spvm_image* image = container->members[0].value.image; - assert(image); - spvm_sampler* sampler = container->members[1].value.sampler; - assert(sampler); - - spvm_result_t sampled_image_type = spvm_state_get_type_info(state->results, &state->results[container->pointer]); - assert(sampled_image_type); - assert(sampled_image_type->value_type == spvm_value_type_sampled_image); - - spvm_result_t image_type = spvm_state_get_type_info(state->results, &state->results[sampled_image_type->pointer]); - assert(image_type); - assert(image_type->value_type == spvm_value_type_image); - assert(image_type->image_info); - - float stu[4] = { 0.0f }; - for (spvm_word i = 0; i < coord->member_count; i++) { - stu[i] = coord->members[i].value.f; - } - - spvm_vec4f res = {0}; - - unsigned dim; - if (image_type->image_info->dim == SpvDim1D) { - dim = 1u; - } else if (image_type->image_info->dim == SpvDim2D || - image_type->image_info->dim == SpvDimSubpassData) { - dim = 2u; - } else if (image_type->image_info->dim == SpvDim3D) { - dim = 3u; - } else if (image_type->image_info->dim == SpvDimCube) { - dim = 3u; - } else { - assert(!"Unhandled SpvDim"); - dim = 3u; - } - - assert(!image_type->image_info->arrayed || !proj); // per spec - - float layer = 0.f; - if (image_type->image_info->arrayed) { - layer = stu[dim]; - - if (image_type->image_info->dim == SpvDimCube) { - layer *= 6; - } - } - - if (proj) { - for (unsigned i = 0u; i < dim; ++i) { - stu[i] /= stu[dim]; - } - } - - if (!operands->uses_offsets) { - stu[0] += operands->offsets[0][0] / (float)image->width; - stu[1] += operands->offsets[0][1] / (float)image->height; - stu[2] += operands->offsets[0][2] / (float)image->depth; - } - - if (image_type->image_info->dim == SpvDimCube) { - layer += process_cubemap_normal(&stu[0]); - } - - float level = 0.f; - if (operands->bits & SpvImageOperandsLodMask) { - level = operands->lod; - } else if (operands->bits & SpvImageOperandsGradMask) { - // TODO: would need to transform grad for cubemap - level = spvm_sampled_image_query_lod_from_grad(state, image, image_type->image_info, - sampler, operands->dx, operands->dy, operands->bias, operands->min_lod).dl; - } else { - level = spvm_sampled_image_query_lod(state, image, image_type->image_info, - sampler, coord_id, operands->bias, operands->min_lod).dl; - } - - spvm_vec4f ret = spvm_sampled_image_sample(state, image, sampler, - stu[0], stu[1], stu[2], layer, level); - - if (dref) { - ret.data[0] = spvm_execute_compare(ret.data[0], *dref, sampler->desc.compare_op); - } - - return ret; -} - -static spvm_vec4f spvm_op_image_gather(spvm_state_t state, - spvm_word sampled_image_id, spvm_word coord_id, int comp, - spvm_image_operands* operands, const float* dref) -{ - spvm_result_t coord = &state->results[coord_id]; - - spvm_result_t container = &state->results[sampled_image_id]; - assert(container->member_count == 2u); - spvm_image* image = container->members[0].value.image; - assert(image); - spvm_sampler* sampler = container->members[1].value.sampler; - assert(sampler); - - spvm_result_t sampled_image_type = spvm_state_get_type_info(state->results, &state->results[container->pointer]); - assert(sampled_image_type); - assert(sampled_image_type->value_type == spvm_value_type_sampled_image); - - spvm_result_t image_type = spvm_state_get_type_info(state->results, &state->results[sampled_image_type->pointer]); - assert(image_type); - assert(image_type->value_type == spvm_value_type_image); - assert(image_type->image_info); - - float stu[4] = { 0.0f }; - for (spvm_word i = 0; i < coord->member_count; i++) { - stu[i] = coord->members[i].value.f; - } - - spvm_vec4f res = {0}; - - unsigned dim; - if (image_type->image_info->dim == SpvDim1D) { - dim = 1u; - } else if (image_type->image_info->dim == SpvDim2D || - image_type->image_info->dim == SpvDimSubpassData) { - dim = 2u; - } else if (image_type->image_info->dim == SpvDim3D) { - dim = 3u; - } else if (image_type->image_info->dim == SpvDimCube) { - dim = 3u; - } else { - assert(!"Unhandled SpvDim"); - dim = 3u; - } - - float layer = 0.f; - if (image_type->image_info->arrayed) { - layer = stu[dim]; - - if (image_type->image_info->dim == SpvDimCube) { - layer *= 6; - } - } - - int offs[4][2] = { - { 0, 1 }, - { 1, 1 }, - { 1, 0 }, - { 0, 0 } - }; - - if (!operands->uses_offsets) { - stu[0] += operands->offsets[0][0] / (float)image->width; - stu[1] += operands->offsets[0][1] / (float)image->height; - stu[2] += operands->offsets[0][2] / (float)image->depth; - } else { - for (int i = 0; i < 4; i++) { - offs[i][0] = operands->offsets[i][0]; - offs[i][1] = operands->offsets[i][1]; - } - } - - if (image_type->image_info->dim == SpvDimCube) { - layer += process_cubemap_normal(&stu[0]); - } - - // Implicit sampling not allowed for gather. The base level - // is used by default. - float level = 0.f; - if (operands->bits & SpvImageOperandsLodMask) { - level = operands->lod; - } - - spvm_vec4f ret; - for (int i = 0; i < 4; i++) { - spvm_vec4f sample = spvm_fetch_texel(state, image, &sampler->desc, - stu[0] + (offs[i][0] / (float)image->width), - stu[1] + (offs[i][1] / (float)image->height), - stu[2], layer, level); - ret.data[i] = sample.data[comp]; - - // comparison is per gather operation - if (dref) { - ret.data[i] = spvm_execute_compare(ret.data[i], *dref, sampler->desc.compare_op); - } - } - - return ret; -} - -// same implementation for ImplicitLod and ExplicitLod -void spvm_execute_OpImageSample_base(spvm_word word_count, spvm_state_t state, bool proj) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word sampled_image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - - spvm_image_operands operands = {0}; - if (word_count > 4) { - spvm_image_operands_parse(&operands, state); - } - - spvm_vec4f res = spvm_op_image_sample(state, sampled_image_id, - coord_id, &operands, NULL, proj); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = res.data[i]; -} - -void spvm_execute_OpImageSample(spvm_word word_count, spvm_state_t state) -{ - spvm_execute_OpImageSample_base(word_count, state, false); -} - -void spvm_execute_OpImageSampleProj(spvm_word word_count, spvm_state_t state) -{ - spvm_execute_OpImageSample_base(word_count, state, true); -} - -void spvm_execute_OpImageSampleDref_base(spvm_word word_count, spvm_state_t state, - bool proj) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word sampled_image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - spvm_word dref_id = SPVM_READ_WORD(state->code_current); - - spvm_image_operands operands = {0}; - if (word_count > 4) { - spvm_image_operands_parse(&operands, state); - } - - spvm_result_t dref = &state->results[dref_id]; - float dref_val = dref->members[0].value.f; - - spvm_vec4f res = spvm_op_image_sample(state, sampled_image_id, - coord_id, &operands, &dref_val, proj); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - state->results[id].members[i].value.f = res.data[i]; - } -} - -void spvm_execute_OpImageSampleDref(spvm_word word_count, spvm_state_t state) -{ - spvm_execute_OpImageSampleDref_base(word_count, state, false); -} - -void spvm_execute_OpImageSampleProjDref(spvm_word word_count, spvm_state_t state) -{ - spvm_execute_OpImageSampleDref_base(word_count, state, true); -} - -void spvm_execute_OpSampledImage(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - spvm_word sampler_id = SPVM_READ_WORD(state->code_current); - - assert(state->results[id].member_count == 2u); - state->results[id].members[0].value.image = state->results[image_id].members[0].value.image; - state->results[id].members[1].value.sampler = state->results[sampler_id].members[0].value.sampler; -} - -void spvm_execute_OpImageFetch(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - - spvm_image_operands operands = {0}; - if (word_count > 4) { - spvm_image_operands_parse(&operands, state); - } - - spvm_result_t coord = &state->results[coord_id]; - - spvm_result_t image_container = &state->results[image_id]; - spvm_image* image = image_container->members[0].value.image; - - int stu[4] = { 0 }; - for (spvm_word i = 0; i < coord->member_count; i++) - stu[i] = coord->members[i].value.s + operands.offsets[0][i]; - - int level = 0u; - if (operands.bits & SpvImageOperandsLodMask) - level = operands.lod; - - spvm_vec4f px = spvm_image_read(state, image, stu[0], stu[1], stu[2], stu[3], level); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = px.data[i]; -} -void spvm_execute_OpImageGather(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word sampled_image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - spvm_word comp_id = SPVM_READ_WORD(state->code_current); - - spvm_image_operands operands = {0}; - if (word_count > 4) { - spvm_image_operands_parse(&operands, state); - } - - int comp = state->results[comp_id].members[0].value.s; - if (state->analyzer && (comp < 0 || comp > 3)) { - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_image_gather_invalid_comp); - } - - spvm_vec4f res = spvm_op_image_gather(state, sampled_image_id, - coord_id, comp, &operands, NULL); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = res.data[i]; -} -void spvm_execute_OpImageDrefGather(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word sampled_image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - spvm_word dref_id = SPVM_READ_WORD(state->code_current); - - spvm_image_operands operands = {0}; - if (word_count > 4) { - spvm_image_operands_parse(&operands, state); - } - - spvm_result_t dref = &state->results[dref_id]; - float dref_val = dref->members[0].value.f; - - const int comp = 0; // fixed for depth compare samplers - spvm_vec4f res = spvm_op_image_gather(state, sampled_image_id, - coord_id, comp, &operands, &dref_val); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = res.data[i]; -} -void spvm_execute_OpImageQuerySizeLod(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - spvm_word lod_id = SPVM_READ_WORD(state->code_current); - - int lod = state->results[lod_id].members[0].value.s; - spvm_image* img = state->results[image_id].members[0].value.image; - - // TODO: we just assume the lod sizes here, might be slightly different - // (there are vulkan extensions allowing to round up lod sizes). - // Should probably just be exposed as callback via state as well. - // TODO: layer, check image type - if (state->results[id].member_count > 0) - state->results[id].members[0].value.s = SPVM_MAX(img->width >> lod, 1); - if (state->results[id].member_count > 1) - state->results[id].members[1].value.s = SPVM_MAX(img->height >> lod, 1); - if (state->results[id].member_count > 2) - state->results[id].members[2].value.s = SPVM_MAX(img->depth >> lod, 1); -} -void spvm_execute_OpImageQuerySize(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - - spvm_image* img = state->results[image_id].members[0].value.image; - - // TODO: layer, check image type - if (state->results[id].member_count > 0) - state->results[id].members[0].value.s = img->width; - if (state->results[id].member_count > 1) - state->results[id].members[1].value.s = img->height; - if (state->results[id].member_count > 2) - state->results[id].members[2].value.s = img->depth; -} -void spvm_execute_OpImageQueryLod(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word sampled_image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - - spvm_result_t container = &state->results[sampled_image_id]; - assert(container->member_count == 2u); - spvm_image* image = container->members[0].value.image; - assert(image); - spvm_sampler* sampler = container->members[1].value.sampler; - assert(sampler); - - spvm_result_t sampled_image_type = spvm_state_get_type_info(state->results, &state->results[container->pointer]); - assert(sampled_image_type); - spvm_result_t image_type = spvm_state_get_type_info(state->results, &state->results[sampled_image_type->pointer]); - - assert(image_type); - assert(image_type->image_info); - assert(image_type->value_type == spvm_value_type_sampled_image); - - struct spvm_sampled_image_lod_query lodq = spvm_sampled_image_query_lod( - state, image, image_type->image_info, sampler, coord_id, 0.f, 0.f); - - // writeback - assert(state->results[id].member_count == 2); - - // Per vulkan spec, those are the returned values - state->results[id].members[0].value.f = lodq.lambda_prime; - state->results[id].members[1].value.f = lodq.dl; -} -void spvm_execute_OpImageQueryLevels(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - - assert(state->results[image_id].members); - state->results[id].members[0].value.u = state->results[image_id].members[0].value.image->levels; -} -void spvm_execute_OpImageQuerySamples(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - - assert(state->results[image_id].members); - (void) image_id; - - // TODO: spvm doesn't support multisampling atm - state->results[id].members[0].value.u = 1u; -} -void spvm_execute_OpImageRead(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - - spvm_image* img = state->results[image_id].members[0].value.image; - assert(img); - - spvm_result_t coord = &state->results[coord_id]; - spvm_result_t output = &state->results[id]; - - int x = 0, y = 0, z = 0; - - x = coord->members[0].value.s; - if (coord->member_count > 1) - y = coord->members[1].value.s; - if (coord->member_count > 2) - z = coord->members[2].value.s; - - int level = 0; - int layer = 0; - - // report undefined behavior - if (state->analyzer) { - if (x < 0 || y < 0 || z < 0 || x >= img->width || y >= img->height || z >= img->depth) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_image_read_out_of_bounds); - } - - spvm_vec4f data = spvm_image_read(state, img, x, y, z, layer, level); - - for (int i = 0; i < output->member_count; i++) - output->members[i].value.f = data.data[i]; -} -void spvm_execute_OpImageWrite(spvm_word word_count, spvm_state_t state) -{ - spvm_word image_id = SPVM_READ_WORD(state->code_current); - spvm_word coord_id = SPVM_READ_WORD(state->code_current); - spvm_word texel_id = SPVM_READ_WORD(state->code_current); - - spvm_image* img = state->results[image_id].members[0].value.image; - assert(img); - - spvm_result_t coord = &state->results[coord_id]; - spvm_result_t texel = &state->results[texel_id]; - - int x = 0, y = 0, z = 0; - - x = coord->members[0].value.s; - if (coord->member_count > 1) - y = coord->members[1].value.s; - if (coord->member_count > 2) - z = coord->members[2].value.s; - - spvm_vec4f rgba; - for (int i = 0; i < texel->member_count; i++) - rgba.data[i] = texel->members[i].value.f; - - int level = 0; - int layer = 0; - - // report undefined behavior - if (state->analyzer) { - if (x < 0 || y < 0 || z < 0 || x >= img->width || y >= img->height || z >= img->depth) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_image_read_out_of_bounds); - } - - spvm_image_write(state, img, x, y, z, level, layer, &rgba); -} -void spvm_execute_OpImage(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word image_id = SPVM_READ_WORD(state->code_current); - - spvm_image* image = state->results[image_id].members[0].value.image; - state->results[id].members[0].value.image = image; -} - -/* 3.32.11 Conversion Instructions */ -void spvm_execute_OpConvertFToU(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[state->results[val].pointer]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = (unsigned long long)state->results[val].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = (unsigned long long)state->results[val].members[i].value.f; -} -void spvm_execute_OpConvertFToS(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[state->results[val].pointer]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = (int)state->results[val].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = (int)state->results[val].members[i].value.f; -} -void spvm_execute_OpConvertUToF(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = (double)state->results[val].members[i].value.u; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = (float)state->results[val].members[i].value.u; -} -void spvm_execute_OpConvertSToF(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = (double)state->results[val].members[i].value.s; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = (float)state->results[val].members[i].value.s; -} -void spvm_execute_OpUConvert(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - spvm_result_t res_type_info = spvm_state_get_type_info(state->results, &state->results[res_type]); - - unsigned long long mask = 0xFF; - if (res_type_info->value_bitcount == 16) - mask = 0xFFFF; - else if (res_type_info->value_bitcount == 32) - mask = 0xFFFFFFFF; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = state->results[val].members[i].value.u & mask; -} -void spvm_execute_OpSConvert(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - spvm_result_t res_type_info = spvm_state_get_type_info(state->results, &state->results[res_type]); - - int mask = 0xFF; - if (res_type_info->value_bitcount == 16) - mask = 0xFFFF; - else if (res_type_info->value_bitcount == 32) - mask = 0xFFFFFFFF; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = state->results[val].members[i].value.s & mask; -} -void spvm_execute_OpFConvert(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - spvm_result_t res_type_info = spvm_state_get_type_info(state->results, &state->results[res_type]); - spvm_result_t val_info = spvm_state_get_type_info(state->results, &state->results[state->results[val].pointer]); - - if (res_type_info->value_bitcount > val_info->value_bitcount) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = (double)state->results[val].members[i].value.f; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = (float)state->results[val].members[i].value.d; -} -void spvm_execute_OpBitcast(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word val = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = state->results[val].members[i].value.u; -} - -/* 3.32.12 Composite Instructions */ -void spvm_execute_OpVectorExtractDynamic(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vector = SPVM_READ_WORD(state->code_current); - spvm_word index_id = SPVM_READ_WORD(state->code_current); - - spvm_word index = state->results[index_id].members[0].value.u; - - if (index < 0 || index >= state->results[vector].member_count) - state->results[id].members[0].value.u = state->results[vector].members[index].value.u; - else if (state->analyzer) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_vector_extract_dynamic); -} -void spvm_execute_OpVectorInsertDynamic(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vector = SPVM_READ_WORD(state->code_current); - spvm_word comp = SPVM_READ_WORD(state->code_current); - spvm_word index_id = SPVM_READ_WORD(state->code_current); - - spvm_word index = state->results[index_id].members[0].value.u; - - spvm_member_memcpy(state->results[id].members, state->results[vector].members, state->results[id].member_count); - - if (index < 0 || index >= state->results[id].member_count) - state->results[id].members[index].value.u = state->results[comp].members[0].value.u; - else if (state->analyzer) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_vector_insert_dynamic); -} -void spvm_execute_OpVectorShuffle(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vector1_id = SPVM_READ_WORD(state->code_current); - spvm_word vector2_id = SPVM_READ_WORD(state->code_current); - - spvm_result_t vector1 = &state->results[vector1_id]; - spvm_result_t vector2 = &state->results[vector2_id]; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - spvm_word index = SPVM_READ_WORD(state->code_current); - - if (index >= vector1->member_count) - state->results[id].members[i].value.u = vector2->members[index - vector1->member_count].value.u; - else - state->results[id].members[i].value.u = vector1->members[index].value.u; - } -} -void spvm_execute_OpCompositeConstruct(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - spvm_word index = SPVM_READ_WORD(state->code_current); - if (state->results[id].members[i].member_count == 0) - state->results[id].members[i].value.u = state->results[index].members[0].value.u; - else - spvm_member_memcpy(&state->results[id].members[i].members[0], &state->results[index].members[0], state->results[index].member_count); - } -} -void spvm_execute_OpCompositeExtract(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word value_id = SPVM_READ_WORD(state->code_current); - - spvm_word index_count = word_count - 4; - - spvm_word index = SPVM_READ_WORD(state->code_current); - spvm_member_t result = state->results[value_id].members + index; - - while (index_count) { - index = SPVM_READ_WORD(state->code_current); - - result = result->members + index; - - index_count--; - } - - spvm_word memcount = 1; - if (result->member_count) { - memcount = result->member_count; - result = result->members; - } - - spvm_member_memcpy(state->results[id].members, result, memcount); -} - -void spvm_execute_OpCompositeInsert(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word object_id = SPVM_READ_WORD(state->code_current); - spvm_word value_id = SPVM_READ_WORD(state->code_current); - - spvm_word index_count = word_count - 5; - - spvm_member_memcpy(state->results[id].members, state->results[value_id].members, state->results[value_id].member_count); - - spvm_word index = SPVM_READ_WORD(state->code_current); - spvm_member_t result = state->results[id].members + index; - - while (index_count) { - index = SPVM_READ_WORD(state->code_current); - - result = result->members + index; - - index_count--; - } - - spvm_member_memcpy(result, state->results[object_id].members, state->results[object_id].member_count); -} - -void spvm_execute_OpCopyObject(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op = SPVM_READ_WORD(state->code_current); - - spvm_member_memcpy(state->results[id].members, state->results[op].members, state->results[op].member_count); -} -void spvm_execute_OpTranspose(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word mat = SPVM_READ_WORD(state->code_current); - - spvm_word s1 = state->results[mat].member_count; - spvm_word s2 = state->results[mat].members[0].member_count; - for (spvm_word i = 0; i < s1; i++) - for (spvm_word j = 0; j < s2; ++j) - state->results[id].members[j].members[i].value.u = state->results[mat].members[i].members[j].value.u; -} -void spvm_execute_OpCopyLogical(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op = SPVM_READ_WORD(state->code_current); - - assert(state->results[id].member_count == state->results[op].member_count); - spvm_member_memcpy(state->results[id].members, state->results[op].members, state->results[op].member_count); -} - -/* 3.32.13 Arithmetic Instructions */ -void spvm_execute_OpSNegate(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = -state->results[op].members[i].value.s; -} -void spvm_execute_OpFNegate(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = -state->results[op].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = -state->results[op].members[i].value.f; -} -void spvm_execute_OpIAdd(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = state->results[op1].members[i].value.s + state->results[op2].members[i].value.s; -} -void spvm_execute_OpFAdd(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - // TODO: is there a better way to do this? - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[op1].members[i].value.d + state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[op1].members[i].value.f + state->results[op2].members[i].value.f; -} -void spvm_execute_OpISub(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = state->results[op1].members[i].value.s - state->results[op2].members[i].value.s; -} -void spvm_execute_OpFSub(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - // TODO: is there a better way to do this? - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[op1].members[i].value.d - state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[op1].members[i].value.f - state->results[op2].members[i].value.f; -} -void spvm_execute_OpIMul(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = state->results[op1].members[i].value.s * state->results[op2].members[i].value.s; -} -void spvm_execute_OpFMul(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - // TODO: is there a better way to do this? - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[op1].members[i].value.d * state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[op1].members[i].value.f * state->results[op2].members[i].value.f; -} -void spvm_execute_OpUDiv(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - if (state->analyzer && state->results[op2].members[i].value.u == 0) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_div_by_zero); - - state->results[id].members[i].value.u = state->results[op1].members[i].value.u / state->results[op2].members[i].value.u; - } -} -void spvm_execute_OpSDiv(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - if (state->analyzer && state->results[op2].members[i].value.s == 0) // TODO: also op2 == -1, op1 == minimum representable value? - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_div_by_zero); - - state->results[id].members[i].value.s = state->results[op1].members[i].value.s / state->results[op2].members[i].value.s; - } -} -void spvm_execute_OpFDiv(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - // TODO: is there a better way to do this? - if (type_info->value_bitcount > 32) { - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - // NOTE: nope, this isn't UB - // if (state->analyzer && state->results[op2].members[i].value.d == 0.0) - // state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_div_by_zero); - - state->results[id].members[i].value.d = state->results[op1].members[i].value.d / state->results[op2].members[i].value.d; - } - } else { - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - // NOTE: nope, this isn't UB - // if (state->analyzer && state->results[op2].members[i].value.f == 0.0f) - // state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_div_by_zero); - - state->results[id].members[i].value.f = state->results[op1].members[i].value.f / state->results[op2].members[i].value.f; - } - } -} -void spvm_execute_OpUMod(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - if (state->analyzer && state->results[op2].members[i].value.u == 0) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_mod_by_zero); - - state->results[id].members[i].value.u = state->results[op1].members[i].value.u % state->results[op2].members[i].value.u; - } -} -void spvm_execute_OpSMod(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - if (state->analyzer && state->results[op2].members[i].value.s == 0) // TODO: mod by -1, while op1 is min representable value for operands type - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_mod_by_zero); - - state->results[id].members[i].value.s = state->results[op1].members[i].value.s % state->results[op2].members[i].value.s; - } -} -void spvm_execute_OpFMod(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - // TODO: is there a better way to do this? - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - double op2_sign = SPVM_SIGN(state->results[op2].members[i].value.d); - double op1_sign = SPVM_SIGN(state->results[op1].members[i].value.d); - double sign = 1.0; - if (op2_sign != op1_sign) - sign = -1.0; - - if (state->analyzer && state->results[op2].members[i].value.d == 0.0) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_mod_by_zero); - - state->results[id].members[i].value.d = sign * fmod(state->results[op1].members[i].value.d, state->results[op2].members[i].value.d); - } - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - float op2_sign = SPVM_SIGN(state->results[op2].members[i].value.f); - float op1_sign = SPVM_SIGN(state->results[op1].members[i].value.f); - float sign = 1.0; - if (op2_sign != op1_sign) - sign = -1.0; - - if (state->analyzer && state->results[op2].members[i].value.f == 0.0f) - state->analyzer->on_undefined_behavior(state, spvm_undefined_behavior_mod_by_zero); - - state->results[id].members[i].value.f = sign * fmodf(state->results[op1].members[i].value.f, state->results[op2].members[i].value.f); - } -} -void spvm_execute_OpVectorTimesScalar(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vec = SPVM_READ_WORD(state->code_current); - spvm_word scalar = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.d = state->results[vec].members[i].value.d * state->results[scalar].members[0].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.f = state->results[vec].members[i].value.f * state->results[scalar].members[0].value.f; -} -void spvm_execute_OpMatrixTimesScalar(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word mat = SPVM_READ_WORD(state->code_current); - spvm_word scalar = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - spvm_word s1 = state->results[mat].member_count; - spvm_word s2 = state->results[mat].members[0].member_count; - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < s1; i++) - for (spvm_word j = 0; j < s2; j++) - state->results[id].members[i].members[j].value.d = state->results[mat].members[i].members[j].value.d * state->results[scalar].members[0].value.d; - else - for (spvm_word i = 0; i < s1; i++) - for (spvm_word j = 0; j < s2; j++) - state->results[id].members[i].members[j].value.f = state->results[mat].members[i].members[j].value.f * state->results[scalar].members[0].value.f; -} -void spvm_execute_OpVectorTimesMatrix(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vec = SPVM_READ_WORD(state->code_current); - spvm_word mat = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - spvm_word resSize = state->results[id].member_count; - spvm_word mySize = state->results[vec].member_count; - if (type_info->value_bitcount > 32) { - for (spvm_word i = 0; i < resSize; i++) { - double res = 0.0; - - for (spvm_word j = 0; j < mySize; j++) - res += state->results[mat].members[i].members[j].value.d * state->results[vec].members[j].value.d; - - state->results[id].members[i].value.d = res; - } - } else { - for (spvm_word i = 0; i < resSize; i++) { - float res = 0.0f; - - for (spvm_word j = 0; j < mySize; j++) - res += state->results[mat].members[i].members[j].value.f * state->results[vec].members[j].value.f; - - state->results[id].members[i].value.f = res; - } - } -} -void spvm_execute_OpMatrixTimesVector(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word mat = SPVM_READ_WORD(state->code_current); - spvm_word vec = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - spvm_word resSize = state->results[id].member_count; - spvm_word mySize = state->results[vec].member_count; - if (type_info->value_bitcount > 32) { - for (spvm_word i = 0; i < resSize; i++) { - double res = 0.0; - - for (spvm_word j = 0; j < mySize; j++) - res += state->results[mat].members[j].members[i].value.d * state->results[vec].members[j].value.d; - - state->results[id].members[i].value.d = res; - } - } else { - for (spvm_word i = 0; i < resSize; i++) { - float res = 0.0f; - - for (spvm_word j = 0; j < mySize; j++) - res += state->results[mat].members[j].members[i].value.f * state->results[vec].members[j].value.f; - - state->results[id].members[i].value.f = res; - } - } -} -void spvm_execute_OpMatrixTimesMatrix(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word left = SPVM_READ_WORD(state->code_current); - spvm_word right = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - spvm_word s1 = state->results[left].member_count; - spvm_word s2 = state->results[left].members[0].member_count; - spvm_word s3 = state->results[right].member_count; - - if (type_info->value_bitcount > 32) { - for (spvm_word i = 0; i < s3; i++) { - for (spvm_word j = 0; j < s2; j++) { - state->results[id].members[i].members[j].value.u = 0; - for (spvm_word k = 0; k < s1; k++) - state->results[id].members[i].members[j].value.d += state->results[left].members[k].members[j].value.d * state->results[right].members[i].members[k].value.d; - } - } - } - else { - for (spvm_word i = 0; i < s3; i++) { - for (spvm_word j = 0; j < s2; j++) { - state->results[id].members[i].members[j].value.u = 0; - for (spvm_word k = 0; k < s1; k++) - state->results[id].members[i].members[j].value.f += state->results[left].members[k].members[j].value.f * state->results[right].members[i].members[k].value.f; - } - } - } -} -void spvm_execute_OpOuterProduct(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vec1 = SPVM_READ_WORD(state->code_current); - spvm_word vec2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - spvm_word s1 = state->results[id].member_count; - spvm_word s2 = state->results[id].members[0].member_count; - if (type_info->value_bitcount > 32) { - for (spvm_word i = 0; i < s1; i++) - for (spvm_word j = 0; j < s2; j++) - state->results[id].members[i].members[j].value.d = state->results[vec1].members[i].value.d * state->results[vec2].members[j].value.d; - } else { - for (spvm_word i = 0; i < s1; i++) - for (spvm_word j = 0; j < s2; j++) - state->results[id].members[i].members[j].value.f = state->results[vec1].members[i].value.f * state->results[vec2].members[j].value.f; - } -} -void spvm_execute_OpDot(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vec1 = SPVM_READ_WORD(state->code_current); - spvm_word vec2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) { - double dot = 0.0; - for (spvm_word i = 0; i < state->results[vec1].member_count; i++) - dot += state->results[vec1].members[i].value.d * state->results[vec2].members[i].value.d; - state->results[id].members[0].value.d = dot; - } else { - float dot = 0.0f; - for (spvm_word i = 0; i < state->results[vec1].member_count; i++) - dot += state->results[vec1].members[i].value.f * state->results[vec2].members[i].value.f; - state->results[id].members[0].value.f = dot; - } -} - -/* 3.32.14 Bit Instructions */ -void spvm_execute_OpShiftRightLogical(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word base = SPVM_READ_WORD(state->code_current); - spvm_word shift = SPVM_READ_WORD(state->code_current); - - // TODO: call state->analyzer->on_defined_behavior when shift is >>> base - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = state->results[base].members[i].value.u >> state->results[shift].members[i].value.u; -} -void spvm_execute_OpShiftRightArithmetic(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word base = SPVM_READ_WORD(state->code_current); - spvm_word shift = SPVM_READ_WORD(state->code_current); - - // TODO: call state->analyzer->on_defined_behavior when shift is >>> base - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.s = state->results[base].members[i].value.s >> state->results[shift].members[i].value.s; -} -void spvm_execute_OpShiftLeftLogical(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word base = SPVM_READ_WORD(state->code_current); - spvm_word shift = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = state->results[base].members[i].value.u << state->results[shift].members[i].value.u; -} -void spvm_execute_OpBitwiseOr(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = state->results[op1].members[i].value.u | state->results[op2].members[i].value.u; -} -void spvm_execute_OpBitwiseAnd(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = state->results[op1].members[i].value.u & state->results[op2].members[i].value.u; -} -void spvm_execute_OpBitwiseXor(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = state->results[op1].members[i].value.u ^ state->results[op2].members[i].value.u; -} -void spvm_execute_OpNot(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.u = ~state->results[op1].members[i].value.u; -} - -/* 3.32.15 Relational and Logical Instructions */ -void spvm_execute_OpAny(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vec = SPVM_READ_WORD(state->code_current); - - spvm_byte result = 0; - for (spvm_word i = 0; i < state->results[vec].member_count; i++) - if (state->results[vec].members[i].value.b) - result = 1; - state->results[id].members[0].value.b = result; -} -void spvm_execute_OpAll(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word vec = SPVM_READ_WORD(state->code_current); - - spvm_byte result = 1; - for (spvm_word i = 0; i < state->results[vec].member_count; i++) - if (!state->results[vec].members[i].value.b) - result = 0; - state->results[id].members[0].value.b = result; -} -void spvm_execute_OpIsNan(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = isnan(state->results[x].members[i].value.f); -} -void spvm_execute_OpIsInf(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word x = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = isinf(state->results[x].members[i].value.f); -} -void spvm_execute_OpLogicalEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.b == state->results[op2].members[i].value.b; -} -void spvm_execute_OpLogicalNotEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.b != state->results[op2].members[i].value.b; -} -void spvm_execute_OpLogicalAnd(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.b && state->results[op2].members[i].value.b; -} -void spvm_execute_OpLogicalOr(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.b || state->results[op2].members[i].value.b; -} -void spvm_execute_OpLogicalNot(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = !state->results[op1].members[i].value.b; -} -void spvm_execute_OpSelect(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word cond = SPVM_READ_WORD(state->code_current); - spvm_word obj1 = SPVM_READ_WORD(state->code_current); - spvm_word obj2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - spvm_byte condValue = state->results[cond].members[0].value.b; - spvm_word obj = condValue ? obj1 : obj2; - if (state->results[id].members[i].member_count == 0) - state->results[id].members[i].value.u = state->results[obj].members[i].value.u; - else - spvm_member_memcpy(&state->results[id].members[i].members[0], &state->results[obj].members[i].members[0], state->results[obj].members[i].member_count); - } -} -void spvm_execute_OpIEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.s == state->results[op2].members[i].value.s; -} -void spvm_execute_OpINotEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.s != state->results[op2].members[i].value.s; -} -void spvm_execute_OpUGreaterThan(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.u > state->results[op2].members[i].value.u; -} -void spvm_execute_OpSGreaterThan(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.s > state->results[op2].members[i].value.s; -} -void spvm_execute_OpUGreaterThanEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.u >= state->results[op2].members[i].value.u; -} -void spvm_execute_OpSGreaterThanEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.s >= state->results[op2].members[i].value.s; -} -void spvm_execute_OpULessThan(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.u < state->results[op2].members[i].value.u; -} -void spvm_execute_OpSLessThan(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.s < state->results[op2].members[i].value.s; -} -void spvm_execute_OpULessThanEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.u <= state->results[op2].members[i].value.u; -} -void spvm_execute_OpSLessThanEqual(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.s <= state->results[op2].members[i].value.s; -} -void spvm_execute_OpFOrdEqual(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.d == state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.f == state->results[op2].members[i].value.f; -} -void spvm_execute_OpFOrdNotEqual(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.d != state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.f != state->results[op2].members[i].value.f; -} -void spvm_execute_OpFOrdLessThan(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.d < state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.f < state->results[op2].members[i].value.f; -} -void spvm_execute_OpFOrdGreaterThan(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.d > state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.f > state->results[op2].members[i].value.f; -} -void spvm_execute_OpFOrdLessThanEqual(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.d <= state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.f <= state->results[op2].members[i].value.f; -} -void spvm_execute_OpFOrdGreaterThanEqual(spvm_word word_count, spvm_state_t state) -{ - spvm_word type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word op1 = SPVM_READ_WORD(state->code_current); - spvm_word op2 = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[type]); - - if (type_info->value_bitcount > 32) - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.d >= state->results[op2].members[i].value.d; - else - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = state->results[op1].members[i].value.f >= state->results[op2].members[i].value.f; -} - -/* 3.32.16 Derivative Instructions */ -void spvm_execute_OpDPdx(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word res_id = SPVM_READ_WORD(state->code_current); - spvm_word P_id = SPVM_READ_WORD(state->code_current); - - int index = 0; - - spvm_state_ddx(state, P_id); - - for (spvm_word i = 0; i < state->results[res_id].member_count; i++) { - if (state->results[res_id].members[i].member_count == 0) { - state->results[res_id].members[i].value.f = state->derivative_buffer_x[index]; - index++; - } - else { - for (spvm_word j = 0; j < state->results[res_id].members[i].member_count; j++) - state->results[res_id].members[i].members[j].value.f = state->derivative_buffer_x[index]; - index += state->results[res_id].members[i].member_count; - } - } - - if (!state->_derivative_is_group_member) - spvm_state_group_step(state); -} -void spvm_execute_OpDPdy(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word res_id = SPVM_READ_WORD(state->code_current); - spvm_word P_id = SPVM_READ_WORD(state->code_current); - - int index = 0; - - spvm_state_ddy(state, P_id); - - for (spvm_word i = 0; i < state->results[res_id].member_count; i++) { - if (state->results[res_id].members[i].member_count == 0) { - state->results[res_id].members[i].value.f = state->derivative_buffer_y[index]; - index++; - } - else { - for (spvm_word j = 0; j < state->results[res_id].members[i].member_count; j++) - state->results[res_id].members[i].members[j].value.f = state->derivative_buffer_y[index]; - index += state->results[res_id].members[i].member_count; - } - } - - if (!state->_derivative_is_group_member) - spvm_state_group_step(state); -} -void spvm_execute_OpFwidth(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word res_id = SPVM_READ_WORD(state->code_current); - spvm_word P_id = SPVM_READ_WORD(state->code_current); - - int index = 0; - - spvm_state_ddx(state, P_id); - spvm_state_ddy(state, P_id); - - for (spvm_word i = 0; i < state->results[res_id].member_count; i++) { - if (state->results[res_id].members[i].member_count == 0) { - state->results[res_id].members[i].value.f = fabsf(state->derivative_buffer_x[index]) + fabsf(state->derivative_buffer_y[index]); - index++; - } - else { - for (spvm_word j = 0; j < state->results[res_id].members[i].member_count; j++) - state->results[res_id].members[i].members[j].value.f = fabsf(state->derivative_buffer_x[index]) + fabsf(state->derivative_buffer_y[index]); - index += state->results[res_id].members[i].member_count; - } - } - - if (!state->_derivative_is_group_member) - spvm_state_group_step(state); -} - -/* 3.32.17 Control-Flow Instructions */ -void spvm_execute_OpPhi(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - word_count = (word_count - 2) / 2; - unsigned found = 0u; - - for (spvm_word i = 0; i < word_count; i++) { - spvm_word variable = SPVM_READ_WORD(state->code_current); - spvm_word parent = SPVM_READ_WORD(state->code_current); - - if (parent == state->function_stack_cfg_parent[state->function_stack_current]) { - spvm_member_memcpy(state->results[id].members, state->results[variable].members, state->results[id].member_count); - found = 1u; - break; - } - } - - assert(found); -} -void spvm_execute_OpLabel(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - state->function_stack_cfg_parent[state->function_stack_current] = state->function_stack_cfg[state->function_stack_current]; - state->function_stack_cfg[state->function_stack_current] = id; -} -void spvm_execute_OpBranch(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - state->code_current = state->results[id].source_location; - - state->did_jump = 1; -} -void spvm_execute_OpBranchConditional(spvm_word word_count, spvm_state_t state) -{ - spvm_word cond = SPVM_READ_WORD(state->code_current); - spvm_word true_branch = SPVM_READ_WORD(state->code_current); - spvm_word false_branch = SPVM_READ_WORD(state->code_current); - - if (state->results[cond].members[0].value.b) - state->code_current = state->results[true_branch].source_location; - else - state->code_current = state->results[false_branch].source_location; - - state->did_jump = 1; -} -void spvm_execute_OpSwitch(spvm_word word_count, spvm_state_t state) -{ - spvm_word sel = SPVM_READ_WORD(state->code_current); - spvm_word def_lbl = SPVM_READ_WORD(state->code_current); - - spvm_word case_count = (word_count - 2) / 2; - - spvm_word val = state->results[sel].members[0].value.s; - - spvm_byte found = 0; - for (spvm_word i = 0; i < case_count; i++) { - spvm_word lit = SPVM_READ_WORD(state->code_current); - spvm_word lbl = SPVM_READ_WORD(state->code_current); - - if (val == lit) { - state->code_current = state->results[lbl].source_location; - found = 1; - break; - } - } - - if (!found) - state->code_current = state->results[def_lbl].source_location; - - state->did_jump = 1; -} -void spvm_execute_OpKill(spvm_word word_count, spvm_state_t state) -{ - state->code_current = NULL; - state->did_jump = 1; - state->discarded = 1; -} - -/* 3.32.18 Atomic Instructions */ -void spvm_execute_OpAtomicLoad(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicLoad, word_count, state); -} -void spvm_execute_OpAtomicStore(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicStore, word_count, state); -} -void spvm_execute_OpAtomicExchange(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicExchange, word_count, state); -} -void spvm_execute_OpAtomicCompareExchange(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicCompareExchange, word_count, state); -} -void spvm_execute_OpAtomicIIncrement(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicIIncrement, word_count, state); -} -void spvm_execute_OpAtomicIDecrement(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicIDecrement, word_count, state); -} -void spvm_execute_OpAtomicIAdd(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicIAdd, word_count, state); -} -void spvm_execute_OpAtomicISub(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicISub, word_count, state); -} -void spvm_execute_OpAtomicSMin(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicSMin, word_count, state); -} -void spvm_execute_OpAtomicUMin(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicUMin, word_count, state); -} -void spvm_execute_OpAtomicSMax(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicSMax, word_count, state); -} -void spvm_execute_OpAtomicUMax(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicUMax, word_count, state); -} -void spvm_execute_OpAtomicAnd(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicAnd, word_count, state); -} -void spvm_execute_OpAtomicOr(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicOr, word_count, state); -} -void spvm_execute_OpAtomicXor(spvm_word word_count, spvm_state_t state) -{ - if (state->owner->atomic_operation) - state->owner->atomic_operation(SpvOpAtomicXor, word_count, state); -} - -/* 3.32.19 Primitive Instructions */ -void spvm_execute_OpEmitVertex(spvm_word word_count, spvm_state_t state) -{ - if (state->emit_vertex) - state->emit_vertex(state, 0); -} -void spvm_execute_OpEndPrimitive(spvm_word word_count, spvm_state_t state) -{ - if (state->end_primitive) - state->end_primitive(state, 0); -} -void spvm_execute_OpEmitStreamVertex(spvm_word word_count, spvm_state_t state) -{ - if (state->emit_vertex) { - spvm_word stream_id = SPVM_READ_WORD(state->code_current); - state->emit_vertex(state, state->results[stream_id].members[0].value.u); - } -} -void spvm_execute_OpEndStreamPrimitive(spvm_word word_count, spvm_state_t state) -{ - if (state->end_primitive) { - spvm_word stream_id = SPVM_READ_WORD(state->code_current); - state->end_primitive(state, state->results[stream_id].members[0].value.u); - } -} - -/* 3.32.20 Barrier Instructions */ -void spvm_execute_OpControlBarrier(spvm_word word_count, spvm_state_t state) -{ - if (state->control_barrier) { - spvm_word execution = SPVM_READ_WORD(state->code_current); - spvm_word memory = SPVM_READ_WORD(state->code_current); - spvm_word semantics = SPVM_READ_WORD(state->code_current); - state->control_barrier(state, execution, memory, semantics); - } -} - -/* At least warn when executing an opcode not implemented yet */ -void spvm_execute_todo(spvm_word word_count, spvm_state_t state) -{ - --state->code_current; - spvm_word opcode_data = SPVM_READ_WORD(state->code_current); - SpvOp opcode = (opcode_data & SpvOpCodeMask); - - spvm_state_log(state, "unhandled opcode: %d", (int) opcode); -} - - -void _spvm_context_create_execute_table(spvm_context_t ctx) -{ - ctx->opcode_execute = (spvm_opcode_func*)calloc(SPVM_OPCODE_TABLE_LENGTH, sizeof(spvm_opcode_func)); - - ctx->opcode_execute[SpvOpLabel] = spvm_execute_OpLabel; - ctx->opcode_execute[SpvOpPhi] = spvm_execute_OpPhi; - - ctx->opcode_execute[SpvOpLine] = spvm_execute_OpLine; - ctx->opcode_execute[SpvOpNoLine] = spvm_execute_OpNoLine; - - ctx->opcode_execute[SpvOpStore] = spvm_execute_OpStore; - ctx->opcode_execute[SpvOpLoad] = spvm_execute_OpLoad; - ctx->opcode_execute[SpvOpArrayLength] = spvm_execute_OpArrayLength; - ctx->opcode_execute[SpvOpCopyMemory] = spvm_execute_OpCopyMemory; - ctx->opcode_execute[SpvOpCopyMemorySized] = spvm_execute_OpCopyMemorySized; - ctx->opcode_execute[SpvOpAccessChain] = spvm_execute_OpAccessChain; - ctx->opcode_execute[SpvOpPtrEqual] = spvm_execute_OpPtrEqual; - ctx->opcode_execute[SpvOpPtrNotEqual] = spvm_execute_OpPtrNotEqual; - ctx->opcode_execute[SpvOpPtrDiff] = spvm_execute_todo; - ctx->opcode_execute[SpvOpFunctionCall] = spvm_execute_OpFunctionCall; - ctx->opcode_execute[SpvOpReturn] = spvm_execute_OpReturn; - ctx->opcode_execute[SpvOpReturnValue] = spvm_execute_OpReturnValue; - - ctx->opcode_execute[SpvOpExtInst] = spvm_execute_OpExtInst; - - ctx->opcode_execute[SpvOpConvertFToU] = spvm_execute_OpConvertFToU; - ctx->opcode_execute[SpvOpConvertFToS] = spvm_execute_OpConvertFToS; - ctx->opcode_execute[SpvOpConvertUToF] = spvm_execute_OpConvertUToF; - ctx->opcode_execute[SpvOpConvertSToF] = spvm_execute_OpConvertSToF; - ctx->opcode_execute[SpvOpUConvert] = spvm_execute_OpUConvert; - ctx->opcode_execute[SpvOpSConvert] = spvm_execute_OpSConvert; - ctx->opcode_execute[SpvOpFConvert] = spvm_execute_OpFConvert; - ctx->opcode_execute[SpvOpQuantizeToF16] = spvm_execute_todo, - ctx->opcode_execute[SpvOpBitcast] = spvm_execute_OpBitcast; - - ctx->opcode_execute[SpvOpVectorExtractDynamic] = spvm_execute_OpVectorExtractDynamic; - ctx->opcode_execute[SpvOpVectorInsertDynamic] = spvm_execute_OpVectorInsertDynamic; - ctx->opcode_execute[SpvOpVectorShuffle] = spvm_execute_OpVectorShuffle; - ctx->opcode_execute[SpvOpCompositeConstruct] = spvm_execute_OpCompositeConstruct; - ctx->opcode_execute[SpvOpCompositeExtract] = spvm_execute_OpCompositeExtract; - ctx->opcode_execute[SpvOpCompositeInsert] = spvm_execute_OpCompositeInsert; - ctx->opcode_execute[SpvOpCopyObject] = spvm_execute_OpCopyObject; - ctx->opcode_execute[SpvOpTranspose] = spvm_execute_OpTranspose; - ctx->opcode_execute[SpvOpCopyLogical] = spvm_execute_OpCopyLogical; - - ctx->opcode_execute[SpvOpSNegate] = spvm_execute_OpSNegate; - ctx->opcode_execute[SpvOpFNegate] = spvm_execute_OpFNegate; - ctx->opcode_execute[SpvOpIAdd] = spvm_execute_OpIAdd; - ctx->opcode_execute[SpvOpFAdd] = spvm_execute_OpFAdd; - ctx->opcode_execute[SpvOpISub] = spvm_execute_OpISub; - ctx->opcode_execute[SpvOpFSub] = spvm_execute_OpFSub; - ctx->opcode_execute[SpvOpIMul] = spvm_execute_OpIMul; - ctx->opcode_execute[SpvOpFMul] = spvm_execute_OpFMul; - ctx->opcode_execute[SpvOpUDiv] = spvm_execute_OpUDiv; - ctx->opcode_execute[SpvOpSDiv] = spvm_execute_OpSDiv; - ctx->opcode_execute[SpvOpFDiv] = spvm_execute_OpFDiv; - ctx->opcode_execute[SpvOpUMod] = spvm_execute_OpUMod; - ctx->opcode_execute[SpvOpSRem] = spvm_execute_todo; - ctx->opcode_execute[SpvOpSMod] = spvm_execute_OpSMod; - ctx->opcode_execute[SpvOpFRem] = spvm_execute_todo; - ctx->opcode_execute[SpvOpFMod] = spvm_execute_OpFMod; - ctx->opcode_execute[SpvOpVectorTimesScalar] = spvm_execute_OpVectorTimesScalar; - ctx->opcode_execute[SpvOpMatrixTimesScalar] = spvm_execute_OpMatrixTimesScalar; - ctx->opcode_execute[SpvOpVectorTimesMatrix] = spvm_execute_OpVectorTimesMatrix; - ctx->opcode_execute[SpvOpMatrixTimesVector] = spvm_execute_OpMatrixTimesVector; - ctx->opcode_execute[SpvOpMatrixTimesMatrix] = spvm_execute_OpMatrixTimesMatrix; - ctx->opcode_execute[SpvOpOuterProduct] = spvm_execute_OpOuterProduct; - ctx->opcode_execute[SpvOpDot] = spvm_execute_OpDot; - ctx->opcode_execute[SpvOpIAddCarry] = spvm_execute_todo; - ctx->opcode_execute[SpvOpISubBorrow] = spvm_execute_todo; - ctx->opcode_execute[SpvOpUMulExtended] = spvm_execute_todo; - ctx->opcode_execute[SpvOpSMulExtended] = spvm_execute_todo; - - ctx->opcode_execute[SpvOpShiftRightLogical] = spvm_execute_OpShiftRightLogical; - ctx->opcode_execute[SpvOpShiftRightArithmetic] = spvm_execute_OpShiftRightArithmetic; - ctx->opcode_execute[SpvOpShiftLeftLogical] = spvm_execute_OpShiftLeftLogical; - ctx->opcode_execute[SpvOpBitwiseOr] = spvm_execute_OpBitwiseOr; - ctx->opcode_execute[SpvOpBitwiseAnd] = spvm_execute_OpBitwiseAnd; - ctx->opcode_execute[SpvOpBitwiseXor] = spvm_execute_OpBitwiseXor; - ctx->opcode_execute[SpvOpNot] = spvm_execute_OpNot; - ctx->opcode_execute[SpvOpBitFieldInsert] = spvm_execute_todo; - ctx->opcode_execute[SpvOpBitFieldSExtract] = spvm_execute_todo; - ctx->opcode_execute[SpvOpBitFieldUExtract] = spvm_execute_todo; - ctx->opcode_execute[SpvOpBitReverse] = spvm_execute_todo; - ctx->opcode_execute[SpvOpBitCount] = spvm_execute_todo; - - ctx->opcode_execute[SpvOpAny] = spvm_execute_OpAny; - ctx->opcode_execute[SpvOpAll] = spvm_execute_OpAll; - ctx->opcode_execute[SpvOpIsNan] = spvm_execute_OpIsNan; - ctx->opcode_execute[SpvOpIsInf] = spvm_execute_OpIsInf; - ctx->opcode_execute[SpvOpLogicalEqual] = spvm_execute_OpLogicalEqual; - ctx->opcode_execute[SpvOpLogicalNotEqual] = spvm_execute_OpLogicalNotEqual; - ctx->opcode_execute[SpvOpLogicalAnd] = spvm_execute_OpLogicalAnd; - ctx->opcode_execute[SpvOpLogicalOr] = spvm_execute_OpLogicalOr; - ctx->opcode_execute[SpvOpLogicalNot] = spvm_execute_OpLogicalNot; - ctx->opcode_execute[SpvOpSelect] = spvm_execute_OpSelect; - ctx->opcode_execute[SpvOpIEqual] = spvm_execute_OpIEqual; - ctx->opcode_execute[SpvOpINotEqual] = spvm_execute_OpINotEqual; - ctx->opcode_execute[SpvOpUGreaterThan] = spvm_execute_OpUGreaterThan; - ctx->opcode_execute[SpvOpSGreaterThan] = spvm_execute_OpSGreaterThan; - ctx->opcode_execute[SpvOpUGreaterThanEqual] = spvm_execute_OpUGreaterThanEqual; - ctx->opcode_execute[SpvOpSGreaterThanEqual] = spvm_execute_OpSGreaterThanEqual; - ctx->opcode_execute[SpvOpULessThan] = spvm_execute_OpULessThan; - ctx->opcode_execute[SpvOpSLessThan] = spvm_execute_OpSLessThan; - ctx->opcode_execute[SpvOpULessThanEqual] = spvm_execute_OpULessThanEqual; - ctx->opcode_execute[SpvOpSLessThanEqual] = spvm_execute_OpSLessThanEqual; - ctx->opcode_execute[SpvOpFOrdEqual] = spvm_execute_OpFOrdEqual; - ctx->opcode_execute[SpvOpFOrdNotEqual] = spvm_execute_OpFOrdNotEqual; - ctx->opcode_execute[SpvOpFOrdLessThan] = spvm_execute_OpFOrdLessThan; - ctx->opcode_execute[SpvOpFOrdGreaterThan] = spvm_execute_OpFOrdGreaterThan; - ctx->opcode_execute[SpvOpFOrdLessThanEqual] = spvm_execute_OpFOrdLessThanEqual; - ctx->opcode_execute[SpvOpFOrdGreaterThanEqual] = spvm_execute_OpFOrdGreaterThanEqual; - // TODO: handle special unordered cases - ctx->opcode_execute[SpvOpFUnordEqual] = spvm_execute_OpFOrdEqual; - ctx->opcode_execute[SpvOpFUnordNotEqual] = spvm_execute_OpFOrdNotEqual; - ctx->opcode_execute[SpvOpFUnordLessThan] = spvm_execute_OpFOrdLessThan; - ctx->opcode_execute[SpvOpFUnordGreaterThan] = spvm_execute_OpFOrdGreaterThan; - ctx->opcode_execute[SpvOpFUnordLessThanEqual] = spvm_execute_OpFOrdLessThanEqual; - ctx->opcode_execute[SpvOpFUnordGreaterThanEqual] = spvm_execute_OpFOrdGreaterThanEqual; - - ctx->opcode_execute[SpvOpSampledImage] = spvm_execute_OpSampledImage; - ctx->opcode_execute[SpvOpImageSampleImplicitLod] = spvm_execute_OpImageSample; - ctx->opcode_execute[SpvOpImageSampleExplicitLod] = spvm_execute_OpImageSample; - ctx->opcode_execute[SpvOpImageFetch] = spvm_execute_OpImageFetch; - ctx->opcode_execute[SpvOpImageGather] = spvm_execute_OpImageGather; - ctx->opcode_execute[SpvOpImageQuerySizeLod] = spvm_execute_OpImageQuerySizeLod; - ctx->opcode_execute[SpvOpImageQuerySize] = spvm_execute_OpImageQuerySize; - ctx->opcode_execute[SpvOpImageSampleDrefImplicitLod] = spvm_execute_OpImageSampleDref; - ctx->opcode_execute[SpvOpImageSampleDrefExplicitLod] = spvm_execute_OpImageSampleDref; - ctx->opcode_execute[SpvOpImageSampleProjImplicitLod] = spvm_execute_OpImageSampleProj; - ctx->opcode_execute[SpvOpImageSampleProjExplicitLod] = spvm_execute_OpImageSampleProj; - ctx->opcode_execute[SpvOpImageSampleProjDrefImplicitLod] = spvm_execute_OpImageSampleProjDref; - ctx->opcode_execute[SpvOpImageSampleProjDrefExplicitLod] = spvm_execute_OpImageSampleProjDref; - ctx->opcode_execute[SpvOpImageDrefGather] = spvm_execute_OpImageDrefGather; - ctx->opcode_execute[SpvOpImageRead] = spvm_execute_OpImageRead; - ctx->opcode_execute[SpvOpImageWrite] = spvm_execute_OpImageWrite; - ctx->opcode_execute[SpvOpImage] = spvm_execute_OpImage; - ctx->opcode_execute[SpvOpImageQueryFormat] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageQueryOrder] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageQueryLod] = spvm_execute_OpImageQueryLod; - ctx->opcode_execute[SpvOpImageQueryLevels] = spvm_execute_OpImageQueryLevels; - ctx->opcode_execute[SpvOpImageQuerySamples] = spvm_execute_OpImageQuerySamples; - - // sparse image support - ctx->opcode_execute[SpvOpImageSparseSampleImplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseSampleExplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseSampleDrefImplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseSampleDrefExplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseSampleProjImplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseSampleProjExplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseSampleProjDrefImplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseSampleProjDrefExplicitLod] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseFetch] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseGather] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseDrefGather] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseTexelsResident] = spvm_execute_todo; - ctx->opcode_execute[SpvOpImageSparseRead] = spvm_execute_todo; - - ctx->opcode_execute[SpvOpDPdx] = spvm_execute_OpDPdx; - ctx->opcode_execute[SpvOpDPdxFine] = spvm_execute_OpDPdx; - ctx->opcode_execute[SpvOpDPdxCoarse] = spvm_execute_OpDPdx; - ctx->opcode_execute[SpvOpDPdy] = spvm_execute_OpDPdy; - ctx->opcode_execute[SpvOpDPdyFine] = spvm_execute_OpDPdy; - ctx->opcode_execute[SpvOpDPdyCoarse] = spvm_execute_OpDPdy; - ctx->opcode_execute[SpvOpFwidth] = spvm_execute_OpFwidth; - ctx->opcode_execute[SpvOpFwidthFine] = spvm_execute_OpFwidth; - ctx->opcode_execute[SpvOpFwidthCoarse] = spvm_execute_OpFwidth; - - ctx->opcode_execute[SpvOpBranch] = spvm_execute_OpBranch; - ctx->opcode_execute[SpvOpBranchConditional] = spvm_execute_OpBranchConditional; - ctx->opcode_execute[SpvOpSwitch] = spvm_execute_OpSwitch; - ctx->opcode_execute[SpvOpKill] = spvm_execute_OpKill; - - ctx->opcode_execute[SpvOpEmitVertex] = spvm_execute_OpEmitVertex; - ctx->opcode_execute[SpvOpEndPrimitive] = spvm_execute_OpEndPrimitive; - ctx->opcode_execute[SpvOpEmitStreamVertex] = spvm_execute_OpEmitStreamVertex; - ctx->opcode_execute[SpvOpEndStreamPrimitive] = spvm_execute_OpEndStreamPrimitive; - - ctx->opcode_execute[SpvOpAtomicLoad] = spvm_execute_OpAtomicLoad; - ctx->opcode_execute[SpvOpAtomicStore] = spvm_execute_OpAtomicStore; - ctx->opcode_execute[SpvOpAtomicExchange] = spvm_execute_OpAtomicExchange; - ctx->opcode_execute[SpvOpAtomicCompareExchange] = spvm_execute_OpAtomicCompareExchange; - ctx->opcode_execute[SpvOpAtomicIIncrement] = spvm_execute_OpAtomicIIncrement; - ctx->opcode_execute[SpvOpAtomicIDecrement] = spvm_execute_OpAtomicIDecrement; - ctx->opcode_execute[SpvOpAtomicIAdd] = spvm_execute_OpAtomicIAdd; - ctx->opcode_execute[SpvOpAtomicISub] = spvm_execute_OpAtomicISub; - ctx->opcode_execute[SpvOpAtomicSMin] = spvm_execute_OpAtomicSMin; - ctx->opcode_execute[SpvOpAtomicUMin] = spvm_execute_OpAtomicUMin; - ctx->opcode_execute[SpvOpAtomicSMax] = spvm_execute_OpAtomicSMax; - ctx->opcode_execute[SpvOpAtomicUMax] = spvm_execute_OpAtomicUMax; - ctx->opcode_execute[SpvOpAtomicAnd] = spvm_execute_OpAtomicAnd; - ctx->opcode_execute[SpvOpAtomicOr] = spvm_execute_OpAtomicOr; - ctx->opcode_execute[SpvOpAtomicXor] = spvm_execute_OpAtomicXor; - - ctx->opcode_execute[SpvOpControlBarrier] = spvm_execute_OpControlBarrier; -} diff --git a/src/spvm/opcode_setup.c b/src/spvm/opcode_setup.c deleted file mode 100644 index 173cafce..00000000 --- a/src/spvm/opcode_setup.c +++ /dev/null @@ -1,784 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -// defined in opcode_execute.c -char spvm_use_access_callback(enum spvm_result_type result_type, - SpvStorageClass storage_class); - -/* 3.32.2 Debug Instructions */ -void spvm_setup_OpSource(spvm_word word_count, spvm_state_t state) -{ - // check if file was already added - for (unsigned i = 0u; i < state->owner->file_count; ++i) { - if (state->owner->files[i].origin == state->code_current) { - return; - } - } - - size_t id = state->owner->file_count++; - state->owner->files = (spvm_file*) realloc(state->owner->files, - sizeof(spvm_file) * state->owner->file_count); - - spvm_file* file = &state->owner->files[id]; - memset(file, 0x0, sizeof(spvm_file)); - file->origin = state->code_current; - file->language = SPVM_READ_WORD(state->code_current); - file->language_version = SPVM_READ_WORD(state->code_current); - - if (word_count > 2) { - spvm_word name = SPVM_READ_WORD(state->code_current); - file->name = state->results[name].name; - } - - if (word_count > 3) { - file->source = (spvm_string) state->code_current; - } -} -void spvm_setup_OpSourceExtension(spvm_word word_count, spvm_state_t state) -{ - spvm_string ext = spvm_program_add_extension(state->owner, word_count); - spvm_string_read(state->code_current, ext, word_count); -} -void spvm_setup_OpName(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - state->results[id].name = (const char*) state->code_current; -} -void spvm_setup_OpMemberName(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word memb = SPVM_READ_WORD(state->code_current); - - state->results[id].member_name_count = SPVM_MAX(memb + 1, state->results[id].member_name_count); - state->results[id].member_name = (spvm_string*)realloc(state->results[id].member_name, sizeof(spvm_string) * state->results[id].member_name_count); - - spvm_word slen = word_count - 2; - state->results[id].member_name[memb] = (spvm_string)malloc(sizeof(spvm_word) * slen); - spvm_string_read(state->code_current, state->results[id].member_name[memb], slen); -} -void spvm_setup_OpString(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - state->results[id].type = spvm_result_type_string; - state->results[id].name = (const char*) state->code_current; -} - -/* 3.32.3 Annotation Instructions */ -void spvm_setup_OpDecorate(spvm_word word_count, spvm_state_t state) -{ - spvm_word target = SPVM_READ_WORD(state->code_current); - SpvDecoration decor = SPVM_READ_WORD(state->code_current); - spvm_word literal1 = 0, literal2 = 0; - - spvm_decoration_read(state->code_current, decor, &literal1, &literal2); - spvm_result_add_decoration(&state->results[target], decor, literal1, literal2); -} -void spvm_setup_OpMemberDecorate(spvm_word word_count, spvm_state_t state) -{ - spvm_word target = SPVM_READ_WORD(state->code_current); - SpvDecoration memb = SPVM_READ_WORD(state->code_current); - SpvDecoration decor = SPVM_READ_WORD(state->code_current); - spvm_word literal1 = 0, literal2 = 0; - - spvm_decoration_read(state->code_current, decor, &literal1, &literal2); - spvm_result_add_member_decoration(&state->results[target], decor, literal1, literal2, memb); -} - -/* 3.32.4 Extension Instructions */ -void spvm_setup_OpExtInstImport(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word name_index = state->owner->import_count; - - word_count--; - - state->results[id].type = spvm_result_type_extension; - state->results[id].name = (const char*) state->code_current; -} - -/* 3.32.5 Mode-Setting Instructions */ -void spvm_setup_OpMemoryModel(spvm_word word_count, spvm_state_t state) -{ - state->owner->addressing = SPVM_READ_WORD(state->code_current); - state->owner->memory_model = SPVM_READ_WORD(state->code_current); -} -void spvm_setup_OpEntryPoint(spvm_word word_count, spvm_state_t state) -{ - spvm_entry_point* entry = spvm_program_create_entry_point(state->owner); - entry->exec_model = SPVM_READ_WORD(state->code_current); - entry->id = SPVM_READ_WORD(state->code_current); - - spvm_word name_length = 0; - entry->name = spvm_string_read_all(state->code_current, &name_length); - state->code_current += name_length; - - spvm_word interface_count = word_count - name_length - 2; - entry->globals_count = interface_count; - - if (interface_count) { - entry->globals = (spvm_word*)calloc(interface_count, sizeof(spvm_word)); - spvm_word interface_index = 0; - while (interface_count) { - entry->globals[interface_index] = SPVM_READ_WORD(state->code_current); - interface_index++; - interface_count--; - } - } -} -void spvm_setup_OpCapability(spvm_word word_count, spvm_state_t state) -{ - SpvCapability cap = SPVM_READ_WORD(state->code_current); - spvm_program_add_capability(state->owner, cap); -} -void spvm_setup_OpExecutionMode(spvm_word word_count, spvm_state_t state) -{ - SPVM_SKIP_WORD(state->code_current); - spvm_word execution_mode = SPVM_READ_WORD(state->code_current); - - if (execution_mode == SpvExecutionModeLocalSize) { - state->owner->local_size_x = SPVM_READ_WORD(state->code_current); - state->owner->local_size_y = SPVM_READ_WORD(state->code_current); - state->owner->local_size_z = SPVM_READ_WORD(state->code_current); - } else if (execution_mode == SpvExecutionModeInvocations) - state->owner->geometry_invocations = SPVM_READ_WORD(state->code_current); - else if (execution_mode == SpvExecutionModeOutputVertices) - state->owner->geometry_output_count = SPVM_READ_WORD(state->code_current); - else if (execution_mode == SpvExecutionModeInputPoints || execution_mode == SpvExecutionModeInputLines || - execution_mode == SpvExecutionModeTriangles || execution_mode == SpvExecutionModeInputLinesAdjacency || - execution_mode == SpvExecutionModeInputTrianglesAdjacency) - state->owner->geometry_input = execution_mode; - else if (execution_mode == SpvExecutionModeOutputPoints || execution_mode == SpvExecutionModeOutputLineStrip || - execution_mode == SpvExecutionModeOutputTriangleStrip) - state->owner->geometry_output = execution_mode; -} - -/* 3.32.6 Type-Declaration Instructions */ -void spvm_setup_OpTypeVoid(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_void; - state->results[store_id].value_bitcount = 0; - state->results[store_id].member_count = 0; -} -void spvm_setup_OpTypeBool(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_bool; - state->results[store_id].value_bitcount = 1; - state->results[store_id].member_count = 1; -} -void spvm_setup_OpTypeInt(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_int; - state->results[store_id].value_bitcount = SPVM_READ_WORD(state->code_current); - state->results[store_id].value_sign = SPVM_READ_WORD(state->code_current); - state->results[store_id].member_count = 1; -} -void spvm_setup_OpTypeFloat(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_float; - state->results[store_id].value_bitcount = SPVM_READ_WORD(state->code_current); - state->results[store_id].member_count = 1; -} -void spvm_setup_OpTypeVector(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_vector; - - state->results[store_id].pointer = SPVM_READ_WORD(state->code_current); - state->results[store_id].member_count = SPVM_READ_WORD(state->code_current); -} -void spvm_setup_OpTypeMatrix(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_matrix; - - state->results[store_id].pointer = SPVM_READ_WORD(state->code_current); - state->results[store_id].member_count = SPVM_READ_WORD(state->code_current); -} -void spvm_setup_OpTypeImage(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - state->results[id].type = spvm_result_type_type; - state->results[id].value_type = spvm_value_type_image; - state->results[id].pointer = SPVM_READ_WORD(state->code_current); // sampled type - state->results[id].member_count = 1; - - spvm_image_info* info = state->results[id].image_info = calloc(1, sizeof(spvm_image_info)); - info->dim = SPVM_READ_WORD(state->code_current); - info->depth = SPVM_READ_WORD(state->code_current); - info->arrayed = SPVM_READ_WORD(state->code_current); - info->ms = SPVM_READ_WORD(state->code_current); - info->sampled = SPVM_READ_WORD(state->code_current); - info->format = SPVM_READ_WORD(state->code_current); - - if (word_count > 8) - info->access = SPVM_READ_WORD(state->code_current); -} -void spvm_setup_OpTypeSampler(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - state->results[id].type = spvm_result_type_type; - state->results[id].value_type = spvm_value_type_sampler; - state->results[id].pointer = SPVM_READ_WORD(state->code_current); - state->results[id].member_count = 1; -} -void spvm_setup_OpTypeSampledImage(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_type; - state->results[id].value_type = spvm_value_type_sampled_image; - state->results[id].pointer = SPVM_READ_WORD(state->code_current); // image type - state->results[id].member_count = 2; -} -void spvm_setup_OpTypeArray(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_array; - - state->results[store_id].pointer = SPVM_READ_WORD(state->code_current); - state->results[store_id].member_count = state->results[SPVM_READ_WORD(state->code_current)].members[0].value.s; - - // we can land here e.g. if somehow the value wasn't initialized correctly - assert(state->results[store_id].member_count > 0); -} -void spvm_setup_OpTypeRuntimeArray(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_runtime_array; - - state->results[store_id].pointer = SPVM_READ_WORD(state->code_current); -} -void spvm_setup_OpTypeStruct(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word mcnt = word_count - 1; - state->results[id].type = spvm_result_type_type; - state->results[id].value_type = spvm_value_type_struct; - state->results[id].member_count = mcnt; - - state->results[id].params = (spvm_word*)malloc(sizeof(spvm_word) * mcnt); - for (spvm_word i = 0; i < mcnt; i++) - state->results[id].params[i] = SPVM_READ_WORD(state->code_current); -} -void spvm_setup_OpTypePointer(spvm_word word_count, spvm_state_t state) -{ - spvm_word store_id = SPVM_READ_WORD(state->code_current); - - state->results[store_id].type = spvm_result_type_type; - state->results[store_id].value_type = spvm_value_type_pointer; - state->results[store_id].storage_class = SPVM_READ_WORD(state->code_current); - state->results[store_id].pointer = SPVM_READ_WORD(state->code_current); -} -void spvm_setup_OpTypeFunction(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word return_id = SPVM_READ_WORD(state->code_current); - spvm_word param_count = word_count - 2; - - state->results[id].type = spvm_result_type_function_type; - state->results[id].pointer = return_id; - state->results[id].member_count = param_count; - state->results[id].params = (spvm_word*)malloc(param_count * sizeof(spvm_word)); - - for (spvm_word i = 0; i < param_count; i++) - state->results[id].params[i] = SPVM_READ_WORD(state->code_current); -} - -/* 3.32.7 Constant-Creation Instructions */ -void spvm_setup_OpConstantTrue(spvm_word word_count, spvm_state_t state) -{ - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, var_type); - state->results[id].source_location = state->code_current; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = 1; -} -void spvm_setup_OpConstantFalse(spvm_word word_count, spvm_state_t state) -{ - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, var_type); - state->results[id].source_location = state->code_current; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) - state->results[id].members[i].value.b = 0; -} -void spvm_setup_OpConstantNull(spvm_word word_count, spvm_state_t state) -{ - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, var_type); - state->results[id].source_location = state->code_current; -} -void spvm_setup_OpConstant(spvm_word word_count, spvm_state_t state) -{ - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, var_type); - state->results[id].source_location = state->code_current; - - state->results[id].members[0].value.u = SPVM_READ_WORD(state->code_current); - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[var_type]); - if (type_info->value_bitcount > 32) { - unsigned long long highBits = SPVM_READ_WORD(state->code_current); - state->results[id].members[0].value.u |= highBits << 32ull; - } -} -void spvm_setup_OpConstantComposite(spvm_word word_count, spvm_state_t state) -{ - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, var_type); - state->results[id].source_location = state->code_current; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - spvm_word index = SPVM_READ_WORD(state->code_current); - - if (state->results[id].members[i].member_count == 0) - state->results[id].members[i].value.s = state->results[index].members[0].value.s; - else - spvm_member_memcpy(&state->results[id].members[i].members[0], &state->results[index].members[0], state->results[index].member_count); - } -} -void spvm_setup_OpSpecConstantOp(spvm_word word_count, spvm_state_t state) { - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word opcode = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, var_type); - state->results[id].source_location = state->code_current; - - // we just call the function with the respective opcode directly - if(opcode >= SPVM_OPCODE_TABLE_LENGTH) { - spvm_state_log(state, "opcode for SpecConstantOp out of range: %d", (int) opcode); - } else if(!state->context->opcode_execute[opcode]) { - spvm_state_log(state, "null opcode for SpecConstantOp in : %d", (int) opcode); - } else { - // TODO: assert on opcode structure using SpvHasResultAndType - // XXX: msvc doesn't support vla - // spvm_word buffer[word_count - 1]; - assert(word_count < 100); - spvm_word buffer[100]; - - buffer[0] = var_type; - buffer[1] = id; - // copy the operands - memcpy(buffer + 2, state->code_current, word_count - 3); - - spvm_source saved = state->code_current; - state->code_current = buffer; - - state->context->opcode_execute[opcode](word_count - 1, state); - - state->code_current = saved; - } -} - -/* 3.32.8 Memory Instructions */ -void spvm_setup_OpVariable(spvm_word word_count, spvm_state_t state) -{ - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word storage_class = SPVM_READ_WORD(state->code_current); - spvm_word initializer = -1; - - if (word_count >= 4) { - initializer = SPVM_READ_WORD(state->code_current); - } - - spvm_result* var = &state->results[id]; - - var->type = spvm_result_type_variable; - var->storage_class = storage_class; - var->owner = state->current_function; - var->pointer = var_type; - - if(!state->load_variable || !state->store_variable || - !spvm_use_access_callback(var->type, var->storage_class)) { - spvm_result_allocate_typed_value(var, state->results, var_type); - state->results[id].source_location = state->code_current; - - if (initializer != -1) - spvm_member_memcpy(state->results[id].members, state->results[initializer].members, state->results[id].member_count); - - if (state->owner->allocate_workgroup_memory && storage_class == SpvStorageClassWorkgroup) - state->owner->allocate_workgroup_memory(state, id, var_type); - } -} -void spvm_setup_OpLoad(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word ptr_id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, res_type); - state->results[id].source_location = state->code_current; -} -void spvm_setup_OpAccessChain(spvm_word word_count, spvm_state_t state) -{ - spvm_source source_pointer = state->code_current; - - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - spvm_word value_id = SPVM_READ_WORD(state->code_current); - - spvm_result* dst = &state->results[id]; - dst->type = spvm_result_type_access_chain; - dst->pointer = var_type; - dst->storage_class = state->results[value_id].storage_class; - dst->source_location = source_pointer; - dst->source_word_count = word_count; - dst->access_chain_ref = value_id; - - spvm_result* src = &state->results[value_id]; - - if(state->load_variable && state->store_variable && - spvm_use_access_callback(src->type, src->storage_class)) { - - if(src->type == spvm_result_type_variable) { - dst->index_count = word_count - 3; - dst->indices = calloc(dst->index_count, sizeof(spvm_word)); - } else if(src->type == spvm_result_type_access_chain) { - dst->access_chain_ref = src->access_chain_ref; - - spvm_word local_index_count = word_count - 3; - dst->index_count = local_index_count + src->index_count; - dst->indices = calloc(dst->index_count, sizeof(spvm_word)); - } else { - assert(!"Unimplemented"); - } - } -} -void spvm_setup_OpFunction(spvm_word word_count, spvm_state_t state) -{ - spvm_word ret_type = SPVM_READ_WORD(state->code_current); - spvm_word store_id = SPVM_READ_WORD(state->code_current); - - state->results[store_id].type = spvm_result_type_function; - state->results[store_id].return_type = ret_type; - - SPVM_SKIP_WORD(state->code_current); // skip function control - - spvm_word info = state->results[store_id].pointer = SPVM_READ_WORD(state->code_current); - - state->results[store_id].source_location = state->code_current; - state->results[info].source_location = state->code_current; - - state->current_parameter = 0; - state->results[store_id].member_count = state->results[info].member_count; - state->results[store_id].params = (spvm_word*)calloc(state->results[store_id].member_count, sizeof(spvm_word)); - - state->current_function = &state->results[store_id]; -} -void spvm_setup_OpFunctionParameter(spvm_word word_count, spvm_state_t state) -{ - spvm_word var_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_function_parameter; - state->current_function->params[state->current_parameter] = id; - state->current_parameter++; - - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[var_type]); - - state->results[id].pointer = var_type; - state->results[id].member_count = type_info->member_count; - state->results[id].owner = state->current_function; - state->results[id].storage_class = state->results[var_type].storage_class; -} -void spvm_setup_OpFunctionEnd(spvm_word word_count, spvm_state_t state) -{ - state->current_function = NULL; -} -void spvm_setup_OpFunctionCall(spvm_word word_count, spvm_state_t state) -{ - spvm_word ret_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, ret_type); - state->results[id].source_location = state->code_current; -} - -/* 3.32.11 Conversion Instructions */ -/* 3.32.13 Arithmetic Instructions */ -/* 3.32.14 Bit Instructions */ -void spvm_setup_constant(spvm_word word_count, spvm_state_t state) -{ - spvm_word res_type = SPVM_READ_WORD(state->code_current); - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_constant; - spvm_result_allocate_typed_value(&state->results[id], state->results, res_type); - state->results[id].source_location = state->code_current; -} - -/* 3.32.16 Derivative Instructions */ -void spvm_setup_derivative(spvm_word word_count, spvm_state_t state) -{ - spvm_setup_constant(word_count, state); - state->derivative_used = 1; -} - - -/* 3.32.17 Control-Flow Instructions */ -void spvm_setup_OpLabel(spvm_word word_count, spvm_state_t state) -{ - spvm_word id = SPVM_READ_WORD(state->code_current); - - state->results[id].type = spvm_result_type_label; - state->results[id].source_location = state->code_current - 2; // store original label location (instruction has length 2) -} - - -/* 3.32.18 Atomic Instructions */ - -void _spvm_context_create_setup_table(spvm_context_t ctx) -{ - ctx->opcode_setup = (spvm_opcode_func*)calloc(SPVM_OPCODE_TABLE_LENGTH, sizeof(spvm_opcode_func)); - - ctx->opcode_setup[SpvOpSource] = spvm_setup_OpSource; - ctx->opcode_setup[SpvOpSourceExtension] = spvm_setup_OpSourceExtension; - ctx->opcode_setup[SpvOpName] = spvm_setup_OpName; - ctx->opcode_setup[SpvOpMemberName] = spvm_setup_OpMemberName; - ctx->opcode_setup[SpvOpString] = spvm_setup_OpString; - - ctx->opcode_setup[SpvOpDecorate] = spvm_setup_OpDecorate; - ctx->opcode_setup[SpvOpMemberDecorate] = spvm_setup_OpMemberDecorate; - - ctx->opcode_setup[SpvOpExtInstImport] = spvm_setup_OpExtInstImport; - ctx->opcode_setup[SpvOpExtInst] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpMemoryModel] = spvm_setup_OpMemoryModel; - ctx->opcode_setup[SpvOpEntryPoint] = spvm_setup_OpEntryPoint; - ctx->opcode_setup[SpvOpExecutionMode] = spvm_setup_OpExecutionMode; - ctx->opcode_setup[SpvOpCapability] = spvm_setup_OpCapability; - - ctx->opcode_setup[SpvOpTypeVoid] = spvm_setup_OpTypeVoid; - ctx->opcode_setup[SpvOpTypeBool] = spvm_setup_OpTypeBool; - ctx->opcode_setup[SpvOpTypeInt] = spvm_setup_OpTypeInt; - ctx->opcode_setup[SpvOpTypeFloat] = spvm_setup_OpTypeFloat; - ctx->opcode_setup[SpvOpTypeVector] = spvm_setup_OpTypeVector; - ctx->opcode_setup[SpvOpTypeMatrix] = spvm_setup_OpTypeMatrix; - ctx->opcode_setup[SpvOpTypeImage] = spvm_setup_OpTypeImage; - ctx->opcode_setup[SpvOpTypeSampler] = spvm_setup_OpTypeSampler; - ctx->opcode_setup[SpvOpTypeSampledImage] = spvm_setup_OpTypeSampledImage; - ctx->opcode_setup[SpvOpTypeArray] = spvm_setup_OpTypeArray; - ctx->opcode_setup[SpvOpTypeRuntimeArray] = spvm_setup_OpTypeRuntimeArray; - ctx->opcode_setup[SpvOpTypeStruct] = spvm_setup_OpTypeStruct; - ctx->opcode_setup[SpvOpTypePointer] = spvm_setup_OpTypePointer; - ctx->opcode_setup[SpvOpTypeFunction] = spvm_setup_OpTypeFunction; - - ctx->opcode_setup[SpvOpConstantTrue] = spvm_setup_OpConstantTrue; - ctx->opcode_setup[SpvOpConstantFalse] = spvm_setup_OpConstantFalse; - ctx->opcode_setup[SpvOpConstantNull] = spvm_setup_OpConstantNull; - ctx->opcode_setup[SpvOpConstant] = spvm_setup_OpConstant; - ctx->opcode_setup[SpvOpConstantComposite] = spvm_setup_OpConstantComposite; - - // spec constants instructions have the same anatomy as constant ones - ctx->opcode_setup[SpvOpSpecConstantTrue] = spvm_setup_OpConstantTrue; - ctx->opcode_setup[SpvOpSpecConstantFalse] = spvm_setup_OpConstantFalse; - ctx->opcode_setup[SpvOpSpecConstant] = spvm_setup_OpConstant; - ctx->opcode_setup[SpvOpSpecConstantComposite] = spvm_setup_OpConstantComposite; - ctx->opcode_setup[SpvOpSpecConstantOp] = spvm_setup_OpSpecConstantOp; - - ctx->opcode_setup[SpvOpVariable] = spvm_setup_OpVariable; - ctx->opcode_setup[SpvOpLoad] = spvm_setup_OpLoad; - ctx->opcode_setup[SpvOpAccessChain] = spvm_setup_OpAccessChain; - ctx->opcode_setup[SpvOpFunction] = spvm_setup_OpFunction; - ctx->opcode_setup[SpvOpFunctionParameter] = spvm_setup_OpFunctionParameter; - ctx->opcode_setup[SpvOpFunctionEnd] = spvm_setup_OpFunctionEnd; - ctx->opcode_setup[SpvOpFunctionCall] = spvm_setup_OpFunctionCall; - ctx->opcode_setup[SpvOpPtrEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpPtrNotEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpArrayLength] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpConvertFToU] = spvm_setup_constant; - ctx->opcode_setup[SpvOpConvertFToS] = spvm_setup_constant; - ctx->opcode_setup[SpvOpConvertUToF] = spvm_setup_constant; - ctx->opcode_setup[SpvOpConvertSToF] = spvm_setup_constant; - ctx->opcode_setup[SpvOpUConvert] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSConvert] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFConvert] = spvm_setup_constant; - ctx->opcode_setup[SpvOpQuantizeToF16] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitcast] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpVectorExtractDynamic] = spvm_setup_constant; - ctx->opcode_setup[SpvOpVectorInsertDynamic] = spvm_setup_constant; - ctx->opcode_setup[SpvOpVectorShuffle] = spvm_setup_constant; - ctx->opcode_setup[SpvOpCompositeConstruct] = spvm_setup_constant; - ctx->opcode_setup[SpvOpCompositeExtract] = spvm_setup_constant; - ctx->opcode_setup[SpvOpCompositeInsert] = spvm_setup_constant; - ctx->opcode_setup[SpvOpCopyObject] = spvm_setup_constant; - ctx->opcode_setup[SpvOpTranspose] = spvm_setup_constant; - ctx->opcode_setup[SpvOpCopyLogical] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpSNegate] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFNegate] = spvm_setup_constant; - ctx->opcode_setup[SpvOpIAdd] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFAdd] = spvm_setup_constant; - ctx->opcode_setup[SpvOpISub] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFSub] = spvm_setup_constant; - ctx->opcode_setup[SpvOpIMul] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFMul] = spvm_setup_constant; - ctx->opcode_setup[SpvOpUDiv] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSDiv] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFDiv] = spvm_setup_constant; - ctx->opcode_setup[SpvOpUMod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSRem] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSMod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFRem] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFMod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpVectorTimesScalar] = spvm_setup_constant; - ctx->opcode_setup[SpvOpMatrixTimesScalar] = spvm_setup_constant; - ctx->opcode_setup[SpvOpVectorTimesMatrix] = spvm_setup_constant; - ctx->opcode_setup[SpvOpMatrixTimesVector] = spvm_setup_constant; - ctx->opcode_setup[SpvOpMatrixTimesMatrix] = spvm_setup_constant; - ctx->opcode_setup[SpvOpOuterProduct] = spvm_setup_constant; - ctx->opcode_setup[SpvOpDot] = spvm_setup_constant; - ctx->opcode_setup[SpvOpIAddCarry] = spvm_setup_constant; - ctx->opcode_setup[SpvOpISubBorrow] = spvm_setup_constant; - ctx->opcode_setup[SpvOpUMulExtended] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSMulExtended] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpShiftRightLogical] = spvm_setup_constant; - ctx->opcode_setup[SpvOpShiftRightArithmetic] = spvm_setup_constant; - ctx->opcode_setup[SpvOpShiftLeftLogical] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitwiseOr] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitwiseAnd] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitwiseXor] = spvm_setup_constant; - ctx->opcode_setup[SpvOpNot] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitFieldInsert] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitFieldSExtract] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitFieldUExtract] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitReverse] = spvm_setup_constant; - ctx->opcode_setup[SpvOpBitCount] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpAny] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAll] = spvm_setup_constant; - ctx->opcode_setup[SpvOpIsNan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpIsInf] = spvm_setup_constant; - ctx->opcode_setup[SpvOpLogicalEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpLogicalNotEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpLogicalAnd] = spvm_setup_constant; - ctx->opcode_setup[SpvOpLogicalOr] = spvm_setup_constant; - ctx->opcode_setup[SpvOpLogicalNot] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSelect] = spvm_setup_constant; - ctx->opcode_setup[SpvOpIEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpINotEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpUGreaterThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSGreaterThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpUGreaterThanEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSGreaterThanEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpULessThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSLessThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpULessThanEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpSLessThanEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFOrdEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFOrdNotEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFOrdLessThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFOrdGreaterThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFOrdLessThanEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFOrdGreaterThanEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFUnordEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFUnordNotEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFUnordLessThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFUnordGreaterThan] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFUnordLessThanEqual] = spvm_setup_constant; - ctx->opcode_setup[SpvOpFUnordGreaterThanEqual] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpSampledImage] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageFetch] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageGather] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageQuerySize] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleDrefImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleDrefExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleProjImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleProjExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleProjDrefImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSampleProjDrefExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageDrefGather] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageRead] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImage] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageQueryFormat] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageQueryOrder] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageQuerySizeLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageQueryLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageQueryLevels] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageQuerySamples] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleDrefImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleDrefExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleProjImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleProjExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleProjDrefImplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseSampleProjDrefExplicitLod] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseFetch] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseGather] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseDrefGather] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseTexelsResident] = spvm_setup_constant; - ctx->opcode_setup[SpvOpImageSparseRead] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpDPdx] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpDPdy] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpDPdxFine] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpDPdyFine] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpDPdxCoarse] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpDPdyCoarse] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpFwidth] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpFwidthFine] = spvm_setup_derivative; - ctx->opcode_setup[SpvOpFwidthCoarse] = spvm_setup_derivative; - - ctx->opcode_setup[SpvOpLabel] = spvm_setup_OpLabel; - ctx->opcode_setup[SpvOpPhi] = spvm_setup_constant; - - ctx->opcode_setup[SpvOpAtomicLoad] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicExchange] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicCompareExchange] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicIIncrement] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicIDecrement] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicIAdd] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicISub] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicSMin] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicUMin] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicSMax] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicUMax] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicAnd] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicOr] = spvm_setup_constant; - ctx->opcode_setup[SpvOpAtomicXor] = spvm_setup_constant; -} diff --git a/src/spvm/program.c b/src/spvm/program.c deleted file mode 100644 index e255a545..00000000 --- a/src/spvm/program.c +++ /dev/null @@ -1,84 +0,0 @@ -#include - - -spvm_program_t spvm_program_create(spvm_context_t ctx, spvm_source spv, size_t spv_length) -{ - spvm_word magic = SPVM_READ_WORD(spv); - if (magic != (spvm_word)SpvMagicNumber) - return NULL; - - spvm_program_t prog = (spvm_program_t)calloc(1, sizeof(spvm_program)); - - prog->context = ctx; - - spvm_word version = SPVM_READ_WORD(spv); - prog->major_version = (version & 0x00FF0000) >> 16; - prog->minor_version = (version & 0x0000FF00) >> 8; - - spvm_word generator = SPVM_READ_WORD(spv); - prog->generator_id = (generator & 0xFFFF0000) >> 16; - prog->generator_version = (generator & 0x0000FFFF); - - prog->bound = SPVM_READ_WORD(spv); - - SPVM_SKIP_WORD(spv); // skip [4] -> 0 - - prog->code_length = spv_length - 5; - prog->code = spv; - - prog->local_size_x = 1; - prog->local_size_y = 1; - prog->local_size_z = 1; - - prog->geometry_invocations = 1; - prog->geometry_output_count = 1; - prog->geometry_input = SpvExecutionModeInputPoints; - prog->geometry_output = SpvExecutionModeOutputPoints; - - return prog; -} -spvm_string spvm_program_add_extension(spvm_program_t prog, spvm_word length) -{ - prog->extension_count++; - prog->extensions = (spvm_string*)realloc(prog->extensions, prog->extension_count * sizeof(spvm_string)); - return (prog->extensions[prog->extension_count - 1] = (spvm_string)malloc(length * sizeof(spvm_word) + 1)); -} -spvm_entry_point* spvm_program_create_entry_point(spvm_program_t prog) -{ - prog->entry_point_count++; - prog->entry_points = (spvm_entry_point*)realloc(prog->entry_points, prog->entry_point_count * sizeof(spvm_entry_point)); - return &prog->entry_points[prog->entry_point_count - 1]; -} -void spvm_program_add_capability(spvm_program_t prog, SpvCapability cap) -{ - prog->capability_count++; - prog->capabilities = (SpvCapability*)realloc(prog->capabilities, prog->capability_count * sizeof(SpvCapability)); - prog->capabilities[prog->capability_count - 1] = cap; -} -void spvm_program_delete(spvm_program_t prog) -{ - if (prog == NULL) return; - - // entry points - for (spvm_word i = 0; i < prog->entry_point_count; i++) { - if (prog->entry_points[i].globals_count > 0) - free(prog->entry_points[i].globals); - free(prog->entry_points[i].name); - } - if (prog->entry_point_count) - free(prog->entry_points); - - // extensions - for (spvm_word i = 0; i < prog->extension_count; i++) - free(prog->extensions[i]); - if (prog->extension_count) - free(prog->extensions); - - // capabilities - if (prog->capability_count) - free(prog->capabilities); - - // files - free(prog->files); - free(prog); -} diff --git a/src/spvm/program.h b/src/spvm/program.h deleted file mode 100644 index 47354e6e..00000000 --- a/src/spvm/program.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef __SPIRV_VM_PROGRAM_H__ -#define __SPIRV_VM_PROGRAM_H__ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -typedef struct -{ - SpvExecutionModel exec_model; - spvm_word id; - spvm_string name; - spvm_word globals_count; - spvm_word* globals; // interface -} spvm_entry_point; - -typedef struct -{ - spvm_source origin; // OpSource instruction that created this spvm_file - const char* name; // points to OpString result - SpvSourceLanguage language; - spvm_word language_version; - spvm_string source; -} spvm_file; - -typedef struct { - spvm_context_t context; - - spvm_byte major_version; - spvm_byte minor_version; - - spvm_word generator_id; - spvm_word generator_version; - - size_t file_count; - spvm_file* files; - - unsigned bound; - - size_t code_length; - spvm_source code; - - spvm_word extension_count; - spvm_string* extensions; - - spvm_word import_count; - spvm_string* imports; - - spvm_word capability_count; - SpvCapability* capabilities; - - SpvAddressingModel addressing; - SpvMemoryModel memory_model; - - spvm_word entry_point_count; - spvm_entry_point* entry_points; - - spvm_word local_size_x; - spvm_word local_size_y; - spvm_word local_size_z; - - spvm_word geometry_invocations; - spvm_word geometry_output_count; - spvm_word geometry_input; - spvm_word geometry_output; - - void(*allocate_workgroup_memory)(struct spvm_state*, spvm_word, spvm_word); - void(*write_workgroup_memory)(struct spvm_state*, spvm_word, spvm_word); - void(*atomic_operation)(spvm_word, spvm_word, struct spvm_state*); - - void* user_data; -} spvm_program; -typedef spvm_program* spvm_program_t; - -spvm_program_t spvm_program_create(spvm_context_t ctx, spvm_source spv, size_t spv_length); -spvm_string spvm_program_add_extension(spvm_program_t prog, spvm_word length); -spvm_entry_point* spvm_program_create_entry_point(spvm_program_t prog); -void spvm_program_add_capability(spvm_program_t prog, SpvCapability cap); -void spvm_program_delete(spvm_program_t prog); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SPIRV_VM_PROGRAM_H__ diff --git a/src/spvm/result.c b/src/spvm/result.c deleted file mode 100644 index 8dcce5db..00000000 --- a/src/spvm/result.c +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include -#include - -void spvm_decoration_read(spvm_source src, SpvDecoration decor, spvm_word* literal1, spvm_word* literal2) -{ - switch (decor) { - case SpvDecorationSpecId: - case SpvDecorationArrayStride: - case SpvDecorationMatrixStride: - case SpvDecorationBuiltIn: - case SpvDecorationUniformId: - case SpvDecorationStream: - case SpvDecorationLocation: - case SpvDecorationComponent: - case SpvDecorationIndex: - case SpvDecorationBinding: - case SpvDecorationDescriptorSet: - case SpvDecorationOffset: - case SpvDecorationXfbBuffer: - case SpvDecorationXfbStride: - case SpvDecorationFuncParamAttr: - case SpvDecorationFPRoundingMode: - case SpvDecorationFPFastMathMode: - case SpvDecorationInputAttachmentIndex: - case SpvDecorationAlignment: - case SpvDecorationMaxByteOffset: - case SpvDecorationAlignmentId: - case SpvDecorationMaxByteOffsetId: - case SpvDecorationSecondaryViewportRelativeNV: - case SpvDecorationCounterBuffer: - case SpvDecorationUserSemantic: - case SpvDecorationUserTypeGOOGLE: - *literal1 = SPVM_READ_WORD(src); - break; - - case SpvDecorationLinkageAttributes: - *literal1 = SPVM_READ_WORD(src); - *literal2 = SPVM_READ_WORD(src); - break; - - default: break; - } -} -void spvm_result_add_member_decoration(spvm_result_t result, SpvDecoration decor, spvm_word literal1, spvm_word literal2, spvm_word index) -{ - result->decoration_count++; - result->decorations = (spvm_decoration*)realloc(result->decorations, result->decoration_count * sizeof(spvm_decoration)); - - spvm_decoration* d = &result->decorations[result->decoration_count - 1]; - d->index = index; - d->type = decor; - d->literal1 = literal1; - d->literal2 = literal2; -} -void spvm_result_add_decoration(spvm_result_t result, SpvDecoration decor, spvm_word literal1, spvm_word literal2) -{ - spvm_result_add_member_decoration(result, decor, literal1, literal2, 0); -} - - -void spvm_member_allocate_value(spvm_member_t val, spvm_word count) -{ - val->member_count = count; - val->members = (spvm_member_t)calloc(count, sizeof(spvm_member)); -} -void spvm_member_allocate_typed_value(spvm_member_t val, spvm_result* results, spvm_word type) -{ - spvm_result_t type_info = spvm_state_get_type_info(results, &results[type]); - - if (type_info->value_type == spvm_value_type_void || - type_info->value_type == spvm_value_type_int || - type_info->value_type == spvm_value_type_float || - type_info->value_type == spvm_value_type_bool) { - assert(type_info->member_count == 1u); // should be 0 really - } else { - spvm_member_allocate_value(val, type_info->member_count); - } - - val->type = type; - assert(type != 0); - - if (type_info->value_type == spvm_value_type_struct) { - for (spvm_word i = 0; i < val->member_count; i++) { - spvm_member_allocate_typed_value(&val->members[i], results, type_info->params[i]); - } - } - else if (type_info->value_type == spvm_value_type_matrix) { - for (spvm_word i = 0; i < val->member_count; i++) - spvm_member_allocate_typed_value(&val->members[i], results, type_info->pointer); - } - else if (type_info->value_type == spvm_value_type_array) { - if (results[type_info->pointer].member_count > 0) - for (spvm_word i = 0; i < val->member_count; i++) - spvm_member_allocate_typed_value(&val->members[i], results, type_info->pointer); - } else if (type_info->value_type == spvm_value_type_vector) { - for (spvm_word i = 0; i < val->member_count; ++i) - val->members[i].type = type_info->pointer; - } else { - assert(type_info->value_type != spvm_value_type_sampled_image); - assert(type_info->value_type != spvm_value_type_image); - assert(type_info->value_type != spvm_value_type_sampler); - } -} -void spvm_result_allocate_value(spvm_result_t val, spvm_word count) -{ - val->member_count = count; - val->members = (spvm_member_t)calloc(count, sizeof(spvm_member)); -} -void spvm_result_allocate_typed_value(spvm_result_t val, spvm_result* results, spvm_word type) -{ - spvm_result_t type_info = spvm_state_get_type_info(results, &results[type]); - - spvm_result_allocate_value(val, type_info->member_count); - val->pointer = type; - assert(type != 0); - - if (type_info->value_type == spvm_value_type_struct) { - for (spvm_word i = 0; i < val->member_count; i++) - spvm_member_allocate_typed_value(&val->members[i], results, type_info->params[i]); - } else if (type_info->value_type == spvm_value_type_matrix) { - for (spvm_word i = 0; i < val->member_count; i++) - spvm_member_allocate_typed_value(&val->members[i], results, type_info->pointer); - } else if (type_info->value_type == spvm_value_type_array) { - if (results[type_info->pointer].member_count > 0) - for (spvm_word i = 0; i < val->member_count; i++) - spvm_member_allocate_typed_value(&val->members[i], results, type_info->pointer); - } else if (type_info->value_type == spvm_value_type_vector) { - for (spvm_word i = 0; i < val->member_count; ++i) - val->members[i].type = type_info->pointer; - } else if(type_info->value_type == spvm_value_type_sampled_image) { - val->members[0].type = type_info->pointer; - val->members[1].type = (spvm_word) -1; // we don't care about the OpTypeSampler used - } else if(type_info->value_type == spvm_value_type_image) { - val->members[0].type = type; - } else if(type_info->value_type == spvm_value_type_sampler) { - // no-op, we don't care about OpTypeSampler - } else if(type_info->value_type == spvm_value_type_float || - type_info->value_type == spvm_value_type_int || - type_info->value_type == spvm_value_type_bool) { - - assert(val->member_count == 1u); - val->members[0].type = type; - } -} -void spvm_result_delete(spvm_result_t res) -{ - // member names - for (spvm_word j = 0; j < res->member_name_count; j++) - free(res->member_name[j]); - if (res->member_name_count) - free(res->member_name); - - // member/parameter types - if (res->value_type == spvm_value_type_struct || res->type == spvm_result_type_function_type) - free(res->params); - - // decorations - if (res->decoration_count) - free(res->decorations); - - // image info - if (res->image_info) - free(res->image_info); - - if (res->indices) - free(res->indices); - - // constants - if (res->type == spvm_result_type_constant || res->type == spvm_result_type_variable) - spvm_member_free(res->members, res->member_count); -} - -spvm_word spvm_result_calculate_size(spvm_result_t results, spvm_word type) -{ - spvm_word ret = 0; - spvm_result_t slot = &results[type]; - - if (slot->value_type == spvm_value_type_vector || slot->value_type == spvm_value_type_matrix || slot->value_type == spvm_value_type_array || slot->value_type == spvm_value_type_runtime_array) - ret += slot->member_count * spvm_result_calculate_size(results, slot->pointer); - else if (slot->value_type == spvm_value_type_float || slot->value_type == spvm_value_type_int || slot->value_type == spvm_value_type_bool) - ret++; - else if (slot->value_type == spvm_value_type_struct) { - for (spvm_word i = 0; i < slot->member_count; i++) - ret += spvm_result_calculate_size(results, slot->params[i]); - } - // TODO: slot->params[0]; - - return ret; -} -void spvm_member_recursive_fill(spvm_result_t results, float* data, spvm_member_t values, spvm_word value_count, spvm_word element_type, spvm_word* offset) -{ - spvm_result_t type_info = &results[element_type]; - for (spvm_word i = 0; i < value_count; i++) { - if (values[i].member_count != 0) - spvm_member_recursive_fill(results, data, values[i].members, values[i].member_count, type_info->pointer, offset); - else { - values[i].value.f = *(data + *offset); - (*offset)++; - } - } -} - diff --git a/src/spvm/result.h b/src/spvm/result.h deleted file mode 100644 index 4e85a2b9..00000000 --- a/src/spvm/result.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef __SPIRV_VM_RESULT_H__ -#define __SPIRV_VM_RESULT_H__ - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include -#include -#include -#include - -enum spvm_result_type { - spvm_result_type_none, - spvm_result_type_string, - spvm_result_type_extension, - spvm_result_type_function_type, - spvm_result_type_type, - spvm_result_type_variable, - spvm_result_type_constant, - spvm_result_type_function, - spvm_result_type_access_chain, - spvm_result_type_function_parameter, - spvm_result_type_label -}; - -typedef struct spvm_image_info { - SpvDim dim; - spvm_byte depth; - spvm_byte arrayed; - spvm_byte ms; - spvm_byte sampled; - SpvImageFormat format; - SpvAccessQualifier access; -} spvm_image_info; - -typedef struct spvm_decoration { - SpvDecoration type; - spvm_word literal1, literal2; - spvm_word index; // member -} spvm_decoration; - -typedef struct spvm_result { - enum spvm_result_type type; - - const char* name; - spvm_word pointer; - SpvStorageClass storage_class; - struct spvm_result* owner; - char stored_to; // For OpVariable values - char was_loaded; - - spvm_word member_count; - spvm_member* members; - - spvm_word decoration_count; - spvm_decoration* decorations; - - /* spvm_result_type_function */ - spvm_word return_type; - - /* spvm_result_type_extension */ - spvm_word extension_name; // index in the spvm_program::imports - spvm_ext_opcode_func* extension; - - /* spvm_result_type_function_type / spvm_result_type_type (structure) / spvm_result_type_function */ - spvm_word* params; - - /* function, label & access chain */ - spvm_source source_location; - - /* spvm_result_type_access_chain*/ - /* word count when a opcode uses source_location (OpAccessChain) */ - spvm_word source_word_count; - spvm_word access_chain_ref; - spvm_word index_count; - spvm_word* indices; - - /* op type */ - enum spvm_value_type value_type; - spvm_word value_bitcount; - char value_sign; - spvm_image_info* image_info; - - spvm_word member_name_count; - spvm_string* member_name; -} spvm_result; -typedef spvm_result* spvm_result_t; - - -void spvm_decoration_read(spvm_source src, SpvDecoration decor, spvm_word* literal1, spvm_word* literal2); -void spvm_result_add_decoration(spvm_result_t result, SpvDecoration decor, spvm_word literal1, spvm_word literal2); -void spvm_result_add_member_decoration(spvm_result_t result, SpvDecoration decor, spvm_word literal1, spvm_word literal2, spvm_word index); -void spvm_result_allocate_value(spvm_result_t val, spvm_word count); -void spvm_result_allocate_typed_value(spvm_result_t val, spvm_result* results, spvm_word type); -void spvm_result_delete(spvm_result_t val); - -void spvm_member_allocate_value(spvm_member_t val, spvm_word count); -void spvm_member_allocate_typed_value(spvm_member_t val, spvm_result* results, spvm_word type); -spvm_word spvm_result_calculate_size(spvm_result_t results, spvm_word type); -void spvm_member_recursive_fill(spvm_result_t results, float* data, spvm_member_t values, spvm_word value_count, spvm_word element_type, spvm_word* offset); // offset is number of 4byte elements - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SPIRV_VM_RESULT_H__ diff --git a/src/spvm/spirv.h b/src/spvm/spirv.h deleted file mode 100644 index d5439886..00000000 --- a/src/spvm/spirv.h +++ /dev/null @@ -1,2568 +0,0 @@ -/* -** Copyright (c) 2014-2020 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and/or associated documentation files (the "Materials"), -** to deal in the Materials without restriction, including without limitation -** the rights to use, copy, modify, merge, publish, distribute, sublicense, -** and/or sell copies of the Materials, and to permit persons to whom the -** Materials are furnished to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in -** all copies or substantial portions of the Materials. -** -** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -** IN THE MATERIALS. -*/ - -/* -** This header is automatically generated by the same tool that creates -** the Binary Section of the SPIR-V specification. -*/ - -/* -** Enumeration tokens for SPIR-V, in various styles: -** C, C++, C++11, JSON, Lua, Python, C#, D, Beef -** -** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -** - C# will use enum classes in the Specification class located in the "Spv" namespace, -** e.g.: Spv.Specification.SourceLanguage.GLSL -** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL -** - Beef will use enum classes in the Specification class located in the "Spv" namespace, -** e.g.: Spv.Specification.SourceLanguage.GLSL -** -** Some tokens act like mask values, which can be OR'd together, -** while others are mutually exclusive. The mask-like ones have -** "Mask" in their name, and a parallel enum that has the shift -** amount (1 << x) for each corresponding enumerant. -*/ - -#ifndef spirv_H -#define spirv_H - -typedef unsigned int SpvId; - -#define SPV_VERSION 0x10600 -#define SPV_REVISION 1 - -static const unsigned int SpvMagicNumber = 0x07230203; -static const unsigned int SpvVersion = 0x00010600; -static const unsigned int SpvRevision = 1; -static const unsigned int SpvOpCodeMask = 0xffff; -static const unsigned int SpvWordCountShift = 16; - -typedef enum SpvSourceLanguage_ { - SpvSourceLanguageUnknown = 0, - SpvSourceLanguageESSL = 1, - SpvSourceLanguageGLSL = 2, - SpvSourceLanguageOpenCL_C = 3, - SpvSourceLanguageOpenCL_CPP = 4, - SpvSourceLanguageHLSL = 5, - SpvSourceLanguageCPP_for_OpenCL = 6, - SpvSourceLanguageSYCL = 7, - SpvSourceLanguageMax = 0x7fffffff, -} SpvSourceLanguage; - -typedef enum SpvExecutionModel_ { - SpvExecutionModelVertex = 0, - SpvExecutionModelTessellationControl = 1, - SpvExecutionModelTessellationEvaluation = 2, - SpvExecutionModelGeometry = 3, - SpvExecutionModelFragment = 4, - SpvExecutionModelGLCompute = 5, - SpvExecutionModelKernel = 6, - SpvExecutionModelTaskNV = 5267, - SpvExecutionModelMeshNV = 5268, - SpvExecutionModelRayGenerationKHR = 5313, - SpvExecutionModelRayGenerationNV = 5313, - SpvExecutionModelIntersectionKHR = 5314, - SpvExecutionModelIntersectionNV = 5314, - SpvExecutionModelAnyHitKHR = 5315, - SpvExecutionModelAnyHitNV = 5315, - SpvExecutionModelClosestHitKHR = 5316, - SpvExecutionModelClosestHitNV = 5316, - SpvExecutionModelMissKHR = 5317, - SpvExecutionModelMissNV = 5317, - SpvExecutionModelCallableKHR = 5318, - SpvExecutionModelCallableNV = 5318, - SpvExecutionModelTaskEXT = 5364, - SpvExecutionModelMeshEXT = 5365, - SpvExecutionModelMax = 0x7fffffff, -} SpvExecutionModel; - -typedef enum SpvAddressingModel_ { - SpvAddressingModelLogical = 0, - SpvAddressingModelPhysical32 = 1, - SpvAddressingModelPhysical64 = 2, - SpvAddressingModelPhysicalStorageBuffer64 = 5348, - SpvAddressingModelPhysicalStorageBuffer64EXT = 5348, - SpvAddressingModelMax = 0x7fffffff, -} SpvAddressingModel; - -typedef enum SpvMemoryModel_ { - SpvMemoryModelSimple = 0, - SpvMemoryModelGLSL450 = 1, - SpvMemoryModelOpenCL = 2, - SpvMemoryModelVulkan = 3, - SpvMemoryModelVulkanKHR = 3, - SpvMemoryModelMax = 0x7fffffff, -} SpvMemoryModel; - -typedef enum SpvExecutionMode_ { - SpvExecutionModeInvocations = 0, - SpvExecutionModeSpacingEqual = 1, - SpvExecutionModeSpacingFractionalEven = 2, - SpvExecutionModeSpacingFractionalOdd = 3, - SpvExecutionModeVertexOrderCw = 4, - SpvExecutionModeVertexOrderCcw = 5, - SpvExecutionModePixelCenterInteger = 6, - SpvExecutionModeOriginUpperLeft = 7, - SpvExecutionModeOriginLowerLeft = 8, - SpvExecutionModeEarlyFragmentTests = 9, - SpvExecutionModePointMode = 10, - SpvExecutionModeXfb = 11, - SpvExecutionModeDepthReplacing = 12, - SpvExecutionModeDepthGreater = 14, - SpvExecutionModeDepthLess = 15, - SpvExecutionModeDepthUnchanged = 16, - SpvExecutionModeLocalSize = 17, - SpvExecutionModeLocalSizeHint = 18, - SpvExecutionModeInputPoints = 19, - SpvExecutionModeInputLines = 20, - SpvExecutionModeInputLinesAdjacency = 21, - SpvExecutionModeTriangles = 22, - SpvExecutionModeInputTrianglesAdjacency = 23, - SpvExecutionModeQuads = 24, - SpvExecutionModeIsolines = 25, - SpvExecutionModeOutputVertices = 26, - SpvExecutionModeOutputPoints = 27, - SpvExecutionModeOutputLineStrip = 28, - SpvExecutionModeOutputTriangleStrip = 29, - SpvExecutionModeVecTypeHint = 30, - SpvExecutionModeContractionOff = 31, - SpvExecutionModeInitializer = 33, - SpvExecutionModeFinalizer = 34, - SpvExecutionModeSubgroupSize = 35, - SpvExecutionModeSubgroupsPerWorkgroup = 36, - SpvExecutionModeSubgroupsPerWorkgroupId = 37, - SpvExecutionModeLocalSizeId = 38, - SpvExecutionModeLocalSizeHintId = 39, - SpvExecutionModeSubgroupUniformControlFlowKHR = 4421, - SpvExecutionModePostDepthCoverage = 4446, - SpvExecutionModeDenormPreserve = 4459, - SpvExecutionModeDenormFlushToZero = 4460, - SpvExecutionModeSignedZeroInfNanPreserve = 4461, - SpvExecutionModeRoundingModeRTE = 4462, - SpvExecutionModeRoundingModeRTZ = 4463, - SpvExecutionModeEarlyAndLateFragmentTestsAMD = 5017, - SpvExecutionModeStencilRefReplacingEXT = 5027, - SpvExecutionModeStencilRefUnchangedFrontAMD = 5079, - SpvExecutionModeStencilRefGreaterFrontAMD = 5080, - SpvExecutionModeStencilRefLessFrontAMD = 5081, - SpvExecutionModeStencilRefUnchangedBackAMD = 5082, - SpvExecutionModeStencilRefGreaterBackAMD = 5083, - SpvExecutionModeStencilRefLessBackAMD = 5084, - SpvExecutionModeOutputLinesEXT = 5269, - SpvExecutionModeOutputLinesNV = 5269, - SpvExecutionModeOutputPrimitivesEXT = 5270, - SpvExecutionModeOutputPrimitivesNV = 5270, - SpvExecutionModeDerivativeGroupQuadsNV = 5289, - SpvExecutionModeDerivativeGroupLinearNV = 5290, - SpvExecutionModeOutputTrianglesEXT = 5298, - SpvExecutionModeOutputTrianglesNV = 5298, - SpvExecutionModePixelInterlockOrderedEXT = 5366, - SpvExecutionModePixelInterlockUnorderedEXT = 5367, - SpvExecutionModeSampleInterlockOrderedEXT = 5368, - SpvExecutionModeSampleInterlockUnorderedEXT = 5369, - SpvExecutionModeShadingRateInterlockOrderedEXT = 5370, - SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371, - SpvExecutionModeSharedLocalMemorySizeINTEL = 5618, - SpvExecutionModeRoundingModeRTPINTEL = 5620, - SpvExecutionModeRoundingModeRTNINTEL = 5621, - SpvExecutionModeFloatingPointModeALTINTEL = 5622, - SpvExecutionModeFloatingPointModeIEEEINTEL = 5623, - SpvExecutionModeMaxWorkgroupSizeINTEL = 5893, - SpvExecutionModeMaxWorkDimINTEL = 5894, - SpvExecutionModeNoGlobalOffsetINTEL = 5895, - SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, - SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, - SpvExecutionModeNamedBarrierCountINTEL = 6417, - SpvExecutionModeMax = 0x7fffffff, -} SpvExecutionMode; - -typedef enum SpvStorageClass_ { - SpvStorageClassUniformConstant = 0, - SpvStorageClassInput = 1, - SpvStorageClassUniform = 2, - SpvStorageClassOutput = 3, - SpvStorageClassWorkgroup = 4, - SpvStorageClassCrossWorkgroup = 5, - SpvStorageClassPrivate = 6, - SpvStorageClassFunction = 7, - SpvStorageClassGeneric = 8, - SpvStorageClassPushConstant = 9, - SpvStorageClassAtomicCounter = 10, - SpvStorageClassImage = 11, - SpvStorageClassStorageBuffer = 12, - SpvStorageClassCallableDataKHR = 5328, - SpvStorageClassCallableDataNV = 5328, - SpvStorageClassIncomingCallableDataKHR = 5329, - SpvStorageClassIncomingCallableDataNV = 5329, - SpvStorageClassRayPayloadKHR = 5338, - SpvStorageClassRayPayloadNV = 5338, - SpvStorageClassHitAttributeKHR = 5339, - SpvStorageClassHitAttributeNV = 5339, - SpvStorageClassIncomingRayPayloadKHR = 5342, - SpvStorageClassIncomingRayPayloadNV = 5342, - SpvStorageClassShaderRecordBufferKHR = 5343, - SpvStorageClassShaderRecordBufferNV = 5343, - SpvStorageClassPhysicalStorageBuffer = 5349, - SpvStorageClassPhysicalStorageBufferEXT = 5349, - SpvStorageClassTaskPayloadWorkgroupEXT = 5402, - SpvStorageClassCodeSectionINTEL = 5605, - SpvStorageClassDeviceOnlyINTEL = 5936, - SpvStorageClassHostOnlyINTEL = 5937, - SpvStorageClassMax = 0x7fffffff, -} SpvStorageClass; - -typedef enum SpvDim_ { - SpvDim1D = 0, - SpvDim2D = 1, - SpvDim3D = 2, - SpvDimCube = 3, - SpvDimRect = 4, - SpvDimBuffer = 5, - SpvDimSubpassData = 6, - SpvDimMax = 0x7fffffff, -} SpvDim; - -typedef enum SpvSamplerAddressingMode_ { - SpvSamplerAddressingModeNone = 0, - SpvSamplerAddressingModeClampToEdge = 1, - SpvSamplerAddressingModeClamp = 2, - SpvSamplerAddressingModeRepeat = 3, - SpvSamplerAddressingModeRepeatMirrored = 4, - SpvSamplerAddressingModeMax = 0x7fffffff, -} SpvSamplerAddressingMode; - -typedef enum SpvSamplerFilterMode_ { - SpvSamplerFilterModeNearest = 0, - SpvSamplerFilterModeLinear = 1, - SpvSamplerFilterModeMax = 0x7fffffff, -} SpvSamplerFilterMode; - -typedef enum SpvImageFormat_ { - SpvImageFormatUnknown = 0, - SpvImageFormatRgba32f = 1, - SpvImageFormatRgba16f = 2, - SpvImageFormatR32f = 3, - SpvImageFormatRgba8 = 4, - SpvImageFormatRgba8Snorm = 5, - SpvImageFormatRg32f = 6, - SpvImageFormatRg16f = 7, - SpvImageFormatR11fG11fB10f = 8, - SpvImageFormatR16f = 9, - SpvImageFormatRgba16 = 10, - SpvImageFormatRgb10A2 = 11, - SpvImageFormatRg16 = 12, - SpvImageFormatRg8 = 13, - SpvImageFormatR16 = 14, - SpvImageFormatR8 = 15, - SpvImageFormatRgba16Snorm = 16, - SpvImageFormatRg16Snorm = 17, - SpvImageFormatRg8Snorm = 18, - SpvImageFormatR16Snorm = 19, - SpvImageFormatR8Snorm = 20, - SpvImageFormatRgba32i = 21, - SpvImageFormatRgba16i = 22, - SpvImageFormatRgba8i = 23, - SpvImageFormatR32i = 24, - SpvImageFormatRg32i = 25, - SpvImageFormatRg16i = 26, - SpvImageFormatRg8i = 27, - SpvImageFormatR16i = 28, - SpvImageFormatR8i = 29, - SpvImageFormatRgba32ui = 30, - SpvImageFormatRgba16ui = 31, - SpvImageFormatRgba8ui = 32, - SpvImageFormatR32ui = 33, - SpvImageFormatRgb10a2ui = 34, - SpvImageFormatRg32ui = 35, - SpvImageFormatRg16ui = 36, - SpvImageFormatRg8ui = 37, - SpvImageFormatR16ui = 38, - SpvImageFormatR8ui = 39, - SpvImageFormatR64ui = 40, - SpvImageFormatR64i = 41, - SpvImageFormatMax = 0x7fffffff, -} SpvImageFormat; - -typedef enum SpvImageChannelOrder_ { - SpvImageChannelOrderR = 0, - SpvImageChannelOrderA = 1, - SpvImageChannelOrderRG = 2, - SpvImageChannelOrderRA = 3, - SpvImageChannelOrderRGB = 4, - SpvImageChannelOrderRGBA = 5, - SpvImageChannelOrderBGRA = 6, - SpvImageChannelOrderARGB = 7, - SpvImageChannelOrderIntensity = 8, - SpvImageChannelOrderLuminance = 9, - SpvImageChannelOrderRx = 10, - SpvImageChannelOrderRGx = 11, - SpvImageChannelOrderRGBx = 12, - SpvImageChannelOrderDepth = 13, - SpvImageChannelOrderDepthStencil = 14, - SpvImageChannelOrdersRGB = 15, - SpvImageChannelOrdersRGBx = 16, - SpvImageChannelOrdersRGBA = 17, - SpvImageChannelOrdersBGRA = 18, - SpvImageChannelOrderABGR = 19, - SpvImageChannelOrderMax = 0x7fffffff, -} SpvImageChannelOrder; - -typedef enum SpvImageChannelDataType_ { - SpvImageChannelDataTypeSnormInt8 = 0, - SpvImageChannelDataTypeSnormInt16 = 1, - SpvImageChannelDataTypeUnormInt8 = 2, - SpvImageChannelDataTypeUnormInt16 = 3, - SpvImageChannelDataTypeUnormShort565 = 4, - SpvImageChannelDataTypeUnormShort555 = 5, - SpvImageChannelDataTypeUnormInt101010 = 6, - SpvImageChannelDataTypeSignedInt8 = 7, - SpvImageChannelDataTypeSignedInt16 = 8, - SpvImageChannelDataTypeSignedInt32 = 9, - SpvImageChannelDataTypeUnsignedInt8 = 10, - SpvImageChannelDataTypeUnsignedInt16 = 11, - SpvImageChannelDataTypeUnsignedInt32 = 12, - SpvImageChannelDataTypeHalfFloat = 13, - SpvImageChannelDataTypeFloat = 14, - SpvImageChannelDataTypeUnormInt24 = 15, - SpvImageChannelDataTypeUnormInt101010_2 = 16, - SpvImageChannelDataTypeMax = 0x7fffffff, -} SpvImageChannelDataType; - -typedef enum SpvImageOperandsShift_ { - SpvImageOperandsBiasShift = 0, - SpvImageOperandsLodShift = 1, - SpvImageOperandsGradShift = 2, - SpvImageOperandsConstOffsetShift = 3, - SpvImageOperandsOffsetShift = 4, - SpvImageOperandsConstOffsetsShift = 5, - SpvImageOperandsSampleShift = 6, - SpvImageOperandsMinLodShift = 7, - SpvImageOperandsMakeTexelAvailableShift = 8, - SpvImageOperandsMakeTexelAvailableKHRShift = 8, - SpvImageOperandsMakeTexelVisibleShift = 9, - SpvImageOperandsMakeTexelVisibleKHRShift = 9, - SpvImageOperandsNonPrivateTexelShift = 10, - SpvImageOperandsNonPrivateTexelKHRShift = 10, - SpvImageOperandsVolatileTexelShift = 11, - SpvImageOperandsVolatileTexelKHRShift = 11, - SpvImageOperandsSignExtendShift = 12, - SpvImageOperandsZeroExtendShift = 13, - SpvImageOperandsNontemporalShift = 14, - SpvImageOperandsOffsetsShift = 16, - SpvImageOperandsMax = 0x7fffffff, -} SpvImageOperandsShift; - -typedef enum SpvImageOperandsMask_ { - SpvImageOperandsMaskNone = 0, - SpvImageOperandsBiasMask = 0x00000001, - SpvImageOperandsLodMask = 0x00000002, - SpvImageOperandsGradMask = 0x00000004, - SpvImageOperandsConstOffsetMask = 0x00000008, - SpvImageOperandsOffsetMask = 0x00000010, - SpvImageOperandsConstOffsetsMask = 0x00000020, - SpvImageOperandsSampleMask = 0x00000040, - SpvImageOperandsMinLodMask = 0x00000080, - SpvImageOperandsMakeTexelAvailableMask = 0x00000100, - SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100, - SpvImageOperandsMakeTexelVisibleMask = 0x00000200, - SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200, - SpvImageOperandsNonPrivateTexelMask = 0x00000400, - SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400, - SpvImageOperandsVolatileTexelMask = 0x00000800, - SpvImageOperandsVolatileTexelKHRMask = 0x00000800, - SpvImageOperandsSignExtendMask = 0x00001000, - SpvImageOperandsZeroExtendMask = 0x00002000, - SpvImageOperandsNontemporalMask = 0x00004000, - SpvImageOperandsOffsetsMask = 0x00010000, -} SpvImageOperandsMask; - -typedef enum SpvFPFastMathModeShift_ { - SpvFPFastMathModeNotNaNShift = 0, - SpvFPFastMathModeNotInfShift = 1, - SpvFPFastMathModeNSZShift = 2, - SpvFPFastMathModeAllowRecipShift = 3, - SpvFPFastMathModeFastShift = 4, - SpvFPFastMathModeAllowContractFastINTELShift = 16, - SpvFPFastMathModeAllowReassocINTELShift = 17, - SpvFPFastMathModeMax = 0x7fffffff, -} SpvFPFastMathModeShift; - -typedef enum SpvFPFastMathModeMask_ { - SpvFPFastMathModeMaskNone = 0, - SpvFPFastMathModeNotNaNMask = 0x00000001, - SpvFPFastMathModeNotInfMask = 0x00000002, - SpvFPFastMathModeNSZMask = 0x00000004, - SpvFPFastMathModeAllowRecipMask = 0x00000008, - SpvFPFastMathModeFastMask = 0x00000010, - SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000, - SpvFPFastMathModeAllowReassocINTELMask = 0x00020000, -} SpvFPFastMathModeMask; - -typedef enum SpvFPRoundingMode_ { - SpvFPRoundingModeRTE = 0, - SpvFPRoundingModeRTZ = 1, - SpvFPRoundingModeRTP = 2, - SpvFPRoundingModeRTN = 3, - SpvFPRoundingModeMax = 0x7fffffff, -} SpvFPRoundingMode; - -typedef enum SpvLinkageType_ { - SpvLinkageTypeExport = 0, - SpvLinkageTypeImport = 1, - SpvLinkageTypeLinkOnceODR = 2, - SpvLinkageTypeMax = 0x7fffffff, -} SpvLinkageType; - -typedef enum SpvAccessQualifier_ { - SpvAccessQualifierReadOnly = 0, - SpvAccessQualifierWriteOnly = 1, - SpvAccessQualifierReadWrite = 2, - SpvAccessQualifierMax = 0x7fffffff, -} SpvAccessQualifier; - -typedef enum SpvFunctionParameterAttribute_ { - SpvFunctionParameterAttributeZext = 0, - SpvFunctionParameterAttributeSext = 1, - SpvFunctionParameterAttributeByVal = 2, - SpvFunctionParameterAttributeSret = 3, - SpvFunctionParameterAttributeNoAlias = 4, - SpvFunctionParameterAttributeNoCapture = 5, - SpvFunctionParameterAttributeNoWrite = 6, - SpvFunctionParameterAttributeNoReadWrite = 7, - SpvFunctionParameterAttributeMax = 0x7fffffff, -} SpvFunctionParameterAttribute; - -typedef enum SpvDecoration_ { - SpvDecorationRelaxedPrecision = 0, - SpvDecorationSpecId = 1, - SpvDecorationBlock = 2, - SpvDecorationBufferBlock = 3, - SpvDecorationRowMajor = 4, - SpvDecorationColMajor = 5, - SpvDecorationArrayStride = 6, - SpvDecorationMatrixStride = 7, - SpvDecorationGLSLShared = 8, - SpvDecorationGLSLPacked = 9, - SpvDecorationCPacked = 10, - SpvDecorationBuiltIn = 11, - SpvDecorationNoPerspective = 13, - SpvDecorationFlat = 14, - SpvDecorationPatch = 15, - SpvDecorationCentroid = 16, - SpvDecorationSample = 17, - SpvDecorationInvariant = 18, - SpvDecorationRestrict = 19, - SpvDecorationAliased = 20, - SpvDecorationVolatile = 21, - SpvDecorationConstant = 22, - SpvDecorationCoherent = 23, - SpvDecorationNonWritable = 24, - SpvDecorationNonReadable = 25, - SpvDecorationUniform = 26, - SpvDecorationUniformId = 27, - SpvDecorationSaturatedConversion = 28, - SpvDecorationStream = 29, - SpvDecorationLocation = 30, - SpvDecorationComponent = 31, - SpvDecorationIndex = 32, - SpvDecorationBinding = 33, - SpvDecorationDescriptorSet = 34, - SpvDecorationOffset = 35, - SpvDecorationXfbBuffer = 36, - SpvDecorationXfbStride = 37, - SpvDecorationFuncParamAttr = 38, - SpvDecorationFPRoundingMode = 39, - SpvDecorationFPFastMathMode = 40, - SpvDecorationLinkageAttributes = 41, - SpvDecorationNoContraction = 42, - SpvDecorationInputAttachmentIndex = 43, - SpvDecorationAlignment = 44, - SpvDecorationMaxByteOffset = 45, - SpvDecorationAlignmentId = 46, - SpvDecorationMaxByteOffsetId = 47, - SpvDecorationNoSignedWrap = 4469, - SpvDecorationNoUnsignedWrap = 4470, - SpvDecorationExplicitInterpAMD = 4999, - SpvDecorationOverrideCoverageNV = 5248, - SpvDecorationPassthroughNV = 5250, - SpvDecorationViewportRelativeNV = 5252, - SpvDecorationSecondaryViewportRelativeNV = 5256, - SpvDecorationPerPrimitiveEXT = 5271, - SpvDecorationPerPrimitiveNV = 5271, - SpvDecorationPerViewNV = 5272, - SpvDecorationPerTaskNV = 5273, - SpvDecorationPerVertexKHR = 5285, - SpvDecorationPerVertexNV = 5285, - SpvDecorationNonUniform = 5300, - SpvDecorationNonUniformEXT = 5300, - SpvDecorationRestrictPointer = 5355, - SpvDecorationRestrictPointerEXT = 5355, - SpvDecorationAliasedPointer = 5356, - SpvDecorationAliasedPointerEXT = 5356, - SpvDecorationBindlessSamplerNV = 5398, - SpvDecorationBindlessImageNV = 5399, - SpvDecorationBoundSamplerNV = 5400, - SpvDecorationBoundImageNV = 5401, - SpvDecorationSIMTCallINTEL = 5599, - SpvDecorationReferencedIndirectlyINTEL = 5602, - SpvDecorationClobberINTEL = 5607, - SpvDecorationSideEffectsINTEL = 5608, - SpvDecorationVectorComputeVariableINTEL = 5624, - SpvDecorationFuncParamIOKindINTEL = 5625, - SpvDecorationVectorComputeFunctionINTEL = 5626, - SpvDecorationStackCallINTEL = 5627, - SpvDecorationGlobalVariableOffsetINTEL = 5628, - SpvDecorationCounterBuffer = 5634, - SpvDecorationHlslCounterBufferGOOGLE = 5634, - SpvDecorationHlslSemanticGOOGLE = 5635, - SpvDecorationUserSemantic = 5635, - SpvDecorationUserTypeGOOGLE = 5636, - SpvDecorationFunctionRoundingModeINTEL = 5822, - SpvDecorationFunctionDenormModeINTEL = 5823, - SpvDecorationRegisterINTEL = 5825, - SpvDecorationMemoryINTEL = 5826, - SpvDecorationNumbanksINTEL = 5827, - SpvDecorationBankwidthINTEL = 5828, - SpvDecorationMaxPrivateCopiesINTEL = 5829, - SpvDecorationSinglepumpINTEL = 5830, - SpvDecorationDoublepumpINTEL = 5831, - SpvDecorationMaxReplicatesINTEL = 5832, - SpvDecorationSimpleDualPortINTEL = 5833, - SpvDecorationMergeINTEL = 5834, - SpvDecorationBankBitsINTEL = 5835, - SpvDecorationForcePow2DepthINTEL = 5836, - SpvDecorationBurstCoalesceINTEL = 5899, - SpvDecorationCacheSizeINTEL = 5900, - SpvDecorationDontStaticallyCoalesceINTEL = 5901, - SpvDecorationPrefetchINTEL = 5902, - SpvDecorationStallEnableINTEL = 5905, - SpvDecorationFuseLoopsInFunctionINTEL = 5907, - SpvDecorationAliasScopeINTEL = 5914, - SpvDecorationNoAliasINTEL = 5915, - SpvDecorationBufferLocationINTEL = 5921, - SpvDecorationIOPipeStorageINTEL = 5944, - SpvDecorationFunctionFloatingPointModeINTEL = 6080, - SpvDecorationSingleElementVectorINTEL = 6085, - SpvDecorationVectorComputeCallableFunctionINTEL = 6087, - SpvDecorationMediaBlockIOINTEL = 6140, - SpvDecorationMax = 0x7fffffff, -} SpvDecoration; - -typedef enum SpvBuiltIn_ { - SpvBuiltInPosition = 0, - SpvBuiltInPointSize = 1, - SpvBuiltInClipDistance = 3, - SpvBuiltInCullDistance = 4, - SpvBuiltInVertexId = 5, - SpvBuiltInInstanceId = 6, - SpvBuiltInPrimitiveId = 7, - SpvBuiltInInvocationId = 8, - SpvBuiltInLayer = 9, - SpvBuiltInViewportIndex = 10, - SpvBuiltInTessLevelOuter = 11, - SpvBuiltInTessLevelInner = 12, - SpvBuiltInTessCoord = 13, - SpvBuiltInPatchVertices = 14, - SpvBuiltInFragCoord = 15, - SpvBuiltInPointCoord = 16, - SpvBuiltInFrontFacing = 17, - SpvBuiltInSampleId = 18, - SpvBuiltInSamplePosition = 19, - SpvBuiltInSampleMask = 20, - SpvBuiltInFragDepth = 22, - SpvBuiltInHelperInvocation = 23, - SpvBuiltInNumWorkgroups = 24, - SpvBuiltInWorkgroupSize = 25, - SpvBuiltInWorkgroupId = 26, - SpvBuiltInLocalInvocationId = 27, - SpvBuiltInGlobalInvocationId = 28, - SpvBuiltInLocalInvocationIndex = 29, - SpvBuiltInWorkDim = 30, - SpvBuiltInGlobalSize = 31, - SpvBuiltInEnqueuedWorkgroupSize = 32, - SpvBuiltInGlobalOffset = 33, - SpvBuiltInGlobalLinearId = 34, - SpvBuiltInSubgroupSize = 36, - SpvBuiltInSubgroupMaxSize = 37, - SpvBuiltInNumSubgroups = 38, - SpvBuiltInNumEnqueuedSubgroups = 39, - SpvBuiltInSubgroupId = 40, - SpvBuiltInSubgroupLocalInvocationId = 41, - SpvBuiltInVertexIndex = 42, - SpvBuiltInInstanceIndex = 43, - SpvBuiltInSubgroupEqMask = 4416, - SpvBuiltInSubgroupEqMaskKHR = 4416, - SpvBuiltInSubgroupGeMask = 4417, - SpvBuiltInSubgroupGeMaskKHR = 4417, - SpvBuiltInSubgroupGtMask = 4418, - SpvBuiltInSubgroupGtMaskKHR = 4418, - SpvBuiltInSubgroupLeMask = 4419, - SpvBuiltInSubgroupLeMaskKHR = 4419, - SpvBuiltInSubgroupLtMask = 4420, - SpvBuiltInSubgroupLtMaskKHR = 4420, - SpvBuiltInBaseVertex = 4424, - SpvBuiltInBaseInstance = 4425, - SpvBuiltInDrawIndex = 4426, - SpvBuiltInPrimitiveShadingRateKHR = 4432, - SpvBuiltInDeviceIndex = 4438, - SpvBuiltInViewIndex = 4440, - SpvBuiltInShadingRateKHR = 4444, - SpvBuiltInBaryCoordNoPerspAMD = 4992, - SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, - SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, - SpvBuiltInBaryCoordSmoothAMD = 4995, - SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, - SpvBuiltInBaryCoordSmoothSampleAMD = 4997, - SpvBuiltInBaryCoordPullModelAMD = 4998, - SpvBuiltInFragStencilRefEXT = 5014, - SpvBuiltInViewportMaskNV = 5253, - SpvBuiltInSecondaryPositionNV = 5257, - SpvBuiltInSecondaryViewportMaskNV = 5258, - SpvBuiltInPositionPerViewNV = 5261, - SpvBuiltInViewportMaskPerViewNV = 5262, - SpvBuiltInFullyCoveredEXT = 5264, - SpvBuiltInTaskCountNV = 5274, - SpvBuiltInPrimitiveCountNV = 5275, - SpvBuiltInPrimitiveIndicesNV = 5276, - SpvBuiltInClipDistancePerViewNV = 5277, - SpvBuiltInCullDistancePerViewNV = 5278, - SpvBuiltInLayerPerViewNV = 5279, - SpvBuiltInMeshViewCountNV = 5280, - SpvBuiltInMeshViewIndicesNV = 5281, - SpvBuiltInBaryCoordKHR = 5286, - SpvBuiltInBaryCoordNV = 5286, - SpvBuiltInBaryCoordNoPerspKHR = 5287, - SpvBuiltInBaryCoordNoPerspNV = 5287, - SpvBuiltInFragSizeEXT = 5292, - SpvBuiltInFragmentSizeNV = 5292, - SpvBuiltInFragInvocationCountEXT = 5293, - SpvBuiltInInvocationsPerPixelNV = 5293, - SpvBuiltInPrimitivePointIndicesEXT = 5294, - SpvBuiltInPrimitiveLineIndicesEXT = 5295, - SpvBuiltInPrimitiveTriangleIndicesEXT = 5296, - SpvBuiltInCullPrimitiveEXT = 5299, - SpvBuiltInLaunchIdKHR = 5319, - SpvBuiltInLaunchIdNV = 5319, - SpvBuiltInLaunchSizeKHR = 5320, - SpvBuiltInLaunchSizeNV = 5320, - SpvBuiltInWorldRayOriginKHR = 5321, - SpvBuiltInWorldRayOriginNV = 5321, - SpvBuiltInWorldRayDirectionKHR = 5322, - SpvBuiltInWorldRayDirectionNV = 5322, - SpvBuiltInObjectRayOriginKHR = 5323, - SpvBuiltInObjectRayOriginNV = 5323, - SpvBuiltInObjectRayDirectionKHR = 5324, - SpvBuiltInObjectRayDirectionNV = 5324, - SpvBuiltInRayTminKHR = 5325, - SpvBuiltInRayTminNV = 5325, - SpvBuiltInRayTmaxKHR = 5326, - SpvBuiltInRayTmaxNV = 5326, - SpvBuiltInInstanceCustomIndexKHR = 5327, - SpvBuiltInInstanceCustomIndexNV = 5327, - SpvBuiltInObjectToWorldKHR = 5330, - SpvBuiltInObjectToWorldNV = 5330, - SpvBuiltInWorldToObjectKHR = 5331, - SpvBuiltInWorldToObjectNV = 5331, - SpvBuiltInHitTNV = 5332, - SpvBuiltInHitKindKHR = 5333, - SpvBuiltInHitKindNV = 5333, - SpvBuiltInCurrentRayTimeNV = 5334, - SpvBuiltInIncomingRayFlagsKHR = 5351, - SpvBuiltInIncomingRayFlagsNV = 5351, - SpvBuiltInRayGeometryIndexKHR = 5352, - SpvBuiltInWarpsPerSMNV = 5374, - SpvBuiltInSMCountNV = 5375, - SpvBuiltInWarpIDNV = 5376, - SpvBuiltInSMIDNV = 5377, - SpvBuiltInCullMaskKHR = 6021, - SpvBuiltInMax = 0x7fffffff, -} SpvBuiltIn; - -typedef enum SpvSelectionControlShift_ { - SpvSelectionControlFlattenShift = 0, - SpvSelectionControlDontFlattenShift = 1, - SpvSelectionControlMax = 0x7fffffff, -} SpvSelectionControlShift; - -typedef enum SpvSelectionControlMask_ { - SpvSelectionControlMaskNone = 0, - SpvSelectionControlFlattenMask = 0x00000001, - SpvSelectionControlDontFlattenMask = 0x00000002, -} SpvSelectionControlMask; - -typedef enum SpvLoopControlShift_ { - SpvLoopControlUnrollShift = 0, - SpvLoopControlDontUnrollShift = 1, - SpvLoopControlDependencyInfiniteShift = 2, - SpvLoopControlDependencyLengthShift = 3, - SpvLoopControlMinIterationsShift = 4, - SpvLoopControlMaxIterationsShift = 5, - SpvLoopControlIterationMultipleShift = 6, - SpvLoopControlPeelCountShift = 7, - SpvLoopControlPartialCountShift = 8, - SpvLoopControlInitiationIntervalINTELShift = 16, - SpvLoopControlMaxConcurrencyINTELShift = 17, - SpvLoopControlDependencyArrayINTELShift = 18, - SpvLoopControlPipelineEnableINTELShift = 19, - SpvLoopControlLoopCoalesceINTELShift = 20, - SpvLoopControlMaxInterleavingINTELShift = 21, - SpvLoopControlSpeculatedIterationsINTELShift = 22, - SpvLoopControlNoFusionINTELShift = 23, - SpvLoopControlMax = 0x7fffffff, -} SpvLoopControlShift; - -typedef enum SpvLoopControlMask_ { - SpvLoopControlMaskNone = 0, - SpvLoopControlUnrollMask = 0x00000001, - SpvLoopControlDontUnrollMask = 0x00000002, - SpvLoopControlDependencyInfiniteMask = 0x00000004, - SpvLoopControlDependencyLengthMask = 0x00000008, - SpvLoopControlMinIterationsMask = 0x00000010, - SpvLoopControlMaxIterationsMask = 0x00000020, - SpvLoopControlIterationMultipleMask = 0x00000040, - SpvLoopControlPeelCountMask = 0x00000080, - SpvLoopControlPartialCountMask = 0x00000100, - SpvLoopControlInitiationIntervalINTELMask = 0x00010000, - SpvLoopControlMaxConcurrencyINTELMask = 0x00020000, - SpvLoopControlDependencyArrayINTELMask = 0x00040000, - SpvLoopControlPipelineEnableINTELMask = 0x00080000, - SpvLoopControlLoopCoalesceINTELMask = 0x00100000, - SpvLoopControlMaxInterleavingINTELMask = 0x00200000, - SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000, - SpvLoopControlNoFusionINTELMask = 0x00800000, -} SpvLoopControlMask; - -typedef enum SpvFunctionControlShift_ { - SpvFunctionControlInlineShift = 0, - SpvFunctionControlDontInlineShift = 1, - SpvFunctionControlPureShift = 2, - SpvFunctionControlConstShift = 3, - SpvFunctionControlOptNoneINTELShift = 16, - SpvFunctionControlMax = 0x7fffffff, -} SpvFunctionControlShift; - -typedef enum SpvFunctionControlMask_ { - SpvFunctionControlMaskNone = 0, - SpvFunctionControlInlineMask = 0x00000001, - SpvFunctionControlDontInlineMask = 0x00000002, - SpvFunctionControlPureMask = 0x00000004, - SpvFunctionControlConstMask = 0x00000008, - SpvFunctionControlOptNoneINTELMask = 0x00010000, -} SpvFunctionControlMask; - -typedef enum SpvMemorySemanticsShift_ { - SpvMemorySemanticsAcquireShift = 1, - SpvMemorySemanticsReleaseShift = 2, - SpvMemorySemanticsAcquireReleaseShift = 3, - SpvMemorySemanticsSequentiallyConsistentShift = 4, - SpvMemorySemanticsUniformMemoryShift = 6, - SpvMemorySemanticsSubgroupMemoryShift = 7, - SpvMemorySemanticsWorkgroupMemoryShift = 8, - SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, - SpvMemorySemanticsAtomicCounterMemoryShift = 10, - SpvMemorySemanticsImageMemoryShift = 11, - SpvMemorySemanticsOutputMemoryShift = 12, - SpvMemorySemanticsOutputMemoryKHRShift = 12, - SpvMemorySemanticsMakeAvailableShift = 13, - SpvMemorySemanticsMakeAvailableKHRShift = 13, - SpvMemorySemanticsMakeVisibleShift = 14, - SpvMemorySemanticsMakeVisibleKHRShift = 14, - SpvMemorySemanticsVolatileShift = 15, - SpvMemorySemanticsMax = 0x7fffffff, -} SpvMemorySemanticsShift; - -typedef enum SpvMemorySemanticsMask_ { - SpvMemorySemanticsMaskNone = 0, - SpvMemorySemanticsAcquireMask = 0x00000002, - SpvMemorySemanticsReleaseMask = 0x00000004, - SpvMemorySemanticsAcquireReleaseMask = 0x00000008, - SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, - SpvMemorySemanticsUniformMemoryMask = 0x00000040, - SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, - SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, - SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, - SpvMemorySemanticsImageMemoryMask = 0x00000800, - SpvMemorySemanticsOutputMemoryMask = 0x00001000, - SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000, - SpvMemorySemanticsMakeAvailableMask = 0x00002000, - SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000, - SpvMemorySemanticsMakeVisibleMask = 0x00004000, - SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000, - SpvMemorySemanticsVolatileMask = 0x00008000, -} SpvMemorySemanticsMask; - -typedef enum SpvMemoryAccessShift_ { - SpvMemoryAccessVolatileShift = 0, - SpvMemoryAccessAlignedShift = 1, - SpvMemoryAccessNontemporalShift = 2, - SpvMemoryAccessMakePointerAvailableShift = 3, - SpvMemoryAccessMakePointerAvailableKHRShift = 3, - SpvMemoryAccessMakePointerVisibleShift = 4, - SpvMemoryAccessMakePointerVisibleKHRShift = 4, - SpvMemoryAccessNonPrivatePointerShift = 5, - SpvMemoryAccessNonPrivatePointerKHRShift = 5, - SpvMemoryAccessAliasScopeINTELMaskShift = 16, - SpvMemoryAccessNoAliasINTELMaskShift = 17, - SpvMemoryAccessMax = 0x7fffffff, -} SpvMemoryAccessShift; - -typedef enum SpvMemoryAccessMask_ { - SpvMemoryAccessMaskNone = 0, - SpvMemoryAccessVolatileMask = 0x00000001, - SpvMemoryAccessAlignedMask = 0x00000002, - SpvMemoryAccessNontemporalMask = 0x00000004, - SpvMemoryAccessMakePointerAvailableMask = 0x00000008, - SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008, - SpvMemoryAccessMakePointerVisibleMask = 0x00000010, - SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, - SpvMemoryAccessNonPrivatePointerMask = 0x00000020, - SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, - SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000, - SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000, -} SpvMemoryAccessMask; - -typedef enum SpvScope_ { - SpvScopeCrossDevice = 0, - SpvScopeDevice = 1, - SpvScopeWorkgroup = 2, - SpvScopeSubgroup = 3, - SpvScopeInvocation = 4, - SpvScopeQueueFamily = 5, - SpvScopeQueueFamilyKHR = 5, - SpvScopeShaderCallKHR = 6, - SpvScopeMax = 0x7fffffff, -} SpvScope; - -typedef enum SpvGroupOperation_ { - SpvGroupOperationReduce = 0, - SpvGroupOperationInclusiveScan = 1, - SpvGroupOperationExclusiveScan = 2, - SpvGroupOperationClusteredReduce = 3, - SpvGroupOperationPartitionedReduceNV = 6, - SpvGroupOperationPartitionedInclusiveScanNV = 7, - SpvGroupOperationPartitionedExclusiveScanNV = 8, - SpvGroupOperationMax = 0x7fffffff, -} SpvGroupOperation; - -typedef enum SpvKernelEnqueueFlags_ { - SpvKernelEnqueueFlagsNoWait = 0, - SpvKernelEnqueueFlagsWaitKernel = 1, - SpvKernelEnqueueFlagsWaitWorkGroup = 2, - SpvKernelEnqueueFlagsMax = 0x7fffffff, -} SpvKernelEnqueueFlags; - -typedef enum SpvKernelProfilingInfoShift_ { - SpvKernelProfilingInfoCmdExecTimeShift = 0, - SpvKernelProfilingInfoMax = 0x7fffffff, -} SpvKernelProfilingInfoShift; - -typedef enum SpvKernelProfilingInfoMask_ { - SpvKernelProfilingInfoMaskNone = 0, - SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, -} SpvKernelProfilingInfoMask; - -typedef enum SpvCapability_ { - SpvCapabilityMatrix = 0, - SpvCapabilityShader = 1, - SpvCapabilityGeometry = 2, - SpvCapabilityTessellation = 3, - SpvCapabilityAddresses = 4, - SpvCapabilityLinkage = 5, - SpvCapabilityKernel = 6, - SpvCapabilityVector16 = 7, - SpvCapabilityFloat16Buffer = 8, - SpvCapabilityFloat16 = 9, - SpvCapabilityFloat64 = 10, - SpvCapabilityInt64 = 11, - SpvCapabilityInt64Atomics = 12, - SpvCapabilityImageBasic = 13, - SpvCapabilityImageReadWrite = 14, - SpvCapabilityImageMipmap = 15, - SpvCapabilityPipes = 17, - SpvCapabilityGroups = 18, - SpvCapabilityDeviceEnqueue = 19, - SpvCapabilityLiteralSampler = 20, - SpvCapabilityAtomicStorage = 21, - SpvCapabilityInt16 = 22, - SpvCapabilityTessellationPointSize = 23, - SpvCapabilityGeometryPointSize = 24, - SpvCapabilityImageGatherExtended = 25, - SpvCapabilityStorageImageMultisample = 27, - SpvCapabilityUniformBufferArrayDynamicIndexing = 28, - SpvCapabilitySampledImageArrayDynamicIndexing = 29, - SpvCapabilityStorageBufferArrayDynamicIndexing = 30, - SpvCapabilityStorageImageArrayDynamicIndexing = 31, - SpvCapabilityClipDistance = 32, - SpvCapabilityCullDistance = 33, - SpvCapabilityImageCubeArray = 34, - SpvCapabilitySampleRateShading = 35, - SpvCapabilityImageRect = 36, - SpvCapabilitySampledRect = 37, - SpvCapabilityGenericPointer = 38, - SpvCapabilityInt8 = 39, - SpvCapabilityInputAttachment = 40, - SpvCapabilitySparseResidency = 41, - SpvCapabilityMinLod = 42, - SpvCapabilitySampled1D = 43, - SpvCapabilityImage1D = 44, - SpvCapabilitySampledCubeArray = 45, - SpvCapabilitySampledBuffer = 46, - SpvCapabilityImageBuffer = 47, - SpvCapabilityImageMSArray = 48, - SpvCapabilityStorageImageExtendedFormats = 49, - SpvCapabilityImageQuery = 50, - SpvCapabilityDerivativeControl = 51, - SpvCapabilityInterpolationFunction = 52, - SpvCapabilityTransformFeedback = 53, - SpvCapabilityGeometryStreams = 54, - SpvCapabilityStorageImageReadWithoutFormat = 55, - SpvCapabilityStorageImageWriteWithoutFormat = 56, - SpvCapabilityMultiViewport = 57, - SpvCapabilitySubgroupDispatch = 58, - SpvCapabilityNamedBarrier = 59, - SpvCapabilityPipeStorage = 60, - SpvCapabilityGroupNonUniform = 61, - SpvCapabilityGroupNonUniformVote = 62, - SpvCapabilityGroupNonUniformArithmetic = 63, - SpvCapabilityGroupNonUniformBallot = 64, - SpvCapabilityGroupNonUniformShuffle = 65, - SpvCapabilityGroupNonUniformShuffleRelative = 66, - SpvCapabilityGroupNonUniformClustered = 67, - SpvCapabilityGroupNonUniformQuad = 68, - SpvCapabilityShaderLayer = 69, - SpvCapabilityShaderViewportIndex = 70, - SpvCapabilityUniformDecoration = 71, - SpvCapabilityFragmentShadingRateKHR = 4422, - SpvCapabilitySubgroupBallotKHR = 4423, - SpvCapabilityDrawParameters = 4427, - SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, - SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, - SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, - SpvCapabilitySubgroupVoteKHR = 4431, - SpvCapabilityStorageBuffer16BitAccess = 4433, - SpvCapabilityStorageUniformBufferBlock16 = 4433, - SpvCapabilityStorageUniform16 = 4434, - SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, - SpvCapabilityStoragePushConstant16 = 4435, - SpvCapabilityStorageInputOutput16 = 4436, - SpvCapabilityDeviceGroup = 4437, - SpvCapabilityMultiView = 4439, - SpvCapabilityVariablePointersStorageBuffer = 4441, - SpvCapabilityVariablePointers = 4442, - SpvCapabilityAtomicStorageOps = 4445, - SpvCapabilitySampleMaskPostDepthCoverage = 4447, - SpvCapabilityStorageBuffer8BitAccess = 4448, - SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449, - SpvCapabilityStoragePushConstant8 = 4450, - SpvCapabilityDenormPreserve = 4464, - SpvCapabilityDenormFlushToZero = 4465, - SpvCapabilitySignedZeroInfNanPreserve = 4466, - SpvCapabilityRoundingModeRTE = 4467, - SpvCapabilityRoundingModeRTZ = 4468, - SpvCapabilityRayQueryProvisionalKHR = 4471, - SpvCapabilityRayQueryKHR = 4472, - SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478, - SpvCapabilityRayTracingKHR = 4479, - SpvCapabilityFloat16ImageAMD = 5008, - SpvCapabilityImageGatherBiasLodAMD = 5009, - SpvCapabilityFragmentMaskAMD = 5010, - SpvCapabilityStencilExportEXT = 5013, - SpvCapabilityImageReadWriteLodAMD = 5015, - SpvCapabilityInt64ImageEXT = 5016, - SpvCapabilityShaderClockKHR = 5055, - SpvCapabilitySampleMaskOverrideCoverageNV = 5249, - SpvCapabilityGeometryShaderPassthroughNV = 5251, - SpvCapabilityShaderViewportIndexLayerEXT = 5254, - SpvCapabilityShaderViewportIndexLayerNV = 5254, - SpvCapabilityShaderViewportMaskNV = 5255, - SpvCapabilityShaderStereoViewNV = 5259, - SpvCapabilityPerViewAttributesNV = 5260, - SpvCapabilityFragmentFullyCoveredEXT = 5265, - SpvCapabilityMeshShadingNV = 5266, - SpvCapabilityImageFootprintNV = 5282, - SpvCapabilityMeshShadingEXT = 5283, - SpvCapabilityFragmentBarycentricKHR = 5284, - SpvCapabilityFragmentBarycentricNV = 5284, - SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, - SpvCapabilityFragmentDensityEXT = 5291, - SpvCapabilityShadingRateNV = 5291, - SpvCapabilityGroupNonUniformPartitionedNV = 5297, - SpvCapabilityShaderNonUniform = 5301, - SpvCapabilityShaderNonUniformEXT = 5301, - SpvCapabilityRuntimeDescriptorArray = 5302, - SpvCapabilityRuntimeDescriptorArrayEXT = 5302, - SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303, - SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, - SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304, - SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, - SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305, - SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, - SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306, - SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, - SpvCapabilitySampledImageArrayNonUniformIndexing = 5307, - SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307, - SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308, - SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, - SpvCapabilityStorageImageArrayNonUniformIndexing = 5309, - SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309, - SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310, - SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, - SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, - SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, - SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, - SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, - SpvCapabilityRayTracingNV = 5340, - SpvCapabilityRayTracingMotionBlurNV = 5341, - SpvCapabilityVulkanMemoryModel = 5345, - SpvCapabilityVulkanMemoryModelKHR = 5345, - SpvCapabilityVulkanMemoryModelDeviceScope = 5346, - SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346, - SpvCapabilityPhysicalStorageBufferAddresses = 5347, - SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347, - SpvCapabilityComputeDerivativeGroupLinearNV = 5350, - SpvCapabilityRayTracingProvisionalKHR = 5353, - SpvCapabilityCooperativeMatrixNV = 5357, - SpvCapabilityFragmentShaderSampleInterlockEXT = 5363, - SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372, - SpvCapabilityShaderSMBuiltinsNV = 5373, - SpvCapabilityFragmentShaderPixelInterlockEXT = 5378, - SpvCapabilityDemoteToHelperInvocation = 5379, - SpvCapabilityDemoteToHelperInvocationEXT = 5379, - SpvCapabilityBindlessTextureNV = 5390, - SpvCapabilitySubgroupShuffleINTEL = 5568, - SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, - SpvCapabilitySubgroupImageBlockIOINTEL = 5570, - SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579, - SpvCapabilityRoundToInfinityINTEL = 5582, - SpvCapabilityFloatingPointModeINTEL = 5583, - SpvCapabilityIntegerFunctions2INTEL = 5584, - SpvCapabilityFunctionPointersINTEL = 5603, - SpvCapabilityIndirectReferencesINTEL = 5604, - SpvCapabilityAsmINTEL = 5606, - SpvCapabilityAtomicFloat32MinMaxEXT = 5612, - SpvCapabilityAtomicFloat64MinMaxEXT = 5613, - SpvCapabilityAtomicFloat16MinMaxEXT = 5616, - SpvCapabilityVectorComputeINTEL = 5617, - SpvCapabilityVectorAnyINTEL = 5619, - SpvCapabilityExpectAssumeKHR = 5629, - SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696, - SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, - SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, - SpvCapabilityVariableLengthArrayINTEL = 5817, - SpvCapabilityFunctionFloatControlINTEL = 5821, - SpvCapabilityFPGAMemoryAttributesINTEL = 5824, - SpvCapabilityFPFastMathModeINTEL = 5837, - SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844, - SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845, - SpvCapabilityUnstructuredLoopControlsINTEL = 5886, - SpvCapabilityFPGALoopControlsINTEL = 5888, - SpvCapabilityKernelAttributesINTEL = 5892, - SpvCapabilityFPGAKernelAttributesINTEL = 5897, - SpvCapabilityFPGAMemoryAccessesINTEL = 5898, - SpvCapabilityFPGAClusterAttributesINTEL = 5904, - SpvCapabilityLoopFuseINTEL = 5906, - SpvCapabilityMemoryAccessAliasingINTEL = 5910, - SpvCapabilityFPGABufferLocationINTEL = 5920, - SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, - SpvCapabilityUSMStorageClassesINTEL = 5935, - SpvCapabilityIOPipesINTEL = 5943, - SpvCapabilityBlockingPipesINTEL = 5945, - SpvCapabilityFPGARegINTEL = 5948, - SpvCapabilityDotProductInputAll = 6016, - SpvCapabilityDotProductInputAllKHR = 6016, - SpvCapabilityDotProductInput4x8Bit = 6017, - SpvCapabilityDotProductInput4x8BitKHR = 6017, - SpvCapabilityDotProductInput4x8BitPacked = 6018, - SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, - SpvCapabilityDotProduct = 6019, - SpvCapabilityDotProductKHR = 6019, - SpvCapabilityRayCullMaskKHR = 6020, - SpvCapabilityBitInstructions = 6025, - SpvCapabilityGroupNonUniformRotateKHR = 6026, - SpvCapabilityAtomicFloat32AddEXT = 6033, - SpvCapabilityAtomicFloat64AddEXT = 6034, - SpvCapabilityLongConstantCompositeINTEL = 6089, - SpvCapabilityOptNoneINTEL = 6094, - SpvCapabilityAtomicFloat16AddEXT = 6095, - SpvCapabilityDebugInfoModuleINTEL = 6114, - SpvCapabilitySplitBarrierINTEL = 6141, - SpvCapabilityGroupUniformArithmeticKHR = 6400, - SpvCapabilityMax = 0x7fffffff, -} SpvCapability; - -typedef enum SpvRayFlagsShift_ { - SpvRayFlagsOpaqueKHRShift = 0, - SpvRayFlagsNoOpaqueKHRShift = 1, - SpvRayFlagsTerminateOnFirstHitKHRShift = 2, - SpvRayFlagsSkipClosestHitShaderKHRShift = 3, - SpvRayFlagsCullBackFacingTrianglesKHRShift = 4, - SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5, - SpvRayFlagsCullOpaqueKHRShift = 6, - SpvRayFlagsCullNoOpaqueKHRShift = 7, - SpvRayFlagsSkipTrianglesKHRShift = 8, - SpvRayFlagsSkipAABBsKHRShift = 9, - SpvRayFlagsMax = 0x7fffffff, -} SpvRayFlagsShift; - -typedef enum SpvRayFlagsMask_ { - SpvRayFlagsMaskNone = 0, - SpvRayFlagsOpaqueKHRMask = 0x00000001, - SpvRayFlagsNoOpaqueKHRMask = 0x00000002, - SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004, - SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008, - SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, - SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, - SpvRayFlagsCullOpaqueKHRMask = 0x00000040, - SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080, - SpvRayFlagsSkipTrianglesKHRMask = 0x00000100, - SpvRayFlagsSkipAABBsKHRMask = 0x00000200, -} SpvRayFlagsMask; - -typedef enum SpvRayQueryIntersection_ { - SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, - SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, - SpvRayQueryIntersectionMax = 0x7fffffff, -} SpvRayQueryIntersection; - -typedef enum SpvRayQueryCommittedIntersectionType_ { - SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, - SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, - SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, - SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff, -} SpvRayQueryCommittedIntersectionType; - -typedef enum SpvRayQueryCandidateIntersectionType_ { - SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, - SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, - SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff, -} SpvRayQueryCandidateIntersectionType; - -typedef enum SpvFragmentShadingRateShift_ { - SpvFragmentShadingRateVertical2PixelsShift = 0, - SpvFragmentShadingRateVertical4PixelsShift = 1, - SpvFragmentShadingRateHorizontal2PixelsShift = 2, - SpvFragmentShadingRateHorizontal4PixelsShift = 3, - SpvFragmentShadingRateMax = 0x7fffffff, -} SpvFragmentShadingRateShift; - -typedef enum SpvFragmentShadingRateMask_ { - SpvFragmentShadingRateMaskNone = 0, - SpvFragmentShadingRateVertical2PixelsMask = 0x00000001, - SpvFragmentShadingRateVertical4PixelsMask = 0x00000002, - SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004, - SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008, -} SpvFragmentShadingRateMask; - -typedef enum SpvFPDenormMode_ { - SpvFPDenormModePreserve = 0, - SpvFPDenormModeFlushToZero = 1, - SpvFPDenormModeMax = 0x7fffffff, -} SpvFPDenormMode; - -typedef enum SpvFPOperationMode_ { - SpvFPOperationModeIEEE = 0, - SpvFPOperationModeALT = 1, - SpvFPOperationModeMax = 0x7fffffff, -} SpvFPOperationMode; - -typedef enum SpvQuantizationModes_ { - SpvQuantizationModesTRN = 0, - SpvQuantizationModesTRN_ZERO = 1, - SpvQuantizationModesRND = 2, - SpvQuantizationModesRND_ZERO = 3, - SpvQuantizationModesRND_INF = 4, - SpvQuantizationModesRND_MIN_INF = 5, - SpvQuantizationModesRND_CONV = 6, - SpvQuantizationModesRND_CONV_ODD = 7, - SpvQuantizationModesMax = 0x7fffffff, -} SpvQuantizationModes; - -typedef enum SpvOverflowModes_ { - SpvOverflowModesWRAP = 0, - SpvOverflowModesSAT = 1, - SpvOverflowModesSAT_ZERO = 2, - SpvOverflowModesSAT_SYM = 3, - SpvOverflowModesMax = 0x7fffffff, -} SpvOverflowModes; - -typedef enum SpvPackedVectorFormat_ { - SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0, - SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0, - SpvPackedVectorFormatMax = 0x7fffffff, -} SpvPackedVectorFormat; - -typedef enum SpvOp_ { - SpvOpNop = 0, - SpvOpUndef = 1, - SpvOpSourceContinued = 2, - SpvOpSource = 3, - SpvOpSourceExtension = 4, - SpvOpName = 5, - SpvOpMemberName = 6, - SpvOpString = 7, - SpvOpLine = 8, - SpvOpExtension = 10, - SpvOpExtInstImport = 11, - SpvOpExtInst = 12, - SpvOpMemoryModel = 14, - SpvOpEntryPoint = 15, - SpvOpExecutionMode = 16, - SpvOpCapability = 17, - SpvOpTypeVoid = 19, - SpvOpTypeBool = 20, - SpvOpTypeInt = 21, - SpvOpTypeFloat = 22, - SpvOpTypeVector = 23, - SpvOpTypeMatrix = 24, - SpvOpTypeImage = 25, - SpvOpTypeSampler = 26, - SpvOpTypeSampledImage = 27, - SpvOpTypeArray = 28, - SpvOpTypeRuntimeArray = 29, - SpvOpTypeStruct = 30, - SpvOpTypeOpaque = 31, - SpvOpTypePointer = 32, - SpvOpTypeFunction = 33, - SpvOpTypeEvent = 34, - SpvOpTypeDeviceEvent = 35, - SpvOpTypeReserveId = 36, - SpvOpTypeQueue = 37, - SpvOpTypePipe = 38, - SpvOpTypeForwardPointer = 39, - SpvOpConstantTrue = 41, - SpvOpConstantFalse = 42, - SpvOpConstant = 43, - SpvOpConstantComposite = 44, - SpvOpConstantSampler = 45, - SpvOpConstantNull = 46, - SpvOpSpecConstantTrue = 48, - SpvOpSpecConstantFalse = 49, - SpvOpSpecConstant = 50, - SpvOpSpecConstantComposite = 51, - SpvOpSpecConstantOp = 52, - SpvOpFunction = 54, - SpvOpFunctionParameter = 55, - SpvOpFunctionEnd = 56, - SpvOpFunctionCall = 57, - SpvOpVariable = 59, - SpvOpImageTexelPointer = 60, - SpvOpLoad = 61, - SpvOpStore = 62, - SpvOpCopyMemory = 63, - SpvOpCopyMemorySized = 64, - SpvOpAccessChain = 65, - SpvOpInBoundsAccessChain = 66, - SpvOpPtrAccessChain = 67, - SpvOpArrayLength = 68, - SpvOpGenericPtrMemSemantics = 69, - SpvOpInBoundsPtrAccessChain = 70, - SpvOpDecorate = 71, - SpvOpMemberDecorate = 72, - SpvOpDecorationGroup = 73, - SpvOpGroupDecorate = 74, - SpvOpGroupMemberDecorate = 75, - SpvOpVectorExtractDynamic = 77, - SpvOpVectorInsertDynamic = 78, - SpvOpVectorShuffle = 79, - SpvOpCompositeConstruct = 80, - SpvOpCompositeExtract = 81, - SpvOpCompositeInsert = 82, - SpvOpCopyObject = 83, - SpvOpTranspose = 84, - SpvOpSampledImage = 86, - SpvOpImageSampleImplicitLod = 87, - SpvOpImageSampleExplicitLod = 88, - SpvOpImageSampleDrefImplicitLod = 89, - SpvOpImageSampleDrefExplicitLod = 90, - SpvOpImageSampleProjImplicitLod = 91, - SpvOpImageSampleProjExplicitLod = 92, - SpvOpImageSampleProjDrefImplicitLod = 93, - SpvOpImageSampleProjDrefExplicitLod = 94, - SpvOpImageFetch = 95, - SpvOpImageGather = 96, - SpvOpImageDrefGather = 97, - SpvOpImageRead = 98, - SpvOpImageWrite = 99, - SpvOpImage = 100, - SpvOpImageQueryFormat = 101, - SpvOpImageQueryOrder = 102, - SpvOpImageQuerySizeLod = 103, - SpvOpImageQuerySize = 104, - SpvOpImageQueryLod = 105, - SpvOpImageQueryLevels = 106, - SpvOpImageQuerySamples = 107, - SpvOpConvertFToU = 109, - SpvOpConvertFToS = 110, - SpvOpConvertSToF = 111, - SpvOpConvertUToF = 112, - SpvOpUConvert = 113, - SpvOpSConvert = 114, - SpvOpFConvert = 115, - SpvOpQuantizeToF16 = 116, - SpvOpConvertPtrToU = 117, - SpvOpSatConvertSToU = 118, - SpvOpSatConvertUToS = 119, - SpvOpConvertUToPtr = 120, - SpvOpPtrCastToGeneric = 121, - SpvOpGenericCastToPtr = 122, - SpvOpGenericCastToPtrExplicit = 123, - SpvOpBitcast = 124, - SpvOpSNegate = 126, - SpvOpFNegate = 127, - SpvOpIAdd = 128, - SpvOpFAdd = 129, - SpvOpISub = 130, - SpvOpFSub = 131, - SpvOpIMul = 132, - SpvOpFMul = 133, - SpvOpUDiv = 134, - SpvOpSDiv = 135, - SpvOpFDiv = 136, - SpvOpUMod = 137, - SpvOpSRem = 138, - SpvOpSMod = 139, - SpvOpFRem = 140, - SpvOpFMod = 141, - SpvOpVectorTimesScalar = 142, - SpvOpMatrixTimesScalar = 143, - SpvOpVectorTimesMatrix = 144, - SpvOpMatrixTimesVector = 145, - SpvOpMatrixTimesMatrix = 146, - SpvOpOuterProduct = 147, - SpvOpDot = 148, - SpvOpIAddCarry = 149, - SpvOpISubBorrow = 150, - SpvOpUMulExtended = 151, - SpvOpSMulExtended = 152, - SpvOpAny = 154, - SpvOpAll = 155, - SpvOpIsNan = 156, - SpvOpIsInf = 157, - SpvOpIsFinite = 158, - SpvOpIsNormal = 159, - SpvOpSignBitSet = 160, - SpvOpLessOrGreater = 161, - SpvOpOrdered = 162, - SpvOpUnordered = 163, - SpvOpLogicalEqual = 164, - SpvOpLogicalNotEqual = 165, - SpvOpLogicalOr = 166, - SpvOpLogicalAnd = 167, - SpvOpLogicalNot = 168, - SpvOpSelect = 169, - SpvOpIEqual = 170, - SpvOpINotEqual = 171, - SpvOpUGreaterThan = 172, - SpvOpSGreaterThan = 173, - SpvOpUGreaterThanEqual = 174, - SpvOpSGreaterThanEqual = 175, - SpvOpULessThan = 176, - SpvOpSLessThan = 177, - SpvOpULessThanEqual = 178, - SpvOpSLessThanEqual = 179, - SpvOpFOrdEqual = 180, - SpvOpFUnordEqual = 181, - SpvOpFOrdNotEqual = 182, - SpvOpFUnordNotEqual = 183, - SpvOpFOrdLessThan = 184, - SpvOpFUnordLessThan = 185, - SpvOpFOrdGreaterThan = 186, - SpvOpFUnordGreaterThan = 187, - SpvOpFOrdLessThanEqual = 188, - SpvOpFUnordLessThanEqual = 189, - SpvOpFOrdGreaterThanEqual = 190, - SpvOpFUnordGreaterThanEqual = 191, - SpvOpShiftRightLogical = 194, - SpvOpShiftRightArithmetic = 195, - SpvOpShiftLeftLogical = 196, - SpvOpBitwiseOr = 197, - SpvOpBitwiseXor = 198, - SpvOpBitwiseAnd = 199, - SpvOpNot = 200, - SpvOpBitFieldInsert = 201, - SpvOpBitFieldSExtract = 202, - SpvOpBitFieldUExtract = 203, - SpvOpBitReverse = 204, - SpvOpBitCount = 205, - SpvOpDPdx = 207, - SpvOpDPdy = 208, - SpvOpFwidth = 209, - SpvOpDPdxFine = 210, - SpvOpDPdyFine = 211, - SpvOpFwidthFine = 212, - SpvOpDPdxCoarse = 213, - SpvOpDPdyCoarse = 214, - SpvOpFwidthCoarse = 215, - SpvOpEmitVertex = 218, - SpvOpEndPrimitive = 219, - SpvOpEmitStreamVertex = 220, - SpvOpEndStreamPrimitive = 221, - SpvOpControlBarrier = 224, - SpvOpMemoryBarrier = 225, - SpvOpAtomicLoad = 227, - SpvOpAtomicStore = 228, - SpvOpAtomicExchange = 229, - SpvOpAtomicCompareExchange = 230, - SpvOpAtomicCompareExchangeWeak = 231, - SpvOpAtomicIIncrement = 232, - SpvOpAtomicIDecrement = 233, - SpvOpAtomicIAdd = 234, - SpvOpAtomicISub = 235, - SpvOpAtomicSMin = 236, - SpvOpAtomicUMin = 237, - SpvOpAtomicSMax = 238, - SpvOpAtomicUMax = 239, - SpvOpAtomicAnd = 240, - SpvOpAtomicOr = 241, - SpvOpAtomicXor = 242, - SpvOpPhi = 245, - SpvOpLoopMerge = 246, - SpvOpSelectionMerge = 247, - SpvOpLabel = 248, - SpvOpBranch = 249, - SpvOpBranchConditional = 250, - SpvOpSwitch = 251, - SpvOpKill = 252, - SpvOpReturn = 253, - SpvOpReturnValue = 254, - SpvOpUnreachable = 255, - SpvOpLifetimeStart = 256, - SpvOpLifetimeStop = 257, - SpvOpGroupAsyncCopy = 259, - SpvOpGroupWaitEvents = 260, - SpvOpGroupAll = 261, - SpvOpGroupAny = 262, - SpvOpGroupBroadcast = 263, - SpvOpGroupIAdd = 264, - SpvOpGroupFAdd = 265, - SpvOpGroupFMin = 266, - SpvOpGroupUMin = 267, - SpvOpGroupSMin = 268, - SpvOpGroupFMax = 269, - SpvOpGroupUMax = 270, - SpvOpGroupSMax = 271, - SpvOpReadPipe = 274, - SpvOpWritePipe = 275, - SpvOpReservedReadPipe = 276, - SpvOpReservedWritePipe = 277, - SpvOpReserveReadPipePackets = 278, - SpvOpReserveWritePipePackets = 279, - SpvOpCommitReadPipe = 280, - SpvOpCommitWritePipe = 281, - SpvOpIsValidReserveId = 282, - SpvOpGetNumPipePackets = 283, - SpvOpGetMaxPipePackets = 284, - SpvOpGroupReserveReadPipePackets = 285, - SpvOpGroupReserveWritePipePackets = 286, - SpvOpGroupCommitReadPipe = 287, - SpvOpGroupCommitWritePipe = 288, - SpvOpEnqueueMarker = 291, - SpvOpEnqueueKernel = 292, - SpvOpGetKernelNDrangeSubGroupCount = 293, - SpvOpGetKernelNDrangeMaxSubGroupSize = 294, - SpvOpGetKernelWorkGroupSize = 295, - SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, - SpvOpRetainEvent = 297, - SpvOpReleaseEvent = 298, - SpvOpCreateUserEvent = 299, - SpvOpIsValidEvent = 300, - SpvOpSetUserEventStatus = 301, - SpvOpCaptureEventProfilingInfo = 302, - SpvOpGetDefaultQueue = 303, - SpvOpBuildNDRange = 304, - SpvOpImageSparseSampleImplicitLod = 305, - SpvOpImageSparseSampleExplicitLod = 306, - SpvOpImageSparseSampleDrefImplicitLod = 307, - SpvOpImageSparseSampleDrefExplicitLod = 308, - SpvOpImageSparseSampleProjImplicitLod = 309, - SpvOpImageSparseSampleProjExplicitLod = 310, - SpvOpImageSparseSampleProjDrefImplicitLod = 311, - SpvOpImageSparseSampleProjDrefExplicitLod = 312, - SpvOpImageSparseFetch = 313, - SpvOpImageSparseGather = 314, - SpvOpImageSparseDrefGather = 315, - SpvOpImageSparseTexelsResident = 316, - SpvOpNoLine = 317, - SpvOpAtomicFlagTestAndSet = 318, - SpvOpAtomicFlagClear = 319, - SpvOpImageSparseRead = 320, - SpvOpSizeOf = 321, - SpvOpTypePipeStorage = 322, - SpvOpConstantPipeStorage = 323, - SpvOpCreatePipeFromPipeStorage = 324, - SpvOpGetKernelLocalSizeForSubgroupCount = 325, - SpvOpGetKernelMaxNumSubgroups = 326, - SpvOpTypeNamedBarrier = 327, - SpvOpNamedBarrierInitialize = 328, - SpvOpMemoryNamedBarrier = 329, - SpvOpModuleProcessed = 330, - SpvOpExecutionModeId = 331, - SpvOpDecorateId = 332, - SpvOpGroupNonUniformElect = 333, - SpvOpGroupNonUniformAll = 334, - SpvOpGroupNonUniformAny = 335, - SpvOpGroupNonUniformAllEqual = 336, - SpvOpGroupNonUniformBroadcast = 337, - SpvOpGroupNonUniformBroadcastFirst = 338, - SpvOpGroupNonUniformBallot = 339, - SpvOpGroupNonUniformInverseBallot = 340, - SpvOpGroupNonUniformBallotBitExtract = 341, - SpvOpGroupNonUniformBallotBitCount = 342, - SpvOpGroupNonUniformBallotFindLSB = 343, - SpvOpGroupNonUniformBallotFindMSB = 344, - SpvOpGroupNonUniformShuffle = 345, - SpvOpGroupNonUniformShuffleXor = 346, - SpvOpGroupNonUniformShuffleUp = 347, - SpvOpGroupNonUniformShuffleDown = 348, - SpvOpGroupNonUniformIAdd = 349, - SpvOpGroupNonUniformFAdd = 350, - SpvOpGroupNonUniformIMul = 351, - SpvOpGroupNonUniformFMul = 352, - SpvOpGroupNonUniformSMin = 353, - SpvOpGroupNonUniformUMin = 354, - SpvOpGroupNonUniformFMin = 355, - SpvOpGroupNonUniformSMax = 356, - SpvOpGroupNonUniformUMax = 357, - SpvOpGroupNonUniformFMax = 358, - SpvOpGroupNonUniformBitwiseAnd = 359, - SpvOpGroupNonUniformBitwiseOr = 360, - SpvOpGroupNonUniformBitwiseXor = 361, - SpvOpGroupNonUniformLogicalAnd = 362, - SpvOpGroupNonUniformLogicalOr = 363, - SpvOpGroupNonUniformLogicalXor = 364, - SpvOpGroupNonUniformQuadBroadcast = 365, - SpvOpGroupNonUniformQuadSwap = 366, - SpvOpCopyLogical = 400, - SpvOpPtrEqual = 401, - SpvOpPtrNotEqual = 402, - SpvOpPtrDiff = 403, - SpvOpTerminateInvocation = 4416, - SpvOpSubgroupBallotKHR = 4421, - SpvOpSubgroupFirstInvocationKHR = 4422, - SpvOpSubgroupAllKHR = 4428, - SpvOpSubgroupAnyKHR = 4429, - SpvOpSubgroupAllEqualKHR = 4430, - SpvOpGroupNonUniformRotateKHR = 4431, - SpvOpSubgroupReadInvocationKHR = 4432, - SpvOpTraceRayKHR = 4445, - SpvOpExecuteCallableKHR = 4446, - SpvOpConvertUToAccelerationStructureKHR = 4447, - SpvOpIgnoreIntersectionKHR = 4448, - SpvOpTerminateRayKHR = 4449, - SpvOpSDot = 4450, - SpvOpSDotKHR = 4450, - SpvOpUDot = 4451, - SpvOpUDotKHR = 4451, - SpvOpSUDot = 4452, - SpvOpSUDotKHR = 4452, - SpvOpSDotAccSat = 4453, - SpvOpSDotAccSatKHR = 4453, - SpvOpUDotAccSat = 4454, - SpvOpUDotAccSatKHR = 4454, - SpvOpSUDotAccSat = 4455, - SpvOpSUDotAccSatKHR = 4455, - SpvOpTypeRayQueryKHR = 4472, - SpvOpRayQueryInitializeKHR = 4473, - SpvOpRayQueryTerminateKHR = 4474, - SpvOpRayQueryGenerateIntersectionKHR = 4475, - SpvOpRayQueryConfirmIntersectionKHR = 4476, - SpvOpRayQueryProceedKHR = 4477, - SpvOpRayQueryGetIntersectionTypeKHR = 4479, - SpvOpGroupIAddNonUniformAMD = 5000, - SpvOpGroupFAddNonUniformAMD = 5001, - SpvOpGroupFMinNonUniformAMD = 5002, - SpvOpGroupUMinNonUniformAMD = 5003, - SpvOpGroupSMinNonUniformAMD = 5004, - SpvOpGroupFMaxNonUniformAMD = 5005, - SpvOpGroupUMaxNonUniformAMD = 5006, - SpvOpGroupSMaxNonUniformAMD = 5007, - SpvOpFragmentMaskFetchAMD = 5011, - SpvOpFragmentFetchAMD = 5012, - SpvOpReadClockKHR = 5056, - SpvOpImageSampleFootprintNV = 5283, - SpvOpEmitMeshTasksEXT = 5294, - SpvOpSetMeshOutputsEXT = 5295, - SpvOpGroupNonUniformPartitionNV = 5296, - SpvOpWritePackedPrimitiveIndices4x8NV = 5299, - SpvOpReportIntersectionKHR = 5334, - SpvOpReportIntersectionNV = 5334, - SpvOpIgnoreIntersectionNV = 5335, - SpvOpTerminateRayNV = 5336, - SpvOpTraceNV = 5337, - SpvOpTraceMotionNV = 5338, - SpvOpTraceRayMotionNV = 5339, - SpvOpTypeAccelerationStructureKHR = 5341, - SpvOpTypeAccelerationStructureNV = 5341, - SpvOpExecuteCallableNV = 5344, - SpvOpTypeCooperativeMatrixNV = 5358, - SpvOpCooperativeMatrixLoadNV = 5359, - SpvOpCooperativeMatrixStoreNV = 5360, - SpvOpCooperativeMatrixMulAddNV = 5361, - SpvOpCooperativeMatrixLengthNV = 5362, - SpvOpBeginInvocationInterlockEXT = 5364, - SpvOpEndInvocationInterlockEXT = 5365, - SpvOpDemoteToHelperInvocation = 5380, - SpvOpDemoteToHelperInvocationEXT = 5380, - SpvOpIsHelperInvocationEXT = 5381, - SpvOpConvertUToImageNV = 5391, - SpvOpConvertUToSamplerNV = 5392, - SpvOpConvertImageToUNV = 5393, - SpvOpConvertSamplerToUNV = 5394, - SpvOpConvertUToSampledImageNV = 5395, - SpvOpConvertSampledImageToUNV = 5396, - SpvOpSamplerImageAddressingModeNV = 5397, - SpvOpSubgroupShuffleINTEL = 5571, - SpvOpSubgroupShuffleDownINTEL = 5572, - SpvOpSubgroupShuffleUpINTEL = 5573, - SpvOpSubgroupShuffleXorINTEL = 5574, - SpvOpSubgroupBlockReadINTEL = 5575, - SpvOpSubgroupBlockWriteINTEL = 5576, - SpvOpSubgroupImageBlockReadINTEL = 5577, - SpvOpSubgroupImageBlockWriteINTEL = 5578, - SpvOpSubgroupImageMediaBlockReadINTEL = 5580, - SpvOpSubgroupImageMediaBlockWriteINTEL = 5581, - SpvOpUCountLeadingZerosINTEL = 5585, - SpvOpUCountTrailingZerosINTEL = 5586, - SpvOpAbsISubINTEL = 5587, - SpvOpAbsUSubINTEL = 5588, - SpvOpIAddSatINTEL = 5589, - SpvOpUAddSatINTEL = 5590, - SpvOpIAverageINTEL = 5591, - SpvOpUAverageINTEL = 5592, - SpvOpIAverageRoundedINTEL = 5593, - SpvOpUAverageRoundedINTEL = 5594, - SpvOpISubSatINTEL = 5595, - SpvOpUSubSatINTEL = 5596, - SpvOpIMul32x16INTEL = 5597, - SpvOpUMul32x16INTEL = 5598, - SpvOpConstantFunctionPointerINTEL = 5600, - SpvOpFunctionPointerCallINTEL = 5601, - SpvOpAsmTargetINTEL = 5609, - SpvOpAsmINTEL = 5610, - SpvOpAsmCallINTEL = 5611, - SpvOpAtomicFMinEXT = 5614, - SpvOpAtomicFMaxEXT = 5615, - SpvOpAssumeTrueKHR = 5630, - SpvOpExpectKHR = 5631, - SpvOpDecorateString = 5632, - SpvOpDecorateStringGOOGLE = 5632, - SpvOpMemberDecorateString = 5633, - SpvOpMemberDecorateStringGOOGLE = 5633, - SpvOpVmeImageINTEL = 5699, - SpvOpTypeVmeImageINTEL = 5700, - SpvOpTypeAvcImePayloadINTEL = 5701, - SpvOpTypeAvcRefPayloadINTEL = 5702, - SpvOpTypeAvcSicPayloadINTEL = 5703, - SpvOpTypeAvcMcePayloadINTEL = 5704, - SpvOpTypeAvcMceResultINTEL = 5705, - SpvOpTypeAvcImeResultINTEL = 5706, - SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, - SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, - SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709, - SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710, - SpvOpTypeAvcRefResultINTEL = 5711, - SpvOpTypeAvcSicResultINTEL = 5712, - SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, - SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, - SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, - SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, - SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, - SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, - SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, - SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, - SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, - SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, - SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, - SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, - SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, - SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, - SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, - SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, - SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, - SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, - SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, - SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732, - SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733, - SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, - SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735, - SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, - SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737, - SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738, - SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739, - SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, - SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, - SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, - SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743, - SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, - SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, - SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, - SpvOpSubgroupAvcImeInitializeINTEL = 5747, - SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748, - SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749, - SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750, - SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, - SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, - SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, - SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, - SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, - SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, - SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765, - SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, - SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, - SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, - SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, - SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, - SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, - SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, - SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, - SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, - SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, - SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776, - SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, - SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, - SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, - SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, - SpvOpSubgroupAvcFmeInitializeINTEL = 5781, - SpvOpSubgroupAvcBmeInitializeINTEL = 5782, - SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, - SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, - SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, - SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, - SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, - SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, - SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, - SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790, - SpvOpSubgroupAvcSicInitializeINTEL = 5791, - SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792, - SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, - SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, - SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, - SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, - SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, - SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, - SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, - SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, - SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, - SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, - SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803, - SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, - SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, - SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, - SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, - SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808, - SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, - SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, - SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, - SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, - SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, - SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, - SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, - SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816, - SpvOpVariableLengthArrayINTEL = 5818, - SpvOpSaveMemoryINTEL = 5819, - SpvOpRestoreMemoryINTEL = 5820, - SpvOpArbitraryFloatSinCosPiINTEL = 5840, - SpvOpArbitraryFloatCastINTEL = 5841, - SpvOpArbitraryFloatCastFromIntINTEL = 5842, - SpvOpArbitraryFloatCastToIntINTEL = 5843, - SpvOpArbitraryFloatAddINTEL = 5846, - SpvOpArbitraryFloatSubINTEL = 5847, - SpvOpArbitraryFloatMulINTEL = 5848, - SpvOpArbitraryFloatDivINTEL = 5849, - SpvOpArbitraryFloatGTINTEL = 5850, - SpvOpArbitraryFloatGEINTEL = 5851, - SpvOpArbitraryFloatLTINTEL = 5852, - SpvOpArbitraryFloatLEINTEL = 5853, - SpvOpArbitraryFloatEQINTEL = 5854, - SpvOpArbitraryFloatRecipINTEL = 5855, - SpvOpArbitraryFloatRSqrtINTEL = 5856, - SpvOpArbitraryFloatCbrtINTEL = 5857, - SpvOpArbitraryFloatHypotINTEL = 5858, - SpvOpArbitraryFloatSqrtINTEL = 5859, - SpvOpArbitraryFloatLogINTEL = 5860, - SpvOpArbitraryFloatLog2INTEL = 5861, - SpvOpArbitraryFloatLog10INTEL = 5862, - SpvOpArbitraryFloatLog1pINTEL = 5863, - SpvOpArbitraryFloatExpINTEL = 5864, - SpvOpArbitraryFloatExp2INTEL = 5865, - SpvOpArbitraryFloatExp10INTEL = 5866, - SpvOpArbitraryFloatExpm1INTEL = 5867, - SpvOpArbitraryFloatSinINTEL = 5868, - SpvOpArbitraryFloatCosINTEL = 5869, - SpvOpArbitraryFloatSinCosINTEL = 5870, - SpvOpArbitraryFloatSinPiINTEL = 5871, - SpvOpArbitraryFloatCosPiINTEL = 5872, - SpvOpArbitraryFloatASinINTEL = 5873, - SpvOpArbitraryFloatASinPiINTEL = 5874, - SpvOpArbitraryFloatACosINTEL = 5875, - SpvOpArbitraryFloatACosPiINTEL = 5876, - SpvOpArbitraryFloatATanINTEL = 5877, - SpvOpArbitraryFloatATanPiINTEL = 5878, - SpvOpArbitraryFloatATan2INTEL = 5879, - SpvOpArbitraryFloatPowINTEL = 5880, - SpvOpArbitraryFloatPowRINTEL = 5881, - SpvOpArbitraryFloatPowNINTEL = 5882, - SpvOpLoopControlINTEL = 5887, - SpvOpAliasDomainDeclINTEL = 5911, - SpvOpAliasScopeDeclINTEL = 5912, - SpvOpAliasScopeListDeclINTEL = 5913, - SpvOpFixedSqrtINTEL = 5923, - SpvOpFixedRecipINTEL = 5924, - SpvOpFixedRsqrtINTEL = 5925, - SpvOpFixedSinINTEL = 5926, - SpvOpFixedCosINTEL = 5927, - SpvOpFixedSinCosINTEL = 5928, - SpvOpFixedSinPiINTEL = 5929, - SpvOpFixedCosPiINTEL = 5930, - SpvOpFixedSinCosPiINTEL = 5931, - SpvOpFixedLogINTEL = 5932, - SpvOpFixedExpINTEL = 5933, - SpvOpPtrCastToCrossWorkgroupINTEL = 5934, - SpvOpCrossWorkgroupCastToPtrINTEL = 5938, - SpvOpReadPipeBlockingINTEL = 5946, - SpvOpWritePipeBlockingINTEL = 5947, - SpvOpFPGARegINTEL = 5949, - SpvOpRayQueryGetRayTMinKHR = 6016, - SpvOpRayQueryGetRayFlagsKHR = 6017, - SpvOpRayQueryGetIntersectionTKHR = 6018, - SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, - SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020, - SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, - SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022, - SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, - SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024, - SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025, - SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, - SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, - SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028, - SpvOpRayQueryGetWorldRayDirectionKHR = 6029, - SpvOpRayQueryGetWorldRayOriginKHR = 6030, - SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031, - SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032, - SpvOpAtomicFAddEXT = 6035, - SpvOpTypeBufferSurfaceINTEL = 6086, - SpvOpTypeStructContinuedINTEL = 6090, - SpvOpConstantCompositeContinuedINTEL = 6091, - SpvOpSpecConstantCompositeContinuedINTEL = 6092, - SpvOpControlBarrierArriveINTEL = 6142, - SpvOpControlBarrierWaitINTEL = 6143, - SpvOpGroupIMulKHR = 6401, - SpvOpGroupFMulKHR = 6402, - SpvOpGroupBitwiseAndKHR = 6403, - SpvOpGroupBitwiseOrKHR = 6404, - SpvOpGroupBitwiseXorKHR = 6405, - SpvOpGroupLogicalAndKHR = 6406, - SpvOpGroupLogicalOrKHR = 6407, - SpvOpGroupLogicalXorKHR = 6408, - SpvOpMax = 0x7fffffff, -} SpvOp; - -#ifdef SPV_ENABLE_UTILITY_CODE -#ifndef __cplusplus -#include -#endif -inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { - *hasResult = *hasResultType = false; - switch (opcode) { - default: /* unknown opcode */ break; - case SpvOpNop: *hasResult = false; *hasResultType = false; break; - case SpvOpUndef: *hasResult = true; *hasResultType = true; break; - case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break; - case SpvOpSource: *hasResult = false; *hasResultType = false; break; - case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break; - case SpvOpName: *hasResult = false; *hasResultType = false; break; - case SpvOpMemberName: *hasResult = false; *hasResultType = false; break; - case SpvOpString: *hasResult = true; *hasResultType = false; break; - case SpvOpLine: *hasResult = false; *hasResultType = false; break; - case SpvOpExtension: *hasResult = false; *hasResultType = false; break; - case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break; - case SpvOpExtInst: *hasResult = true; *hasResultType = true; break; - case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break; - case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break; - case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break; - case SpvOpCapability: *hasResult = false; *hasResultType = false; break; - case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break; - case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break; - case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; - case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break; - case SpvOpConstant: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break; - case SpvOpFunction: *hasResult = true; *hasResultType = true; break; - case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break; - case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break; - case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break; - case SpvOpVariable: *hasResult = true; *hasResultType = true; break; - case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break; - case SpvOpLoad: *hasResult = true; *hasResultType = true; break; - case SpvOpStore: *hasResult = false; *hasResultType = false; break; - case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break; - case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break; - case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break; - case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; - case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break; - case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break; - case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break; - case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break; - case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break; - case SpvOpTranspose: *hasResult = true; *hasResultType = true; break; - case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break; - case SpvOpImageGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageRead: *hasResult = true; *hasResultType = true; break; - case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break; - case SpvOpImage: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break; - case SpvOpUConvert: *hasResult = true; *hasResultType = true; break; - case SpvOpSConvert: *hasResult = true; *hasResultType = true; break; - case SpvOpFConvert: *hasResult = true; *hasResultType = true; break; - case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break; - case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break; - case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; - case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; - case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; - case SpvOpBitcast: *hasResult = true; *hasResultType = true; break; - case SpvOpSNegate: *hasResult = true; *hasResultType = true; break; - case SpvOpFNegate: *hasResult = true; *hasResultType = true; break; - case SpvOpIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpFAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpISub: *hasResult = true; *hasResultType = true; break; - case SpvOpFSub: *hasResult = true; *hasResultType = true; break; - case SpvOpIMul: *hasResult = true; *hasResultType = true; break; - case SpvOpFMul: *hasResult = true; *hasResultType = true; break; - case SpvOpUDiv: *hasResult = true; *hasResultType = true; break; - case SpvOpSDiv: *hasResult = true; *hasResultType = true; break; - case SpvOpFDiv: *hasResult = true; *hasResultType = true; break; - case SpvOpUMod: *hasResult = true; *hasResultType = true; break; - case SpvOpSRem: *hasResult = true; *hasResultType = true; break; - case SpvOpSMod: *hasResult = true; *hasResultType = true; break; - case SpvOpFRem: *hasResult = true; *hasResultType = true; break; - case SpvOpFMod: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; - case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; - case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; - case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; - case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break; - case SpvOpDot: *hasResult = true; *hasResultType = true; break; - case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break; - case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break; - case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break; - case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break; - case SpvOpAny: *hasResult = true; *hasResultType = true; break; - case SpvOpAll: *hasResult = true; *hasResultType = true; break; - case SpvOpIsNan: *hasResult = true; *hasResultType = true; break; - case SpvOpIsInf: *hasResult = true; *hasResultType = true; break; - case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break; - case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break; - case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break; - case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break; - case SpvOpOrdered: *hasResult = true; *hasResultType = true; break; - case SpvOpUnordered: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break; - case SpvOpSelect: *hasResult = true; *hasResultType = true; break; - case SpvOpIEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpULessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break; - case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; - case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; - case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break; - case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break; - case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpNot: *hasResult = true; *hasResultType = true; break; - case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break; - case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break; - case SpvOpBitCount: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdx: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdy: *hasResult = true; *hasResultType = true; break; - case SpvOpFwidth: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break; - case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break; - case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break; - case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break; - case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break; - case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; - case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; - case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break; - case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break; - case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break; - case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break; - case SpvOpPhi: *hasResult = true; *hasResultType = true; break; - case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break; - case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break; - case SpvOpLabel: *hasResult = true; *hasResultType = false; break; - case SpvOpBranch: *hasResult = false; *hasResultType = false; break; - case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break; - case SpvOpSwitch: *hasResult = false; *hasResultType = false; break; - case SpvOpKill: *hasResult = false; *hasResultType = false; break; - case SpvOpReturn: *hasResult = false; *hasResultType = false; break; - case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break; - case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break; - case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break; - case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break; - case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break; - case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break; - case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break; - case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break; - case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break; - case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break; - case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; - case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break; - case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break; - case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break; - case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break; - case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; - case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; - case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; - case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; - case SpvOpNoLine: *hasResult = false; *hasResultType = false; break; - case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; - case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break; - case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break; - case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break; - case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; - case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; - case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; - case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; - case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break; - case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break; - case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; - case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break; - case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpSDot: *hasResult = true; *hasResultType = true; break; - case SpvOpUDot: *hasResult = true; *hasResultType = true; break; - case SpvOpSUDot: *hasResult = true; *hasResultType = true; break; - case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break; - case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break; - case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; - case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; - case SpvOpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; - case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; - case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; - case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; - case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; - case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; - case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; - case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; - case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; - case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; - case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; - case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAsmINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpExpectKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break; - case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break; - case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; - } -} -#endif /* SPV_ENABLE_UTILITY_CODE */ - -#endif - diff --git a/src/spvm/state.c b/src/spvm/state.c deleted file mode 100644 index b219d804..00000000 --- a/src/spvm/state.c +++ /dev/null @@ -1,474 +0,0 @@ -#include -#include -#include -#include - -spvm_state_t spvm_state_create(spvm_program_t prog, spvm_state_settings settings) -{ - spvm_state_t state = (spvm_state_t)calloc(1, sizeof(spvm_state)); - - state->owner = prog; - state->code_current = prog->code; - state->results = (spvm_result*)calloc(prog->bound + 1, sizeof(spvm_result)); - state->current_file = NULL; - state->current_line = -1; - state->current_column = -1; - state->current_parameter = 0; - state->return_id = -1; - state->function_stack_count = 0; - state->function_stack_current = 0; - state->function_stack = NULL; - state->context = prog->context; - state->analyzer = NULL; - state->load_variable = settings.load_variable; - state->store_variable = settings.store_variable; - state->log = settings.log; - state->_derivative_is_group_member = settings.is_derv_member; - - state->read_image = spvm_image_read_impl; - state->write_image = spvm_image_write_impl; - - for (size_t i = 0; i < prog->bound; i++) - state->results[i].storage_class = SpvStorageClassMax; - - for (size_t i = 0; i < prog->code_length; i++) { - spvm_word opcode_data = SPVM_READ_WORD(state->code_current); - spvm_word word_count = ((opcode_data & (~SpvOpCodeMask)) >> SpvWordCountShift) - 1; - spvm_word opcode = (opcode_data & SpvOpCodeMask); - spvm_source cur_code = state->code_current; - - if (opcode >= SPVM_OPCODE_TABLE_LENGTH) { - spvm_state_log(state, "opcode out of range: %d", (int) opcode); - } else if (state->context->opcode_setup[opcode]) { - state->context->opcode_setup[opcode](word_count, state); - } - - state->code_current = (cur_code + word_count); - i += word_count; - } - - state->derivative_used = settings.force_derv; - - if (!settings.is_derv_member && state->derivative_used) { - spvm_state_settings derv_settings = settings; - derv_settings.is_derv_member = 1; - - state->derivative_group_x = spvm_state_create(prog, derv_settings); - state->derivative_group_y = spvm_state_create(prog, derv_settings); - state->derivative_group_d = spvm_state_create(prog, derv_settings); - - // setup pointers - // x - state->derivative_group_x->derivative_group_x = state; - state->derivative_group_x->derivative_group_y = state->derivative_group_d; - state->derivative_group_x->derivative_group_d = state->derivative_group_y; - - // y - state->derivative_group_y->derivative_group_x = state->derivative_group_d; - state->derivative_group_y->derivative_group_y = state; - state->derivative_group_y->derivative_group_d = state->derivative_group_x; - - // d - state->derivative_group_d->derivative_group_x = state->derivative_group_y; - state->derivative_group_d->derivative_group_y = state->derivative_group_x; - state->derivative_group_d->derivative_group_d = state; - } - - return state; -} -spvm_result_t spvm_state_get_type_info(spvm_result_t res_list, spvm_result_t res) -{ - if (res->value_type == spvm_value_type_pointer) - return spvm_state_get_type_info(res_list, &res_list[res->pointer]); - return res; -} -void spvm_state_set_extension(spvm_state_t state, const char* name, spvm_ext_opcode_func* ext) -{ - spvm_result_t ptr = spvm_state_get_result(state, name); - if (ptr) ptr->extension = ext; - if (!state->_derivative_is_group_member) { - if (state->derivative_group_x) { - ptr = spvm_state_get_result(state->derivative_group_x, name); - if (ptr) ptr->extension = ext; - } - if (state->derivative_group_y) { - ptr = spvm_state_get_result(state->derivative_group_y, name); - if (ptr) ptr->extension = ext; - } - if (state->derivative_group_d) { - ptr = spvm_state_get_result(state->derivative_group_d, name); - if (ptr) ptr->extension = ext; - } - } -} - -void spvm_state_prepare(spvm_state_t state, spvm_word fnLocation) -{ - state->code_current = state->results[fnLocation].source_location; - state->current_function = &state->results[fnLocation]; - - if (state->function_stack_count == 0) { - state->function_stack_count = 10; - state->function_stack = (spvm_source*)malloc(state->function_stack_count * sizeof(spvm_source)); - state->function_stack_info = (spvm_result_t*)malloc(state->function_stack_count * sizeof(spvm_result_t)); - state->function_stack_returns = (spvm_word*)malloc(state->function_stack_count * sizeof(spvm_word)); - state->function_stack_cfg = (spvm_word*)malloc(state->function_stack_count * sizeof(spvm_word)); - state->function_stack_cfg_parent = (spvm_word*)malloc(state->function_stack_count * sizeof(spvm_word)); - } - - state->function_stack_current = 0; - state->function_stack[0] = state->code_current; - state->function_stack_info[0] = state->current_function; - state->function_stack_cfg[0] = 0; - state->function_stack_cfg_parent[0] = 0; - state->did_jump = 0; - state->discarded = 0; - state->instruction_count = 0; - - if (!state->_derivative_is_group_member) { - if (state->derivative_group_x) spvm_state_prepare(state->derivative_group_x, fnLocation); - if (state->derivative_group_y) spvm_state_prepare(state->derivative_group_y, fnLocation); - if (state->derivative_group_d) spvm_state_prepare(state->derivative_group_d, fnLocation); - } -} -void spvm_state_set_frag_coord(spvm_state_t state, float x, float y, float z, float w) -{ - state->frag_coord[0] = x; - state->frag_coord[1] = y; - state->frag_coord[2] = z; - state->frag_coord[3] = w; - - spvm_word fc_count = 0; - spvm_member_t fc = spvm_state_get_builtin(state, SpvBuiltInFragCoord, &fc_count); - - if (fc) { - for (spvm_word i = 0; i < fc_count; i++) - fc[i].value.f = state->frag_coord[i]; - - if (state->derivative_used && !state->_derivative_is_group_member) { - spvm_byte is_odd_x = ((int)x) % 2 != 0; - spvm_byte is_odd_y = ((int)y) % 2 != 0; - float mod_x = 1, mod_y = 1; - - // setup frag_coord - if (is_odd_x) mod_x = -1; - if (is_odd_y) mod_y = -1; - - spvm_state_set_frag_coord(state->derivative_group_x, x+mod_x, y, z, w); - spvm_state_set_frag_coord(state->derivative_group_y, x, y+mod_y, z, w); - spvm_state_set_frag_coord(state->derivative_group_d, x+mod_x, y+mod_y, z, w); - } - } -} -void spvm_state_copy_uniforms(spvm_state_t dst, spvm_state_t src) -{ - for (unsigned i = 0; i < dst->owner->bound; i++) { - const char* name1 = dst->results[i].name; - if (name1 == NULL) - continue; - - spvm_word ptr = dst->results[i].pointer; - if (dst->results[ptr].storage_class != SpvStorageClassUniform && - dst->results[ptr].storage_class != SpvStorageClassUniformConstant) - continue; - - for (unsigned j = 0; j < src->owner->bound; j++) { - const char* name2 = src->results[j].name; - ptr = src->results[j].pointer; - - if (name2 != NULL) { - ptr = src->results[i].pointer; - if (src->results[ptr].storage_class != SpvStorageClassUniform && - src->results[ptr].storage_class != SpvStorageClassUniformConstant) - continue; - - if (strcmp(name1, name2) == 0) - spvm_member_memcpy(dst->results[i].members, src->results[j].members, dst->results[i].member_count); - } - } - } -} -void spvm_state_group_sync(spvm_state_t state) -{ - if (state->derivative_group_x) spvm_state_jump_to_instruction(state->derivative_group_x, state->instruction_count); - if (state->derivative_group_y) spvm_state_jump_to_instruction(state->derivative_group_y, state->instruction_count); - if (state->derivative_group_d) spvm_state_jump_to_instruction(state->derivative_group_d, state->instruction_count); -} -void spvm_state_group_step(spvm_state_t state) -{ - if (state->derivative_group_x) spvm_state_step_opcode(state->derivative_group_x); - if (state->derivative_group_y) spvm_state_step_opcode(state->derivative_group_y); - if (state->derivative_group_d) spvm_state_step_opcode(state->derivative_group_d); -} - -void spvm_state_step_opcode(spvm_state_t state) -{ - // read data - spvm_word opcode_data = SPVM_READ_WORD(state->code_current); - spvm_word word_count = ((opcode_data & (~SpvOpCodeMask)) >> SpvWordCountShift) - 1; - SpvOp opcode = (opcode_data & SpvOpCodeMask); - spvm_source cur_code = state->code_current; - - if (opcode >= SPVM_OPCODE_TABLE_LENGTH) { - spvm_state_log(state, "opcode out of range: %d", (int) opcode); - } else if (state->context->opcode_execute[opcode]) { - state->context->opcode_execute[opcode](word_count, state); - if (opcode != SpvOpLine && opcode != SpvOpNoLine) - state->instruction_count++; - } - - if (!state->did_jump) - state->code_current = (cur_code + word_count); - else state->did_jump = 0; -} -void spvm_state_step_into(spvm_state_t state) -{ - spvm_word ln = state->current_line; - while (ln == state->current_line && state->code_current) - spvm_state_step_opcode(state); -} -void spvm_state_jump_to(spvm_state_t state, spvm_word line) -{ - while (line != state->current_line && state->code_current) - spvm_state_step_opcode(state); -} -void spvm_state_jump_to_instruction(spvm_state_t state, spvm_word inst) -{ - while (state->instruction_count < inst && state->code_current) - spvm_state_step_opcode(state); -} -void spvm_state_call_function(spvm_state_t state) -{ - while (state->code_current) - spvm_state_step_opcode(state); -} -void spvm_state_ddx(spvm_state_t state, spvm_word id) -{ - if (!state->derivative_group_x) return; - - if (!state->_derivative_is_group_member) - spvm_state_group_sync(state); // first sync the group - - spvm_byte is_even = ((int)state->frag_coord[0]) % 2 == 0; - int index = 0; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - if (state->results[id].members[i].member_count == 0) { - if (is_even) - state->derivative_buffer_x[index] = state->derivative_group_x->results[id].members[i].value.f - state->results[id].members[i].value.f; - else - state->derivative_buffer_x[index] = state->results[id].members[i].value.f - state->derivative_group_x->results[id].members[i].value.f; - index++; - } - else { - if (is_even) { - for (spvm_word j = 0; j < state->results[id].members[i].member_count; j++) - state->derivative_buffer_x[index] = state->derivative_group_x->results[id].members[i].members[j].value.f - state->results[id].members[i].members[j].value.f; - } else { - for (spvm_word j = 0; j < state->results[id].members[i].member_count; j++) - state->derivative_buffer_x[index] = state->results[id].members[i].members[j].value.f - state->derivative_group_x->results[id].members[i].members[j].value.f; - } - index += state->results[id].members[i].member_count; - } - } -} -void spvm_state_ddy(spvm_state_t state, spvm_word id) -{ - if (!state->derivative_group_y) return; - - if (!state->_derivative_is_group_member) - spvm_state_group_sync(state); // first sync the group - - spvm_byte is_even = ((int)state->frag_coord[1]) % 2 == 0; - int index = 0; - - for (spvm_word i = 0; i < state->results[id].member_count; i++) { - if (state->results[id].members[i].member_count == 0) { - if (is_even) - state->derivative_buffer_y[index] = state->derivative_group_y->results[id].members[i].value.f - state->results[id].members[i].value.f; - else - state->derivative_buffer_y[index] = state->results[id].members[i].value.f - state->derivative_group_y->results[id].members[i].value.f; - index++; - } - else { - if (is_even) { - for (spvm_word j = 0; j < state->results[id].members[i].member_count; j++) - state->derivative_buffer_y[index] = state->derivative_group_y->results[id].members[i].members[j].value.f - state->results[id].members[i].members[j].value.f; - } - else { - for (spvm_word j = 0; j < state->results[id].members[i].member_count; j++) - state->derivative_buffer_y[index] = state->results[id].members[i].members[j].value.f - state->derivative_group_y->results[id].members[i].members[j].value.f; - } - index += state->results[id].members[i].member_count; - } - } -} - -spvm_member_t spvm_state_get_builtin(spvm_state_t state, SpvBuiltIn builtin, spvm_word* mem_count) -{ - for (unsigned i = 0; i < state->owner->bound; i++) { - spvm_result_t slot = &state->results[i]; - spvm_result_t type = NULL; - - if (slot->pointer) - type = spvm_state_get_type_info(state->results, &state->results[slot->pointer]); - - if (type == NULL || slot->member_count == 0 || slot->members == NULL) - continue; - - int found = 0; - int index = -1; - for (spvm_word j = 0; j < slot->decoration_count; j++) - if (slot->decorations[j].type == SpvDecorationBuiltIn) { - if (slot->decorations[j].literal1 == (spvm_word)builtin) { - found = 1; - break; - } - } - - for (spvm_word j = 0; j < type->decoration_count; j++) - if (type->decorations[j].type == SpvDecorationBuiltIn) { - if (type->decorations[j].literal1 == (spvm_word)builtin) { - found = 1; - index = type->decorations[j].index; - break; - } - } - - if (found) { - if (index == -1) { - *mem_count = slot->member_count; - return slot->members; - } else { - *mem_count = slot->members[index].member_count; - return slot->members[index].members; - } - } - } - - return NULL; -} -spvm_result_t spvm_state_get_local_result(spvm_state_t state, spvm_result_t fn, const char* str) -{ - for (unsigned i = 0; i < state->owner->bound; i++) - if (state->results[i].name != NULL && strcmp(state->results[i].name, str) == 0 && - state->results[i].owner == fn) - return &state->results[i]; - - return NULL; -} -spvm_word spvm_state_get_result_location(spvm_state_t state, const char* str) -{ - for (unsigned i = 0; i < state->owner->bound; i++) - if (state->results[i].name != NULL && strcmp(state->results[i].name, str) == 0 && state->results[i].owner == NULL) - return i; - - return 0; -} -spvm_result_t spvm_state_get_result(spvm_state_t state, const char* str) -{ - for (unsigned i = 0; i < state->owner->bound; i++) - if (state->results[i].name != NULL && strcmp(state->results[i].name, str) == 0 && state->results[i].owner == NULL) - return &state->results[i]; - - return NULL; -} -spvm_result_t spvm_state_get_result_with_value(spvm_state_t state, const char* str) -{ - for (unsigned i = 0; i < state->owner->bound; i++) - if (state->results[i].name != NULL && strcmp(state->results[i].name, str) == 0 && state->results[i].owner == NULL && state->results[i].members != NULL) - return &state->results[i]; - - return NULL; -} -spvm_member_t spvm_state_get_object_member(spvm_state_t state, spvm_result_t var, const char* member_name) -{ - spvm_result_t type_info = spvm_state_get_type_info(state->results, &state->results[var->pointer]); - spvm_word index = -1; - - for (spvm_word i = 0; i < type_info->member_name_count; i++) - if (strcmp(type_info->member_name[i], member_name) == 0) { - index = i; - break; - } - - if (index == -1) - return NULL; - return &var->members[index]; -} - -void spvm_state_push_function_stack(spvm_state_t state, spvm_result_t func, spvm_word func_res_id) -{ - state->function_stack[state->function_stack_current] = state->code_current; - - state->function_stack_current++; - - if (state->function_stack_current >= state->function_stack_count) { - state->function_stack_count += 10; - state->function_stack = (spvm_source*)realloc(state->function_stack, state->function_stack_count * sizeof(spvm_source)); - state->function_stack_info = (spvm_result_t*)realloc(state->function_stack_info, state->function_stack_count * sizeof(spvm_result_t)); - state->function_stack_returns = (spvm_word*)realloc(state->function_stack_returns, state->function_stack_count * sizeof(spvm_word)); - state->function_stack_cfg = (spvm_word*)realloc(state->function_stack_cfg, state->function_stack_count * sizeof(spvm_word)); - state->function_stack_cfg_parent = (spvm_word*)realloc(state->function_stack_cfg_parent, state->function_stack_count * sizeof(spvm_word)); - } - - state->function_stack[state->function_stack_current] = func->source_location; - state->function_stack_info[state->function_stack_current] = func; - state->function_stack_returns[state->function_stack_current] = func_res_id; - state->function_stack_cfg[state->function_stack_current] = 0; - state->function_stack_cfg_parent[state->function_stack_current] = 0; - - state->code_current = func->source_location; - state->current_function = func; - - state->did_jump = 1; -} -void spvm_state_pop_function_stack(spvm_state_t state) -{ - if (state->return_id >= 0) { - spvm_word store_id = state->function_stack_returns[state->function_stack_current]; - spvm_member_memcpy(state->results[store_id].members, state->results[state->return_id].members, state->results[store_id].member_count); - } - - state->function_stack_current--; - - if (state->function_stack_current < 0) { - state->code_current = NULL; - state->current_function = NULL; - } else { - state->code_current = state->function_stack[state->function_stack_current]; - state->current_function = state->function_stack_info[state->function_stack_current]; - } - - state->did_jump = 1; -} -void spvm_state_delete(spvm_state_t state) -{ - for (unsigned i = 0; i < state->owner->bound; i++) { - spvm_result_t res = &state->results[i]; - spvm_result_delete(res); - } - - if (state->function_stack_count) { - free(state->function_stack); - free(state->function_stack_info); - free(state->function_stack_returns); - free(state->function_stack_cfg); - free(state->function_stack_cfg_parent); - } - - free(state->results); - free(state); -} -void spvm_state_log(struct spvm_state* state, const char* fmt, ...) -{ - va_list vargs; - va_start(vargs, fmt); - - if (state->log) { - state->log(state, fmt, vargs); - } - - va_end(vargs); -} - diff --git a/src/spvm/state.h b/src/spvm/state.h deleted file mode 100644 index 169479ab..00000000 --- a/src/spvm/state.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef __SPIRV_VM_STATE_H__ -#define __SPIRV_VM_STATE_H__ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -struct spvm_state; -struct spvm_image; - -typedef struct spvm_stack_entry { - spvm_source source; - spvm_result_t function; - spvm_word function_stack_returns; - spvm_word function_stack_cfg; - const char* file; - spvm_word line; -} spvm_stack_entry; - -typedef struct spvm_member_list { - unsigned member_count; - spvm_member* members; -} spvm_member_list; - -// When loading: should evaluate the OpVariable varID with the given access chain -// indiices and copy it into the given members list. The members are already -// initialized to the correct types, just their values need to be set. -// When storing: should take the given members and store them into the -// memory pointed to by the given varID and access chain indices. -typedef void(*spvm_access_variable_fn)(struct spvm_state*, unsigned varID, - unsigned index_count, const spvm_word* indices, - spvm_member_list members, spvm_word res_type_id); -typedef unsigned(*spvm_array_length_fn)(struct spvm_state*, unsigned varID, - unsigned index_count, const spvm_word* indices); - -typedef spvm_vec4f (*spvm_image_read_fn)(struct spvm_state*, struct spvm_image*, - int x, int y, int z, int layer, int level); -typedef void (*spvm_image_write_fn)(struct spvm_state*, struct spvm_image*, - int x, int y, int z, int layer, int level, const spvm_vec4f* data); - -typedef void(*spvm_log_fn)(struct spvm_state*, const char* fmt, va_list); - -typedef struct spvm_state { - spvm_context_t context; - spvm_program_t owner; - spvm_source code_current; // current position in the code - spvm_result* results; - - spvm_byte did_jump; - spvm_byte discarded; - - spvm_result_t current_function; - - spvm_word current_parameter; - - spvm_word function_stack_current; - spvm_word function_stack_count; - spvm_source* function_stack; - spvm_result_t* function_stack_info; - spvm_word return_id; - spvm_word* function_stack_returns; - spvm_word* function_stack_cfg; - spvm_word* function_stack_cfg_parent; - - void(*emit_vertex)(struct spvm_state*, spvm_word); - void(*end_primitive)(struct spvm_state*, spvm_word); - - void(*control_barrier)(struct spvm_state*, spvm_word, spvm_word, spvm_word); - - // Will be called every time the shader accesses a variable. - // Will only be called while executing code, not during setup. - // TODO: maybe just pass id of AccessChain in case of access chain store/load? - // Would allow removing the indices from the call, letting the caller - // figure it out. And would probably allow the caller to use the - // members of the result as cache. - spvm_access_variable_fn load_variable; - spvm_access_variable_fn store_variable; - spvm_array_length_fn array_length; - - spvm_image_read_fn read_image; - spvm_image_write_fn write_image; - spvm_log_fn log; - - float frag_coord[4]; - - // derivative group - spvm_byte _derivative_is_group_member; - spvm_byte derivative_used; - float derivative_buffer_x[16]; - float derivative_buffer_y[16]; - struct spvm_state* derivative_group_x; // right - struct spvm_state* derivative_group_y; // bottom - struct spvm_state* derivative_group_d; // bottom right / diagonal - - // debug information - const char* current_file; - spvm_word current_line; - spvm_word current_column; - spvm_word instruction_count; - - // pointer to analyzer - spvm_analyzer_t analyzer; - - void* user_data; -} spvm_state; -typedef spvm_state* spvm_state_t; - -typedef struct spvm_state_settings { - spvm_access_variable_fn load_variable; - spvm_access_variable_fn store_variable; - spvm_log_fn log; - - spvm_byte force_derv; - spvm_byte is_derv_member; -} spvm_state_settings; - -spvm_result_t spvm_state_get_type_info(spvm_result_t res_list, spvm_result_t res); - -spvm_state_t spvm_state_create(spvm_program_t prog, spvm_state_settings); -void spvm_state_set_extension(spvm_state_t state, const char* name, spvm_ext_opcode_func* ext); -void spvm_state_call_function(spvm_state_t state); -void spvm_state_prepare(spvm_state_t state, spvm_word fnLocation); -void spvm_state_copy_uniforms(spvm_state_t dst, spvm_state_t src); -void spvm_state_set_frag_coord(spvm_state_t state, float x, float y, float z, float w); -void spvm_state_ddx(spvm_state_t state, spvm_word id); -void spvm_state_ddy(spvm_state_t state, spvm_word id); -void spvm_state_group_sync(spvm_state_t state); -void spvm_state_group_step(spvm_state_t state); -void spvm_state_step_opcode(spvm_state_t state); -void spvm_state_step_into(spvm_state_t state); -void spvm_state_jump_to(spvm_state_t state, spvm_word line); -void spvm_state_jump_to_instruction(spvm_state_t state, spvm_word instruction_count); -spvm_word spvm_state_get_result_location(spvm_state_t state, const char* str); -spvm_member_t spvm_state_get_builtin(spvm_state_t state, SpvBuiltIn decor, spvm_word* mem_count); -spvm_result_t spvm_state_get_result(spvm_state_t state, const char* str); -spvm_result_t spvm_state_get_result_with_value(spvm_state_t state, const char* str); -spvm_result_t spvm_state_get_local_result(spvm_state_t state, spvm_result_t fn, const char* str); -spvm_member_t spvm_state_get_object_member(spvm_state_t state, spvm_result_t var, const char* member_name); -void spvm_state_push_function_stack(spvm_state_t state, spvm_result_t func, spvm_word func_res_id); -void spvm_state_pop_function_stack(spvm_state_t state); -void spvm_state_delete(spvm_state_t state); -void spvm_state_log(struct spvm_state* state, const char* fmt, ...); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SPIRV_VM_STATE_H__ diff --git a/src/spvm/types.c b/src/spvm/types.c deleted file mode 100644 index 8d4c824b..00000000 --- a/src/spvm/types.c +++ /dev/null @@ -1,45 +0,0 @@ -#include - -void spvm_string_read(spvm_source spv, spvm_string str, spvm_word length) -{ - while (length) { - spvm_word word = SPVM_READ_WORD(spv); - - str[0] = (word & 0x000000FF); - str[1] = (word & 0x0000FF00) >> 8; - str[2] = (word & 0x00FF0000) >> 16; - str[3] = (word & 0xFF000000) >> 24; - str += 4; - - length--; - } -} -spvm_string spvm_string_read_all(spvm_source spv, spvm_word* length) -{ - spvm_word word_count = 8; - spvm_string ret = (spvm_string)malloc(word_count * sizeof(spvm_word)); - spvm_byte run = 1; - - spvm_string start = ret; - - while (run) { - spvm_word word = SPVM_READ_WORD(spv); - - ret[0] = (word & 0x000000FF); - ret[1] = (word & 0x0000FF00) >> 8; - ret[2] = (word & 0x00FF0000) >> 16; - ret[3] = (word & 0xFF000000) >> 24; - (*length)++; - - if (ret[3] == 0) - run = 0; - else if (*length >= word_count) { - word_count += 8; - ret = start = (spvm_string)realloc(start, word_count * sizeof(spvm_word)); - ret += (*length) * 4; - } - else ret += 4; - } - - return start; -} \ No newline at end of file diff --git a/src/spvm/types.h b/src/spvm/types.h deleted file mode 100644 index eafc45e5..00000000 --- a/src/spvm/types.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __SPIRV_VM_TYPES_H__ -#define __SPIRV_VM_TYPES_H__ - -#include - -typedef unsigned char spvm_byte; -typedef int spvm_word; -typedef const spvm_word* spvm_source; -typedef char* spvm_string; -struct spvm_state; - -#define SPVM_READ_WORD(spv) *((spv)++) -#define SPVM_SKIP_WORD(spv) ((spv)++) - -void spvm_string_read(spvm_source spv, spvm_string str, spvm_word length); -spvm_string spvm_string_read_all(spvm_source spv, spvm_word* length); - -#endif // __SPIRV_VM_TYPES_H__ diff --git a/src/spvm/value.c b/src/spvm/value.c deleted file mode 100644 index 96000ab9..00000000 --- a/src/spvm/value.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -void spvm_member_free(spvm_member_t source, spvm_word value_count) -{ - for (spvm_word i = 0; i < value_count; i++) - if (source[i].member_count) - spvm_member_free(source[i].members, source[i].member_count); - - free(source); -} -void spvm_member_memcpy(spvm_member_t target, spvm_member_t source, spvm_word value_count) -{ - for (spvm_word i = 0; i < value_count; i++) { - target[i].value.u = source[i].value.u; - - assert(target[i].member_count == source[i].member_count); - if (target[i].member_count != 0) { - spvm_member_memcpy(target[i].members, source[i].members, target[i].member_count); - } - } -} - -void spvm_member_set_value_f(spvm_member_t mems, size_t mem_count, float* f) -{ - if (mems != NULL && mem_count != 0) - for (unsigned i = 0; i < mem_count; i++) { - if (mems[i].member_count == 0) - mems[i].value.f = f[i]; - else - for (spvm_word j = 0; j < mems[i].member_count; j++) - mems[i].members[j].value.f = f[i * mems[i].member_count + j]; - } -} -void spvm_member_set_value_i(spvm_member_t mems, size_t mem_count, int* d) -{ - if (mems != NULL && mem_count != 0) - for (unsigned i = 0; i < mem_count; i++) - mems[i].value.s = d[i]; -} - diff --git a/src/spvm/value.h b/src/spvm/value.h deleted file mode 100644 index 4a6cab34..00000000 --- a/src/spvm/value.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef __SPIRV_VM_VALUE_H__ -#define __SPIRV_VM_VALUE_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#define SPVM_MAX(x, y) (((x) > (y)) ? (x) : (y)) -#define SPVM_MIN(x, y) (((x) < (y)) ? (x) : (y)) -#define SPVM_CLAMP(x, minVal, maxVal) SPVM_MIN(SPVM_MAX((x), (minVal)), (maxVal)) -#define SPVM_NMAX(x, y) (isnan(x) ? (y) : (isnan(y) ? (x) : SPVM_MAX(x,y))) -#define SPVM_NMIN(x, y) (isnan(x) ? (y) : (isnan(y) ? (x) : SPVM_MIN(x,y))) -#define SPVM_NCLAMP(x, minVal, maxVal) SPVM_NMIN(SPVM_NMAX((x), (minVal)), (maxVal)) -#define SPVM_SIGN(x) ((x) > 0) - ((x) < 0) - -enum spvm_value_type -{ - spvm_value_type_void, - spvm_value_type_bool, - spvm_value_type_int, - spvm_value_type_float, - spvm_value_type_vector, - spvm_value_type_matrix, - spvm_value_type_array, - spvm_value_type_runtime_array, - spvm_value_type_struct, - spvm_value_type_image, - spvm_value_type_sampler, - spvm_value_type_sampled_image, - spvm_value_type_pointer, -}; - -typedef struct spvm_member { - spvm_word type; - - union spvm_value - { - float f; - double d; - long long s; - unsigned long long u; - char b; - spvm_image* image; - spvm_sampler* sampler; - } value; - - spvm_word member_count; - struct spvm_member* members; -} spvm_member; -typedef spvm_member* spvm_member_t; - -void spvm_member_free(spvm_member_t source, spvm_word value_count); -void spvm_member_memcpy(spvm_member_t target, spvm_member_t source, spvm_word value_count); - -void spvm_member_set_value_f(spvm_member_t mems, size_t mem_count, float* f); -void spvm_member_set_value_i(spvm_member_t mems, size_t mem_count, int* d); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // __SPIRV_VM_VALUE_H__ diff --git a/src/util/patch.cpp b/src/util/patch.cpp index 0ac26c30..986a4a7b 100644 --- a/src/util/patch.cpp +++ b/src/util/patch.cpp @@ -150,11 +150,16 @@ struct ShaderPatch { u32 funcInstrOffset {}; u32 typeBool = u32(-1); + u32 typeFloat = u32(-1); + u32 typeFloat4 = u32(-1); u32 typeUint = u32(-1); u32 typeUint2 = u32(-1); u32 typeUint3 = u32(-1); u32 typeBool3 = u32(-1); + u32 const0 = u32(-1); + u32 const1 = u32(-1); + LinAllocator alloc {}; template @@ -166,8 +171,11 @@ struct ShaderPatch { FuncInstrBuilder instr(spv::Op op); - // template - // FuncInstrBuilder instr(spv::Op op, Args... args); + template + void instr(spv::Op op, Args... args); + + template + u32 genOp(spv::Op op, u32 type, Args... args); }; struct FuncInstrBuilder : InstrBuilder { @@ -208,11 +216,18 @@ FuncInstrBuilder ShaderPatch::instr(spv::Op op) { return {op, *this}; } -// template -// FuncInstrBuilder ShaderPatch::instr(spv::Op op, Args... args) { -// auto builder = instr(op); -// (builder.push(args), ...); -// } +template +u32 ShaderPatch::genOp(spv::Op op, u32 type, Args... args) { + auto id = ++freeID; + instr(op, type, id, args...); + return id; +} + +template +void ShaderPatch::instr(spv::Op op, Args... args) { + auto builder = instr(op); + (builder.push(args), ...); +} u32 declareBufferStruct(ShaderPatch& patch, u32 captureStruct) { const u32 inputStruct = ++patch.freeID; @@ -251,11 +266,14 @@ u32 declareBufferStruct(ShaderPatch& patch, u32 captureStruct) { return bufferStruct; } -void findDeclareScalarTypes(ShaderPatch& patch) { +void findDeclareBaseTypes(ShaderPatch& patch) { + // spir-v does not allow duplicate declarations of non-aggregate types patch.typeBool = u32(-1); + patch.typeFloat = u32(-1); patch.typeUint = u32(-1); patch.typeUint2 = u32(-1); patch.typeUint3 = u32(-1); + patch.typeFloat4 = u32(-1); for(auto& id : patch.compiler.get_ir().ids) { if(id.get_type() != spc::TypeType) { @@ -267,6 +285,7 @@ void findDeclareScalarTypes(ShaderPatch& patch) { continue; } + // scalar if(type.basetype == spc::SPIRType::UInt && type.columns == 1u && type.vecsize == 1u && type.width == 32u) { @@ -274,27 +293,51 @@ void findDeclareScalarTypes(ShaderPatch& patch) { patch.typeUint = id.get_id(); } + if(type.basetype == spc::SPIRType::Boolean && + type.columns == 1u && type.vecsize == 1u) { + dlg_assert(patch.typeBool == u32(-1)); + patch.typeBool = id.get_id(); + } + + if(type.basetype == spc::SPIRType::Float && + type.columns == 1u && type.vecsize == 1u && + type.width == 32u) { + dlg_assert(patch.typeFloat == u32(-1)); + patch.typeFloat = id.get_id(); + } + + // vector + if(type.basetype == spc::SPIRType::Float && + type.columns == 1u && type.vecsize == 4u && + type.width == 32u) { + dlg_assert(patch.typeFloat4 == u32(-1)); + patch.typeFloat4 = id.get_id(); + } if(type.basetype == spc::SPIRType::UInt && type.columns == 1u && type.vecsize == 2u && type.width == 32u) { dlg_assert(patch.typeUint2 == u32(-1)); patch.typeUint2 = id.get_id(); } - if(type.basetype == spc::SPIRType::UInt && type.columns == 1u && type.vecsize == 3u && type.width == 32u) { dlg_assert(patch.typeUint3 == u32(-1)); patch.typeUint3 = id.get_id(); } - if(type.basetype == spc::SPIRType::Boolean && - type.columns == 1u && type.vecsize == 1u) { - dlg_assert(patch.typeBool == u32(-1)); - patch.typeBool = id.get_id(); + type.columns == 1u && type.vecsize == 3u && + type.width == 32u) { + dlg_assert(patch.typeBool3 == u32(-1)); + patch.typeBool3 = id.get_id(); } } + // scalars + if(patch.typeBool == u32(-1)) { + patch.typeBool = ++patch.freeID; + patch.decl().push(patch.typeBool); + } if(patch.typeUint == u32(-1)) { patch.typeUint = ++patch.freeID; patch.decl() @@ -302,6 +345,21 @@ void findDeclareScalarTypes(ShaderPatch& patch) { .push(32) .push(0); } + if(patch.typeFloat == u32(-1)) { + patch.typeFloat = ++patch.freeID; + patch.decl() + .push(patch.typeFloat) + .push(32); + } + // vectors + if(patch.typeBool3 == u32(-1)) { + patch.typeBool3 = ++patch.freeID; + patch.decl() + .push(patch.typeBool3) + .push(patch.typeBool) + .push(3); + } + if(patch.typeUint2 == u32(-1)) { patch.typeUint2 = ++patch.freeID; patch.decl() @@ -316,16 +374,20 @@ void findDeclareScalarTypes(ShaderPatch& patch) { .push(patch.typeUint) .push(3); } - if(patch.typeBool == u32(-1)) { - patch.typeBool = ++patch.freeID; - patch.decl().push(patch.typeBool); + if(patch.typeFloat4 == u32(-1)) { + patch.typeFloat4 = ++patch.freeID; + patch.decl() + .push(patch.typeFloat4) + .push(patch.typeFloat) + .push(4); } +} - patch.typeBool3 = ++patch.freeID; - patch.decl() - .push(patch.typeBool3) - .push(patch.typeBool) - .push(3); +void declareConstants(ShaderPatch& patch) { + patch.const0 = ++patch.freeID; + patch.const1 = ++patch.freeID; + patch.decl().push(patch.typeUint).push(patch.const0).push(0); + patch.decl().push(patch.typeUint).push(patch.const1).push(1); } struct VariableCapture { @@ -391,6 +453,116 @@ void fixDecorateCaptureType(ShaderPatch& patch, Type& type) { } } +u32 findBuiltin(ShaderPatch& patch, + const spc::SPIREntryPoint& entryPoint, spv::BuiltIn builtinType) { + auto& compiler = patch.compiler; + + u32 ret = u32(-1); + for(auto& builtin : compiler.get_shader_resources().builtin_inputs) { + if(builtin.builtin == builtinType) { + auto varID = builtin.resource.id; + if(contains(entryPoint.interface_variables, varID)) { + ret = varID; + break; + } + } + } + + return ret; +} + +u32 findOrDeclareBuiltinInput(ShaderPatch& patch, + const spc::SPIREntryPoint& entryPoint, spv::BuiltIn builtinType, u32 type) { + u32 id = findBuiltin(patch, entryPoint, builtinType); + if(id != u32(-1)) { + return id; + } + + auto pointerType = ++patch.freeID; + + patch.decl() + .push(pointerType) + .push(spv::StorageClassInput) + .push(type); + + auto varID = ++patch.freeID; + patch.decl() + .push(pointerType) + .push(varID) + .push(spv::StorageClassInput); + + return varID; +} + +u32 generateInvocationCompute(ShaderPatch& patch, + const spc::SPIREntryPoint& entryPoint) { + u32 globalInvocationVar = findOrDeclareBuiltinInput(patch, entryPoint, + spv::BuiltInGlobalInvocationId, patch.typeUint3); + return patch.genOp(spv::OpLoad, patch.typeUint3, globalInvocationVar); +} + +u32 generateInvocationVertex(ShaderPatch& patch, + const spc::SPIREntryPoint& entryPoint) { + u32 drawIndexVar = findOrDeclareBuiltinInput(patch, entryPoint, + spv::BuiltInDrawIndex, patch.typeUint); + u32 instanceIndexVar = findOrDeclareBuiltinInput(patch, entryPoint, + spv::BuiltInInstanceIndex, patch.typeUint); + u32 vertexIndexVar = findOrDeclareBuiltinInput(patch, entryPoint, + spv::BuiltInVertexIndex, patch.typeUint); + + auto drawIndex = patch.genOp(spv::OpLoad, patch.typeUint, drawIndexVar); + auto instanceIndex = patch.genOp(spv::OpLoad, patch.typeUint, instanceIndexVar); + auto vertexIndex = patch.genOp(spv::OpLoad, patch.typeUint, vertexIndexVar); + auto composited = patch.genOp(spv::OpCompositeConstruct, patch.typeUint3, + drawIndex, instanceIndex, vertexIndex); + + return composited; +} + +u32 generateInvocationFragment(ShaderPatch& patch, + const spc::SPIREntryPoint& entryPoint) { + u32 positionVar = findOrDeclareBuiltinInput(patch, entryPoint, + spv::BuiltInFragCoord, patch.typeFloat4); + + u32 fx = patch.genOp(spv::OpCompositeExtract, patch.typeFloat, positionVar, 0); + u32 fy = patch.genOp(spv::OpCompositeExtract, patch.typeFloat, positionVar, 0); + u32 ux = patch.genOp(spv::OpConvertFToU, patch.typeUint, fx); + u32 uy = patch.genOp(spv::OpConvertFToU, patch.typeUint, fy); + u32 composite = patch.genOp(spv::OpCompositeConstruct, patch.typeUint3, + ux, uy, patch.const0); + + return composite; +} + +u32 generateInvocationRaytrace(ShaderPatch& patch, + const spc::SPIREntryPoint& entryPoint) { + u32 launchIDVar = findOrDeclareBuiltinInput(patch, entryPoint, + spv::BuiltInLaunchIdKHR, patch.typeFloat4); + return patch.genOp(spv::OpLoad, patch.typeUint3, launchIDVar); +} + +u32 generateCurrentInvocation(ShaderPatch& patch, + const spc::SPIREntryPoint& entryPoint, VkShaderStageFlagBits stage) { + switch(stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + return generateInvocationVertex(patch, entryPoint); + case VK_SHADER_STAGE_FRAGMENT_BIT: + return generateInvocationFragment(patch, entryPoint); + case VK_SHADER_STAGE_COMPUTE_BIT: + return generateInvocationCompute(patch, entryPoint); + case VK_SHADER_STAGE_RAYGEN_BIT_KHR: + case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: + case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: + case VK_SHADER_STAGE_MISS_BIT_KHR: + case VK_SHADER_STAGE_CALLABLE_BIT_KHR: + case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: + return generateInvocationCompute(patch, entryPoint); + default: + dlg_error("unsupported shader stage"); + return {}; + } +} + PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line, u64 captureAddress, const std::string& entryPointName, VkShaderStageFlagBits stage) { @@ -443,7 +615,8 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line addressing = u32(spv::AddressingModelPhysicalStorageBuffer64); } - findDeclareScalarTypes(patch); + findDeclareBaseTypes(patch); + declareConstants(patch); // add extension patch.decl().push("SPV_KHR_physical_storage_buffer"); @@ -579,32 +752,6 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line .push(addressConstHigh); // find builtin GlobalInvocationID - u32 globalInvocationVar = u32(-1); - for(auto& builtin : compiler.get_shader_resources().builtin_inputs) { - if(builtin.builtin == spv::BuiltInGlobalInvocationId) { - auto varID = builtin.resource.id; - if(contains(entryPoint.interface_variables, varID)) { - globalInvocationVar = varID; - break; - } - } - } - - if(globalInvocationVar == u32(-1)) { - auto globalInvocationType = ++freeID; - - patch.decl() - .push(globalInvocationType) - .push(spv::StorageClassInput) - .push(patch.typeUint3); - - globalInvocationVar = ++freeID; - patch.decl() - .push(globalInvocationType) - .push(globalInvocationVar) - .push(spv::StorageClassInput); - } - // - construct struct C via OpCompositeConstruct patch.funcInstrOffset = lb->offset; auto srcStruct = ++freeID; @@ -629,12 +776,8 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line } } - auto const0 = ++freeID; - auto const1 = ++freeID; auto constScopeDevice = ++freeID; auto constMemorySemanticsBuf = ++freeID; - patch.decl().push(patch.typeUint).push(const0).push(0); - patch.decl().push(patch.typeUint).push(const1).push(1); patch.decl(). push(patch.typeUint). push(constScopeDevice). @@ -644,12 +787,7 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line push(constMemorySemanticsBuf). push(u32(spv::MemorySemanticsMaskNone | spv::MemorySemanticsUniformMemoryMask)); - // - at dst: OpBitcast B from A to type TP - auto bufferPointer = ++freeID; - patch.instr(spv::OpBitcast) - .push(bufferPointerType) - .push(bufferPointer) - .push(addressUint2); + auto bufferPointer = patch.genOp(spv::OpBitcast, bufferPointerType, addressUint2); // access chains auto inputThreadAccessType = ++freeID; @@ -663,8 +801,8 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line .push(inputThreadAccessType) .push(inputThreadAccess) .push(bufferPointer) - .push(const0) - .push(const0); + .push(patch.const0) + .push(patch.const0); auto ioCounterAccessType = ++freeID; patch.decl() @@ -677,49 +815,27 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line .push(ioCounterAccessType) .push(ioCounterAccess) .push(bufferPointer) - .push(const0) - .push(const1); + .push(patch.const0) + .push(patch.const1); // ========== - auto loadedCurrentThreadID = ++freeID; - auto loadedWriteThreadID = ++freeID; - auto vecEqualID = ++freeID; - auto allEqualID = ++freeID; - auto blockWriteID = ++freeID; - auto blockRestID = ++freeID; - - patch.instr(spv::OpLoad) - .push(patch.typeUint3) - .push(loadedCurrentThreadID) - .push(globalInvocationVar); - patch.instr(spv::OpLoad) - .push(patch.typeUint3) - .push(loadedWriteThreadID) - .push(inputThreadAccess) - .push(spv::MemoryAccessAlignedMask) - .push(16u); + auto blockWrite = ++freeID; + auto blockRest = ++freeID; - patch.instr(spv::OpIEqual) - .push(patch.typeBool3) - .push(vecEqualID) - .push(loadedCurrentThreadID) - .push(loadedWriteThreadID); - patch.instr(spv::OpAll) - .push(patch.typeBool) - .push(allEqualID) - .push(vecEqualID); - - patch.instr(spv::OpSelectionMerge) - .push(blockRestID) - .push(spv::SelectionControlMaskNone); - patch.instr(spv::OpBranchConditional) - .push(allEqualID) - .push(blockWriteID) - .push(blockRestID); + auto writingInvocation = patch.genOp(spv::OpLoad, patch.typeUint3, + inputThreadAccess, spv::MemoryAccessAlignedMask, 16u); + auto currentInvocation = generateCurrentInvocation(patch, + entryPoint, stage); + auto vecEqual = patch.genOp(spv::OpIEqual, patch.typeBool3, + writingInvocation, currentInvocation); + auto allEqual = patch.genOp(spv::OpAll, patch.typeBool, vecEqual); + + patch.instr(spv::OpSelectionMerge, blockRest, spv::SelectionControlMaskNone); + patch.instr(spv::OpBranchConditional, allEqual, blockWrite, blockRest); // block for writing output { - patch.instr(spv::OpLabel).push(blockWriteID); + patch.instr(spv::OpLabel, blockWrite); auto captureAccessType = ++freeID; patch.decl() @@ -732,7 +848,7 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line .push(captureAccessType) .push(captureAccess) .push(bufferPointer) - .push(const1); + .push(patch.const1); // atomic counter auto oldCounter = ++freeID; @@ -750,30 +866,34 @@ PatchResult patchShaderCapture(const spc::Compiler& compiler, u32 file, u32 line .push(patch.typeBool) .push(counterEqual) .push(oldCounter) - .push(const0); + .push(patch.const0); - auto blockOutputID = ++freeID; + auto blockNoWrite = ++freeID; // spirv does not allow re-using merge block + auto blockOutput = ++freeID; patch.instr(spv::OpSelectionMerge) - .push(blockRestID) + .push(blockNoWrite) .push(spv::SelectionControlMaskNone); patch.instr(spv::OpBranchConditional) .push(counterEqual) - .push(blockOutputID) - .push(blockRestID); + .push(blockOutput) + .push(blockNoWrite); { - patch.instr(spv::OpLabel).push(blockOutputID); + patch.instr(spv::OpLabel).push(blockOutput); patch.instr(spv::OpStore) .push(captureAccess) .push(srcStruct) .push(spv::MemoryAccessAlignedMask) .push(16u); - patch.instr(spv::OpBranch).push(blockRestID); + patch.instr(spv::OpBranch, blockNoWrite); } + + patch.instr(spv::OpLabel, blockNoWrite); + patch.instr(spv::OpBranch, blockRest); } // rest of the current block - patch.instr(spv::OpLabel).push(blockRestID); + patch.instr(spv::OpLabel, blockRest); // update ID bound copy[3] = freeID + 1;