From 3532c9c11e99c3da67463f5bf52672526c3773de Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 29 Oct 2025 18:10:10 +0800 Subject: [PATCH 01/37] update --- cmake/TransmuteClient.cmake | 9 + cmake/TransmuteCommon.cmake | 8 + src/client/graphics/webgl_active_info.hpp | 6 + src/client/graphics/webgl_context.cpp | 246 +- src/client/graphics/webgl_program.cpp | 266 +- src/client/graphics/webgl_program.hpp | 230 +- src/client/graphics/webgl_shader.cpp | 101 + src/client/graphics/webgl_shader.hpp | 51 +- .../command_buffers/details/program.hpp | 267 +- src/common/command_buffers/macros.hpp | 1 - src/renderer/gles/context_app.cpp | 2 +- src/renderer/render_api_opengles.cpp | 216 +- .../include/glslang/Include/ResourceLimits.h | 159 + .../glslang/Include/glslang_c_interface.h | 299 + .../glslang/Include/glslang_c_shader_types.h | 235 + .../include/glslang/Include/visibility.h | 58 + .../glslang/MachineIndependent/Versions.h | 404 ++ .../include/glslang/Public/ResourceLimits.h | 58 + .../include/glslang/Public/ShaderLang.h | 1012 ++++ .../glslang/Public/resource_limits_c.h | 58 + .../include/glslang/SPIRV/GlslangToSpv.h | 69 + .../glslang/include/glslang/SPIRV/Logger.h | 75 + .../glslang/include/glslang/SPIRV/SpvTools.h | 109 + .../include/glslang/SPIRV/disassemble.h | 55 + .../glslang/include/glslang/SPIRV/spirv.hpp11 | 5230 +++++++++++++++++ .../glslang/include/glslang/build_info.h | 62 + .../glslang/include/spirv-tools/libspirv.h | 1071 ++++ .../glslang/include/spirv-tools/libspirv.hpp | 410 ++ .../glslang/include/spirv-tools/linker.hpp | 128 + .../glslang/include/spirv-tools/optimizer.hpp | 1037 ++++ .../Darwin/lib/glslang/libGenericCodeGen.a | Bin 0 -> 608 bytes .../lib/glslang/libMachineIndependent.a | Bin 0 -> 608 bytes .../libs/Darwin/lib/glslang/libOSDependent.a | Bin 0 -> 608 bytes thirdparty/libs/Darwin/lib/glslang/libSPIRV.a | Bin 0 -> 608 bytes .../libglslang-default-resource-limits.a | Bin 0 -> 43784 bytes .../libs/Darwin/lib/glslang/libglslang.a | Bin 0 -> 4963096 bytes 36 files changed, 11231 insertions(+), 701 deletions(-) create mode 100644 src/client/graphics/webgl_shader.cpp create mode 100644 thirdparty/headers/glslang/include/glslang/Include/ResourceLimits.h create mode 100644 thirdparty/headers/glslang/include/glslang/Include/glslang_c_interface.h create mode 100644 thirdparty/headers/glslang/include/glslang/Include/glslang_c_shader_types.h create mode 100644 thirdparty/headers/glslang/include/glslang/Include/visibility.h create mode 100644 thirdparty/headers/glslang/include/glslang/MachineIndependent/Versions.h create mode 100644 thirdparty/headers/glslang/include/glslang/Public/ResourceLimits.h create mode 100644 thirdparty/headers/glslang/include/glslang/Public/ShaderLang.h create mode 100644 thirdparty/headers/glslang/include/glslang/Public/resource_limits_c.h create mode 100644 thirdparty/headers/glslang/include/glslang/SPIRV/GlslangToSpv.h create mode 100644 thirdparty/headers/glslang/include/glslang/SPIRV/Logger.h create mode 100644 thirdparty/headers/glslang/include/glslang/SPIRV/SpvTools.h create mode 100644 thirdparty/headers/glslang/include/glslang/SPIRV/disassemble.h create mode 100644 thirdparty/headers/glslang/include/glslang/SPIRV/spirv.hpp11 create mode 100644 thirdparty/headers/glslang/include/glslang/build_info.h create mode 100644 thirdparty/headers/glslang/include/spirv-tools/libspirv.h create mode 100644 thirdparty/headers/glslang/include/spirv-tools/libspirv.hpp create mode 100644 thirdparty/headers/glslang/include/spirv-tools/linker.hpp create mode 100644 thirdparty/headers/glslang/include/spirv-tools/optimizer.hpp create mode 100644 thirdparty/libs/Darwin/lib/glslang/libGenericCodeGen.a create mode 100644 thirdparty/libs/Darwin/lib/glslang/libMachineIndependent.a create mode 100644 thirdparty/libs/Darwin/lib/glslang/libOSDependent.a create mode 100644 thirdparty/libs/Darwin/lib/glslang/libSPIRV.a create mode 100644 thirdparty/libs/Darwin/lib/glslang/libglslang-default-resource-limits.a create mode 100644 thirdparty/libs/Darwin/lib/glslang/libglslang.a diff --git a/cmake/TransmuteClient.cmake b/cmake/TransmuteClient.cmake index b9ba7e87d..b03fc77a0 100644 --- a/cmake/TransmuteClient.cmake +++ b/cmake/TransmuteClient.cmake @@ -73,11 +73,20 @@ set(NODE_ADDON_API_HEADERS_PATH ${CMAKE_SOURCE_DIR}/thirdparty/headers/node-addo target_include_directories(TransmuteClient PRIVATE ${NODE_ADDON_API_HEADERS_PATH}) target_include_directories(TransmuteClientLibrary PRIVATE ${NODE_ADDON_API_HEADERS_PATH}) +# # Link libraries +# + tr_target_link_library(TransmuteClientLibrary ${TR_CRATE_BUILD_PATH} jsar_jsbindings STATIC) tr_target_link_thirdparty_library(TransmuteClientLibrary node) tr_target_link_skia_library(TransmuteClientLibrary) +# GLSLang libraries +tr_target_link_thirdparty_library_with_path(TransmuteClientLibrary glslang glslang) +tr_target_link_thirdparty_library_with_path(TransmuteClientLibrary glslang glslang-default-resource-limits) +tr_target_link_thirdparty_library_with_path(TransmuteClientLibrary glslang MachineIndependent) +tr_target_link_thirdparty_library_with_path(TransmuteClientLibrary glslang OSDependent) + if(APPLE) set(APPLE_CLIENT_DEPS "-framework Carbon" diff --git a/cmake/TransmuteCommon.cmake b/cmake/TransmuteCommon.cmake index f994f6f60..5116c1e37 100644 --- a/cmake/TransmuteCommon.cmake +++ b/cmake/TransmuteCommon.cmake @@ -101,6 +101,10 @@ include_directories( ${SKIA_HEADERS_PATH}/include ) +# GLSLang headers +set(GLSLANG_HEADERS_PATH ${CMAKE_SOURCE_DIR}/thirdparty/headers/glslang/include) +include_directories(${GLSLANG_HEADERS_PATH}) + # Add Unity headers set(UNITY_HEADERS_PATH ${CMAKE_SOURCE_DIR}/thirdparty/headers/Unity/include) include_directories(${UNITY_HEADERS_PATH}) @@ -132,6 +136,10 @@ function(tr_target_link_thirdparty_library TARGET LIBRARY_NAME) endif() endfunction() +function(tr_target_link_thirdparty_library_with_path TARGET LIBRARY_PATH LIBRARY_NAME) + tr_target_link_library(${TARGET} ${TR_THIRDPARTY_PATH}/lib/${LIBRARY_PATH} ${LIBRARY_NAME} STATIC) +endfunction() + function(tr_target_link_skia_library TARGET) tr_target_link_thirdparty_library(${TARGET} skia) tr_target_link_thirdparty_library(${TARGET} skparagraph) diff --git a/src/client/graphics/webgl_active_info.hpp b/src/client/graphics/webgl_active_info.hpp index 27c063db7..3c0f9be6b 100644 --- a/src/client/graphics/webgl_active_info.hpp +++ b/src/client/graphics/webgl_active_info.hpp @@ -20,6 +20,12 @@ namespace endor , type(info.type) { } + WebGLActiveInfo(const std::string &name, int type, int size) + : name(name) + , size(size) + , type(type) + { + } public: std::string name; diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index f950907c5..c65f0a510 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "./webgl_context.hpp" #include "./webgl_active_info.hpp" @@ -54,6 +55,13 @@ namespace endor clientContext_ = TrClientContextPerProcess::Get(); assert(clientContext_ != nullptr); + static bool is_glslang_initialized = false; + if (!is_glslang_initialized) + { + glslang::InitializeProcess(); + is_glslang_initialized = true; + } + static TrIdGeneratorBase idGen(commandbuffers::MinimumContextId); id = idGen.get(); if (id >= commandbuffers::MinimumContextId + commandbuffers::MaxinumContextsCountPerContent) @@ -76,10 +84,6 @@ namespace endor throw runtime_error("Failed to initialize WebGL context"); } - auto initializedAt = chrono::system_clock::now(); - logging::LogInfo("Initialized `WebGL1Context` in " + - to_string(chrono::duration_cast(initializedAt - sentAt).count()) + "ms"); - viewport_ = initResp->drawingViewport; maxCombinedTextureImageUnits = initResp->maxCombinedTextureImageUnits; maxCubeMapTextureSize = initResp->maxCubeMapTextureSize; @@ -109,6 +113,10 @@ namespace endor fragmentFormat[2]); } } + + auto initializedAt = chrono::system_clock::now(); + logging::LogInfo("Initialized `WebGL1Context` in " + + to_string(chrono::duration_cast(initializedAt - sentAt).count()) + "ms"); } WebGLContext::~WebGLContext() @@ -154,105 +162,20 @@ namespace endor if (program == nullptr || !program->isValid()) [[unlikely]] return; - auto req = LinkProgramCommandBufferRequest(program->id); - if (!sendCommandBufferRequest(req, true)) - throw LinkProgramException(*program, "Failed to send the command buffer."); - - auto onLinkProgramResponse = [this, program](const LinkProgramCommandBufferResponse &resp) + program->link(); + if (program->getLinkStatus()) [[likely]] { - // Directly return if the link failed. - if (!resp.success) [[unlikely]] - { - program->setCompleted(false); - return; - } - - /** - * Update the program's active attributes and uniforms. - */ - { - int index = 0; - for (auto &activeInfo : resp.activeAttribs) - program->setActiveAttrib(index++, activeInfo); - index = 0; - for (auto &activeInfo : resp.activeUniforms) - program->setActiveUniform(index++, activeInfo); - } - - /** - * Update the program's attribute locations. - */ - for (auto &attribLocation : resp.attribLocations) - program->setAttribLocation(attribLocation.name, attribLocation.location); - - /** - * See https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getUniformLocation#name - * - * When uniforms declared as an array, the valid name might be like the followings: - * - * - foo - * - foo[0] - * - foo[1] - */ - for (auto &uniformLocation : resp.uniformLocations) - { - auto name = uniformLocation.name; - auto location = uniformLocation.location; - auto size = uniformLocation.size; - - /** - * FIXME: The OpenGL returns "foo[0]" from `glGetActiveUniform()`, thus we need to handle it here: - * - * 1. check if the name ends with "[0]" - * 2. grab the name without "[0]" - * 3. set the uniform location for the name without "[0]" - * 4. set the uniform location for the name with "[0]" and the index - * 5. repeat 4 for the rest of the indices - * - * After the above steps, we will have the names looks like: foo, foo[0], foo[1], foo[2], ... - */ - string arraySuffix = "[0]"; - int endedAt = name.length() - arraySuffix.length(); - bool endsWithArray = name.size() > arraySuffix.size() && name.rfind(arraySuffix) != string::npos; - - /** - * Check if size is 1 and not ends with [0], WebGL developers might use 1-size array such as: `[0]`. - */ - if (size == 1 && !endsWithArray) - { - program->setUniformLocation(name, location); - } - else if (endsWithArray) - { - auto arrayName = name.substr(0, endedAt); - program->setUniformLocation(arrayName, location); - program->setUniformLocation(name, location); - for (int i = 1; i < size; i++) - program->setUniformLocation(arrayName + "[" + to_string(i) + "]", location + i); - } - else - { - // TODO: warning size is invalid? - continue; - } - } - - if (isWebGL2_ == true) - { - /** - * Save the uniform block indices to the program object - */ - for (auto &uniformBlock : resp.uniformBlocks) - program->setUniformBlockIndex(uniformBlock.name, uniformBlock.index); - } + auto req = LinkProgramCommandBufferRequest(program->id); + req.attribLocations = program->getAttribLocationsInfo(); + req.uniformLocations = program->getUniformLocationsInfo(); - // Mark the program as completed. - program->setCompleted(true); - }; - recvResponseAsync(COMMAND_BUFFER_LINK_PROGRAM_RES, req, onLinkProgramResponse); - - // Mark the program linked successfully. - program->setLinkStatus(true); + if (!sendCommandBufferRequest(req)) + throw LinkProgramException(*program, "Failed to send the command buffer."); + } + else + { + throw LinkProgramException(*program, string(program->getInfoLog())); + } } void WebGLContext::validateProgram(shared_ptr program) @@ -284,9 +207,9 @@ namespace endor int WebGLContext::getProgramParameter(shared_ptr program, int pname) { /** - * The following parameters are carried when linkProgram() is responded, thus we could return them from the client-side - * `WebGLProgram` object directly. - */ + * The following parameters are carried when linkProgram() is responded, thus we could return them from the client-side + * `WebGLProgram` object directly. + */ if (pname == WEBGL_LINK_STATUS) return static_cast(program->getLinkStatus(false)); if (pname == WEBGL_VALIDATE_STATUS) @@ -297,8 +220,8 @@ namespace endor return static_cast(program->countActiveUniforms()); /** - * Send a command buffer request and wait for the response if not hit the above conditions. - */ + * Send a command buffer request and wait for the response if not hit the above conditions. + */ auto req = GetProgramParamCommandBufferRequest(program->id, pname); sendCommandBufferRequest(req, true); @@ -312,27 +235,7 @@ namespace endor string WebGLContext::getProgramInfoLog(shared_ptr program) { assert(program != nullptr && "Program is not null"); - if (program->isIncomplete()) - { - return ""; - } - else - { - auto req = GetProgramInfoLogCommandBufferRequest(program->id); - sendCommandBufferRequest(req, true); - - auto resp = recvResponse(COMMAND_BUFFER_GET_PROGRAM_INFO_LOG_RES, req); - if (resp != nullptr) [[likely]] - { - string log(resp->infoLog); - delete resp; - return log; - } - else - { - throw runtime_error("Failed to get program info log: timeout."); - } - } + return string(program->getInfoLog()); } shared_ptr WebGLContext::createShader(WebGLShaderType type) @@ -352,45 +255,36 @@ namespace endor void WebGLContext::shaderSource(shared_ptr shader, const string &source) { - shader->source = GLSLSourcePatcher2::GetPatchedSource(source); - auto req = ShaderSourceCommandBufferRequest(shader->id, shader->source); + shader->setSource(GLSLSourcePatcher2::GetPatchedSource(source)); + auto req = ShaderSourceCommandBufferRequest(shader->id, shader->source()); sendCommandBufferRequest(req); } void WebGLContext::compileShader(shared_ptr shader) { + // TODO(yorkie): verify the compilation on the client side using glslang. + shader->compile(); auto req = CompileShaderCommandBufferRequest(shader->id); sendCommandBufferRequest(req); } void WebGLContext::attachShader(shared_ptr program, shared_ptr shader) { + program->attachShader(shader); auto req = AttachShaderCommandBufferRequest(program->id, shader->id); sendCommandBufferRequest(req); } void WebGLContext::detachShader(shared_ptr program, shared_ptr shader) { + program->detachShader(shader); auto req = DetachShaderCommandBufferRequest(program->id, shader->id); sendCommandBufferRequest(req); } string WebGLContext::getShaderSource(shared_ptr shader) { - auto req = GetShaderSourceCommandBufferRequest(shader->id); - sendCommandBufferRequest(req, true); - - auto resp = recvResponse(COMMAND_BUFFER_GET_SHADER_SOURCE_RES, req); - if (resp != nullptr) [[likely]] - { - string source(resp->source); - delete resp; - return source; - } - else - { - throw runtime_error("Failed to get shader source: timeout."); - } + return shader->source(); } int WebGLContext::getShaderParameter(shared_ptr shader, int pname) @@ -420,28 +314,7 @@ namespace endor string WebGLContext::getShaderInfoLog(shared_ptr shader) { - auto req = GetShaderInfoLogCommandBufferRequest(shader->id); - sendCommandBufferRequest(req, true); - - auto onGetShaderInfoLogResponse = [shader](const GetShaderInfoLogCommandBufferResponse &resp) - { - if (!resp.infoLog.empty() && resp.infoLog.find("ERROR:") == 0) - { - // TODO(yorkie): print to console domain in inspector. - cerr << "Shader(" << shader->id << ") compilation error:" << endl - << resp.infoLog << endl - << "============== shader source ==============" << endl - << shader->source << endl - << "============================================" << endl; - } - }; - recvResponseAsync(COMMAND_BUFFER_GET_SHADER_INFO_LOG_RES, - req, - onGetShaderInfoLogResponse); - - // Return an empty string directly, and the response will be logged in the async callback. - // This is to avoid blocking the main thread. - return ""; + return string(shader->getInfoLog()); } shared_ptr WebGLContext::createBuffer() @@ -449,6 +322,7 @@ namespace endor auto buffer = make_shared(); auto req = CreateBufferCommandBufferRequest(buffer->id); sendCommandBufferRequest(req); + cerr << "Created buffer with id: " << buffer->id << endl; return buffer; } @@ -946,52 +820,28 @@ namespace endor optional WebGLContext::getActiveAttrib(shared_ptr program, unsigned int index) { assert(program != nullptr && "Program is not null"); - program->waitForCompleted(); - - if (program->hasActiveAttrib(index)) - return program->getActiveAttrib(index); - else - return nullopt; + return program->hasActiveAttrib(index) ? optional(program->getActiveAttrib(index)) : nullopt; } optional WebGLContext::getActiveUniform(shared_ptr program, unsigned int index) { assert(program != nullptr && "Program is not null"); - program->waitForCompleted(); - - if (program->hasActiveUniform(index)) - return program->getActiveUniform(index); - else - return nullopt; + return program->hasActiveUniform(index) ? optional(program->getActiveUniform(index)) : nullopt; } optional WebGLContext::getAttribLocation(shared_ptr program, const string &name) { assert(program != nullptr && "Program is not null"); - program->waitForCompleted(); - - // Returns `nullopt` if the program is incomplete or not linked. - if (!program->hasAttribLocation(name)) - return nullopt; - - auto &location = program->getAttribLocation(name); - return location; + return program->hasAttribLocation(name) ? optional(program->getAttribLocation(name)) : nullopt; } optional WebGLContext::getUniformLocation(shared_ptr program, const string &name) { - if (program->isIncomplete()) - { - return WebGLUniformLocation(program->id, name); - } + if (program->hasUniformLocation(name)) + return program->getUniformLocation(name); else - { - if (program->hasUniformLocation(name)) - return program->getUniformLocation(name); - else - return nullopt; - } + return nullopt; } void WebGLContext::uniform1f(WebGLUniformLocation location, float v0) @@ -2116,8 +1966,8 @@ namespace endor int WebGL2Context::getParameterV2(WebGL2IntegerParameterName pname) { /** - * The following parameters are static and could be returned directly. - */ + * The following parameters are static and could be returned directly. + */ if (pname == WebGL2IntegerParameterName::kMax3DTextureSize) return max3DTextureSize; else if (pname == WebGL2IntegerParameterName::kMaxArrayTextureLayers) @@ -2198,8 +2048,6 @@ namespace endor int WebGL2Context::getUniformBlockIndex(shared_ptr program, const string &uniformBlockName) { assert(program != nullptr && "Program must not be null."); - program->waitForCompleted(); - if (program == nullptr || !program->isValid() || !program->hasUniformBlockIndex(uniformBlockName)) return -1; else diff --git a/src/client/graphics/webgl_program.cpp b/src/client/graphics/webgl_program.cpp index a44046565..b1f86e44c 100644 --- a/src/client/graphics/webgl_program.cpp +++ b/src/client/graphics/webgl_program.cpp @@ -1,3 +1,4 @@ +#include #include "./webgl_program.hpp" namespace endor @@ -6,11 +7,149 @@ namespace endor { using namespace std; - void WebGLProgram::waitForCompleted(int timeout) const + void WebGLProgram::attachShader(shared_ptr shader) { - std::unique_lock lock(setCompletedMutex_); - setCompletedCv_.wait_for(lock, std::chrono::milliseconds(timeout), [this]() + switch (shader->type) + { + case WebGLShaderType::kVertex: + vertexShader_ = shader; + glslang_program_.addShader(shader->glslangShader()); + break; + case WebGLShaderType::kFragment: + fragmentShader_ = shader; + glslang_program_.addShader(shader->glslangShader()); + break; + default: + throw runtime_error("Unknown WebGLShaderType"); + } + } + + void WebGLProgram::detachShader(shared_ptr shader) + { + switch (shader->type) + { + case WebGLShaderType::kVertex: + vertexShader_ = nullptr; + break; + case WebGLShaderType::kFragment: + fragmentShader_ = nullptr; + break; + default: + throw runtime_error("Unknown WebGLShaderType"); + } + } + + void WebGLProgram::link() + { + if (!glslang_program_.link(EShMsgDefault)) + { + linkStatus_ = false; + return; + } + + // Build reflection to get active attributes and uniforms. + int opts = EShReflectionDefault | + EShReflectionBasicArraySuffix | + EShReflectionIntermediateIO; + if (!glslang_program_.buildReflection(opts)) + { + throw runtime_error("Program link failed: " + string(glslang_program_.getInfoLog())); + } + + { + // Add active attributes. + int loc = 0; + int size = glslang_program_.getNumLiveAttributes(); + for (int i = 0; i < size; ++i) + { + const auto &ref = glslang_program_.getPipeInput(i); + auto type = ref.glDefineType; + int size = ref.size; + string name = ref.name; + if (size > 1 && name.find("[0]") == string::npos) + { + // For array uniforms, append "[0]" to the name. + name += "[0]"; + } + + activeAttribs_[i] = WebGLActiveInfo(name, type, size); + attribLocations_[name] = WebGLAttribLocation(id, loc, name); + + // Update location for next attribute. + int slots = 1; + switch (type) + { + case WEBGL_FLOAT_MAT2: + case WEBGL2_FLOAT_MAT2x3: + case WEBGL2_FLOAT_MAT2x4: + slots = 2; + break; + case WEBGL_FLOAT_MAT3: + case WEBGL2_FLOAT_MAT3x2: + case WEBGL2_FLOAT_MAT3x4: + slots = 3; + break; + case WEBGL_FLOAT_MAT4: + case WEBGL2_FLOAT_MAT4x2: + case WEBGL2_FLOAT_MAT4x3: + slots = 4; + break; + default: + break; + } + loc += slots; + } + } + { + // Add active uniforms. + int loc = 0; + int size = glslang_program_.getNumLiveUniformVariables(); + for (int i = 0; i < size; ++i) + { + const auto &ref = glslang_program_.getUniform(i); + auto type = ref.glDefineType; + int size = ref.size; + string name = ref.name; + if (size > 1 && name.find("[0]") == string::npos) + { + // For array uniforms, append "[0]" to the name. + name += "[0]"; + } + + activeUniforms_[i] = WebGLActiveInfo(name, type, size); + uniformLocations_[name] = WebGLUniformLocation(id, loc, name); + loc += size; + } + } + { + // Add uniform block indices. + int size = glslang_program_.getNumLiveUniformBlocks(); + for (int i = 0; i < size; ++i) + { + const auto &ref = glslang_program_.getUniformBlock(i); + uniformBlockIndices_[ref.name] = i; + } + } + + // Mark as complete. + linkStatus_ = true; + validateStatus_ = true; + } + + const char *WebGLProgram::getInfoLog() + { + return glslang_program_.getInfoLog(); + } + + void WebGLProgram::waitForCompleted(const string &label, int timeout) const + { + chrono::steady_clock::time_point startTime = chrono::steady_clock::now(); + unique_lock lock(setCompletedMutex_); + setCompletedCv_.wait_for(lock, chrono::milliseconds(timeout), [this]() { return !incomplete_; }); + + auto duration = chrono::duration_cast(chrono::steady_clock::now() - startTime).count(); + cerr << "Waited for program " << id << " (" << label << ") completion for " << duration << " ms." << endl; } void WebGLProgram::setCompleted(bool linkStatus) @@ -18,25 +157,136 @@ namespace endor linkStatus_ = linkStatus; incomplete_ = false; { - std::unique_lock lock(setCompletedMutex_); + unique_lock lock(setCompletedMutex_); setCompletedCv_.notify_all(); } } + void WebGLProgram::setLinkStatus(bool linkStatus) + { + linkStatus_ = linkStatus; + } + + void WebGLProgram::setValidateStatus(bool validateStatus) + { + validateStatus_ = validateStatus; + } + bool WebGLProgram::getLinkStatus(bool sync) const { - if (sync) - waitForCompleted(); return linkStatus_; } bool WebGLProgram::getValidateStatus(bool sync) const { - if (sync) - waitForCompleted(); return validateStatus_; } + size_t WebGLProgram::countActiveAttribs() const + { + return activeAttribs_.size(); + } + + WebGLActiveInfo WebGLProgram::getActiveAttrib(int index) + { + return activeAttribs_[index]; + } + + void WebGLProgram::setActiveAttrib(int index, const commandbuffers::ActiveInfo &activeInfo) + { + activeAttribs_[index] = WebGLActiveInfo(activeInfo); + } + + bool WebGLProgram::hasActiveAttrib(int index) + { + return activeAttribs_.find(index) != activeAttribs_.end(); + } + + size_t WebGLProgram::countActiveUniforms() const + { + return activeUniforms_.size(); + } + + WebGLActiveInfo WebGLProgram::getActiveUniform(int index) + { + return activeUniforms_[index]; + } + + void WebGLProgram::setActiveUniform(int index, const commandbuffers::ActiveInfo &activeInfo) + { + activeUniforms_[index] = activeInfo; + } + + bool WebGLProgram::hasActiveUniform(int index) + { + return activeUniforms_.find(index) != activeUniforms_.end(); + } + + void WebGLProgram::setAttribLocation(const string &name, int location) + { + attribLocations_[name] = WebGLAttribLocation(id, location, name); + } + + bool WebGLProgram::hasAttribLocation(const string &name) + { + return attribLocations_.find(name) != attribLocations_.end(); + } + + const WebGLAttribLocation &WebGLProgram::getAttribLocation(const string &name) + { + return attribLocations_[name]; + } + + vector WebGLProgram::getAttribLocationsInfo() const + { + vector list; + for (const auto &pair : attribLocations_) + { + auto loc = pair.second; + list.push_back(commandbuffers::AttribLocation(loc.name, loc.index.value_or(-1))); + } + return list; + } + + void WebGLProgram::setUniformLocation(const string &name, int location) + { + uniformLocations_[name] = WebGLUniformLocation(id, location, name); + } + + bool WebGLProgram::hasUniformLocation(const string &name) + { + return uniformLocations_.find(name) != uniformLocations_.end(); + } + + const WebGLUniformLocation &WebGLProgram::getUniformLocation(const string &name) + { + return uniformLocations_[name]; + } + + vector WebGLProgram::getUniformLocationsInfo() const + { + vector list; + for (const auto &pair : uniformLocations_) + { + auto loc = pair.second; + list.push_back(commandbuffers::UniformLocation(loc.name, loc.index.value_or(-1))); + } + return list; + } + + void WebGLProgram::setUniformBlockIndex(const string &name, int index) + { + uniformBlockIndices_[name] = index; + } + bool WebGLProgram::hasUniformBlockIndex(const string &name) + { + return uniformBlockIndices_.find(name) != uniformBlockIndices_.end(); + } + int WebGLProgram::getUniformBlockIndex(const string &name) + { + return uniformBlockIndices_[name]; + } + void WebGLProgram::printInfo() const { cout << "Program " << id << " info:" << endl; diff --git a/src/client/graphics/webgl_program.hpp b/src/client/graphics/webgl_program.hpp index c62873af7..795e2a266 100644 --- a/src/client/graphics/webgl_program.hpp +++ b/src/client/graphics/webgl_program.hpp @@ -6,9 +6,11 @@ #include #include #include +#include #include #include "./webgl_object.hpp" +#include "./webgl_shader.hpp" #include "./webgl_active_info.hpp" #include "./webgl_attrib_location.hpp" #include "./webgl_uniform_location.hpp" @@ -26,209 +28,71 @@ namespace endor } public: + void attachShader(std::shared_ptr shader); + void detachShader(std::shared_ptr shader); + void link(); + const char* getInfoLog(); + // Returns if this program is incomplete, it means the program response has not been received from channel peer. bool isIncomplete() const { return incomplete_; } // Waits for the program to be completed, it will block until the program response is received from channel peer. - void waitForCompleted(int timeout = 2000) const; + void waitForCompleted(const std::string &label = "", int timeout = 2000) const; // Calls setCompleted() when the program response is received from channel peer and updates the link status. void setCompleted(bool linkStatus); - /** - * It sets the link status of the program. - * - * @param linkStatus The link status of the program. - */ - void setLinkStatus(bool linkStatus) - { - linkStatus_ = linkStatus; - } - /** - * It sets the validate status of the program. - * - * @param validateStatus The validate status of the program. - */ - void setValidateStatus(bool validateStatus) - { - validateStatus_ = validateStatus; - } - /** - * This method gets the current link status of the program. - * - * @param sync If `true`, it will wait for the program to be completed before returning the link status. - * @returns The current link status of the program. - */ + + void setLinkStatus(bool linkStatus); + void setValidateStatus(bool validateStatus); bool getLinkStatus(bool sync = false) const; - /** - * This method gets the current validate status of the program. - * - * @param sync If `true`, it will wait for the program to be completed before returning the validate status. - * @returns The current validate status of the program. - */ bool getValidateStatus(bool sync = false) const; - /** - * @returns The number of active attributes in the program. - */ - size_t countActiveAttribs() const - { - waitForCompleted(); - return activeAttribs_.size(); - } - /** - * @returns The active attribute information at the given index. - */ - WebGLActiveInfo getActiveAttrib(int index) - { - return activeAttribs_[index]; - } - /** - * It sets the active attribute information at the given index. - * - * @param index The index of the active attribute. - * @param activeInfo The active attribute information. - */ - void setActiveAttrib(int index, const commandbuffers::ActiveInfo &activeInfo) - { - activeAttribs_[index] = WebGLActiveInfo(activeInfo); - } - /** - * @returns If the active attribute exists at the given index. - */ - bool hasActiveAttrib(int index) - { - return activeAttribs_.find(index) != activeAttribs_.end(); - } - /** - * @returns The number of active uniforms in the program. - */ - size_t countActiveUniforms() const - { - waitForCompleted(); - return activeUniforms_.size(); - } - /** - * @param index The index of the active uniform. - * @returns The active uniform information at the given index. - */ - WebGLActiveInfo getActiveUniform(int index) - { - return activeUniforms_[index]; - } - /** - * It sets the active uniform information at the given index. - * - * @param index The index of the active uniform. - * @param activeInfo The active uniform information. - */ - void setActiveUniform(int index, const commandbuffers::ActiveInfo &activeInfo) - { - activeUniforms_[index] = activeInfo; - } - /** - * @param index The index of the active uniform. - * @returns If the active uniform exists at the given index. - */ - bool hasActiveUniform(int index) - { - return activeUniforms_.find(index) != activeUniforms_.end(); - } - /** - * It sets the attribute location for the given name. - * - * @param name The name of the attribute. - * @param location The location of the attribute. - */ - void setAttribLocation(const std::string &name, int location) - { - attribLocations_[name] = WebGLAttribLocation(id, location, name); - } - /** - * @param name The name of the attribute. - * @returns If the attribute location exists for the given name. - */ - bool hasAttribLocation(const std::string &name) - { - return attribLocations_.find(name) != attribLocations_.end(); - } - /** - * @param name The name of the attribute. - * @returns The attribute location for the given name. - */ - const WebGLAttribLocation &getAttribLocation(const std::string &name) - { - return attribLocations_[name]; - } - /** - * It sets the uniform location for the given name. - * - * @param name The name of the uniform. - * @param location The location of the uniform. - */ - void setUniformLocation(const std::string &name, int location) - { - uniformLocations_[name] = WebGLUniformLocation(id, location, name); - } - /** - * @param name The name of the uniform. - * @returns If the uniform location exists for the given name. - */ - bool hasUniformLocation(const std::string &name) - { - return uniformLocations_.find(name) != uniformLocations_.end(); - } - /** - * @param name The name of the uniform. - * @returns The uniform location for the given name. - */ - const WebGLUniformLocation &getUniformLocation(const std::string &name) - { - return uniformLocations_[name]; - } - /** - * It sets the uniform block index for the given name. - * - * @param name The name of the uniform block. - * @param index The index of the uniform block. - */ - void setUniformBlockIndex(const std::string &name, int index) - { - uniformBlockIndices_[name] = index; - } - /** - * @param name The name of the uniform block. - * @returns If the uniform block index exists for the given name. - */ - bool hasUniformBlockIndex(const std::string &name) - { - return uniformBlockIndices_.find(name) != uniformBlockIndices_.end(); - } - /** - * @param name The name of the uniform block. - * @returns The uniform block index for the given name. - */ - int getUniformBlockIndex(const std::string &name) - { - return uniformBlockIndices_[name]; - } + + size_t countActiveAttribs() const; + WebGLActiveInfo getActiveAttrib(int index); + void setActiveAttrib(int index, const commandbuffers::ActiveInfo &activeInfo); + bool hasActiveAttrib(int index); + + size_t countActiveUniforms() const; + WebGLActiveInfo getActiveUniform(int index); + void setActiveUniform(int index, const commandbuffers::ActiveInfo &activeInfo); + bool hasActiveUniform(int index); + + void setAttribLocation(const std::string &name, int location); + bool hasAttribLocation(const std::string &name); + const WebGLAttribLocation &getAttribLocation(const std::string &name); + std::vector getAttribLocationsInfo() const; + + void setUniformLocation(const std::string &name, int location); + bool hasUniformLocation(const std::string &name); + const WebGLUniformLocation &getUniformLocation(const std::string &name); + std::vector getUniformLocationsInfo() const; + + void setUniformBlockIndex(const std::string &name, int index); + bool hasUniformBlockIndex(const std::string &name); + int getUniformBlockIndex(const std::string &name); public: /** - * It prints the information of the program to stdout, including: - * - * - Link status - * - Active attributes - * - Active uniforms - * - Attribute locations - * - Uniform locations - */ + * It prints the information of the program to stdout, including: + * + * - Link status + * - Active attributes + * - Active uniforms + * - Attribute locations + * - Uniform locations + */ void printInfo() const; private: + glslang::TProgram glslang_program_; std::atomic incomplete_ = true; mutable std::mutex setCompletedMutex_; mutable std::condition_variable setCompletedCv_; + std::shared_ptr vertexShader_; + std::shared_ptr fragmentShader_; + bool linkStatus_ = false; bool validateStatus_ = false; std::map activeAttribs_; diff --git a/src/client/graphics/webgl_shader.cpp b/src/client/graphics/webgl_shader.cpp new file mode 100644 index 000000000..cb657a4dd --- /dev/null +++ b/src/client/graphics/webgl_shader.cpp @@ -0,0 +1,101 @@ + +#include +#include "./webgl_shader.hpp" + +using namespace std; + +namespace endor +{ + namespace client_graphics + { + inline EShLanguage EShLang(WebGLShaderType type) + { + switch (type) + { + case WebGLShaderType::kVertex: + return EShLangVertex; + case WebGLShaderType::kFragment: + return EShLangFragment; + default: + throw runtime_error("Unknown WebGLShaderType"); + } + } + + WebGLShader::WebGLShader(WebGLShaderType type) + : WebGLObject(WebGLObjectType::Shader) + , type(type) + , glslang_shader_(make_unique(EShLang(type))) + { + assert(glslang_shader_ != nullptr && "Failed to create glslang shader"); + glslang_shader_->setAutoMapBindings(true); + glslang_shader_->setAutoMapLocations(true); + } + + void WebGLShader::setSource(const string &source) + { + source_ = source; + source_cstr_ = source_.c_str(); + glslang_shader_->setStrings(&source_cstr_, 1); + + // Configure the environment for WebGL (OpenGL ES) + glslang_shader_->setEnvInput(glslang::EShSourceGlsl, EShLang(type), glslang::EShClientOpenGL, s_DefaultVersion); + glslang_shader_->setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450); + glslang_shader_->setEnvTarget(glslang::EShTargetNone, glslang::EShTargetSpv_1_0); + } + + const string &WebGLShader::source() const + { + return source_; + } + + void WebGLShader::compile() + { + EShMessages messages = EShMsgDefault; + messages = (EShMessages)(messages | EShMsgRelaxedErrors); + + if (!glslang_shader_->parse(GetDefaultResources(), + s_DefaultVersion, + EProfile::EEsProfile, + false, + false, + messages)) + { + auto debug_log = glslang_shader_->getInfoDebugLog(); + cerr << "Shader Debug Log:" << endl + << debug_log << endl; + throw runtime_error("Shader compilation failed: " + string(glslang_shader_->getInfoLog())); + } + } + + const char *WebGLShader::getInfoLog() + { + return glslang_shader_->getInfoLog(); + } + + bool WebGLShader::hasDeleteStatus() const + { + return delete_status_.has_value(); + } + + bool WebGLShader::hasCompileStatus() const + { + return compile_status_.has_value(); + } + + bool WebGLShader::getDeleteStatus() + { + return delete_status_.value_or(false); + } + + bool WebGLShader::getCompileStatus() + { + return compile_status_.value_or(false); + } + + void WebGLShader::setShaderParameters(bool deleteStatus, bool compileStatus) + { + delete_status_ = deleteStatus; + compile_status_ = compileStatus; + } + } +} diff --git a/src/client/graphics/webgl_shader.hpp b/src/client/graphics/webgl_shader.hpp index cf057d2a5..ec52312a8 100644 --- a/src/client/graphics/webgl_shader.hpp +++ b/src/client/graphics/webgl_shader.hpp @@ -1,9 +1,10 @@ #pragma once #include +#include #include - -#include "common/command_buffers/details/program.hpp" +#include +#include #include "./webgl_object.hpp" namespace endor @@ -21,43 +22,39 @@ namespace endor friend class WebGLContext; public: - WebGLShader(WebGLShaderType type) - : WebGLObject(WebGLObjectType::Shader) - , type(type) - { - } + WebGLShader(WebGLShaderType type); - bool hasDeleteStatus() const - { - return delete_status_.has_value(); - } - bool hasCompileStatus() const - { - return compile_status_.has_value(); - } - bool getDeleteStatus() - { - return delete_status_.value_or(false); - } - bool getCompileStatus() + glslang::TShader *glslangShader() { - return compile_status_.value_or(false); + return glslang_shader_.get(); } + void setSource(const std::string &source); + const std::string &source() const; + void compile(); + const char *getInfoLog(); + + bool hasDeleteStatus() const; + bool hasCompileStatus() const; + bool getDeleteStatus(); + bool getCompileStatus(); + private: - void setShaderParameters(bool deleteStatus, bool compileStatus) - { - delete_status_ = deleteStatus; - compile_status_ = compileStatus; - } + void setShaderParameters(bool deleteStatus, bool compileStatus); public: WebGLShaderType type; - std::string source; private: + std::string source_; + const char *source_cstr_ = nullptr; + + std::unique_ptr glslang_shader_; std::optional delete_status_; std::optional compile_status_; + + private: + static constexpr int s_DefaultVersion = 300; }; } } // namespace endor diff --git a/src/common/command_buffers/details/program.hpp b/src/common/command_buffers/details/program.hpp index 925cae0af..57dac3e2b 100644 --- a/src/common/command_buffers/details/program.hpp +++ b/src/common/command_buffers/details/program.hpp @@ -5,6 +5,63 @@ namespace commandbuffers { + enum LinkProgramCommandBufferResponseSegmentType + { + SEGMENT_ACTIVE_ATTRIB, + SEGMENT_ACTIVE_UNIFORM, + SEGMENT_ATTRIB_LOCATION, + SEGMENT_UNIFORM_LOCATION, + SEGMENT_UNIFORM_BLOCK + }; + + class ActiveInfo + { + public: + ActiveInfo() = default; + ActiveInfo(const ActiveInfo &that) = default; + ActiveInfo(string name, int size, int type) + : name(name) + , size(size) + , type(type) + { + } + + public: + string name; + int size = 0; + int type = 0; + }; + + class Location + { + public: + Location(string name, int location) + : name(name) + , location(location) + { + } + + public: + string name; + int location; + }; + using AttribLocation = Location; + using UniformLocation = Location; + + class UniformBlock + { + public: + UniformBlock(string name, int index) + : name(name) + , index(index) + { + } + + public: + string name; + int index; + }; + class CreateProgramCommandBufferRequest final : public TrCommandBufferSimpleRequest @@ -103,150 +160,13 @@ namespace commandbuffers ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; return ss.str(); } - - public: - uint32_t clientId; - }; - - class ValidateProgramCommandBufferRequest final - : public TrCommandBufferSimpleRequest - { - public: - ValidateProgramCommandBufferRequest() = delete; - ValidateProgramCommandBufferRequest(uint32_t clientId) - : TrCommandBufferSimpleRequest() - , clientId(clientId) - { - } - ValidateProgramCommandBufferRequest(const ValidateProgramCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that) - , clientId(that.clientId) - { - } - - std::string toString(const char *line_prefix) const override - { - std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; - return ss.str(); - } - - public: - uint32_t clientId; - }; - - class ActiveInfo - { - public: - ActiveInfo() = default; - ActiveInfo(const ActiveInfo &that) = default; - ActiveInfo(string name, int size, int type) - : name(name) - , size(size) - , type(type) - { - } - - public: - string name; - int size; - int type; - }; - - class AttribLocation - { - public: - AttribLocation(string name, int location) - : name(name) - , location(location) - { - } - - public: - string name; - int location; - }; - - class UniformLocation - { - public: - UniformLocation(string name, int location, int size) - : name(name) - , location(location) - , size(size) - { - } - - public: - string name; - int location; - int size; - }; - - class UniformBlock - { - public: - UniformBlock(string name, int index) - : name(name) - , index(index) - { - } - - public: - string name; - int index; - }; - - enum LinkProgramCommandBufferResponseSegmentType - { - SEGMENT_ACTIVE_ATTRIB, - SEGMENT_ACTIVE_UNIFORM, - SEGMENT_ATTRIB_LOCATION, - SEGMENT_UNIFORM_LOCATION, - SEGMENT_UNIFORM_BLOCK - }; - - class LinkProgramCommandBufferResponse final - : public TrCommandBufferSimpleResponse - { - public: - LinkProgramCommandBufferResponse(LinkProgramCommandBufferResponse &that) - : TrCommandBufferSimpleResponse(that) - , success(that.success) - { - } - LinkProgramCommandBufferResponse(LinkProgramCommandBufferRequest *req, bool success) - : TrCommandBufferSimpleResponse(COMMAND_BUFFER_LINK_PROGRAM_RES, req) - , success(success) - { - } - LinkProgramCommandBufferResponse(const LinkProgramCommandBufferResponse &that, bool clone = false) - : TrCommandBufferSimpleResponse(that, clone) - , success(that.success) - { - if (clone) - { - activeAttribs = that.activeAttribs; - activeUniforms = that.activeUniforms; - attribLocations = that.attribLocations; - uniformLocations = that.uniformLocations; - uniformBlocks = that.uniformBlocks; - } - } - - public: TrCommandBufferMessage *serialize() override { auto message = new TrCommandBufferMessage(type, size, this); - for (auto &activeAttrib : activeAttribs) - addActiveInfoSegment(activeAttrib, SEGMENT_ACTIVE_ATTRIB, message); - for (auto &activeUniform : activeUniforms) - addActiveInfoSegment(activeUniform, SEGMENT_ACTIVE_UNIFORM, message); for (auto &attribLocation : attribLocations) - addAttribLocationSegment(attribLocation, message); + addLocationSegment(SEGMENT_ATTRIB_LOCATION, attribLocation, message); for (auto &uniformLocation : uniformLocations) - addUniformLocationSegment(uniformLocation, message); + addLocationSegment(SEGMENT_UNIFORM_LOCATION, uniformLocation, message); for (auto &uniformBlock : uniformBlocks) addUniformBlockSegment(uniformBlock, message); return message; @@ -275,16 +195,6 @@ namespace commandbuffers switch (segmentType) { - case SEGMENT_ACTIVE_ATTRIB: - { - activeAttribs.push_back(getActiveInfoFromBuffer(name, &pSourceData)); - break; - } - case SEGMENT_ACTIVE_UNIFORM: - { - activeUniforms.push_back(getActiveInfoFromBuffer(name, &pSourceData)); - break; - } case SEGMENT_ATTRIB_LOCATION: { int location; @@ -298,10 +208,7 @@ namespace commandbuffers int location; memcpy(&location, pSourceData, sizeof(int)); pSourceData += sizeof(int); - int size; - memcpy(&size, pSourceData, sizeof(int)); - pSourceData += sizeof(int); - uniformLocations.push_back(UniformLocation(name, location, size)); + uniformLocations.push_back(UniformLocation(name, location)); break; }; case SEGMENT_UNIFORM_BLOCK: @@ -362,24 +269,14 @@ namespace commandbuffers message->addSegment(new ipc::TrIpcMessageSegment(base)); } - void addAttribLocationSegment(AttribLocation &attribLocation, TrCommandBufferMessage *message) + void addLocationSegment(LinkProgramCommandBufferResponseSegmentType type, + Location &loc, + TrCommandBufferMessage *message) { - auto base = getSegmentBase(SEGMENT_ATTRIB_LOCATION, attribLocation.name); + auto base = getSegmentBase(type, loc.name); base.insert(base.end(), - reinterpret_cast(&attribLocation.location), - reinterpret_cast(&attribLocation.location) + sizeof(attribLocation.location)); - message->addSegment(new ipc::TrIpcMessageSegment(base)); - } - - void addUniformLocationSegment(UniformLocation &uniformLocation, TrCommandBufferMessage *message) - { - auto base = getSegmentBase(SEGMENT_UNIFORM_LOCATION, uniformLocation.name); - base.insert(base.end(), - reinterpret_cast(&uniformLocation.location), - reinterpret_cast(&uniformLocation.location) + sizeof(uniformLocation.location)); - base.insert(base.end(), - reinterpret_cast(&uniformLocation.size), - reinterpret_cast(&uniformLocation.size) + sizeof(uniformLocation.size)); + reinterpret_cast(&loc.location), + reinterpret_cast(&loc.location) + sizeof(loc.location)); message->addSegment(new ipc::TrIpcMessageSegment(base)); } @@ -393,14 +290,40 @@ namespace commandbuffers } public: - bool success; - vector activeAttribs; - vector activeUniforms; + uint32_t clientId; vector attribLocations; vector uniformLocations; vector uniformBlocks; }; + class ValidateProgramCommandBufferRequest final + : public TrCommandBufferSimpleRequest + { + public: + ValidateProgramCommandBufferRequest() = delete; + ValidateProgramCommandBufferRequest(uint32_t clientId) + : TrCommandBufferSimpleRequest() + , clientId(clientId) + { + } + ValidateProgramCommandBufferRequest(const ValidateProgramCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that) + , clientId(that.clientId) + { + } + + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + + public: + uint32_t clientId; + }; + class UseProgramCommandBufferRequest final : public TrCommandBufferSimpleRequest { diff --git a/src/common/command_buffers/macros.hpp b/src/common/command_buffers/macros.hpp index db0b669e4..00c9ad7d6 100644 --- a/src/common/command_buffers/macros.hpp +++ b/src/common/command_buffers/macros.hpp @@ -156,7 +156,6 @@ XX(WEBGL_CONTEXT_INIT, WebGL1ContextInitCommandBufferResponse, "GL::ContextInit") \ XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferResponse, "GL::Context2Init") \ XX(GET_EXTENSIONS, GetExtensionsCommandBufferResponse, "GL::GetExtensions") \ - XX(LINK_PROGRAM, LinkProgramCommandBufferResponse, "GL::LinkProgram") \ XX(GET_PROGRAM_PARAM, GetProgramParamCommandBufferResponse, "GL::GetProgramParam") \ XX(GET_PROGRAM_INFO_LOG, GetProgramInfoLogCommandBufferResponse, "GL::GetProgramInfoLog") \ XX(GET_SHADER_SOURCE, GetShaderSourceCommandBufferResponse, "GL::GetShaderSource") \ diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 1981787a7..ec2d1258d 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -462,7 +462,7 @@ std::optional ContextGLApp::getAttribLoc(commandbuffers::SetVertexAttribC optional ContextGLApp::getUniformLoc(commandbuffers::SetUniformCommandBufferRequestBase *req) const { optional loc = nullopt; - if (req->locationAvailable) + if (req->locationAvailable && false) { loc = req->location; } diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 606c09cbf..4071bc27a 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -506,108 +506,104 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto glContext = reqContentRenderer->getContextGL(); GLuint program = glContext->ObjectManagerRef().FindProgram(req->clientId); - glLinkProgram(program); - reqContentRenderer->getContextGL()->MarkAsDirty(); - - /** - * Check the link status of the program. - */ - GLenum status; - glGetProgramiv(program, GL_LINK_STATUS, (GLint *)&status); - if (status == GL_FALSE) - { - GLint errorLength; - glGetProgramiv(program, GL_INFO_LOG_LENGTH, &errorLength); - GLchar *errorStr = new GLchar[errorLength]; - glGetProgramInfoLog(program, errorLength, NULL, errorStr); - DEBUG(LOG_TAG_ERROR, "Failed to link program(%d): %s", program, errorStr); - delete[] errorStr; - - LinkProgramCommandBufferResponse failureRes(req, false); - // reqContentRenderer->sendCommandBufferResponse(failureRes); - return; - } - // Create response object - LinkProgramCommandBufferResponse res(req, true); - - /** - * Fetch the locations of the attributes when link successfully. - */ - GLint numAttributes = 0; - glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes); - for (int i = 0; i < numAttributes; i++) + for (const auto &attrib : req->attribLocations) { - GLsizei nameLength; - GLint size; /** FIXME: need size for attribs? */ - GLenum type; - GLchar name[256]; - - glGetActiveAttrib(program, i, sizeof(name) - 1, &nameLength, &size, &type, name); - name[nameLength] = '\0'; - res.activeAttribs.push_back(ActiveInfo(name, size, type)); - - GLint location = glGetAttribLocation(program, name); - res.attribLocations.push_back(AttribLocation(name, location)); - DEBUG(DEBUG_TAG, - " Attribute[%d](%s) => (size=%d, type=%s)", - location, - name, - size, - gles::glUniformTypesToString(type).c_str()); + if (attrib.name.rfind("gl_", 0) != 0) + { + glBindAttribLocation(program, attrib.location, attrib.name.c_str()); + DEBUG(LOG_TAG_RENDERER, + "[%d] GL::BindAttribLocation(program=%d, location=%d, name=%s)", + options.isDefaultQueue(), + program, + attrib.location, + attrib.name.c_str()); + } } + glLinkProgram(program); + reqContentRenderer->getContextGL()->MarkAsDirty(); - /** - * Fetch the locations of the uniforms and attributes when link successfully. - */ - GLint numUniforms = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms); - for (int i = 0; i < numUniforms; i++) + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - GLsizei nameLength; - GLint size; - GLenum type; - GLchar name[256]; + PrintDebugInfo(req, to_string(program).c_str(), nullptr, options); - glGetActiveUniform(program, i, sizeof(name) - 1, &nameLength, &size, &type, name); - name[nameLength] = '\0'; - res.activeUniforms.push_back(ActiveInfo(name, size, type)); + // Check the link status of the program. + GLenum status; + glGetProgramiv(program, GL_LINK_STATUS, (GLint *)&status); + if (status == GL_FALSE) + { + GLint errorLength; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &errorLength); + GLchar *errorStr = new GLchar[errorLength]; + glGetProgramInfoLog(program, errorLength, NULL, errorStr); + DEBUG(LOG_TAG_ERROR, "Failed to link program(%d): %s", program, errorStr); + delete[] errorStr; + return; + } - GLint location = glGetUniformLocation(program, name); - if (location <= -1) - continue; + // Fetch the locations of the attributes when link successfully. + GLint numAttributes = 0; + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes); + for (int i = 0; i < numAttributes; i++) + { + GLsizei nameLength; + GLint size; /** FIXME: need size for attribs? */ + GLenum type; + GLchar name[256]; + + glGetActiveAttrib(program, i, sizeof(name) - 1, &nameLength, &size, &type, name); + name[nameLength] = '\0'; + + GLint location = glGetAttribLocation(program, name); + DEBUG(DEBUG_TAG, + " Attribute[%d](%s) => (size=%d, type=%s)", + location, + name, + size, + gles::glUniformTypesToString(type).c_str()); + } - res.uniformLocations.push_back(UniformLocation(name, location, size)); - DEBUG(DEBUG_TAG, - " Uniform[%d](%s) => (loc=%d, size=%d, type=%s)", - i, - name, - location, - size, - gles::glUniformTypesToString(type).c_str()); - } + // Fetch the locations of the uniforms and attributes when link successfully. + GLint numUniforms = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms); + for (int i = 0; i < numUniforms; i++) + { + GLsizei nameLength; + GLint size; + GLenum type; + GLchar name[256]; + + glGetActiveUniform(program, i, sizeof(name) - 1, &nameLength, &size, &type, name); + name[nameLength] = '\0'; + + GLint location = glGetUniformLocation(program, name); + if (location <= -1) + continue; + + DEBUG(DEBUG_TAG, + " Uniform[%d](%s) => (loc=%d, size=%d, type=%s)", + i, + name, + location, + size, + gles::glUniformTypesToString(type).c_str()); + } - /** - * Fetch the uniform blocks when link successfully. - */ - GLint numUniformBlocks = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks); - for (int i = 0; i < numUniformBlocks; i++) - { - GLsizei nameLength; - GLchar name[256]; + // Fetch the uniform blocks when link successfully. + GLint numUniformBlocks = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks); + for (int i = 0; i < numUniformBlocks; i++) + { + GLsizei nameLength; + GLchar name[256]; - glGetActiveUniformBlockName(program, i, sizeof(name) - 1, &nameLength, name); - name[nameLength] = '\0'; + glGetActiveUniformBlockName(program, i, sizeof(name) - 1, &nameLength, name); + name[nameLength] = '\0'; - GLuint index = glGetUniformBlockIndex(program, name); - res.uniformBlocks.push_back(UniformBlock(name, index)); - DEBUG(DEBUG_TAG, " UniformBlock[%s] => %d", name, index); + GLuint index = glGetUniformBlockIndex(program, name); + DEBUG(DEBUG_TAG, " UniformBlock[%s] => %d", name, index); + } } - - if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - PrintDebugInfo(req, to_string(program).c_str(), nullptr, options); - reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnUseProgram(UseProgramCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2820,26 +2816,26 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectortype; - if (commandType == COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ) - { - auto req = dynamic_cast(commandbuffer); - assert(req != nullptr); - - if (pass_type == ExecutingPassType::kXRFrame && - (req->target == GL_FRAMEBUFFER || - req->target == GL_DRAW_FRAMEBUFFER)) - { - if (req->isBindToDefault()) // Stop copying commandbuffers into offscreen pass if it is to bind to default. - should_move_to_offscreen_pass = false; - else - { - GLuint framebuffer = contentGlContext->ObjectManagerRef().FindFramebuffer(req->framebuffer); - should_move_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); - if (should_move_to_offscreen_pass == true) - content_renderer->resetOffscreenPassGLContext(framebuffer); - } - } - } + // if (commandType == COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ) + // { + // auto req = dynamic_cast(commandbuffer); + // assert(req != nullptr); + + // if (pass_type == ExecutingPassType::kXRFrame && + // (req->target == GL_FRAMEBUFFER || + // req->target == GL_DRAW_FRAMEBUFFER)) + // { + // if (req->isBindToDefault()) // Stop copying commandbuffers into offscreen pass if it is to bind to default. + // should_move_to_offscreen_pass = false; + // else + // { + // GLuint framebuffer = contentGlContext->ObjectManagerRef().FindFramebuffer(req->framebuffer); + // should_move_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); + // if (should_move_to_offscreen_pass == true) + // content_renderer->resetOffscreenPassGLContext(framebuffer); + // } + // } + // } // Move the command buffers to offscreen pass if needed if (pass_type == ExecutingPassType::kXRFrame && should_move_to_offscreen_pass == true) diff --git a/thirdparty/headers/glslang/include/glslang/Include/ResourceLimits.h b/thirdparty/headers/glslang/include/glslang/Include/ResourceLimits.h new file mode 100644 index 000000000..b36c8d627 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/Include/ResourceLimits.h @@ -0,0 +1,159 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _RESOURCE_LIMITS_INCLUDED_ +#define _RESOURCE_LIMITS_INCLUDED_ + +struct TLimits { + bool nonInductiveForLoops; + bool whileLoops; + bool doWhileLoops; + bool generalUniformIndexing; + bool generalAttributeMatrixVectorIndexing; + bool generalVaryingIndexing; + bool generalSamplerIndexing; + bool generalVariableIndexing; + bool generalConstantMatrixVectorIndexing; +}; + +struct TBuiltInResource { + int maxLights; + int maxClipPlanes; + int maxTextureUnits; + int maxTextureCoords; + int maxVertexAttribs; + int maxVertexUniformComponents; + int maxVaryingFloats; + int maxVertexTextureImageUnits; + int maxCombinedTextureImageUnits; + int maxTextureImageUnits; + int maxFragmentUniformComponents; + int maxDrawBuffers; + int maxVertexUniformVectors; + int maxVaryingVectors; + int maxFragmentUniformVectors; + int maxVertexOutputVectors; + int maxFragmentInputVectors; + int minProgramTexelOffset; + int maxProgramTexelOffset; + int maxClipDistances; + int maxComputeWorkGroupCountX; + int maxComputeWorkGroupCountY; + int maxComputeWorkGroupCountZ; + int maxComputeWorkGroupSizeX; + int maxComputeWorkGroupSizeY; + int maxComputeWorkGroupSizeZ; + int maxComputeUniformComponents; + int maxComputeTextureImageUnits; + int maxComputeImageUniforms; + int maxComputeAtomicCounters; + int maxComputeAtomicCounterBuffers; + int maxVaryingComponents; + int maxVertexOutputComponents; + int maxGeometryInputComponents; + int maxGeometryOutputComponents; + int maxFragmentInputComponents; + int maxImageUnits; + int maxCombinedImageUnitsAndFragmentOutputs; + int maxCombinedShaderOutputResources; + int maxImageSamples; + int maxVertexImageUniforms; + int maxTessControlImageUniforms; + int maxTessEvaluationImageUniforms; + int maxGeometryImageUniforms; + int maxFragmentImageUniforms; + int maxCombinedImageUniforms; + int maxGeometryTextureImageUnits; + int maxGeometryOutputVertices; + int maxGeometryTotalOutputComponents; + int maxGeometryUniformComponents; + int maxGeometryVaryingComponents; + int maxTessControlInputComponents; + int maxTessControlOutputComponents; + int maxTessControlTextureImageUnits; + int maxTessControlUniformComponents; + int maxTessControlTotalOutputComponents; + int maxTessEvaluationInputComponents; + int maxTessEvaluationOutputComponents; + int maxTessEvaluationTextureImageUnits; + int maxTessEvaluationUniformComponents; + int maxTessPatchComponents; + int maxPatchVertices; + int maxTessGenLevel; + int maxViewports; + int maxVertexAtomicCounters; + int maxTessControlAtomicCounters; + int maxTessEvaluationAtomicCounters; + int maxGeometryAtomicCounters; + int maxFragmentAtomicCounters; + int maxCombinedAtomicCounters; + int maxAtomicCounterBindings; + int maxVertexAtomicCounterBuffers; + int maxTessControlAtomicCounterBuffers; + int maxTessEvaluationAtomicCounterBuffers; + int maxGeometryAtomicCounterBuffers; + int maxFragmentAtomicCounterBuffers; + int maxCombinedAtomicCounterBuffers; + int maxAtomicCounterBufferSize; + int maxTransformFeedbackBuffers; + int maxTransformFeedbackInterleavedComponents; + int maxCullDistances; + int maxCombinedClipAndCullDistances; + int maxSamples; + int maxMeshOutputVerticesNV; + int maxMeshOutputPrimitivesNV; + int maxMeshWorkGroupSizeX_NV; + int maxMeshWorkGroupSizeY_NV; + int maxMeshWorkGroupSizeZ_NV; + int maxTaskWorkGroupSizeX_NV; + int maxTaskWorkGroupSizeY_NV; + int maxTaskWorkGroupSizeZ_NV; + int maxMeshViewCountNV; + int maxMeshOutputVerticesEXT; + int maxMeshOutputPrimitivesEXT; + int maxMeshWorkGroupSizeX_EXT; + int maxMeshWorkGroupSizeY_EXT; + int maxMeshWorkGroupSizeZ_EXT; + int maxTaskWorkGroupSizeX_EXT; + int maxTaskWorkGroupSizeY_EXT; + int maxTaskWorkGroupSizeZ_EXT; + int maxMeshViewCountEXT; + int maxDualSourceDrawBuffersEXT; + + TLimits limits; +}; + +#endif // _RESOURCE_LIMITS_INCLUDED_ diff --git a/thirdparty/headers/glslang/include/glslang/Include/glslang_c_interface.h b/thirdparty/headers/glslang/include/glslang/Include/glslang_c_interface.h new file mode 100644 index 000000000..4eec55b58 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/Include/glslang_c_interface.h @@ -0,0 +1,299 @@ +/** + This code is based on the glslang_c_interface implementation by Viktor Latypov +**/ + +/** +BSD 2-Clause License + +Copyright (c) 2019, Viktor Latypov +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**/ + +#ifndef GLSLANG_C_IFACE_H_INCLUDED +#define GLSLANG_C_IFACE_H_INCLUDED + +#include +#include + +#include "glslang_c_shader_types.h" +#include "visibility.h" + +typedef struct glslang_shader_s glslang_shader_t; +typedef struct glslang_program_s glslang_program_t; +typedef struct glslang_mapper_s glslang_mapper_t; +typedef struct glslang_resolver_s glslang_resolver_t; + +/* Version counterpart */ +typedef struct glslang_version_s { + int major; + int minor; + int patch; + const char* flavor; +} glslang_version_t; + +/* TLimits counterpart */ +typedef struct glslang_limits_s { + bool non_inductive_for_loops; + bool while_loops; + bool do_while_loops; + bool general_uniform_indexing; + bool general_attribute_matrix_vector_indexing; + bool general_varying_indexing; + bool general_sampler_indexing; + bool general_variable_indexing; + bool general_constant_matrix_vector_indexing; +} glslang_limits_t; + +/* TBuiltInResource counterpart */ +typedef struct glslang_resource_s { + int max_lights; + int max_clip_planes; + int max_texture_units; + int max_texture_coords; + int max_vertex_attribs; + int max_vertex_uniform_components; + int max_varying_floats; + int max_vertex_texture_image_units; + int max_combined_texture_image_units; + int max_texture_image_units; + int max_fragment_uniform_components; + int max_draw_buffers; + int max_vertex_uniform_vectors; + int max_varying_vectors; + int max_fragment_uniform_vectors; + int max_vertex_output_vectors; + int max_fragment_input_vectors; + int min_program_texel_offset; + int max_program_texel_offset; + int max_clip_distances; + int max_compute_work_group_count_x; + int max_compute_work_group_count_y; + int max_compute_work_group_count_z; + int max_compute_work_group_size_x; + int max_compute_work_group_size_y; + int max_compute_work_group_size_z; + int max_compute_uniform_components; + int max_compute_texture_image_units; + int max_compute_image_uniforms; + int max_compute_atomic_counters; + int max_compute_atomic_counter_buffers; + int max_varying_components; + int max_vertex_output_components; + int max_geometry_input_components; + int max_geometry_output_components; + int max_fragment_input_components; + int max_image_units; + int max_combined_image_units_and_fragment_outputs; + int max_combined_shader_output_resources; + int max_image_samples; + int max_vertex_image_uniforms; + int max_tess_control_image_uniforms; + int max_tess_evaluation_image_uniforms; + int max_geometry_image_uniforms; + int max_fragment_image_uniforms; + int max_combined_image_uniforms; + int max_geometry_texture_image_units; + int max_geometry_output_vertices; + int max_geometry_total_output_components; + int max_geometry_uniform_components; + int max_geometry_varying_components; + int max_tess_control_input_components; + int max_tess_control_output_components; + int max_tess_control_texture_image_units; + int max_tess_control_uniform_components; + int max_tess_control_total_output_components; + int max_tess_evaluation_input_components; + int max_tess_evaluation_output_components; + int max_tess_evaluation_texture_image_units; + int max_tess_evaluation_uniform_components; + int max_tess_patch_components; + int max_patch_vertices; + int max_tess_gen_level; + int max_viewports; + int max_vertex_atomic_counters; + int max_tess_control_atomic_counters; + int max_tess_evaluation_atomic_counters; + int max_geometry_atomic_counters; + int max_fragment_atomic_counters; + int max_combined_atomic_counters; + int max_atomic_counter_bindings; + int max_vertex_atomic_counter_buffers; + int max_tess_control_atomic_counter_buffers; + int max_tess_evaluation_atomic_counter_buffers; + int max_geometry_atomic_counter_buffers; + int max_fragment_atomic_counter_buffers; + int max_combined_atomic_counter_buffers; + int max_atomic_counter_buffer_size; + int max_transform_feedback_buffers; + int max_transform_feedback_interleaved_components; + int max_cull_distances; + int max_combined_clip_and_cull_distances; + int max_samples; + int max_mesh_output_vertices_nv; + int max_mesh_output_primitives_nv; + int max_mesh_work_group_size_x_nv; + int max_mesh_work_group_size_y_nv; + int max_mesh_work_group_size_z_nv; + int max_task_work_group_size_x_nv; + int max_task_work_group_size_y_nv; + int max_task_work_group_size_z_nv; + int max_mesh_view_count_nv; + int max_mesh_output_vertices_ext; + int max_mesh_output_primitives_ext; + int max_mesh_work_group_size_x_ext; + int max_mesh_work_group_size_y_ext; + int max_mesh_work_group_size_z_ext; + int max_task_work_group_size_x_ext; + int max_task_work_group_size_y_ext; + int max_task_work_group_size_z_ext; + int max_mesh_view_count_ext; + union + { + int max_dual_source_draw_buffers_ext; + + /* Incorrectly capitalized name retained for backward compatibility */ + int maxDualSourceDrawBuffersEXT; + }; + + glslang_limits_t limits; +} glslang_resource_t; + +/* Inclusion result structure allocated by C include_local/include_system callbacks */ +typedef struct glsl_include_result_s { + /* Header file name or NULL if inclusion failed */ + const char* header_name; + + /* Header contents or NULL */ + const char* header_data; + size_t header_length; + +} glsl_include_result_t; + +/* Callback for local file inclusion */ +typedef glsl_include_result_t* (*glsl_include_local_func)(void* ctx, const char* header_name, const char* includer_name, + size_t include_depth); + +/* Callback for system file inclusion */ +typedef glsl_include_result_t* (*glsl_include_system_func)(void* ctx, const char* header_name, + const char* includer_name, size_t include_depth); + +/* Callback for include result destruction */ +typedef int (*glsl_free_include_result_func)(void* ctx, glsl_include_result_t* result); + +/* Collection of callbacks for GLSL preprocessor */ +typedef struct glsl_include_callbacks_s { + glsl_include_system_func include_system; + glsl_include_local_func include_local; + glsl_free_include_result_func free_include_result; +} glsl_include_callbacks_t; + +typedef struct glslang_input_s { + glslang_source_t language; + glslang_stage_t stage; + glslang_client_t client; + glslang_target_client_version_t client_version; + glslang_target_language_t target_language; + glslang_target_language_version_t target_language_version; + /** Shader source code */ + const char* code; + int default_version; + glslang_profile_t default_profile; + int force_default_version_and_profile; + int forward_compatible; + glslang_messages_t messages; + const glslang_resource_t* resource; + glsl_include_callbacks_t callbacks; + void* callbacks_ctx; +} glslang_input_t; + +/* SpvOptions counterpart */ +typedef struct glslang_spv_options_s { + bool generate_debug_info; + bool strip_debug_info; + bool disable_optimizer; + bool optimize_size; + bool disassemble; + bool validate; + bool emit_nonsemantic_shader_debug_info; + bool emit_nonsemantic_shader_debug_source; + bool compile_only; + bool optimize_allow_expanded_id_bound; +} glslang_spv_options_t; + +#ifdef __cplusplus +extern "C" { +#endif + +GLSLANG_EXPORT void glslang_get_version(glslang_version_t* version); + +GLSLANG_EXPORT int glslang_initialize_process(void); +GLSLANG_EXPORT void glslang_finalize_process(void); + +GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input); +GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader); +GLSLANG_EXPORT void glslang_shader_set_preamble(glslang_shader_t* shader, const char* s); +GLSLANG_EXPORT void glslang_shader_set_entry_point(glslang_shader_t* shader, const char* s); +GLSLANG_EXPORT void glslang_shader_set_invert_y(glslang_shader_t* shader, bool y); +GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base); +GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set); +GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t +GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version); +GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_set_and_binding(glslang_shader_t* shader, unsigned int set, unsigned int binding); +GLSLANG_EXPORT void glslang_shader_set_default_uniform_block_name(glslang_shader_t* shader, const char *name); +GLSLANG_EXPORT void glslang_shader_set_resource_set_binding(glslang_shader_t* shader, const char *const *bindings, unsigned int num_bindings); +GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input); +GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input); +GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader); +GLSLANG_EXPORT void glslang_shader_set_preprocessed_code(glslang_shader_t* shader, const char* code); +GLSLANG_EXPORT const char* glslang_shader_get_info_log(glslang_shader_t* shader); +GLSLANG_EXPORT const char* glslang_shader_get_info_debug_log(glslang_shader_t* shader); + +GLSLANG_EXPORT glslang_program_t* glslang_program_create(void); +GLSLANG_EXPORT void glslang_program_delete(glslang_program_t* program); +GLSLANG_EXPORT void glslang_program_add_shader(glslang_program_t* program, glslang_shader_t* shader); +GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages); // glslang_messages_t +GLSLANG_EXPORT void glslang_program_add_source_text(glslang_program_t* program, glslang_stage_t stage, const char* text, size_t len); +GLSLANG_EXPORT void glslang_program_set_source_file(glslang_program_t* program, glslang_stage_t stage, const char* file); +GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program); +GLSLANG_EXPORT int glslang_program_map_io_with_resolver_and_mapper(glslang_program_t* program, glslang_resolver_t* resolver, glslang_mapper_t* mapper); +GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage); +GLSLANG_EXPORT void glslang_program_SPIRV_generate_with_options(glslang_program_t* program, glslang_stage_t stage, glslang_spv_options_t* spv_options); +GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program); +GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int*); +GLSLANG_EXPORT unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program); +GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* program); +GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program); +GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* program); + +GLSLANG_EXPORT glslang_mapper_t* glslang_glsl_mapper_create(void); +GLSLANG_EXPORT void glslang_glsl_mapper_delete(glslang_mapper_t* mapper); + +GLSLANG_EXPORT glslang_resolver_t* glslang_glsl_resolver_create(glslang_program_t* program, glslang_stage_t stage); +GLSLANG_EXPORT void glslang_glsl_resolver_delete(glslang_resolver_t* resolver); + +#ifdef __cplusplus +} +#endif + +#endif /* #ifdef GLSLANG_C_IFACE_INCLUDED */ diff --git a/thirdparty/headers/glslang/include/glslang/Include/glslang_c_shader_types.h b/thirdparty/headers/glslang/include/glslang/Include/glslang_c_shader_types.h new file mode 100644 index 000000000..ccba2fde6 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/Include/glslang_c_shader_types.h @@ -0,0 +1,235 @@ +/** + This code is based on the glslang_c_interface implementation by Viktor Latypov +**/ + +/** +BSD 2-Clause License + +Copyright (c) 2019, Viktor Latypov +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**/ + +#ifndef C_SHADER_TYPES_H_INCLUDED +#define C_SHADER_TYPES_H_INCLUDED + +#define LAST_ELEMENT_MARKER(x) x + +/* EShLanguage counterpart */ +typedef enum { + GLSLANG_STAGE_VERTEX, + GLSLANG_STAGE_TESSCONTROL, + GLSLANG_STAGE_TESSEVALUATION, + GLSLANG_STAGE_GEOMETRY, + GLSLANG_STAGE_FRAGMENT, + GLSLANG_STAGE_COMPUTE, + GLSLANG_STAGE_RAYGEN, + GLSLANG_STAGE_RAYGEN_NV = GLSLANG_STAGE_RAYGEN, + GLSLANG_STAGE_INTERSECT, + GLSLANG_STAGE_INTERSECT_NV = GLSLANG_STAGE_INTERSECT, + GLSLANG_STAGE_ANYHIT, + GLSLANG_STAGE_ANYHIT_NV = GLSLANG_STAGE_ANYHIT, + GLSLANG_STAGE_CLOSESTHIT, + GLSLANG_STAGE_CLOSESTHIT_NV = GLSLANG_STAGE_CLOSESTHIT, + GLSLANG_STAGE_MISS, + GLSLANG_STAGE_MISS_NV = GLSLANG_STAGE_MISS, + GLSLANG_STAGE_CALLABLE, + GLSLANG_STAGE_CALLABLE_NV = GLSLANG_STAGE_CALLABLE, + GLSLANG_STAGE_TASK, + GLSLANG_STAGE_TASK_NV = GLSLANG_STAGE_TASK, + GLSLANG_STAGE_MESH, + GLSLANG_STAGE_MESH_NV = GLSLANG_STAGE_MESH, + LAST_ELEMENT_MARKER(GLSLANG_STAGE_COUNT), +} glslang_stage_t; // would be better as stage, but this is ancient now + +/* EShLanguageMask counterpart */ +typedef enum { + GLSLANG_STAGE_VERTEX_MASK = (1 << GLSLANG_STAGE_VERTEX), + GLSLANG_STAGE_TESSCONTROL_MASK = (1 << GLSLANG_STAGE_TESSCONTROL), + GLSLANG_STAGE_TESSEVALUATION_MASK = (1 << GLSLANG_STAGE_TESSEVALUATION), + GLSLANG_STAGE_GEOMETRY_MASK = (1 << GLSLANG_STAGE_GEOMETRY), + GLSLANG_STAGE_FRAGMENT_MASK = (1 << GLSLANG_STAGE_FRAGMENT), + GLSLANG_STAGE_COMPUTE_MASK = (1 << GLSLANG_STAGE_COMPUTE), + GLSLANG_STAGE_RAYGEN_MASK = (1 << GLSLANG_STAGE_RAYGEN), + GLSLANG_STAGE_RAYGEN_NV_MASK = GLSLANG_STAGE_RAYGEN_MASK, + GLSLANG_STAGE_INTERSECT_MASK = (1 << GLSLANG_STAGE_INTERSECT), + GLSLANG_STAGE_INTERSECT_NV_MASK = GLSLANG_STAGE_INTERSECT_MASK, + GLSLANG_STAGE_ANYHIT_MASK = (1 << GLSLANG_STAGE_ANYHIT), + GLSLANG_STAGE_ANYHIT_NV_MASK = GLSLANG_STAGE_ANYHIT_MASK, + GLSLANG_STAGE_CLOSESTHIT_MASK = (1 << GLSLANG_STAGE_CLOSESTHIT), + GLSLANG_STAGE_CLOSESTHIT_NV_MASK = GLSLANG_STAGE_CLOSESTHIT_MASK, + GLSLANG_STAGE_MISS_MASK = (1 << GLSLANG_STAGE_MISS), + GLSLANG_STAGE_MISS_NV_MASK = GLSLANG_STAGE_MISS_MASK, + GLSLANG_STAGE_CALLABLE_MASK = (1 << GLSLANG_STAGE_CALLABLE), + GLSLANG_STAGE_CALLABLE_NV_MASK = GLSLANG_STAGE_CALLABLE_MASK, + GLSLANG_STAGE_TASK_MASK = (1 << GLSLANG_STAGE_TASK), + GLSLANG_STAGE_TASK_NV_MASK = GLSLANG_STAGE_TASK_MASK, + GLSLANG_STAGE_MESH_MASK = (1 << GLSLANG_STAGE_MESH), + GLSLANG_STAGE_MESH_NV_MASK = GLSLANG_STAGE_MESH_MASK, + LAST_ELEMENT_MARKER(GLSLANG_STAGE_MASK_COUNT), +} glslang_stage_mask_t; + +/* EShSource counterpart */ +typedef enum { + GLSLANG_SOURCE_NONE, + GLSLANG_SOURCE_GLSL, + GLSLANG_SOURCE_HLSL, + LAST_ELEMENT_MARKER(GLSLANG_SOURCE_COUNT), +} glslang_source_t; + +/* EShClient counterpart */ +typedef enum { + GLSLANG_CLIENT_NONE, + GLSLANG_CLIENT_VULKAN, + GLSLANG_CLIENT_OPENGL, + LAST_ELEMENT_MARKER(GLSLANG_CLIENT_COUNT), +} glslang_client_t; + +/* EShTargetLanguage counterpart */ +typedef enum { + GLSLANG_TARGET_NONE, + GLSLANG_TARGET_SPV, + LAST_ELEMENT_MARKER(GLSLANG_TARGET_COUNT), +} glslang_target_language_t; + +/* SH_TARGET_ClientVersion counterpart */ +typedef enum { + GLSLANG_TARGET_VULKAN_1_0 = (1 << 22), + GLSLANG_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12), + GLSLANG_TARGET_VULKAN_1_2 = (1 << 22) | (2 << 12), + GLSLANG_TARGET_VULKAN_1_3 = (1 << 22) | (3 << 12), + GLSLANG_TARGET_VULKAN_1_4 = (1 << 22) | (4 << 12), + GLSLANG_TARGET_OPENGL_450 = 450, + LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT = 6), +} glslang_target_client_version_t; + +/* SH_TARGET_LanguageVersion counterpart */ +typedef enum { + GLSLANG_TARGET_SPV_1_0 = (1 << 16), + GLSLANG_TARGET_SPV_1_1 = (1 << 16) | (1 << 8), + GLSLANG_TARGET_SPV_1_2 = (1 << 16) | (2 << 8), + GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8), + GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8), + GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8), + GLSLANG_TARGET_SPV_1_6 = (1 << 16) | (6 << 8), + LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 7), +} glslang_target_language_version_t; + +/* EShExecutable counterpart */ +typedef enum { GLSLANG_EX_VERTEX_FRAGMENT, GLSLANG_EX_FRAGMENT } glslang_executable_t; + +// EShOptimizationLevel counterpart +// This enum is not used in the current C interface, but could be added at a later date. +// GLSLANG_OPT_NONE is the current default. +typedef enum { + GLSLANG_OPT_NO_GENERATION, + GLSLANG_OPT_NONE, + GLSLANG_OPT_SIMPLE, + GLSLANG_OPT_FULL, + LAST_ELEMENT_MARKER(GLSLANG_OPT_LEVEL_COUNT), +} glslang_optimization_level_t; + +/* EShTextureSamplerTransformMode counterpart */ +typedef enum { + GLSLANG_TEX_SAMP_TRANS_KEEP, + GLSLANG_TEX_SAMP_TRANS_UPGRADE_TEXTURE_REMOVE_SAMPLER, + LAST_ELEMENT_MARKER(GLSLANG_TEX_SAMP_TRANS_COUNT), +} glslang_texture_sampler_transform_mode_t; + +/* EShMessages counterpart */ +typedef enum { + GLSLANG_MSG_DEFAULT_BIT = 0, + GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0), + GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1), + GLSLANG_MSG_AST_BIT = (1 << 2), + GLSLANG_MSG_SPV_RULES_BIT = (1 << 3), + GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4), + GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5), + GLSLANG_MSG_READ_HLSL_BIT = (1 << 6), + GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7), + GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8), + GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9), + GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10), + GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT = (1 << 11), + GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12), + GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13), + GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14), + GLSLANG_MSG_ENHANCED = (1 << 15), + GLSLANG_MSG_ABSOLUTE_PATH = (1 << 16), + GLSLANG_MSG_DISPLAY_ERROR_COLUMN = (1 << 17), + GLSLANG_MSG_LINK_TIME_OPTIMIZATION_BIT = (1 << 18), + GLSLANG_MSG_VALIDATE_CROSS_STAGE_IO_BIT = (1 << 19), + LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT), +} glslang_messages_t; + +/* EShReflectionOptions counterpart */ +typedef enum { + GLSLANG_REFLECTION_DEFAULT_BIT = 0, + GLSLANG_REFLECTION_STRICT_ARRAY_SUFFIX_BIT = (1 << 0), + GLSLANG_REFLECTION_BASIC_ARRAY_SUFFIX_BIT = (1 << 1), + GLSLANG_REFLECTION_INTERMEDIATE_IOO_BIT = (1 << 2), + GLSLANG_REFLECTION_SEPARATE_BUFFERS_BIT = (1 << 3), + GLSLANG_REFLECTION_ALL_BLOCK_VARIABLES_BIT = (1 << 4), + GLSLANG_REFLECTION_UNWRAP_IO_BLOCKS_BIT = (1 << 5), + GLSLANG_REFLECTION_ALL_IO_VARIABLES_BIT = (1 << 6), + GLSLANG_REFLECTION_SHARED_STD140_SSBO_BIT = (1 << 7), + GLSLANG_REFLECTION_SHARED_STD140_UBO_BIT = (1 << 8), + LAST_ELEMENT_MARKER(GLSLANG_REFLECTION_COUNT), +} glslang_reflection_options_t; + +/* EProfile counterpart (from Versions.h) */ +typedef enum { + GLSLANG_BAD_PROFILE = 0, + GLSLANG_NO_PROFILE = (1 << 0), + GLSLANG_CORE_PROFILE = (1 << 1), + GLSLANG_COMPATIBILITY_PROFILE = (1 << 2), + GLSLANG_ES_PROFILE = (1 << 3), + LAST_ELEMENT_MARKER(GLSLANG_PROFILE_COUNT), +} glslang_profile_t; + +/* Shader options */ +typedef enum { + GLSLANG_SHADER_DEFAULT_BIT = 0, + GLSLANG_SHADER_AUTO_MAP_BINDINGS = (1 << 0), + GLSLANG_SHADER_AUTO_MAP_LOCATIONS = (1 << 1), + GLSLANG_SHADER_VULKAN_RULES_RELAXED = (1 << 2), + LAST_ELEMENT_MARKER(GLSLANG_SHADER_COUNT), +} glslang_shader_options_t; + +/* TResourceType counterpart */ +typedef enum { + GLSLANG_RESOURCE_TYPE_SAMPLER, + GLSLANG_RESOURCE_TYPE_TEXTURE, + GLSLANG_RESOURCE_TYPE_IMAGE, + GLSLANG_RESOURCE_TYPE_UBO, + GLSLANG_RESOURCE_TYPE_SSBO, + GLSLANG_RESOURCE_TYPE_UAV, + GLSLANG_RESOURCE_TYPE_COMBINED_SAMPLER, + GLSLANG_RESOURCE_TYPE_AS, + GLSLANG_RESOURCE_TYPE_TENSOR, + LAST_ELEMENT_MARKER(GLSLANG_RESOURCE_TYPE_COUNT), +} glslang_resource_type_t; + +#undef LAST_ELEMENT_MARKER + +#endif diff --git a/thirdparty/headers/glslang/include/glslang/Include/visibility.h b/thirdparty/headers/glslang/include/glslang/Include/visibility.h new file mode 100644 index 000000000..dd32351f8 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/Include/visibility.h @@ -0,0 +1,58 @@ +// +// Copyright (C) 2023 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#ifdef GLSLANG_IS_SHARED_LIBRARY + #ifdef _WIN32 + #ifdef GLSLANG_EXPORTING + #define GLSLANG_EXPORT __declspec(dllexport) + #else + #define GLSLANG_EXPORT __declspec(dllimport) + #endif + #elif __GNUC__ >= 4 + #define GLSLANG_EXPORT __attribute__((visibility("default"))) + #endif +#endif // GLSLANG_IS_SHARED_LIBRARY + +#ifndef GLSLANG_EXPORT +#define GLSLANG_EXPORT +#endif + +// Symbols marked with this macro are only meant for public use by the test suite +// and do not appear in publicly installed headers. They are not considered to be +// part of the glslang library ABI. +#ifdef GLSLANG_TEST_BUILD + #define GLSLANG_EXPORT_FOR_TESTS GLSLANG_EXPORT +#else + #define GLSLANG_EXPORT_FOR_TESTS +#endif diff --git a/thirdparty/headers/glslang/include/glslang/MachineIndependent/Versions.h b/thirdparty/headers/glslang/include/glslang/MachineIndependent/Versions.h new file mode 100644 index 000000000..8bc4f7132 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/MachineIndependent/Versions.h @@ -0,0 +1,404 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2012-2013 LunarG, Inc. +// Copyright (C) 2017, 2022-2024 Arm Limited. +// Copyright (C) 2015-2018 Google, Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved. +// Modifications Copyright (C) 2024 Valve Corporation. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef _VERSIONS_INCLUDED_ +#define _VERSIONS_INCLUDED_ + +#define LAST_ELEMENT_MARKER(x) x + +// +// Help manage multiple profiles, versions, extensions etc. +// + +// +// Profiles are set up for masking operations, so queries can be done on multiple +// profiles at the same time. +// +// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible +// defects from mixing the two different forms. +// +typedef enum : unsigned { + EBadProfile = 0, + ENoProfile = (1 << 0), // only for desktop, before profiles showed up + ECoreProfile = (1 << 1), + ECompatibilityProfile = (1 << 2), + EEsProfile = (1 << 3), + LAST_ELEMENT_MARKER(EProfileCount), +} EProfile; + +namespace glslang { + +// +// Map from profile enum to externally readable text name. +// +inline const char* ProfileName(EProfile profile) +{ + switch (profile) { + case ENoProfile: return "none"; + case ECoreProfile: return "core"; + case ECompatibilityProfile: return "compatibility"; + case EEsProfile: return "es"; + default: return "unknown profile"; + } +} + +// +// What source rules, validation rules, target language, etc. are needed or +// desired for SPIR-V? +// +// 0 means a target or rule set is not enabled (ignore rules from that entity). +// Non-0 means to apply semantic rules arising from that version of its rule set. +// The union of all requested rule sets will be applied. +// +struct SpvVersion { + SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0), vulkanRelaxed(false) {} + unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header + int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX" + int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use + int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX" + bool vulkanRelaxed; // relax changes to GLSL for Vulkan, allowing some GL-specific to be compiled to Vulkan SPIR-V target +}; + +// +// The behaviors from the GLSL "#extension extension_name : behavior" +// +typedef enum { + EBhMissing = 0, + EBhRequire, + EBhEnable, + EBhWarn, + EBhDisable, + EBhDisablePartial // use as initial state of an extension that is only partially implemented +} TExtensionBehavior; + +// +// Symbolic names for extensions. Strings may be directly used when calling the +// functions, but better to have the compiler do spelling checks. +// +const char* const E_GL_OES_texture_3D = "GL_OES_texture_3D"; +const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_derivatives"; +const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth"; +const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external"; +const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3"; +const char* const E_GL_EXT_YUV_target = "GL_EXT_YUV_target"; +const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod"; +const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers"; + +const char* const E_GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle"; +const char* const E_GL_3DL_array_objects = "GL_3DL_array_objects"; +const char* const E_GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack"; +const char* const E_GL_ARB_texture_gather = "GL_ARB_texture_gather"; +const char* const E_GL_ARB_gpu_shader5 = "GL_ARB_gpu_shader5"; +const char* const E_GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects"; +const char* const E_GL_ARB_compute_shader = "GL_ARB_compute_shader"; +const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader"; +const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts"; +const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array"; +const char* const E_GL_ARB_texture_multisample = "GL_ARB_texture_multisample"; +const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod"; +const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location"; +const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location"; +const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store"; +const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters"; +const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops"; +const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters"; +const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote"; +const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control"; +const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples"; +const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array"; +const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64"; +const char* const E_GL_ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64"; +const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot"; +const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2"; +const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp"; +const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil_export"; +// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members +const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage"; +const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array"; +const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock"; +const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock"; +const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object"; +const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading"; +const char* const E_GL_ARB_shader_bit_encoding = "GL_ARB_shader_bit_encoding"; +const char* const E_GL_ARB_shader_image_size = "GL_ARB_shader_image_size"; +const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage_buffer_object"; +const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing"; +const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod"; +const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit"; +const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced"; +const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions"; +const char* const E_GL_ARB_bindless_texture = "GL_ARB_bindless_texture"; + +const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic"; +const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote"; +const char* const E_GL_KHR_shader_subgroup_arithmetic = "GL_KHR_shader_subgroup_arithmetic"; +const char* const E_GL_KHR_shader_subgroup_ballot = "GL_KHR_shader_subgroup_ballot"; +const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_subgroup_shuffle"; +const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative"; +const char* const E_GL_KHR_shader_subgroup_rotate = "GL_KHR_shader_subgroup_rotate"; +const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered"; +const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad"; +const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics"; +const char* const E_GL_KHR_cooperative_matrix = "GL_KHR_cooperative_matrix"; + +const char* const E_GL_EXT_shader_atomic_int64 = "GL_EXT_shader_atomic_int64"; + +const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers"; +const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted"; + +const char* const E_GL_EXT_shader_16bit_storage = "GL_EXT_shader_16bit_storage"; +const char* const E_GL_EXT_shader_8bit_storage = "GL_EXT_shader_8bit_storage"; + + +// EXT extensions +const char* const E_GL_EXT_device_group = "GL_EXT_device_group"; +const char* const E_GL_EXT_multiview = "GL_EXT_multiview"; +const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage"; +const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes"; +const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier"; +const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions"; +const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout"; +const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density"; +const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference"; +const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2"; +const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2"; +const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation"; +const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock"; +const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_printf"; +const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing"; +const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query"; +const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling"; +const char* const E_GL_EXT_ray_cull_mask = "GL_EXT_ray_cull_mask"; +const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended"; +const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions"; +const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate"; +const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64"; +const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer"; +const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block"; +const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow"; +const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics"; +const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric"; +const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader"; +const char* const E_GL_EXT_opacity_micromap = "GL_EXT_opacity_micromap"; +const char* const E_GL_EXT_shader_quad_control = "GL_EXT_shader_quad_control"; +const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_instanced"; +const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array"; +const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence"; +const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume"; +const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2"; +const char* const E_GL_EXT_spec_constant_composites = "GL_EXT_spec_constant_composites"; +const char* const E_GL_EXT_texture_offset_non_const = "GL_EXT_texture_offset_non_const"; +const char* const E_GL_EXT_nontemporal_keyword = "GL_EXT_nontemporal_keyword"; + +// Arrays of extensions for the above viewportEXTs duplications + +const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage }; +const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]); + +// Array of extensions to cover both extensions providing ray tracing capabilities. +const char* const ray_tracing_EXTs[] = { E_GL_EXT_ray_query, E_GL_EXT_ray_tracing }; +const int Num_ray_tracing_EXTs = sizeof(ray_tracing_EXTs) / sizeof(ray_tracing_EXTs[0]); + +// OVR extensions +const char* const E_GL_OVR_multiview = "GL_OVR_multiview"; +const char* const E_GL_OVR_multiview2 = "GL_OVR_multiview2"; + +const char* const OVR_multiview_EXTs[] = { E_GL_OVR_multiview, E_GL_OVR_multiview2 }; +const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multiview_EXTs[0]); + +// #line and #include +const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive"; +const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive"; +const char* const E_GL_ARB_shading_language_include = "GL_ARB_shading_language_include"; + +const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot"; +const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax"; +const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter"; +const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader"; +const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float"; +const char* const E_GL_AMD_texture_gather_bias_lod = "GL_AMD_texture_gather_bias_lod"; +const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16"; +const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod"; +const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask"; +const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch"; +const char* const E_GL_AMD_shader_early_and_late_fragment_tests = "GL_AMD_shader_early_and_late_fragment_tests"; + +const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2"; + +const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage"; +const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough"; +const char* const E_GL_NV_viewport_array2 = "GL_NV_viewport_array2"; +const char* const E_GL_NV_stereo_view_rendering = "GL_NV_stereo_view_rendering"; +const char* const E_GL_NVX_multiview_per_view_attributes = "GL_NVX_multiview_per_view_attributes"; +const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_atomic_int64"; +const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation"; +const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_noperspective_interpolation"; +const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned"; +const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image"; +const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing"; +const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur"; +const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric"; +const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives"; +const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint"; +const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_shader"; +const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix"; +const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins"; +const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix"; +const char* const E_GL_NV_shader_invocation_reorder = "GL_NV_shader_invocation_reorder"; +const char* const E_GL_EXT_ray_tracing_position_fetch = "GL_EXT_ray_tracing_position_fetch"; +const char* const E_GL_NV_displacement_micromap = "GL_NV_displacement_micromap"; +const char* const E_GL_NV_shader_atomic_fp16_vector = "GL_NV_shader_atomic_fp16_vector"; +const char* const E_GL_NV_cooperative_matrix2 = "GL_NV_cooperative_matrix2"; +const char* const E_GL_NV_cooperative_vector = "GL_NV_cooperative_vector"; +const char* const E_GL_NV_cluster_acceleration_structure = "GL_NV_cluster_acceleration_structure"; +const char* const E_GL_NV_linear_swept_spheres = "GL_NV_linear_swept_spheres"; +const char* const E_GL_NV_gpu_shader5 = "GL_NV_gpu_shader5"; + +// ARM +const char* const E_GL_ARM_shader_core_builtins = "GL_ARM_shader_core_builtins"; +const char* const E_GL_ARM_tensors = "GL_ARM_tensors"; + +// Arrays of extensions for the above viewportEXTs duplications + +const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 }; +const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]); + + +const char* const E_GL_QCOM_image_processing = "GL_QCOM_image_processing"; +const char* const E_GL_QCOM_image_processing2 = "GL_QCOM_image_processing2"; +const char* const E_GL_QCOM_tile_shading = "GL_QCOM_tile_shading"; +const char* const E_GL_QCOM_cooperative_matrix_conversion = "GL_QCOM_cooperative_matrix_conversion"; + +// AEP +const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a"; +const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced"; +const char* const E_GL_OES_sample_variables = "GL_OES_sample_variables"; +const char* const E_GL_OES_shader_image_atomic = "GL_OES_shader_image_atomic"; +const char* const E_GL_OES_shader_multisample_interpolation = "GL_OES_shader_multisample_interpolation"; +const char* const E_GL_OES_texture_storage_multisample_2d_array = "GL_OES_texture_storage_multisample_2d_array"; +const char* const E_GL_EXT_geometry_shader = "GL_EXT_geometry_shader"; +const char* const E_GL_EXT_geometry_point_size = "GL_EXT_geometry_point_size"; +const char* const E_GL_EXT_gpu_shader5 = "GL_EXT_gpu_shader5"; +const char* const E_GL_EXT_primitive_bounding_box = "GL_EXT_primitive_bounding_box"; +const char* const E_GL_EXT_shader_io_blocks = "GL_EXT_shader_io_blocks"; +const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessellation_shader"; +const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size"; +const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer"; +const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array"; +const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix"; + +// OES matching AEP +const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader"; +const char* const E_GL_OES_geometry_point_size = "GL_OES_geometry_point_size"; +const char* const E_GL_OES_gpu_shader5 = "GL_OES_gpu_shader5"; +const char* const E_GL_OES_primitive_bounding_box = "GL_OES_primitive_bounding_box"; +const char* const E_GL_OES_shader_io_blocks = "GL_OES_shader_io_blocks"; +const char* const E_GL_OES_tessellation_shader = "GL_OES_tessellation_shader"; +const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessellation_point_size"; +const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer"; +const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array"; + +// EXT +const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int32 = "GL_EXT_shader_explicit_arithmetic_types_int32"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_int64 = "GL_EXT_shader_explicit_arithmetic_types_int64"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_float16 = "GL_EXT_shader_explicit_arithmetic_types_float16"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32"; +const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64"; + +const char* const E_GL_EXT_shader_subgroup_extended_types_int8 = "GL_EXT_shader_subgroup_extended_types_int8"; +const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shader_subgroup_extended_types_int16"; +const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64"; +const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16"; +const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation"; + +const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float"; +const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2"; + +const char* const E_GL_EXT_shader_tile_image = "GL_EXT_shader_tile_image"; + +const char* const E_GL_EXT_texture_shadow_lod = "GL_EXT_texture_shadow_lod"; + +const char* const E_GL_EXT_integer_dot_product = "GL_EXT_integer_dot_product"; + +const char* const E_GL_EXT_bfloat16 = "GL_EXT_bfloat16"; +const char* const E_GL_EXT_float_e5m2 = "GL_EXT_float_e5m2"; +const char* const E_GL_EXT_float_e4m3 = "GL_EXT_float_e4m3"; + +// Arrays of extensions for the above AEP duplications + +const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; +const int Num_AEP_geometry_shader = sizeof(AEP_geometry_shader)/sizeof(AEP_geometry_shader[0]); + +const char* const AEP_geometry_point_size[] = { E_GL_EXT_geometry_point_size, E_GL_OES_geometry_point_size }; +const int Num_AEP_geometry_point_size = sizeof(AEP_geometry_point_size)/sizeof(AEP_geometry_point_size[0]); + +const char* const AEP_gpu_shader5[] = { E_GL_EXT_gpu_shader5, E_GL_OES_gpu_shader5 }; +const int Num_AEP_gpu_shader5 = sizeof(AEP_gpu_shader5)/sizeof(AEP_gpu_shader5[0]); + +const char* const AEP_core_gpu_shader5[] = { E_GL_ARB_gpu_shader5, E_GL_NV_gpu_shader5}; +const int Num_AEP_core_gpu_shader5 = sizeof(AEP_core_gpu_shader5)/sizeof(AEP_core_gpu_shader5[0]); + +const char* const AEP_primitive_bounding_box[] = { E_GL_EXT_primitive_bounding_box, E_GL_OES_primitive_bounding_box }; +const int Num_AEP_primitive_bounding_box = sizeof(AEP_primitive_bounding_box)/sizeof(AEP_primitive_bounding_box[0]); + +const char* const AEP_shader_io_blocks[] = { E_GL_EXT_shader_io_blocks, E_GL_OES_shader_io_blocks }; +const int Num_AEP_shader_io_blocks = sizeof(AEP_shader_io_blocks)/sizeof(AEP_shader_io_blocks[0]); + +const char* const AEP_tessellation_shader[] = { E_GL_EXT_tessellation_shader, E_GL_OES_tessellation_shader }; +const int Num_AEP_tessellation_shader = sizeof(AEP_tessellation_shader)/sizeof(AEP_tessellation_shader[0]); + +const char* const AEP_tessellation_point_size[] = { E_GL_EXT_tessellation_point_size, E_GL_OES_tessellation_point_size }; +const int Num_AEP_tessellation_point_size = sizeof(AEP_tessellation_point_size)/sizeof(AEP_tessellation_point_size[0]); + +const char* const AEP_texture_buffer[] = { E_GL_EXT_texture_buffer, E_GL_OES_texture_buffer }; +const int Num_AEP_texture_buffer = sizeof(AEP_texture_buffer)/sizeof(AEP_texture_buffer[0]); + +const char* const AEP_texture_cube_map_array[] = { E_GL_EXT_texture_cube_map_array, E_GL_OES_texture_cube_map_array }; +const int Num_AEP_texture_cube_map_array = sizeof(AEP_texture_cube_map_array)/sizeof(AEP_texture_cube_map_array[0]); + +const char* const AEP_mesh_shader[] = { E_GL_NV_mesh_shader, E_GL_EXT_mesh_shader }; +const int Num_AEP_mesh_shader = sizeof(AEP_mesh_shader)/sizeof(AEP_mesh_shader[0]); + +} // end namespace glslang + +#endif // _VERSIONS_INCLUDED_ diff --git a/thirdparty/headers/glslang/include/glslang/Public/ResourceLimits.h b/thirdparty/headers/glslang/include/glslang/Public/ResourceLimits.h new file mode 100644 index 000000000..8245e12d7 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/Public/ResourceLimits.h @@ -0,0 +1,58 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ +#define _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ + +#include + +#include "../Include/ResourceLimits.h" +#include "../Include/visibility.h" + +// Return pointer to user-writable Resource to pass through API in +// future-proof way. +GLSLANG_EXPORT extern TBuiltInResource* GetResources(); + +// These are the default resources for TBuiltInResources, used for both +// - parsing this string for the case where the user didn't supply one, +// - dumping out a template for user construction of a config file. +GLSLANG_EXPORT extern const TBuiltInResource* GetDefaultResources(); + +// Returns the DefaultTBuiltInResource as a human-readable string. +GLSLANG_EXPORT std::string GetDefaultTBuiltInResourceString(); + +// Decodes the resource limits from |config| to |resources|. +GLSLANG_EXPORT void DecodeResourceLimits(TBuiltInResource* resources, char* config); + +#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ diff --git a/thirdparty/headers/glslang/include/glslang/Public/ShaderLang.h b/thirdparty/headers/glslang/include/glslang/Public/ShaderLang.h new file mode 100644 index 000000000..8ca4ed9ce --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/Public/ShaderLang.h @@ -0,0 +1,1012 @@ +// +// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013-2016 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +#ifndef _COMPILER_INTERFACE_INCLUDED_ +#define _COMPILER_INTERFACE_INCLUDED_ + +#include "../Include/ResourceLimits.h" +#include "../Include/visibility.h" +#include "../MachineIndependent/Versions.h" + +#include +#include + +#ifdef _WIN32 + #define C_DECL __cdecl +#else + #define C_DECL +#endif + +// +// This is the platform independent interface between an OGL driver +// and the shading language compiler/linker. +// + +#ifdef __cplusplus + extern "C" { +#endif + +// +// Call before doing any other compiler/linker operations. +// +// (Call once per process, not once per thread.) +// +GLSLANG_EXPORT int ShInitialize(); + +// +// Call this at process shutdown to clean up memory. +// +GLSLANG_EXPORT int ShFinalize(); + +// +// Types of languages the compiler can consume. +// +typedef enum { + EShLangVertex, + EShLangTessControl, + EShLangTessEvaluation, + EShLangGeometry, + EShLangFragment, + EShLangCompute, + EShLangRayGen, + EShLangRayGenNV = EShLangRayGen, + EShLangIntersect, + EShLangIntersectNV = EShLangIntersect, + EShLangAnyHit, + EShLangAnyHitNV = EShLangAnyHit, + EShLangClosestHit, + EShLangClosestHitNV = EShLangClosestHit, + EShLangMiss, + EShLangMissNV = EShLangMiss, + EShLangCallable, + EShLangCallableNV = EShLangCallable, + EShLangTask, + EShLangTaskNV = EShLangTask, + EShLangMesh, + EShLangMeshNV = EShLangMesh, + LAST_ELEMENT_MARKER(EShLangCount), +} EShLanguage; // would be better as stage, but this is ancient now + +typedef enum : unsigned { + EShLangVertexMask = (1 << EShLangVertex), + EShLangTessControlMask = (1 << EShLangTessControl), + EShLangTessEvaluationMask = (1 << EShLangTessEvaluation), + EShLangGeometryMask = (1 << EShLangGeometry), + EShLangFragmentMask = (1 << EShLangFragment), + EShLangComputeMask = (1 << EShLangCompute), + EShLangRayGenMask = (1 << EShLangRayGen), + EShLangRayGenNVMask = EShLangRayGenMask, + EShLangIntersectMask = (1 << EShLangIntersect), + EShLangIntersectNVMask = EShLangIntersectMask, + EShLangAnyHitMask = (1 << EShLangAnyHit), + EShLangAnyHitNVMask = EShLangAnyHitMask, + EShLangClosestHitMask = (1 << EShLangClosestHit), + EShLangClosestHitNVMask = EShLangClosestHitMask, + EShLangMissMask = (1 << EShLangMiss), + EShLangMissNVMask = EShLangMissMask, + EShLangCallableMask = (1 << EShLangCallable), + EShLangCallableNVMask = EShLangCallableMask, + EShLangTaskMask = (1 << EShLangTask), + EShLangTaskNVMask = EShLangTaskMask, + EShLangMeshMask = (1 << EShLangMesh), + EShLangMeshNVMask = EShLangMeshMask, + LAST_ELEMENT_MARKER(EShLanguageMaskCount), +} EShLanguageMask; + +namespace glslang { + +class TType; + +typedef enum { + EShSourceNone, + EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL) + EShSourceHlsl, // HLSL + LAST_ELEMENT_MARKER(EShSourceCount), +} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead + +typedef enum { + EShClientNone, // use when there is no client, e.g. for validation + EShClientVulkan, // as GLSL dialect, specifies KHR_vulkan_glsl extension + EShClientOpenGL, // as GLSL dialect, specifies ARB_gl_spirv extension + LAST_ELEMENT_MARKER(EShClientCount), +} EShClient; + +typedef enum { + EShTargetNone, + EShTargetSpv, // SPIR-V (preferred spelling) + EshTargetSpv = EShTargetSpv, // legacy spelling + LAST_ELEMENT_MARKER(EShTargetCount), +} EShTargetLanguage; + +typedef enum { + EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0 + EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1 + EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2 + EShTargetVulkan_1_3 = (1 << 22) | (3 << 12), // Vulkan 1.3 + EShTargetVulkan_1_4 = (1 << 22) | (4 << 12), // Vulkan 1.4 + EShTargetOpenGL_450 = 450, // OpenGL + LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 6), +} EShTargetClientVersion; + +typedef EShTargetClientVersion EshTargetClientVersion; + +typedef enum { + EShTargetSpv_1_0 = (1 << 16), // SPIR-V 1.0 + EShTargetSpv_1_1 = (1 << 16) | (1 << 8), // SPIR-V 1.1 + EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2 + EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3 + EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4 + EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5 + EShTargetSpv_1_6 = (1 << 16) | (6 << 8), // SPIR-V 1.6 + LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 7), +} EShTargetLanguageVersion; + +// +// Following are a series of helper enums for managing layouts and qualifiers, +// used for TPublicType, TType, others. +// + +enum TLayoutPacking { + ElpNone, + ElpShared, // default, but different than saying nothing + ElpStd140, + ElpStd430, + ElpPacked, + ElpScalar, + ElpCount // If expanding, see bitfield width below +}; + +struct TInputLanguage { + EShSource languageFamily; // redundant information with other input, this one overrides when not EShSourceNone + EShLanguage stage; // redundant information with other input, this one overrides when not EShSourceNone + EShClient dialect; + int dialectVersion; // version of client's language definition, not the client (when not EShClientNone) + bool vulkanRulesRelaxed; +}; + +struct TClient { + EShClient client; + EShTargetClientVersion version; // version of client itself (not the client's input dialect) +}; + +struct TTarget { + EShTargetLanguage language; + EShTargetLanguageVersion version; // version to target, if SPIR-V, defined by "word 1" of the SPIR-V header + bool hlslFunctionality1; // can target hlsl_functionality1 extension(s) +}; + +// All source/client/target versions and settings. +// Can override previous methods of setting, when items are set here. +// Expected to grow, as more are added, rather than growing parameter lists. +struct TEnvironment { + TInputLanguage input; // definition of the input language + TClient client; // what client is the overall compilation being done for? + TTarget target; // what to generate +}; + +GLSLANG_EXPORT const char* StageName(EShLanguage); + +} // end namespace glslang + +// +// Types of output the linker will create. +// +typedef enum { + EShExVertexFragment, + EShExFragment +} EShExecutable; + +// +// Optimization level for the compiler. +// +typedef enum { + EShOptNoGeneration, + EShOptNone, + EShOptSimple, // Optimizations that can be done quickly + EShOptFull, // Optimizations that will take more time + LAST_ELEMENT_MARKER(EshOptLevelCount), +} EShOptimizationLevel; + +// +// Texture and Sampler transformation mode. +// +typedef enum { + EShTexSampTransKeep, // keep textures and samplers as is (default) + EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers + LAST_ELEMENT_MARKER(EShTexSampTransCount), +} EShTextureSamplerTransformMode; + +// +// Message choices for what errors and warnings are given. +// +enum EShMessages : unsigned { + EShMsgDefault = 0, // default is to give all required errors and extra warnings + EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input + EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification + EShMsgAST = (1 << 2), // print the AST intermediate representation + EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation + EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V + EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor + EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics + EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit + EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions + EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules + EShMsgDebugInfo = (1 << 10), // save debug information + EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL + EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages + EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics) + EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table + EShMsgEnhanced = (1 << 15), // enhanced message readability + EShMsgAbsolutePath = (1 << 16), // Output Absolute path for messages + EShMsgDisplayErrorColumn = (1 << 17), // Display error message column aswell as line + EShMsgLinkTimeOptimization = (1 << 18), // perform cross-stage optimizations during linking + EShMsgValidateCrossStageIO = (1 << 19), // validate shader inputs have matching outputs in previous stage + LAST_ELEMENT_MARKER(EShMsgCount), +}; + +// +// Options for building reflection +// +typedef enum { + EShReflectionDefault = 0, // default is original behaviour before options were added + EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes + EShReflectionBasicArraySuffix = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection + EShReflectionIntermediateIO = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader + EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately + EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive + EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks + EShReflectionAllIOVariables = (1 << 6), // reflect all input/output variables, even if they are inactive + EShReflectionSharedStd140SSBO = (1 << 7), // Apply std140/shared rules for ubo to ssbo + EShReflectionSharedStd140UBO = (1 << 8), // Apply std140/shared rules for ubo to ssbo + LAST_ELEMENT_MARKER(EShReflectionCount), +} EShReflectionOptions; + +// +// Build a table for bindings. This can be used for locating +// attributes, uniforms, globals, etc., as needed. +// +typedef struct { + const char* name; + int binding; +} ShBinding; + +typedef struct { + int numBindings; + ShBinding* bindings; // array of bindings +} ShBindingTable; + +// +// ShHandle held by but opaque to the driver. It is allocated, +// managed, and de-allocated by the compiler/linker. Its contents +// are defined by and used by the compiler and linker. For example, +// symbol table information and object code passed from the compiler +// to the linker can be stored where ShHandle points. +// +// If handle creation fails, 0 will be returned. +// +typedef void* ShHandle; + +// +// Driver calls these to create and destroy compiler/linker +// objects. +// +GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int /*debugOptions unused*/); // one per shader +GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int /*debugOptions unused*/); // one per shader pair +GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) +GLSLANG_EXPORT void ShDestruct(ShHandle); + +// +// The return value of ShCompile is boolean, non-zero indicating +// success. +// +// The info-log should be written by ShCompile into +// ShHandle, so it can answer future queries. +// +GLSLANG_EXPORT int ShCompile(const ShHandle, const char* const shaderStrings[], const int numStrings, + const int* lengths, const EShOptimizationLevel, const TBuiltInResource* resources, + int, // debugOptions unused + int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader + bool forwardCompatible = false, // give errors for use of deprecated features + EShMessages messages = EShMsgDefault, // warnings and errors + const char* fileName = nullptr +); + +GLSLANG_EXPORT int ShLinkExt( + const ShHandle, // linker object + const ShHandle h[], // compiler objects to link together + const int numHandles); + +// +// ShSetEncrpytionMethod is a place-holder for specifying +// how source code is encrypted. +// +GLSLANG_EXPORT void ShSetEncryptionMethod(ShHandle); + +// +// All the following return 0 if the information is not +// available in the object passed down, or the object is bad. +// +GLSLANG_EXPORT const char* ShGetInfoLog(const ShHandle); +GLSLANG_EXPORT const void* ShGetExecutable(const ShHandle); +GLSLANG_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); // to detect user aliasing +GLSLANG_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); // to force any physical mappings +// +// Tell the linker to never assign a vertex attribute to this list of physical attributes +// +GLSLANG_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count); + +// +// Returns the location ID of the named uniform. +// Returns -1 if error. +// +GLSLANG_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name); + +#ifdef __cplusplus + } // end extern "C" +#endif + +//////////////////////////////////////////////////////////////////////////////////////////// +// +// Deferred-Lowering C++ Interface +// ----------------------------------- +// +// Below is a new alternate C++ interface, which deprecates the above +// opaque handle-based interface. +// +// The below is further designed to handle multiple compilation units per stage, where +// the intermediate results, including the parse tree, are preserved until link time, +// rather than the above interface which is designed to have each compilation unit +// lowered at compile time. In the above model, linking occurs on the lowered results, +// whereas in this model intra-stage linking can occur at the parse tree +// (treeRoot in TIntermediate) level, and then a full stage can be lowered. +// + +#include +#include +#include + +class TCompiler; +class TInfoSink; + +namespace glslang { + +struct Version { + int major; + int minor; + int patch; + const char* flavor; +}; + +GLSLANG_EXPORT Version GetVersion(); +GLSLANG_EXPORT const char* GetEsslVersionString(); +GLSLANG_EXPORT const char* GetGlslVersionString(); +GLSLANG_EXPORT int GetKhronosToolId(); + +class TIntermediate; +class TProgram; +class TPoolAllocator; +class TIoMapResolver; + +// Call this exactly once per process before using anything else +GLSLANG_EXPORT bool InitializeProcess(); + +// Call once per process to tear down everything +GLSLANG_EXPORT void FinalizeProcess(); + +// Resource type for IO resolver +enum TResourceType { + EResSampler, + EResTexture, + EResImage, + EResUbo, + EResSsbo, + EResUav, + EResCombinedSampler, + EResAs, + EResTensor, + EResCount +}; + +enum TBlockStorageClass +{ + EbsUniform = 0, + EbsStorageBuffer, + EbsPushConstant, + EbsNone, // not a uniform or buffer variable + EbsCount, +}; + +// Make one TShader per shader that you will link into a program. Then +// - provide the shader through setStrings() or setStringsWithLengths() +// - optionally call setEnv*(), see below for more detail +// - optionally use setPreamble() to set a special shader string that will be +// processed before all others but won't affect the validity of #version +// - optionally call addProcesses() for each setting/transform, +// see comment for class TProcesses +// - call parse(): source language and target environment must be selected +// either by correct setting of EShMessages sent to parse(), or by +// explicitly calling setEnv*() +// - query the info logs +// +// N.B.: Does not yet support having the same TShader instance being linked into +// multiple programs. +// +// N.B.: Destruct a linked program *before* destructing the shaders linked into it. +// +class GLSLANG_EXPORT TShader { +public: + explicit TShader(EShLanguage); + virtual ~TShader(); + void setStrings(const char* const* s, int n); + void setStringsWithLengths( + const char* const* s, const int* l, int n); + void setStringsWithLengthsAndNames( + const char* const* s, const int* l, const char* const* names, int n); + void setPreamble(const char* s) { preamble = s; } + void setEntryPoint(const char* entryPoint); + void setSourceEntryPoint(const char* sourceEntryPointName); + void addProcesses(const std::vector&); + void setUniqueId(unsigned long long id); + void setOverrideVersion(int version); + void setDebugInfo(bool debugInfo); + + // IO resolver binding data: see comments in ShaderLang.cpp + void setShiftBinding(TResourceType res, unsigned int base); + void setShiftSamplerBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftTextureBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftImageBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftUboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftUavBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding + void setShiftSsboBinding(unsigned int base); // DEPRECATED: use setShiftBinding + void setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set); + void setResourceSetBinding(const std::vector& base); + void setAutoMapBindings(bool map); + void setAutoMapLocations(bool map); + void addUniformLocationOverride(const char* name, int loc); + void setUniformLocationBase(int base); + void setInvertY(bool invert); + void setDxPositionW(bool dxPosW); + void setEnhancedMsgs(); +#ifdef ENABLE_HLSL + void setHlslIoMapping(bool hlslIoMap); + void setFlattenUniformArrays(bool flatten); +#endif + void setNoStorageFormat(bool useUnknownFormat); + void setNanMinMaxClamp(bool nanMinMaxClamp); + void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); + void addBlockStorageOverride(const char* nameStr, glslang::TBlockStorageClass backing); + + void setGlobalUniformBlockName(const char* name); + void setAtomicCounterBlockName(const char* name); + void setGlobalUniformSet(unsigned int set); + void setGlobalUniformBinding(unsigned int binding); + void setAtomicCounterBlockSet(unsigned int set); + void setAtomicCounterBlockBinding(unsigned int binding); + + void addSourceText(const char* text, size_t len); + void setSourceFile(const char* file); + + // For setting up the environment (cleared to nothingness in the constructor). + // These must be called so that parsing is done for the right source language and + // target environment, either indirectly through TranslateEnvironment() based on + // EShMessages et. al., or directly by the user. + // + // setEnvInput: The input source language and stage. If generating code for a + // specific client, the input client semantics to use and the + // version of that client's input semantics to use, otherwise + // use EShClientNone and version of 0, e.g. for validation mode. + // Note 'version' does not describe the target environment, + // just the version of the source dialect to compile under. + // For example, to choose the Vulkan dialect of GLSL defined by + // version 100 of the KHR_vulkan_glsl extension: lang = EShSourceGlsl, + // dialect = EShClientVulkan, and version = 100. + // + // See the definitions of TEnvironment, EShSource, EShLanguage, + // and EShClient for choices and more detail. + // + // setEnvClient: The client that will be hosting the execution, and its version. + // Note 'version' is not the version of the languages involved, but + // the version of the client environment. + // Use EShClientNone and version of 0 if there is no client, e.g. + // for validation mode. + // + // See EShTargetClientVersion for choices. + // + // setEnvTarget: The language to translate to when generating code, and that + // language's version. + // Use EShTargetNone and version of 0 if there is no client, e.g. + // for validation mode. + // + void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version) + { + environment.input.languageFamily = lang; + environment.input.stage = envStage; + environment.input.dialect = client; + environment.input.dialectVersion = version; + } + void setEnvClient(EShClient client, EShTargetClientVersion version) + { + environment.client.client = client; + environment.client.version = version; + } + void setEnvTarget(EShTargetLanguage lang, EShTargetLanguageVersion version) + { + environment.target.language = lang; + environment.target.version = version; + } + + void getStrings(const char* const* &s, int& n) { s = strings; n = numStrings; } + +#ifdef ENABLE_HLSL + void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; } + bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; } +#else + bool getEnvTargetHlslFunctionality1() const { return false; } +#endif + + void setEnvInputVulkanRulesRelaxed() { environment.input.vulkanRulesRelaxed = true; } + bool getEnvInputVulkanRulesRelaxed() const { return environment.input.vulkanRulesRelaxed; } + + void setCompileOnly() { compileOnly = true; } + bool getCompileOnly() const { return compileOnly; } + + // Interface to #include handlers. + // + // To support #include, a client of Glslang does the following: + // 1. Call setStringsWithNames to set the source strings and associated + // names. For example, the names could be the names of the files + // containing the shader sources. + // 2. Call parse with an Includer. + // + // When the Glslang parser encounters an #include directive, it calls + // the Includer's include method with the requested include name + // together with the current string name. The returned IncludeResult + // contains the fully resolved name of the included source, together + // with the source text that should replace the #include directive + // in the source stream. After parsing that source, Glslang will + // release the IncludeResult object. + class Includer { + public: + // An IncludeResult contains the resolved name and content of a source + // inclusion. + struct IncludeResult { + IncludeResult(const std::string& headerName, const char* const headerData, const size_t headerLength, void* userData) : + headerName(headerName), headerData(headerData), headerLength(headerLength), userData(userData) { } + // For a successful inclusion, the fully resolved name of the requested + // include. For example, in a file system-based includer, full resolution + // should convert a relative path name into an absolute path name. + // For a failed inclusion, this is an empty string. + const std::string headerName; + // The content and byte length of the requested inclusion. The + // Includer producing this IncludeResult retains ownership of the + // storage. + // For a failed inclusion, the header + // field points to a string containing error details. + const char* const headerData; + const size_t headerLength; + // Include resolver's context. + void* userData; + protected: + IncludeResult& operator=(const IncludeResult&); + IncludeResult(); + }; + + // For both include methods below: + // + // Resolves an inclusion request by name, current source name, + // and include depth. + // On success, returns an IncludeResult containing the resolved name + // and content of the include. + // On failure, returns a nullptr, or an IncludeResult + // with an empty string for the headerName and error details in the + // header field. + // The Includer retains ownership of the contents + // of the returned IncludeResult value, and those contents must + // remain valid until the releaseInclude method is called on that + // IncludeResult object. + // + // Note "local" vs. "system" is not an "either/or": "local" is an + // extra thing to do over "system". Both might get called, as per + // the C++ specification. + + // For the "system" or <>-style includes; search the "system" paths. + virtual IncludeResult* includeSystem(const char* /*headerName*/, + const char* /*includerName*/, + size_t /*inclusionDepth*/) { return nullptr; } + + // For the "local"-only aspect of a "" include. Should not search in the + // "system" paths, because on returning a failure, the parser will + // call includeSystem() to look in the "system" locations. + virtual IncludeResult* includeLocal(const char* /*headerName*/, + const char* /*includerName*/, + size_t /*inclusionDepth*/) { return nullptr; } + + // Signals that the parser will no longer use the contents of the + // specified IncludeResult. + virtual void releaseInclude(IncludeResult*) = 0; + virtual ~Includer() {} + }; + + // Fail all Includer searches + class ForbidIncluder : public Includer { + public: + virtual void releaseInclude(IncludeResult*) override { } + }; + + bool parse( + const TBuiltInResource*, int defaultVersion, EProfile defaultProfile, + bool forceDefaultVersionAndProfile, bool forwardCompatible, + EShMessages, Includer&); + + bool parse(const TBuiltInResource* res, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages messages) + { + TShader::ForbidIncluder includer; + return parse(res, defaultVersion, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, messages, includer); + } + + // Equivalent to parse() without a default profile and without forcing defaults. + bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages) + { + return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages); + } + + bool parse(const TBuiltInResource* builtInResources, int defaultVersion, bool forwardCompatible, EShMessages messages, + Includer& includer) + { + return parse(builtInResources, defaultVersion, ENoProfile, false, forwardCompatible, messages, includer); + } + + // NOTE: Doing just preprocessing to obtain a correct preprocessed shader string + // is not an officially supported or fully working path. + bool preprocess( + const TBuiltInResource* builtInResources, int defaultVersion, + EProfile defaultProfile, bool forceDefaultVersionAndProfile, + bool forwardCompatible, EShMessages message, std::string* outputString, + Includer& includer); + + const char* getInfoLog(); + const char* getInfoDebugLog(); + EShLanguage getStage() const { return stage; } + TIntermediate* getIntermediate() const { return intermediate; } + +protected: + TPoolAllocator* pool; + EShLanguage stage; + TCompiler* compiler; + TIntermediate* intermediate; + TInfoSink* infoSink; + // strings and lengths follow the standard for glShaderSource: + // strings is an array of numStrings pointers to string data. + // lengths can be null, but if not it is an array of numStrings + // integers containing the length of the associated strings. + // if lengths is null or lengths[n] < 0 the associated strings[n] is + // assumed to be null-terminated. + // stringNames is the optional names for all the strings. If stringNames + // is null, then none of the strings has name. If a certain element in + // stringNames is null, then the corresponding string does not have name. + const char* const* strings; // explicit code to compile, see previous comment + const int* lengths; + const char* const* stringNames; + int numStrings; // size of the above arrays + const char* preamble; // string of implicit code to compile before the explicitly provided code + + // a function in the source string can be renamed FROM this TO the name given in setEntryPoint. + std::string sourceEntryPointName; + + // overrides #version in shader source or default version if #version isn't present + int overrideVersion; + + TEnvironment environment; + + // Indicates this shader is meant to be used without linking + bool compileOnly = false; + + friend class TProgram; + +private: + TShader& operator=(TShader&); +}; + +// +// A reflection database and its interface, consistent with the OpenGL API reflection queries. +// + +// Data needed for just a single object at the granularity exchanged by the reflection API +class GLSLANG_EXPORT TObjectReflection { +public: + TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex); + + const TType* getType() const { return type; } + int getBinding() const; + void dump() const; + static TObjectReflection badReflection() { return TObjectReflection(); } + + unsigned int layoutLocation() const; + + std::string name; + int offset; + int glDefineType; + int size; // data size in bytes for a block, array size for a (non-block) object that's an array + int index; + int counterIndex; + int numMembers; + int arrayStride; // stride of an array variable + int topLevelArraySize; // size of the top-level variable in a storage buffer member + int topLevelArrayStride; // stride of the top-level variable in a storage buffer member + EShLanguageMask stages; + +protected: + TObjectReflection() + : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0), + topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr) + { + } + + const TType* type; +}; + +class TReflection; +class TIoMapper; +struct TVarEntryInfo; + +// Allows to customize the binding layout after linking. +// All used uniform variables will invoke at least validateBinding. +// If validateBinding returned true then the other resolveBinding, +// resolveSet, and resolveLocation are invoked to resolve the binding +// and descriptor set index respectively. +// +// Invocations happen in a particular order: +// 1) all shader inputs +// 2) all shader outputs +// 3) all uniforms with binding and set already defined +// 4) all uniforms with binding but no set defined +// 5) all uniforms with set but no binding defined +// 6) all uniforms with no binding and no set defined +// +// mapIO will use this resolver in two phases. The first +// phase is a notification phase, calling the corresponging +// notifiy callbacks, this phase ends with a call to endNotifications. +// Phase two starts directly after the call to endNotifications +// and calls all other callbacks to validate and to get the +// bindings, sets, locations, component and color indices. +// +// NOTE: that still limit checks are applied to bindings and sets +// and may result in an error. +class GLSLANG_EXPORT TIoMapResolver { +public: + virtual ~TIoMapResolver() {} + + // Should return true if the resulting/current binding would be okay. + // Basic idea is to do aliasing binding checks with this. + virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current binding should be overridden. + // Return -1 if the current binding (including no binding) should be kept. + virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current set should be overridden. + // Return -1 if the current set (including no set) should be kept. + virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return true if the resulting/current setup would be okay. + // Basic idea is to do aliasing checks and reject invalid semantic names. + virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current location should be overridden. + // Return -1 if the current location (including no location) should be kept. + virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current component index should be overridden. + // Return -1 if the current component index (including no index) should be kept. + virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Should return a value >= 0 if the current color index should be overridden. + // Return -1 if the current color index (including no index) should be kept. + virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Notification of a uniform variable + virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Notification of a in or out variable + virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; + // Called by mapIO when it starts its notify pass for the given stage + virtual void beginNotifications(EShLanguage stage) = 0; + // Called by mapIO when it has finished the notify pass + virtual void endNotifications(EShLanguage stage) = 0; + // Called by mipIO when it starts its resolve pass for the given stage + virtual void beginResolve(EShLanguage stage) = 0; + // Called by mapIO when it has finished the resolve pass + virtual void endResolve(EShLanguage stage) = 0; + // Called by mapIO when it starts its symbol collect for teh given stage + virtual void beginCollect(EShLanguage stage) = 0; + // Called by mapIO when it has finished the symbol collect + virtual void endCollect(EShLanguage stage) = 0; + // Called by TSlotCollector to resolve storage locations or bindings + virtual void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; + // Called by TSlotCollector to resolve resource locations or bindings + virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; + // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline + virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0; +}; + +// I/O mapper +class TIoMapper { +public: + TIoMapper() {} + virtual ~TIoMapper() {} + // grow the reflection stage by stage + bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); + bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; } + bool virtual setAutoPushConstantBlock(const char*, unsigned int, TLayoutPacking) { return false; } +}; + +// Get the default GLSL IO mapper +GLSLANG_EXPORT TIoMapper* GetGlslIoMapper(); + +// Make one TProgram per set of shaders that will get linked together. Add all +// the shaders that are to be linked together. After calling shader.parse() +// for all shaders, call link(). +// +// N.B.: Destruct a linked program *before* destructing the shaders linked into it. +// +class GLSLANG_EXPORT TProgram { +public: + TProgram(); + virtual ~TProgram(); + void addShader(TShader* shader) { stages[shader->stage].push_back(shader); } + std::list& getShaders(EShLanguage stage) { return stages[stage]; } + // Link Validation interface + bool link(EShMessages); + const char* getInfoLog(); + const char* getInfoDebugLog(); + + TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } + + // Reflection Interface + + // call first, to do liveness analysis, index mapping, etc.; returns false on failure + bool buildReflection(int opts = EShReflectionDefault); + unsigned getLocalSize(int dim) const; // return dim'th local size + unsigned getTileShadingRateQCOM(int dim) const; // return dim'th tile shading rate QCOM + int getReflectionIndex(const char *name) const; + int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const; + int getNumUniformVariables() const; + const TObjectReflection& getUniform(int index) const; + int getNumUniformBlocks() const; + const TObjectReflection& getUniformBlock(int index) const; + int getNumPipeInputs() const; + const TObjectReflection& getPipeInput(int index) const; + int getNumPipeOutputs() const; + const TObjectReflection& getPipeOutput(int index) const; + int getNumBufferVariables() const; + const TObjectReflection& getBufferVariable(int index) const; + int getNumBufferBlocks() const; + const TObjectReflection& getBufferBlock(int index) const; + int getNumAtomicCounters() const; + const TObjectReflection& getAtomicCounter(int index) const; + + // Legacy Reflection Interface - expressed in terms of above interface + + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) + int getNumLiveUniformVariables() const { return getNumUniformVariables(); } + + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) + int getNumLiveUniformBlocks() const { return getNumUniformBlocks(); } + + // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + int getNumLiveAttributes() const { return getNumPipeInputs(); } + + // can be used for glGetUniformIndices() + int getUniformIndex(const char *name) const { return getReflectionIndex(name); } + + int getPipeIOIndex(const char *name, const bool inOrOut) const + { return getReflectionPipeIOIndex(name, inOrOut); } + + // can be used for "name" part of glGetActiveUniform() + const char *getUniformName(int index) const { return getUniform(index).name.c_str(); } + + // returns the binding number + int getUniformBinding(int index) const { return getUniform(index).getBinding(); } + + // returns Shaders Stages where a Uniform is present + EShLanguageMask getUniformStages(int index) const { return getUniform(index).stages; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) + int getUniformBlockIndex(int index) const { return getUniform(index).index; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) + int getUniformType(int index) const { return getUniform(index).glDefineType; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) + int getUniformBufferOffset(int index) const { return getUniform(index).offset; } + + // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) + int getUniformArraySize(int index) const { return getUniform(index).size; } + + // returns a TType* + const TType *getUniformTType(int index) const { return getUniform(index).getType(); } + + // can be used for glGetActiveUniformBlockName() + const char *getUniformBlockName(int index) const { return getUniformBlock(index).name.c_str(); } + + // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) + int getUniformBlockSize(int index) const { return getUniformBlock(index).size; } + + // returns the block binding number + int getUniformBlockBinding(int index) const { return getUniformBlock(index).getBinding(); } + + // returns block index of associated counter. + int getUniformBlockCounterIndex(int index) const { return getUniformBlock(index).counterIndex; } + + // returns a TType* + const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); } + + // can be used for glGetActiveAttrib() + const char *getAttributeName(int index) const { return getPipeInput(index).name.c_str(); } + + // can be used for glGetActiveAttrib() + int getAttributeType(int index) const { return getPipeInput(index).glDefineType; } + + // returns a TType* + const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); } + + void dumpReflection(); + + // Get the IO resolver to use for mapIO + TIoMapResolver* getGlslIoResolver(EShLanguage stage); + + // I/O mapping: apply base offsets and map live unbound variables + // If resolver is not provided it uses the previous approach + // and respects auto assignment and offsets. + bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr); + +protected: + bool linkStage(EShLanguage, EShMessages); + bool crossStageCheck(EShMessages); + + TPoolAllocator* pool; + std::list stages[EShLangCount]; + TIntermediate* intermediate[EShLangCount]; + bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage + TInfoSink* infoSink; + TReflection* reflection; + bool linked; + +private: + TProgram(TProgram&); + TProgram& operator=(TProgram&); +}; + +} // end namespace glslang + +#endif // _COMPILER_INTERFACE_INCLUDED_ diff --git a/thirdparty/headers/glslang/include/glslang/Public/resource_limits_c.h b/thirdparty/headers/glslang/include/glslang/Public/resource_limits_c.h new file mode 100644 index 000000000..4ad052b0b --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/Public/resource_limits_c.h @@ -0,0 +1,58 @@ +/** +BSD 2-Clause License + +Copyright (c) 2020, Travis Fort +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**/ + +#ifndef _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_ +#define _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_ + +#include "../Include/glslang_c_interface.h" +#include "../Include/visibility.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns a struct that can be use to create custom resource values. +GLSLANG_EXPORT glslang_resource_t* glslang_resource(void); + +// These are the default resources for TBuiltInResources, used for both +// - parsing this string for the case where the user didn't supply one, +// - dumping out a template for user construction of a config file. +GLSLANG_EXPORT const glslang_resource_t* glslang_default_resource(void); + +// Returns the DefaultTBuiltInResource as a human-readable string. +// NOTE: User is responsible for freeing this string. +GLSLANG_EXPORT const char* glslang_default_resource_string(void); + +// Decodes the resource limits from |config| to |resources|. +GLSLANG_EXPORT void glslang_decode_resource_limits(glslang_resource_t* resources, char* config); + +#ifdef __cplusplus +} +#endif + +#endif // _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_ diff --git a/thirdparty/headers/glslang/include/glslang/SPIRV/GlslangToSpv.h b/thirdparty/headers/glslang/include/glslang/SPIRV/GlslangToSpv.h new file mode 100644 index 000000000..9fb4f3fff --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/SPIRV/GlslangToSpv.h @@ -0,0 +1,69 @@ +// +// Copyright (C) 2014 LunarG, Inc. +// Copyright (C) 2015-2018 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include + +#include "Logger.h" +#include "glslang/Include/visibility.h" + +namespace glslang { +class TIntermediate; + +struct SpvOptions { + bool generateDebugInfo {false}; + bool stripDebugInfo {false}; + bool disableOptimizer {true}; + bool optimizeSize {false}; + bool disassemble {false}; + bool validate {false}; + bool emitNonSemanticShaderDebugInfo {false}; + bool emitNonSemanticShaderDebugSource{ false }; + bool compileOnly{false}; + bool optimizerAllowExpandedIDBound{false}; +}; + +GLSLANG_EXPORT void GetSpirvVersion(std::string&); +GLSLANG_EXPORT int GetSpirvGeneratorVersion(); +GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, + SpvOptions* options = nullptr); +GLSLANG_EXPORT void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger* logger, SpvOptions* options = nullptr); +GLSLANG_EXPORT bool OutputSpvBin(const std::vector& spirv, const char* baseName); +GLSLANG_EXPORT bool OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName); + +} diff --git a/thirdparty/headers/glslang/include/glslang/SPIRV/Logger.h b/thirdparty/headers/glslang/include/glslang/SPIRV/Logger.h new file mode 100644 index 000000000..c64a3b8a3 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/SPIRV/Logger.h @@ -0,0 +1,75 @@ +// +// Copyright (C) 2016 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef GLSLANG_SPIRV_LOGGER_H +#define GLSLANG_SPIRV_LOGGER_H + +#include +#include +#include "glslang/Include/visibility.h" + +namespace spv { + +// A class for holding all SPIR-V build status messages, including +// missing/TBD functionalities, warnings, and errors. +class GLSLANG_EXPORT SpvBuildLogger { +public: + SpvBuildLogger() {} + + // Registers a TBD functionality. + void tbdFunctionality(const std::string& f); + // Registers a missing functionality. + void missingFunctionality(const std::string& f); + + // Logs a warning. + void warning(const std::string& w) { warnings.push_back(w); } + // Logs an error. + void error(const std::string& e) { errors.push_back(e); } + + // Returns all messages accumulated in the order of: + // TBD functionalities, missing functionalities, warnings, errors. + std::string getAllMessages() const; + +private: + SpvBuildLogger(const SpvBuildLogger&); + + std::vector tbdFeatures; + std::vector missingFeatures; + std::vector warnings; + std::vector errors; +}; + +} // end spv namespace + +#endif // GLSLANG_SPIRV_LOGGER_H diff --git a/thirdparty/headers/glslang/include/glslang/SPIRV/SpvTools.h b/thirdparty/headers/glslang/include/glslang/SPIRV/SpvTools.h new file mode 100644 index 000000000..455857235 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/SPIRV/SpvTools.h @@ -0,0 +1,109 @@ +// +// Copyright (C) 2014-2016 LunarG, Inc. +// Copyright (C) 2018 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// +// Call into SPIRV-Tools to disassemble, validate, and optimize. +// + +#pragma once +#ifndef GLSLANG_SPV_TOOLS_H +#define GLSLANG_SPV_TOOLS_H + +#if ENABLE_OPT +#include +#include +#include +#include "spirv-tools/libspirv.h" +#endif + +#include "glslang/MachineIndependent/Versions.h" +#include "glslang/Include/visibility.h" +#include "GlslangToSpv.h" +#include "Logger.h" + +namespace glslang { + +#if ENABLE_OPT + +class TIntermediate; + +// Translate glslang's view of target versioning to what SPIRV-Tools uses. +GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger); +GLSLANG_EXPORT spv_target_env MapToSpirvToolsEnv(const glslang::TIntermediate& intermediate, spv::SpvBuildLogger* logger); + +// Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment. +GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); + +// Use the SPIRV-Tools disassembler to print SPIR-V with a provided SPIR-V environment. +GLSLANG_EXPORT void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv, + spv_target_env requested_context); + +// Apply the SPIRV-Tools validator to generated SPIR-V. +GLSLANG_EXPORT void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*, bool prelegalization); + +// Apply the SPIRV-Tools optimizer to generated SPIR-V. HLSL SPIR-V is legalized in the process. +GLSLANG_EXPORT void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector& spirv, + spv::SpvBuildLogger*, const SpvOptions*); + +// Apply the SPIRV-Tools EliminateDeadInputComponents pass to generated SPIR-V. Put result in |spirv|. +GLSLANG_EXPORT void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector& spirv, + spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools AnalyzeDeadOutputStores pass to generated SPIR-V. Put result in |live_locs|. +// Return true if the result is valid. +GLSLANG_EXPORT bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, + spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools EliminateDeadOutputStores and AggressiveDeadCodeElimination passes to generated SPIR-V using +// |live_locs|. Put result in |spirv|. +GLSLANG_EXPORT void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, + spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by +// SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if +// optimization is disabled. +GLSLANG_EXPORT void SpirvToolsStripDebugInfo(const glslang::TIntermediate& intermediate, + std::vector& spirv, spv::SpvBuildLogger*); + +#endif + +} // end namespace glslang + +#endif // GLSLANG_SPV_TOOLS_H diff --git a/thirdparty/headers/glslang/include/glslang/SPIRV/disassemble.h b/thirdparty/headers/glslang/include/glslang/SPIRV/disassemble.h new file mode 100644 index 000000000..3bded14f2 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/SPIRV/disassemble.h @@ -0,0 +1,55 @@ +// +// Copyright (C) 2014-2015 LunarG, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// +// Disassembler for SPIR-V. +// + +#pragma once +#ifndef disassembler_H +#define disassembler_H + +#include +#include + +#include "glslang/Include/visibility.h" + +namespace spv { + + // disassemble with glslang custom disassembler + GLSLANG_EXPORT void Disassemble(std::ostream& out, const std::vector&); + +} // end namespace spv + +#endif // disassembler_H diff --git a/thirdparty/headers/glslang/include/glslang/SPIRV/spirv.hpp11 b/thirdparty/headers/glslang/include/glslang/SPIRV/spirv.hpp11 new file mode 100644 index 000000000..2ad294db8 --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/SPIRV/spirv.hpp11 @@ -0,0 +1,5230 @@ +// Copyright (c) 2014-2024 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_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010600; +static const unsigned int Revision = 1; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum class SourceLanguage : unsigned { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + Rust = 13, + Max = 0x7fffffff, +}; + +enum class ExecutionModel : unsigned { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + RayGenerationNV = 5313, + IntersectionKHR = 5314, + IntersectionNV = 5314, + AnyHitKHR = 5315, + AnyHitNV = 5315, + ClosestHitKHR = 5316, + ClosestHitNV = 5316, + MissKHR = 5317, + MissNV = 5317, + CallableKHR = 5318, + CallableNV = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + Max = 0x7fffffff, +}; + +enum class AddressingModel : unsigned { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + PhysicalStorageBuffer64EXT = 5348, + Max = 0x7fffffff, +}; + +enum class MemoryModel : unsigned { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + VulkanKHR = 3, + Max = 0x7fffffff, +}; + +enum class ExecutionMode : unsigned { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + NonCoherentTileAttachmentReadQCOM = 4489, + TileShadingRateQCOM = 4490, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + IsApiEntryAMDX = 5070, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + SharesInputWithAMDX = 5102, + OutputLinesEXT = 5269, + OutputLinesNV = 5269, + OutputPrimitivesEXT = 5270, + OutputPrimitivesNV = 5270, + DerivativeGroupQuadsKHR = 5289, + DerivativeGroupQuadsNV = 5289, + DerivativeGroupLinearKHR = 5290, + DerivativeGroupLinearNV = 5290, + OutputTrianglesEXT = 5298, + OutputTrianglesNV = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + Max = 0x7fffffff, +}; + +enum class StorageClass : unsigned { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + TileAttachmentQCOM = 4491, + NodePayloadAMDX = 5068, + CallableDataKHR = 5328, + CallableDataNV = 5328, + IncomingCallableDataKHR = 5329, + IncomingCallableDataNV = 5329, + RayPayloadKHR = 5338, + RayPayloadNV = 5338, + HitAttributeKHR = 5339, + HitAttributeNV = 5339, + IncomingRayPayloadKHR = 5342, + IncomingRayPayloadNV = 5342, + ShaderRecordBufferKHR = 5343, + ShaderRecordBufferNV = 5343, + PhysicalStorageBuffer = 5349, + PhysicalStorageBufferEXT = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + Max = 0x7fffffff, +}; + +enum class Dim : unsigned { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + Max = 0x7fffffff, +}; + +enum class SamplerAddressingMode : unsigned { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class SamplerFilterMode : unsigned { + Nearest = 0, + Linear = 1, + Max = 0x7fffffff, +}; + +enum class ImageFormat : unsigned { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + Max = 0x7fffffff, +}; + +enum class ImageChannelOrder : unsigned { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + Max = 0x7fffffff, +}; + +enum class ImageChannelDataType : unsigned { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + UnormInt2_101010EXT = 21, + Max = 0x7fffffff, +}; + +enum class ImageOperandsShift : unsigned { + Bias = 0, + Lod = 1, + Grad = 2, + ConstOffset = 3, + Offset = 4, + ConstOffsets = 5, + Sample = 6, + MinLod = 7, + MakeTexelAvailable = 8, + MakeTexelAvailableKHR = 8, + MakeTexelVisible = 9, + MakeTexelVisibleKHR = 9, + NonPrivateTexel = 10, + NonPrivateTexelKHR = 10, + VolatileTexel = 11, + VolatileTexelKHR = 11, + SignExtend = 12, + ZeroExtend = 13, + Nontemporal = 14, + Offsets = 16, + Max = 0x7fffffff, +}; + +enum class ImageOperandsMask : unsigned { + MaskNone = 0, + Bias = 0x00000001, + Lod = 0x00000002, + Grad = 0x00000004, + ConstOffset = 0x00000008, + Offset = 0x00000010, + ConstOffsets = 0x00000020, + Sample = 0x00000040, + MinLod = 0x00000080, + MakeTexelAvailable = 0x00000100, + MakeTexelAvailableKHR = 0x00000100, + MakeTexelVisible = 0x00000200, + MakeTexelVisibleKHR = 0x00000200, + NonPrivateTexel = 0x00000400, + NonPrivateTexelKHR = 0x00000400, + VolatileTexel = 0x00000800, + VolatileTexelKHR = 0x00000800, + SignExtend = 0x00001000, + ZeroExtend = 0x00002000, + Nontemporal = 0x00004000, + Offsets = 0x00010000, +}; + +enum class FPFastMathModeShift : unsigned { + NotNaN = 0, + NotInf = 1, + NSZ = 2, + AllowRecip = 3, + Fast = 4, + AllowContract = 16, + AllowContractFastINTEL = 16, + AllowReassoc = 17, + AllowReassocINTEL = 17, + AllowTransform = 18, + Max = 0x7fffffff, +}; + +enum class FPFastMathModeMask : unsigned { + MaskNone = 0, + NotNaN = 0x00000001, + NotInf = 0x00000002, + NSZ = 0x00000004, + AllowRecip = 0x00000008, + Fast = 0x00000010, + AllowContract = 0x00010000, + AllowContractFastINTEL = 0x00010000, + AllowReassoc = 0x00020000, + AllowReassocINTEL = 0x00020000, + AllowTransform = 0x00040000, +}; + +enum class FPRoundingMode : unsigned { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + Max = 0x7fffffff, +}; + +enum class LinkageType : unsigned { + Export = 0, + Import = 1, + LinkOnceODR = 2, + Max = 0x7fffffff, +}; + +enum class AccessQualifier : unsigned { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + Max = 0x7fffffff, +}; + +enum class FunctionParameterAttribute : unsigned { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + Max = 0x7fffffff, +}; + +enum class Decoration : unsigned { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + SaturatedToLargestFloat8NormalConversionEXT = 4216, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + PayloadNodeBaseIndexAMDX = 5098, + PayloadNodeSparseArrayAMDX = 5099, + PayloadNodeArraySizeAMDX = 5100, + PayloadDispatchIndirectAMDX = 5105, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerPrimitiveNV = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + PerVertexNV = 5285, + NonUniform = 5300, + NonUniformEXT = 5300, + RestrictPointer = 5355, + RestrictPointerEXT = 5355, + AliasedPointer = 5356, + AliasedPointerEXT = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + HlslCounterBufferGOOGLE = 5634, + HlslSemanticGOOGLE = 5635, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + Max = 0x7fffffff, +}; + +enum class BuiltIn : unsigned { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupEqMaskKHR = 4416, + SubgroupGeMask = 4417, + SubgroupGeMaskKHR = 4417, + SubgroupGtMask = 4418, + SubgroupGtMaskKHR = 4418, + SubgroupLeMask = 4419, + SubgroupLeMaskKHR = 4419, + SubgroupLtMask = 4420, + SubgroupLtMaskKHR = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + TileOffsetQCOM = 4492, + TileDimensionQCOM = 4493, + TileApronSizeQCOM = 4494, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + RemainingRecursionLevelsAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNV = 5286, + BaryCoordNoPerspKHR = 5287, + BaryCoordNoPerspNV = 5287, + FragSizeEXT = 5292, + FragmentSizeNV = 5292, + FragInvocationCountEXT = 5293, + InvocationsPerPixelNV = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchIdNV = 5319, + LaunchSizeKHR = 5320, + LaunchSizeNV = 5320, + WorldRayOriginKHR = 5321, + WorldRayOriginNV = 5321, + WorldRayDirectionKHR = 5322, + WorldRayDirectionNV = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayOriginNV = 5323, + ObjectRayDirectionKHR = 5324, + ObjectRayDirectionNV = 5324, + RayTminKHR = 5325, + RayTminNV = 5325, + RayTmaxKHR = 5326, + RayTmaxNV = 5326, + InstanceCustomIndexKHR = 5327, + InstanceCustomIndexNV = 5327, + ObjectToWorldKHR = 5330, + ObjectToWorldNV = 5330, + WorldToObjectKHR = 5331, + WorldToObjectNV = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + HitKindNV = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + IncomingRayFlagsNV = 5351, + RayGeometryIndexKHR = 5352, + HitIsSphereNV = 5359, + HitIsLSSNV = 5360, + HitSpherePositionNV = 5361, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitLSSPositionsNV = 5396, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + HitSphereRadiusNV = 5420, + HitLSSRadiiNV = 5421, + ClusterIDNV = 5436, + CullMaskKHR = 6021, + Max = 0x7fffffff, +}; + +enum class SelectionControlShift : unsigned { + Flatten = 0, + DontFlatten = 1, + Max = 0x7fffffff, +}; + +enum class SelectionControlMask : unsigned { + MaskNone = 0, + Flatten = 0x00000001, + DontFlatten = 0x00000002, +}; + +enum class LoopControlShift : unsigned { + Unroll = 0, + DontUnroll = 1, + DependencyInfinite = 2, + DependencyLength = 3, + MinIterations = 4, + MaxIterations = 5, + IterationMultiple = 6, + PeelCount = 7, + PartialCount = 8, + InitiationIntervalINTEL = 16, + MaxConcurrencyINTEL = 17, + DependencyArrayINTEL = 18, + PipelineEnableINTEL = 19, + LoopCoalesceINTEL = 20, + MaxInterleavingINTEL = 21, + SpeculatedIterationsINTEL = 22, + NoFusionINTEL = 23, + LoopCountINTEL = 24, + MaxReinvocationDelayINTEL = 25, + Max = 0x7fffffff, +}; + +enum class LoopControlMask : unsigned { + MaskNone = 0, + Unroll = 0x00000001, + DontUnroll = 0x00000002, + DependencyInfinite = 0x00000004, + DependencyLength = 0x00000008, + MinIterations = 0x00000010, + MaxIterations = 0x00000020, + IterationMultiple = 0x00000040, + PeelCount = 0x00000080, + PartialCount = 0x00000100, + InitiationIntervalINTEL = 0x00010000, + MaxConcurrencyINTEL = 0x00020000, + DependencyArrayINTEL = 0x00040000, + PipelineEnableINTEL = 0x00080000, + LoopCoalesceINTEL = 0x00100000, + MaxInterleavingINTEL = 0x00200000, + SpeculatedIterationsINTEL = 0x00400000, + NoFusionINTEL = 0x00800000, + LoopCountINTEL = 0x01000000, + MaxReinvocationDelayINTEL = 0x02000000, +}; + +enum class FunctionControlShift : unsigned { + Inline = 0, + DontInline = 1, + Pure = 2, + Const = 3, + OptNoneEXT = 16, + OptNoneINTEL = 16, + Max = 0x7fffffff, +}; + +enum class FunctionControlMask : unsigned { + MaskNone = 0, + Inline = 0x00000001, + DontInline = 0x00000002, + Pure = 0x00000004, + Const = 0x00000008, + OptNoneEXT = 0x00010000, + OptNoneINTEL = 0x00010000, +}; + +enum class MemorySemanticsShift : unsigned { + Acquire = 1, + Release = 2, + AcquireRelease = 3, + SequentiallyConsistent = 4, + UniformMemory = 6, + SubgroupMemory = 7, + WorkgroupMemory = 8, + CrossWorkgroupMemory = 9, + AtomicCounterMemory = 10, + ImageMemory = 11, + OutputMemory = 12, + OutputMemoryKHR = 12, + MakeAvailable = 13, + MakeAvailableKHR = 13, + MakeVisible = 14, + MakeVisibleKHR = 14, + Volatile = 15, + Max = 0x7fffffff, +}; + +enum class MemorySemanticsMask : unsigned { + MaskNone = 0, + Acquire = 0x00000002, + Release = 0x00000004, + AcquireRelease = 0x00000008, + SequentiallyConsistent = 0x00000010, + UniformMemory = 0x00000040, + SubgroupMemory = 0x00000080, + WorkgroupMemory = 0x00000100, + CrossWorkgroupMemory = 0x00000200, + AtomicCounterMemory = 0x00000400, + ImageMemory = 0x00000800, + OutputMemory = 0x00001000, + OutputMemoryKHR = 0x00001000, + MakeAvailable = 0x00002000, + MakeAvailableKHR = 0x00002000, + MakeVisible = 0x00004000, + MakeVisibleKHR = 0x00004000, + Volatile = 0x00008000, +}; + +enum class MemoryAccessShift : unsigned { + Volatile = 0, + Aligned = 1, + Nontemporal = 2, + MakePointerAvailable = 3, + MakePointerAvailableKHR = 3, + MakePointerVisible = 4, + MakePointerVisibleKHR = 4, + NonPrivatePointer = 5, + NonPrivatePointerKHR = 5, + AliasScopeINTELMask = 16, + NoAliasINTELMask = 17, + Max = 0x7fffffff, +}; + +enum class MemoryAccessMask : unsigned { + MaskNone = 0, + Volatile = 0x00000001, + Aligned = 0x00000002, + Nontemporal = 0x00000004, + MakePointerAvailable = 0x00000008, + MakePointerAvailableKHR = 0x00000008, + MakePointerVisible = 0x00000010, + MakePointerVisibleKHR = 0x00000010, + NonPrivatePointer = 0x00000020, + NonPrivatePointerKHR = 0x00000020, + AliasScopeINTELMask = 0x00010000, + NoAliasINTELMask = 0x00020000, +}; + +enum class Scope : unsigned { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + QueueFamilyKHR = 5, + ShaderCallKHR = 6, + Max = 0x7fffffff, +}; + +enum class GroupOperation : unsigned { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + Max = 0x7fffffff, +}; + +enum class KernelEnqueueFlags : unsigned { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoShift : unsigned { + CmdExecTime = 0, + Max = 0x7fffffff, +}; + +enum class KernelProfilingInfoMask : unsigned { + MaskNone = 0, + CmdExecTime = 0x00000001, +}; + +enum class Capability : unsigned { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + TensorsARM = 4174, + CooperativeMatrixLayoutsARM = 4201, + Float8EXT = 4212, + Float8CooperativeMatrixEXT = 4213, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + StorageUniformBufferBlock16 = 4433, + StorageUniform16 = 4434, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + UntypedPointersKHR = 4473, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TileShadingQCOM = 4495, + CooperativeMatrixConversionQCOM = 4496, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + BFloat16TypeKHR = 5116, + BFloat16DotProductKHR = 5117, + BFloat16CooperativeMatrixKHR = 5118, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportIndexLayerNV = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + FragmentBarycentricNV = 5284, + ComputeDerivativeGroupQuadsKHR = 5288, + ComputeDerivativeGroupQuadsNV = 5288, + FragmentDensityEXT = 5291, + ShadingRateNV = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + ShaderNonUniformEXT = 5301, + RuntimeDescriptorArray = 5302, + RuntimeDescriptorArrayEXT = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + InputAttachmentArrayDynamicIndexingEXT = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + UniformTexelBufferArrayDynamicIndexingEXT = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + StorageTexelBufferArrayDynamicIndexingEXT = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + UniformBufferArrayNonUniformIndexingEXT = 5306, + SampledImageArrayNonUniformIndexing = 5307, + SampledImageArrayNonUniformIndexingEXT = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageBufferArrayNonUniformIndexingEXT = 5308, + StorageImageArrayNonUniformIndexing = 5309, + StorageImageArrayNonUniformIndexingEXT = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + InputAttachmentArrayNonUniformIndexingEXT = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + UniformTexelBufferArrayNonUniformIndexingEXT = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + StorageTexelBufferArrayNonUniformIndexingEXT = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelKHR = 5345, + VulkanMemoryModelDeviceScope = 5346, + VulkanMemoryModelDeviceScopeKHR = 5346, + PhysicalStorageBufferAddresses = 5347, + PhysicalStorageBufferAddressesEXT = 5347, + ComputeDerivativeGroupLinearKHR = 5350, + ComputeDerivativeGroupLinearNV = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DemoteToHelperInvocationEXT = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + CooperativeVectorNV = 5394, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + RawAccessChainsNV = 5414, + RayTracingSpheresGeometryNV = 5418, + RayTracingLinearSweptSpheresGeometryNV = 5419, + CooperativeMatrixReductionsNV = 5430, + CooperativeMatrixConversionsNV = 5431, + CooperativeMatrixPerElementOperationsNV = 5432, + CooperativeMatrixTensorAddressingNV = 5433, + CooperativeMatrixBlockLoadsNV = 5434, + CooperativeVectorTrainingNV = 5435, + RayTracingClusterAccelerationStructureNV = 5437, + TensorAddressingNV = 5439, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInputAllKHR = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitKHR = 6017, + DotProductInput4x8BitPacked = 6018, + DotProductInput4x8BitPackedKHR = 6018, + DotProduct = 6019, + DotProductKHR = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + ReplicatedCompositesEXT = 6024, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneEXT = 6094, + OptNoneINTEL = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + ArithmeticFenceEXT = 6144, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + SubgroupBufferPrefetchINTEL = 6220, + Subgroup2DBlockIOINTEL = 6228, + Subgroup2DBlockTransformINTEL = 6229, + Subgroup2DBlockTransposeINTEL = 6230, + SubgroupMatrixMultiplyAccumulateINTEL = 6236, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + Max = 0x7fffffff, +}; + +enum class RayFlagsShift : unsigned { + OpaqueKHR = 0, + NoOpaqueKHR = 1, + TerminateOnFirstHitKHR = 2, + SkipClosestHitShaderKHR = 3, + CullBackFacingTrianglesKHR = 4, + CullFrontFacingTrianglesKHR = 5, + CullOpaqueKHR = 6, + CullNoOpaqueKHR = 7, + SkipBuiltinPrimitivesNV = 8, + SkipTrianglesKHR = 8, + SkipAABBsKHR = 9, + ForceOpacityMicromap2StateEXT = 10, + Max = 0x7fffffff, +}; + +enum class RayFlagsMask : unsigned { + MaskNone = 0, + OpaqueKHR = 0x00000001, + NoOpaqueKHR = 0x00000002, + TerminateOnFirstHitKHR = 0x00000004, + SkipClosestHitShaderKHR = 0x00000008, + CullBackFacingTrianglesKHR = 0x00000010, + CullFrontFacingTrianglesKHR = 0x00000020, + CullOpaqueKHR = 0x00000040, + CullNoOpaqueKHR = 0x00000080, + SkipBuiltinPrimitivesNV = 0x00000100, + SkipTrianglesKHR = 0x00000100, + SkipAABBsKHR = 0x00000200, + ForceOpacityMicromap2StateEXT = 0x00000400, +}; + +enum class RayQueryIntersection : unsigned { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + Max = 0x7fffffff, +}; + +enum class RayQueryCommittedIntersectionType : unsigned { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + Max = 0x7fffffff, +}; + +enum class RayQueryCandidateIntersectionType : unsigned { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + Max = 0x7fffffff, +}; + +enum class FragmentShadingRateShift : unsigned { + Vertical2Pixels = 0, + Vertical4Pixels = 1, + Horizontal2Pixels = 2, + Horizontal4Pixels = 3, + Max = 0x7fffffff, +}; + +enum class FragmentShadingRateMask : unsigned { + MaskNone = 0, + Vertical2Pixels = 0x00000001, + Vertical4Pixels = 0x00000002, + Horizontal2Pixels = 0x00000004, + Horizontal4Pixels = 0x00000008, +}; + +enum class FPDenormMode : unsigned { + Preserve = 0, + FlushToZero = 1, + Max = 0x7fffffff, +}; + +enum class FPOperationMode : unsigned { + IEEE = 0, + ALT = 1, + Max = 0x7fffffff, +}; + +enum class QuantizationModes : unsigned { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + Max = 0x7fffffff, +}; + +enum class OverflowModes : unsigned { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + Max = 0x7fffffff, +}; + +enum class PackedVectorFormat : unsigned { + PackedVectorFormat4x8Bit = 0, + PackedVectorFormat4x8BitKHR = 0, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixOperandsShift : unsigned { + MatrixASignedComponentsKHR = 0, + MatrixBSignedComponentsKHR = 1, + MatrixCSignedComponentsKHR = 2, + MatrixResultSignedComponentsKHR = 3, + SaturatingAccumulationKHR = 4, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixOperandsMask : unsigned { + MaskNone = 0, + MatrixASignedComponentsKHR = 0x00000001, + MatrixBSignedComponentsKHR = 0x00000002, + MatrixCSignedComponentsKHR = 0x00000004, + MatrixResultSignedComponentsKHR = 0x00000008, + SaturatingAccumulationKHR = 0x00000010, +}; + +enum class CooperativeMatrixLayout : unsigned { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixUse : unsigned { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixReduceShift : unsigned { + Row = 0, + Column = 1, + CooperativeMatrixReduce2x2 = 2, + Max = 0x7fffffff, +}; + +enum class CooperativeMatrixReduceMask : unsigned { + MaskNone = 0, + Row = 0x00000001, + Column = 0x00000002, + CooperativeMatrixReduce2x2 = 0x00000004, +}; + +enum class TensorClampMode : unsigned { + Undefined = 0, + Constant = 1, + ClampToEdge = 2, + Repeat = 3, + RepeatMirrored = 4, + Max = 0x7fffffff, +}; + +enum class TensorAddressingOperandsShift : unsigned { + TensorView = 0, + DecodeFunc = 1, + Max = 0x7fffffff, +}; + +enum class TensorAddressingOperandsMask : unsigned { + MaskNone = 0, + TensorView = 0x00000001, + DecodeFunc = 0x00000002, +}; + +enum class TensorOperandsShift : unsigned { + NontemporalARM = 0, + OutOfBoundsValueARM = 1, + Max = 0x7fffffff, +}; + +enum class TensorOperandsMask : unsigned { + MaskNone = 0, + NontemporalARM = 0x00000001, + OutOfBoundsValueARM = 0x00000002, +}; + +enum class InitializationModeQualifier : unsigned { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + Max = 0x7fffffff, +}; + +enum class HostAccessQualifier : unsigned { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + Max = 0x7fffffff, +}; + +enum class LoadCacheControl : unsigned { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + Max = 0x7fffffff, +}; + +enum class StoreCacheControl : unsigned { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + Max = 0x7fffffff, +}; + +enum class NamedMaximumNumberOfRegisters : unsigned { + AutoINTEL = 0, + Max = 0x7fffffff, +}; + +enum class MatrixMultiplyAccumulateOperandsShift : unsigned { + MatrixASignedComponentsINTEL = 0, + MatrixBSignedComponentsINTEL = 1, + MatrixCBFloat16INTEL = 2, + MatrixResultBFloat16INTEL = 3, + MatrixAPackedInt8INTEL = 4, + MatrixBPackedInt8INTEL = 5, + MatrixAPackedInt4INTEL = 6, + MatrixBPackedInt4INTEL = 7, + MatrixATF32INTEL = 8, + MatrixBTF32INTEL = 9, + MatrixAPackedFloat16INTEL = 10, + MatrixBPackedFloat16INTEL = 11, + MatrixAPackedBFloat16INTEL = 12, + MatrixBPackedBFloat16INTEL = 13, + Max = 0x7fffffff, +}; + +enum class MatrixMultiplyAccumulateOperandsMask : unsigned { + MaskNone = 0, + MatrixASignedComponentsINTEL = 0x00000001, + MatrixBSignedComponentsINTEL = 0x00000002, + MatrixCBFloat16INTEL = 0x00000004, + MatrixResultBFloat16INTEL = 0x00000008, + MatrixAPackedInt8INTEL = 0x00000010, + MatrixBPackedInt8INTEL = 0x00000020, + MatrixAPackedInt4INTEL = 0x00000040, + MatrixBPackedInt4INTEL = 0x00000080, + MatrixATF32INTEL = 0x00000100, + MatrixBTF32INTEL = 0x00000200, + MatrixAPackedFloat16INTEL = 0x00000400, + MatrixBPackedFloat16INTEL = 0x00000800, + MatrixAPackedBFloat16INTEL = 0x00001000, + MatrixBPackedBFloat16INTEL = 0x00002000, +}; + +enum class RawAccessChainOperandsShift : unsigned { + RobustnessPerComponentNV = 0, + RobustnessPerElementNV = 1, + Max = 0x7fffffff, +}; + +enum class RawAccessChainOperandsMask : unsigned { + MaskNone = 0, + RobustnessPerComponentNV = 0x00000001, + RobustnessPerElementNV = 0x00000002, +}; + +enum class FPEncoding : unsigned { + BFloat16KHR = 0, + Float8E4M3EXT = 4214, + Float8E5M2EXT = 4215, + Max = 0x7fffffff, +}; + +enum class CooperativeVectorMatrixLayout : unsigned { + RowMajorNV = 0, + ColumnMajorNV = 1, + InferencingOptimalNV = 2, + TrainingOptimalNV = 3, + Max = 0x7fffffff, +}; + +enum class ComponentType : unsigned { + Float16NV = 0, + Float32NV = 1, + Float64NV = 2, + SignedInt8NV = 3, + SignedInt16NV = 4, + SignedInt32NV = 5, + SignedInt64NV = 6, + UnsignedInt8NV = 7, + UnsignedInt16NV = 8, + UnsignedInt32NV = 9, + UnsignedInt64NV = 10, + SignedInt8PackedNV = 1000491000, + UnsignedInt8PackedNV = 1000491001, + FloatE4M3NV = 1000491002, + FloatE5M2NV = 1000491003, + Max = 0x7fffffff, +}; + +enum class Op : unsigned { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTypeTensorARM = 4163, + OpTensorReadARM = 4164, + OpTensorWriteARM = 4165, + OpTensorQuerySizeARM = 4166, + OpTerminateInvocation = 4416, + OpTypeUntypedPointerKHR = 4417, + OpUntypedVariableKHR = 4418, + OpUntypedAccessChainKHR = 4419, + OpUntypedInBoundsAccessChainKHR = 4420, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpUntypedPtrAccessChainKHR = 4423, + OpUntypedInBoundsPtrAccessChainKHR = 4424, + OpUntypedArrayLengthKHR = 4425, + OpUntypedPrefetchKHR = 4426, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpExtInstWithForwardRefsKHR = 4433, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpBitCastArrayQCOM = 4497, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpCompositeConstructCoopMatQCOM = 4540, + OpCompositeExtractCoopMatQCOM = 4541, + OpExtractSubArrayQCOM = 4542, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpAllocateNodePayloadsAMDX = 5074, + OpEnqueueNodePayloadsAMDX = 5075, + OpTypeNodePayloadArrayAMDX = 5076, + OpFinishWritingNodePayloadAMDX = 5078, + OpNodePayloadArrayLengthAMDX = 5090, + OpIsNodePayloadValidAMDX = 5101, + OpConstantStringAMDX = 5103, + OpSpecConstantStringAMDX = 5104, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpTypeCooperativeVectorNV = 5288, + OpCooperativeVectorMatrixMulNV = 5289, + OpCooperativeVectorOuterProductAccumulateNV = 5290, + OpCooperativeVectorReduceSumAccumulateNV = 5291, + OpCooperativeVectorMatrixMulAddNV = 5292, + OpCooperativeMatrixConvertNV = 5293, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpCooperativeVectorLoadNV = 5302, + OpCooperativeVectorStoreNV = 5303, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpRayQueryGetClusterIdNV = 5345, + OpHitObjectGetClusterIdNV = 5346, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpCooperativeMatrixReduceNV = 5366, + OpCooperativeMatrixLoadTensorNV = 5367, + OpCooperativeMatrixStoreTensorNV = 5368, + OpCooperativeMatrixPerElementOpNV = 5369, + OpTypeTensorLayoutNV = 5370, + OpTypeTensorViewNV = 5371, + OpCreateTensorLayoutNV = 5372, + OpTensorLayoutSetDimensionNV = 5373, + OpTensorLayoutSetStrideNV = 5374, + OpTensorLayoutSliceNV = 5375, + OpTensorLayoutSetClampValueNV = 5376, + OpCreateTensorViewNV = 5377, + OpTensorViewSetDimensionNV = 5378, + OpTensorViewSetStrideNV = 5379, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpTensorViewSetClipNV = 5382, + OpTensorLayoutSetBlockSizeNV = 5384, + OpCooperativeMatrixTransposeNV = 5390, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpRawAccessChainNV = 5398, + OpRayQueryGetIntersectionSpherePositionNV = 5427, + OpRayQueryGetIntersectionSphereRadiusNV = 5428, + OpRayQueryGetIntersectionLSSPositionsNV = 5429, + OpRayQueryGetIntersectionLSSRadiiNV = 5430, + OpRayQueryGetIntersectionLSSHitValueNV = 5431, + OpHitObjectGetSpherePositionNV = 5432, + OpHitObjectGetSphereRadiusNV = 5433, + OpHitObjectGetLSSPositionsNV = 5434, + OpHitObjectGetLSSRadiiNV = 5435, + OpHitObjectIsSphereHitNV = 5436, + OpHitObjectIsLSSHitNV = 5437, + OpRayQueryIsSphereHitNV = 5438, + OpRayQueryIsLSSHitNV = 5439, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpArithmeticFenceEXT = 6145, + OpSubgroupBlockPrefetchINTEL = 6221, + OpSubgroup2DBlockLoadINTEL = 6231, + OpSubgroup2DBlockLoadTransformINTEL = 6232, + OpSubgroup2DBlockLoadTransposeINTEL = 6233, + OpSubgroup2DBlockPrefetchINTEL = 6234, + OpSubgroup2DBlockStoreINTEL = 6235, + OpSubgroupMatrixMultiplyAccumulateINTEL = 6237, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + Max = 0x7fffffff, +}; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case Op::OpNop: *hasResult = false; *hasResultType = false; break; + case Op::OpUndef: *hasResult = true; *hasResultType = true; break; + case Op::OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case Op::OpSource: *hasResult = false; *hasResultType = false; break; + case Op::OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case Op::OpName: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberName: *hasResult = false; *hasResultType = false; break; + case Op::OpString: *hasResult = true; *hasResultType = false; break; + case Op::OpLine: *hasResult = false; *hasResultType = false; break; + case Op::OpExtension: *hasResult = false; *hasResultType = false; break; + case Op::OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case Op::OpExtInst: *hasResult = true; *hasResultType = true; break; + case Op::OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case Op::OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case Op::OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case Op::OpCapability: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeBool: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeInt: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeVector: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeImage: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeArray: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case Op::OpTypePointer: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case Op::OpTypePipe: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case Op::OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case Op::OpConstant: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantNull: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case Op::OpFunction: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case Op::OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case Op::OpVariable: *hasResult = true; *hasResultType = true; break; + case Op::OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case Op::OpLoad: *hasResult = true; *hasResultType = true; break; + case Op::OpStore: *hasResult = false; *hasResultType = false; break; + case Op::OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case Op::OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case Op::OpAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpArrayLength: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case Op::OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case Op::OpDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case Op::OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case Op::OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case Op::OpCopyObject: *hasResult = true; *hasResultType = true; break; + case Op::OpTranspose: *hasResult = true; *hasResultType = true; break; + case Op::OpSampledImage: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageFetch: *hasResult = true; *hasResultType = true; break; + case Op::OpImageGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageRead: *hasResult = true; *hasResultType = true; break; + case Op::OpImageWrite: *hasResult = false; *hasResultType = false; break; + case Op::OpImage: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case Op::OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case Op::OpUConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpSConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpFConvert: *hasResult = true; *hasResultType = true; break; + case Op::OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case Op::OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case Op::OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case Op::OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case Op::OpBitcast: *hasResult = true; *hasResultType = true; break; + case Op::OpSNegate: *hasResult = true; *hasResultType = true; break; + case Op::OpFNegate: *hasResult = true; *hasResultType = true; break; + case Op::OpIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpISub: *hasResult = true; *hasResultType = true; break; + case Op::OpFSub: *hasResult = true; *hasResultType = true; break; + case Op::OpIMul: *hasResult = true; *hasResultType = true; break; + case Op::OpFMul: *hasResult = true; *hasResultType = true; break; + case Op::OpUDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpSDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpFDiv: *hasResult = true; *hasResultType = true; break; + case Op::OpUMod: *hasResult = true; *hasResultType = true; break; + case Op::OpSRem: *hasResult = true; *hasResultType = true; break; + case Op::OpSMod: *hasResult = true; *hasResultType = true; break; + case Op::OpFRem: *hasResult = true; *hasResultType = true; break; + case Op::OpFMod: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case Op::OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case Op::OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case Op::OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case Op::OpDot: *hasResult = true; *hasResultType = true; break; + case Op::OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case Op::OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case Op::OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case Op::OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case Op::OpAny: *hasResult = true; *hasResultType = true; break; + case Op::OpAll: *hasResult = true; *hasResultType = true; break; + case Op::OpIsNan: *hasResult = true; *hasResultType = true; break; + case Op::OpIsInf: *hasResult = true; *hasResultType = true; break; + case Op::OpIsFinite: *hasResult = true; *hasResultType = true; break; + case Op::OpIsNormal: *hasResult = true; *hasResultType = true; break; + case Op::OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case Op::OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case Op::OpOrdered: *hasResult = true; *hasResultType = true; break; + case Op::OpUnordered: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case Op::OpSelect: *hasResult = true; *hasResultType = true; break; + case Op::OpIEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpINotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpULessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpSLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case Op::OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case Op::OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpNot: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpBitReverse: *hasResult = true; *hasResultType = true; break; + case Op::OpBitCount: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdx: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdy: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidth: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case Op::OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case Op::OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case Op::OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case Op::OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case Op::OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case Op::OpPhi: *hasResult = true; *hasResultType = true; break; + case Op::OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case Op::OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case Op::OpLabel: *hasResult = true; *hasResultType = false; break; + case Op::OpBranch: *hasResult = false; *hasResultType = false; break; + case Op::OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case Op::OpSwitch: *hasResult = false; *hasResultType = false; break; + case Op::OpKill: *hasResult = false; *hasResultType = false; break; + case Op::OpReturn: *hasResult = false; *hasResultType = false; break; + case Op::OpReturnValue: *hasResult = false; *hasResultType = false; break; + case Op::OpUnreachable: *hasResult = false; *hasResultType = false; break; + case Op::OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case Op::OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupAll: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupAny: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpReadPipe: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case Op::OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case Op::OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case Op::OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case Op::OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case Op::OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case Op::OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case Op::OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case Op::OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case Op::OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case Op::OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case Op::OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case Op::OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case Op::OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case Op::OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case Op::OpNoLine: *hasResult = false; *hasResultType = false; break; + case Op::OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case Op::OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case Op::OpSizeOf: *hasResult = true; *hasResultType = true; break; + case Op::OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case Op::OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case Op::OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case Op::OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case Op::OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case Op::OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case Op::OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case Op::OpDecorateId: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case Op::OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case Op::OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeTensorARM: *hasResult = true; *hasResultType = false; break; + case Op::OpTensorReadARM: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorWriteARM: *hasResult = false; *hasResultType = false; break; + case Op::OpTensorQuerySizeARM: *hasResult = true; *hasResultType = true; break; + case Op::OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeUntypedPointerKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpUntypedVariableKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpUntypedAccessChainKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpUntypedInBoundsAccessChainKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpUntypedPtrAccessChainKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpUntypedInBoundsPtrAccessChainKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpUntypedArrayLengthKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpUntypedPrefetchKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpExtInstWithForwardRefsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpSDot: *hasResult = true; *hasResultType = true; break; + case Op::OpUDot: *hasResult = true; *hasResultType = true; break; + case Op::OpSUDot: *hasResult = true; *hasResultType = true; break; + case Op::OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeConstructReplicateEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpBitCastArrayQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeConstructCoopMatQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeExtractCoopMatQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpExtractSubArrayQCOM: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case Op::OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpAllocateNodePayloadsAMDX: *hasResult = true; *hasResultType = true; break; + case Op::OpEnqueueNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeNodePayloadArrayAMDX: *hasResult = true; *hasResultType = false; break; + case Op::OpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break; + case Op::OpNodePayloadArrayLengthAMDX: *hasResult = true; *hasResultType = true; break; + case Op::OpIsNodePayloadValidAMDX: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantStringAMDX: *hasResult = true; *hasResultType = false; break; + case Op::OpSpecConstantStringAMDX: *hasResult = true; *hasResultType = false; break; + case Op::OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case Op::OpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case Op::OpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case Op::OpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case Op::OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeCooperativeVectorNV: *hasResult = true; *hasResultType = false; break; + case Op::OpCooperativeVectorMatrixMulNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeVectorOuterProductAccumulateNV: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeVectorReduceSumAccumulateNV: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeVectorMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixConvertNV: *hasResult = true; *hasResultType = true; break; + case Op::OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case Op::OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeVectorLoadNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeVectorStoreNV: *hasResult = false; *hasResultType = false; break; + case Op::OpReportIntersectionKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeAccelerationStructureKHR: *hasResult = true; *hasResultType = false; break; + case Op::OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case Op::OpRayQueryGetClusterIdNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetClusterIdNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case Op::OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case Op::OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixReduceNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixLoadTensorNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixStoreTensorNV: *hasResult = false; *hasResultType = false; break; + case Op::OpCooperativeMatrixPerElementOpNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeTensorLayoutNV: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeTensorViewNV: *hasResult = true; *hasResultType = false; break; + case Op::OpCreateTensorLayoutNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorLayoutSetDimensionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorLayoutSetStrideNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorLayoutSliceNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorLayoutSetClampValueNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCreateTensorViewNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorViewSetDimensionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorViewSetStrideNV: *hasResult = true; *hasResultType = true; break; + case Op::OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case Op::OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorViewSetClipNV: *hasResult = true; *hasResultType = true; break; + case Op::OpTensorLayoutSetBlockSizeNV: *hasResult = true; *hasResultType = true; break; + case Op::OpCooperativeMatrixTransposeNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case Op::OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case Op::OpRawAccessChainNV: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionSpherePositionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionSphereRadiusNV: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionLSSPositionsNV: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionLSSRadiiNV: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionLSSHitValueNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetSpherePositionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetSphereRadiusNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetLSSPositionsNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectGetLSSRadiiNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsSphereHitNV: *hasResult = true; *hasResultType = true; break; + case Op::OpHitObjectIsLSSHitNV: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryIsSphereHitNV: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryIsLSSHitNV: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmTargetINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case Op::OpExpectKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpDecorateString: *hasResult = false; *hasResultType = false; break; + case Op::OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case Op::OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpArithmeticFenceEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpSubgroupBlockPrefetchINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroup2DBlockLoadINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroup2DBlockLoadTransformINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroup2DBlockLoadTransposeINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroup2DBlockPrefetchINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroup2DBlockStoreINTEL: *hasResult = false; *hasResultType = false; break; + case Op::OpSubgroupMatrixMultiplyAccumulateINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break; + case Op::OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; + } +} +inline const char* SourceLanguageToString(SourceLanguage value) { + switch (value) { + case SourceLanguage::Unknown: return "Unknown"; + case SourceLanguage::ESSL: return "ESSL"; + case SourceLanguage::GLSL: return "GLSL"; + case SourceLanguage::OpenCL_C: return "OpenCL_C"; + case SourceLanguage::OpenCL_CPP: return "OpenCL_CPP"; + case SourceLanguage::HLSL: return "HLSL"; + case SourceLanguage::CPP_for_OpenCL: return "CPP_for_OpenCL"; + case SourceLanguage::SYCL: return "SYCL"; + case SourceLanguage::HERO_C: return "HERO_C"; + case SourceLanguage::NZSL: return "NZSL"; + case SourceLanguage::WGSL: return "WGSL"; + case SourceLanguage::Slang: return "Slang"; + case SourceLanguage::Zig: return "Zig"; + case SourceLanguage::Rust: return "Rust"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModelToString(ExecutionModel value) { + switch (value) { + case ExecutionModel::Vertex: return "Vertex"; + case ExecutionModel::TessellationControl: return "TessellationControl"; + case ExecutionModel::TessellationEvaluation: return "TessellationEvaluation"; + case ExecutionModel::Geometry: return "Geometry"; + case ExecutionModel::Fragment: return "Fragment"; + case ExecutionModel::GLCompute: return "GLCompute"; + case ExecutionModel::Kernel: return "Kernel"; + case ExecutionModel::TaskNV: return "TaskNV"; + case ExecutionModel::MeshNV: return "MeshNV"; + case ExecutionModel::RayGenerationKHR: return "RayGenerationKHR"; + case ExecutionModel::IntersectionKHR: return "IntersectionKHR"; + case ExecutionModel::AnyHitKHR: return "AnyHitKHR"; + case ExecutionModel::ClosestHitKHR: return "ClosestHitKHR"; + case ExecutionModel::MissKHR: return "MissKHR"; + case ExecutionModel::CallableKHR: return "CallableKHR"; + case ExecutionModel::TaskEXT: return "TaskEXT"; + case ExecutionModel::MeshEXT: return "MeshEXT"; + default: return "Unknown"; + } +} + +inline const char* AddressingModelToString(AddressingModel value) { + switch (value) { + case AddressingModel::Logical: return "Logical"; + case AddressingModel::Physical32: return "Physical32"; + case AddressingModel::Physical64: return "Physical64"; + case AddressingModel::PhysicalStorageBuffer64: return "PhysicalStorageBuffer64"; + default: return "Unknown"; + } +} + +inline const char* MemoryModelToString(MemoryModel value) { + switch (value) { + case MemoryModel::Simple: return "Simple"; + case MemoryModel::GLSL450: return "GLSL450"; + case MemoryModel::OpenCL: return "OpenCL"; + case MemoryModel::Vulkan: return "Vulkan"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModeToString(ExecutionMode value) { + switch (value) { + case ExecutionMode::Invocations: return "Invocations"; + case ExecutionMode::SpacingEqual: return "SpacingEqual"; + case ExecutionMode::SpacingFractionalEven: return "SpacingFractionalEven"; + case ExecutionMode::SpacingFractionalOdd: return "SpacingFractionalOdd"; + case ExecutionMode::VertexOrderCw: return "VertexOrderCw"; + case ExecutionMode::VertexOrderCcw: return "VertexOrderCcw"; + case ExecutionMode::PixelCenterInteger: return "PixelCenterInteger"; + case ExecutionMode::OriginUpperLeft: return "OriginUpperLeft"; + case ExecutionMode::OriginLowerLeft: return "OriginLowerLeft"; + case ExecutionMode::EarlyFragmentTests: return "EarlyFragmentTests"; + case ExecutionMode::PointMode: return "PointMode"; + case ExecutionMode::Xfb: return "Xfb"; + case ExecutionMode::DepthReplacing: return "DepthReplacing"; + case ExecutionMode::DepthGreater: return "DepthGreater"; + case ExecutionMode::DepthLess: return "DepthLess"; + case ExecutionMode::DepthUnchanged: return "DepthUnchanged"; + case ExecutionMode::LocalSize: return "LocalSize"; + case ExecutionMode::LocalSizeHint: return "LocalSizeHint"; + case ExecutionMode::InputPoints: return "InputPoints"; + case ExecutionMode::InputLines: return "InputLines"; + case ExecutionMode::InputLinesAdjacency: return "InputLinesAdjacency"; + case ExecutionMode::Triangles: return "Triangles"; + case ExecutionMode::InputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case ExecutionMode::Quads: return "Quads"; + case ExecutionMode::Isolines: return "Isolines"; + case ExecutionMode::OutputVertices: return "OutputVertices"; + case ExecutionMode::OutputPoints: return "OutputPoints"; + case ExecutionMode::OutputLineStrip: return "OutputLineStrip"; + case ExecutionMode::OutputTriangleStrip: return "OutputTriangleStrip"; + case ExecutionMode::VecTypeHint: return "VecTypeHint"; + case ExecutionMode::ContractionOff: return "ContractionOff"; + case ExecutionMode::Initializer: return "Initializer"; + case ExecutionMode::Finalizer: return "Finalizer"; + case ExecutionMode::SubgroupSize: return "SubgroupSize"; + case ExecutionMode::SubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case ExecutionMode::SubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case ExecutionMode::LocalSizeId: return "LocalSizeId"; + case ExecutionMode::LocalSizeHintId: return "LocalSizeHintId"; + case ExecutionMode::NonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT"; + case ExecutionMode::NonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT"; + case ExecutionMode::NonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT"; + case ExecutionMode::SubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlowKHR"; + case ExecutionMode::PostDepthCoverage: return "PostDepthCoverage"; + case ExecutionMode::DenormPreserve: return "DenormPreserve"; + case ExecutionMode::DenormFlushToZero: return "DenormFlushToZero"; + case ExecutionMode::SignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case ExecutionMode::RoundingModeRTE: return "RoundingModeRTE"; + case ExecutionMode::RoundingModeRTZ: return "RoundingModeRTZ"; + case ExecutionMode::NonCoherentTileAttachmentReadQCOM: return "NonCoherentTileAttachmentReadQCOM"; + case ExecutionMode::TileShadingRateQCOM: return "TileShadingRateQCOM"; + case ExecutionMode::EarlyAndLateFragmentTestsAMD: return "EarlyAndLateFragmentTestsAMD"; + case ExecutionMode::StencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case ExecutionMode::CoalescingAMDX: return "CoalescingAMDX"; + case ExecutionMode::IsApiEntryAMDX: return "IsApiEntryAMDX"; + case ExecutionMode::MaxNodeRecursionAMDX: return "MaxNodeRecursionAMDX"; + case ExecutionMode::StaticNumWorkgroupsAMDX: return "StaticNumWorkgroupsAMDX"; + case ExecutionMode::ShaderIndexAMDX: return "ShaderIndexAMDX"; + case ExecutionMode::MaxNumWorkgroupsAMDX: return "MaxNumWorkgroupsAMDX"; + case ExecutionMode::StencilRefUnchangedFrontAMD: return "StencilRefUnchangedFrontAMD"; + case ExecutionMode::StencilRefGreaterFrontAMD: return "StencilRefGreaterFrontAMD"; + case ExecutionMode::StencilRefLessFrontAMD: return "StencilRefLessFrontAMD"; + case ExecutionMode::StencilRefUnchangedBackAMD: return "StencilRefUnchangedBackAMD"; + case ExecutionMode::StencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD"; + case ExecutionMode::StencilRefLessBackAMD: return "StencilRefLessBackAMD"; + case ExecutionMode::QuadDerivativesKHR: return "QuadDerivativesKHR"; + case ExecutionMode::RequireFullQuadsKHR: return "RequireFullQuadsKHR"; + case ExecutionMode::SharesInputWithAMDX: return "SharesInputWithAMDX"; + case ExecutionMode::OutputLinesEXT: return "OutputLinesEXT"; + case ExecutionMode::OutputPrimitivesEXT: return "OutputPrimitivesEXT"; + case ExecutionMode::DerivativeGroupQuadsKHR: return "DerivativeGroupQuadsKHR"; + case ExecutionMode::DerivativeGroupLinearKHR: return "DerivativeGroupLinearKHR"; + case ExecutionMode::OutputTrianglesEXT: return "OutputTrianglesEXT"; + case ExecutionMode::PixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case ExecutionMode::PixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case ExecutionMode::SampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case ExecutionMode::SampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case ExecutionMode::ShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case ExecutionMode::ShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case ExecutionMode::SharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL"; + case ExecutionMode::RoundingModeRTPINTEL: return "RoundingModeRTPINTEL"; + case ExecutionMode::RoundingModeRTNINTEL: return "RoundingModeRTNINTEL"; + case ExecutionMode::FloatingPointModeALTINTEL: return "FloatingPointModeALTINTEL"; + case ExecutionMode::FloatingPointModeIEEEINTEL: return "FloatingPointModeIEEEINTEL"; + case ExecutionMode::MaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case ExecutionMode::MaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case ExecutionMode::NoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case ExecutionMode::NumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case ExecutionMode::SchedulerTargetFmaxMhzINTEL: return "SchedulerTargetFmaxMhzINTEL"; + case ExecutionMode::MaximallyReconvergesKHR: return "MaximallyReconvergesKHR"; + case ExecutionMode::FPFastMathDefault: return "FPFastMathDefault"; + case ExecutionMode::StreamingInterfaceINTEL: return "StreamingInterfaceINTEL"; + case ExecutionMode::RegisterMapInterfaceINTEL: return "RegisterMapInterfaceINTEL"; + case ExecutionMode::NamedBarrierCountINTEL: return "NamedBarrierCountINTEL"; + case ExecutionMode::MaximumRegistersINTEL: return "MaximumRegistersINTEL"; + case ExecutionMode::MaximumRegistersIdINTEL: return "MaximumRegistersIdINTEL"; + case ExecutionMode::NamedMaximumRegistersINTEL: return "NamedMaximumRegistersINTEL"; + default: return "Unknown"; + } +} + +inline const char* StorageClassToString(StorageClass value) { + switch (value) { + case StorageClass::UniformConstant: return "UniformConstant"; + case StorageClass::Input: return "Input"; + case StorageClass::Uniform: return "Uniform"; + case StorageClass::Output: return "Output"; + case StorageClass::Workgroup: return "Workgroup"; + case StorageClass::CrossWorkgroup: return "CrossWorkgroup"; + case StorageClass::Private: return "Private"; + case StorageClass::Function: return "Function"; + case StorageClass::Generic: return "Generic"; + case StorageClass::PushConstant: return "PushConstant"; + case StorageClass::AtomicCounter: return "AtomicCounter"; + case StorageClass::Image: return "Image"; + case StorageClass::StorageBuffer: return "StorageBuffer"; + case StorageClass::TileImageEXT: return "TileImageEXT"; + case StorageClass::TileAttachmentQCOM: return "TileAttachmentQCOM"; + case StorageClass::NodePayloadAMDX: return "NodePayloadAMDX"; + case StorageClass::CallableDataKHR: return "CallableDataKHR"; + case StorageClass::IncomingCallableDataKHR: return "IncomingCallableDataKHR"; + case StorageClass::RayPayloadKHR: return "RayPayloadKHR"; + case StorageClass::HitAttributeKHR: return "HitAttributeKHR"; + case StorageClass::IncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case StorageClass::ShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case StorageClass::PhysicalStorageBuffer: return "PhysicalStorageBuffer"; + case StorageClass::HitObjectAttributeNV: return "HitObjectAttributeNV"; + case StorageClass::TaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT"; + case StorageClass::CodeSectionINTEL: return "CodeSectionINTEL"; + case StorageClass::DeviceOnlyINTEL: return "DeviceOnlyINTEL"; + case StorageClass::HostOnlyINTEL: return "HostOnlyINTEL"; + default: return "Unknown"; + } +} + +inline const char* DimToString(Dim value) { + switch (value) { + case Dim::Dim1D: return "1D"; + case Dim::Dim2D: return "2D"; + case Dim::Dim3D: return "3D"; + case Dim::Cube: return "Cube"; + case Dim::Rect: return "Rect"; + case Dim::Buffer: return "Buffer"; + case Dim::SubpassData: return "SubpassData"; + case Dim::TileImageDataEXT: return "TileImageDataEXT"; + default: return "Unknown"; + } +} + +inline const char* SamplerAddressingModeToString(SamplerAddressingMode value) { + switch (value) { + case SamplerAddressingMode::None: return "None"; + case SamplerAddressingMode::ClampToEdge: return "ClampToEdge"; + case SamplerAddressingMode::Clamp: return "Clamp"; + case SamplerAddressingMode::Repeat: return "Repeat"; + case SamplerAddressingMode::RepeatMirrored: return "RepeatMirrored"; + default: return "Unknown"; + } +} + +inline const char* SamplerFilterModeToString(SamplerFilterMode value) { + switch (value) { + case SamplerFilterMode::Nearest: return "Nearest"; + case SamplerFilterMode::Linear: return "Linear"; + default: return "Unknown"; + } +} + +inline const char* ImageFormatToString(ImageFormat value) { + switch (value) { + case ImageFormat::Unknown: return "Unknown"; + case ImageFormat::Rgba32f: return "Rgba32f"; + case ImageFormat::Rgba16f: return "Rgba16f"; + case ImageFormat::R32f: return "R32f"; + case ImageFormat::Rgba8: return "Rgba8"; + case ImageFormat::Rgba8Snorm: return "Rgba8Snorm"; + case ImageFormat::Rg32f: return "Rg32f"; + case ImageFormat::Rg16f: return "Rg16f"; + case ImageFormat::R11fG11fB10f: return "R11fG11fB10f"; + case ImageFormat::R16f: return "R16f"; + case ImageFormat::Rgba16: return "Rgba16"; + case ImageFormat::Rgb10A2: return "Rgb10A2"; + case ImageFormat::Rg16: return "Rg16"; + case ImageFormat::Rg8: return "Rg8"; + case ImageFormat::R16: return "R16"; + case ImageFormat::R8: return "R8"; + case ImageFormat::Rgba16Snorm: return "Rgba16Snorm"; + case ImageFormat::Rg16Snorm: return "Rg16Snorm"; + case ImageFormat::Rg8Snorm: return "Rg8Snorm"; + case ImageFormat::R16Snorm: return "R16Snorm"; + case ImageFormat::R8Snorm: return "R8Snorm"; + case ImageFormat::Rgba32i: return "Rgba32i"; + case ImageFormat::Rgba16i: return "Rgba16i"; + case ImageFormat::Rgba8i: return "Rgba8i"; + case ImageFormat::R32i: return "R32i"; + case ImageFormat::Rg32i: return "Rg32i"; + case ImageFormat::Rg16i: return "Rg16i"; + case ImageFormat::Rg8i: return "Rg8i"; + case ImageFormat::R16i: return "R16i"; + case ImageFormat::R8i: return "R8i"; + case ImageFormat::Rgba32ui: return "Rgba32ui"; + case ImageFormat::Rgba16ui: return "Rgba16ui"; + case ImageFormat::Rgba8ui: return "Rgba8ui"; + case ImageFormat::R32ui: return "R32ui"; + case ImageFormat::Rgb10a2ui: return "Rgb10a2ui"; + case ImageFormat::Rg32ui: return "Rg32ui"; + case ImageFormat::Rg16ui: return "Rg16ui"; + case ImageFormat::Rg8ui: return "Rg8ui"; + case ImageFormat::R16ui: return "R16ui"; + case ImageFormat::R8ui: return "R8ui"; + case ImageFormat::R64ui: return "R64ui"; + case ImageFormat::R64i: return "R64i"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelOrderToString(ImageChannelOrder value) { + switch (value) { + case ImageChannelOrder::R: return "R"; + case ImageChannelOrder::A: return "A"; + case ImageChannelOrder::RG: return "RG"; + case ImageChannelOrder::RA: return "RA"; + case ImageChannelOrder::RGB: return "RGB"; + case ImageChannelOrder::RGBA: return "RGBA"; + case ImageChannelOrder::BGRA: return "BGRA"; + case ImageChannelOrder::ARGB: return "ARGB"; + case ImageChannelOrder::Intensity: return "Intensity"; + case ImageChannelOrder::Luminance: return "Luminance"; + case ImageChannelOrder::Rx: return "Rx"; + case ImageChannelOrder::RGx: return "RGx"; + case ImageChannelOrder::RGBx: return "RGBx"; + case ImageChannelOrder::Depth: return "Depth"; + case ImageChannelOrder::DepthStencil: return "DepthStencil"; + case ImageChannelOrder::sRGB: return "sRGB"; + case ImageChannelOrder::sRGBx: return "sRGBx"; + case ImageChannelOrder::sRGBA: return "sRGBA"; + case ImageChannelOrder::sBGRA: return "sBGRA"; + case ImageChannelOrder::ABGR: return "ABGR"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelDataTypeToString(ImageChannelDataType value) { + switch (value) { + case ImageChannelDataType::SnormInt8: return "SnormInt8"; + case ImageChannelDataType::SnormInt16: return "SnormInt16"; + case ImageChannelDataType::UnormInt8: return "UnormInt8"; + case ImageChannelDataType::UnormInt16: return "UnormInt16"; + case ImageChannelDataType::UnormShort565: return "UnormShort565"; + case ImageChannelDataType::UnormShort555: return "UnormShort555"; + case ImageChannelDataType::UnormInt101010: return "UnormInt101010"; + case ImageChannelDataType::SignedInt8: return "SignedInt8"; + case ImageChannelDataType::SignedInt16: return "SignedInt16"; + case ImageChannelDataType::SignedInt32: return "SignedInt32"; + case ImageChannelDataType::UnsignedInt8: return "UnsignedInt8"; + case ImageChannelDataType::UnsignedInt16: return "UnsignedInt16"; + case ImageChannelDataType::UnsignedInt32: return "UnsignedInt32"; + case ImageChannelDataType::HalfFloat: return "HalfFloat"; + case ImageChannelDataType::Float: return "Float"; + case ImageChannelDataType::UnormInt24: return "UnormInt24"; + case ImageChannelDataType::UnormInt101010_2: return "UnormInt101010_2"; + case ImageChannelDataType::UnsignedIntRaw10EXT: return "UnsignedIntRaw10EXT"; + case ImageChannelDataType::UnsignedIntRaw12EXT: return "UnsignedIntRaw12EXT"; + case ImageChannelDataType::UnormInt2_101010EXT: return "UnormInt2_101010EXT"; + default: return "Unknown"; + } +} + +inline const char* FPRoundingModeToString(FPRoundingMode value) { + switch (value) { + case FPRoundingMode::RTE: return "RTE"; + case FPRoundingMode::RTZ: return "RTZ"; + case FPRoundingMode::RTP: return "RTP"; + case FPRoundingMode::RTN: return "RTN"; + default: return "Unknown"; + } +} + +inline const char* LinkageTypeToString(LinkageType value) { + switch (value) { + case LinkageType::Export: return "Export"; + case LinkageType::Import: return "Import"; + case LinkageType::LinkOnceODR: return "LinkOnceODR"; + default: return "Unknown"; + } +} + +inline const char* AccessQualifierToString(AccessQualifier value) { + switch (value) { + case AccessQualifier::ReadOnly: return "ReadOnly"; + case AccessQualifier::WriteOnly: return "WriteOnly"; + case AccessQualifier::ReadWrite: return "ReadWrite"; + default: return "Unknown"; + } +} + +inline const char* FunctionParameterAttributeToString(FunctionParameterAttribute value) { + switch (value) { + case FunctionParameterAttribute::Zext: return "Zext"; + case FunctionParameterAttribute::Sext: return "Sext"; + case FunctionParameterAttribute::ByVal: return "ByVal"; + case FunctionParameterAttribute::Sret: return "Sret"; + case FunctionParameterAttribute::NoAlias: return "NoAlias"; + case FunctionParameterAttribute::NoCapture: return "NoCapture"; + case FunctionParameterAttribute::NoWrite: return "NoWrite"; + case FunctionParameterAttribute::NoReadWrite: return "NoReadWrite"; + case FunctionParameterAttribute::RuntimeAlignedINTEL: return "RuntimeAlignedINTEL"; + default: return "Unknown"; + } +} + +inline const char* DecorationToString(Decoration value) { + switch (value) { + case Decoration::RelaxedPrecision: return "RelaxedPrecision"; + case Decoration::SpecId: return "SpecId"; + case Decoration::Block: return "Block"; + case Decoration::BufferBlock: return "BufferBlock"; + case Decoration::RowMajor: return "RowMajor"; + case Decoration::ColMajor: return "ColMajor"; + case Decoration::ArrayStride: return "ArrayStride"; + case Decoration::MatrixStride: return "MatrixStride"; + case Decoration::GLSLShared: return "GLSLShared"; + case Decoration::GLSLPacked: return "GLSLPacked"; + case Decoration::CPacked: return "CPacked"; + case Decoration::BuiltIn: return "BuiltIn"; + case Decoration::NoPerspective: return "NoPerspective"; + case Decoration::Flat: return "Flat"; + case Decoration::Patch: return "Patch"; + case Decoration::Centroid: return "Centroid"; + case Decoration::Sample: return "Sample"; + case Decoration::Invariant: return "Invariant"; + case Decoration::Restrict: return "Restrict"; + case Decoration::Aliased: return "Aliased"; + case Decoration::Volatile: return "Volatile"; + case Decoration::Constant: return "Constant"; + case Decoration::Coherent: return "Coherent"; + case Decoration::NonWritable: return "NonWritable"; + case Decoration::NonReadable: return "NonReadable"; + case Decoration::Uniform: return "Uniform"; + case Decoration::UniformId: return "UniformId"; + case Decoration::SaturatedConversion: return "SaturatedConversion"; + case Decoration::Stream: return "Stream"; + case Decoration::Location: return "Location"; + case Decoration::Component: return "Component"; + case Decoration::Index: return "Index"; + case Decoration::Binding: return "Binding"; + case Decoration::DescriptorSet: return "DescriptorSet"; + case Decoration::Offset: return "Offset"; + case Decoration::XfbBuffer: return "XfbBuffer"; + case Decoration::XfbStride: return "XfbStride"; + case Decoration::FuncParamAttr: return "FuncParamAttr"; + case Decoration::FPRoundingMode: return "FPRoundingMode"; + case Decoration::FPFastMathMode: return "FPFastMathMode"; + case Decoration::LinkageAttributes: return "LinkageAttributes"; + case Decoration::NoContraction: return "NoContraction"; + case Decoration::InputAttachmentIndex: return "InputAttachmentIndex"; + case Decoration::Alignment: return "Alignment"; + case Decoration::MaxByteOffset: return "MaxByteOffset"; + case Decoration::AlignmentId: return "AlignmentId"; + case Decoration::MaxByteOffsetId: return "MaxByteOffsetId"; + case Decoration::SaturatedToLargestFloat8NormalConversionEXT: return "SaturatedToLargestFloat8NormalConversionEXT"; + case Decoration::NoSignedWrap: return "NoSignedWrap"; + case Decoration::NoUnsignedWrap: return "NoUnsignedWrap"; + case Decoration::WeightTextureQCOM: return "WeightTextureQCOM"; + case Decoration::BlockMatchTextureQCOM: return "BlockMatchTextureQCOM"; + case Decoration::BlockMatchSamplerQCOM: return "BlockMatchSamplerQCOM"; + case Decoration::ExplicitInterpAMD: return "ExplicitInterpAMD"; + case Decoration::NodeSharesPayloadLimitsWithAMDX: return "NodeSharesPayloadLimitsWithAMDX"; + case Decoration::NodeMaxPayloadsAMDX: return "NodeMaxPayloadsAMDX"; + case Decoration::TrackFinishWritingAMDX: return "TrackFinishWritingAMDX"; + case Decoration::PayloadNodeNameAMDX: return "PayloadNodeNameAMDX"; + case Decoration::PayloadNodeBaseIndexAMDX: return "PayloadNodeBaseIndexAMDX"; + case Decoration::PayloadNodeSparseArrayAMDX: return "PayloadNodeSparseArrayAMDX"; + case Decoration::PayloadNodeArraySizeAMDX: return "PayloadNodeArraySizeAMDX"; + case Decoration::PayloadDispatchIndirectAMDX: return "PayloadDispatchIndirectAMDX"; + case Decoration::OverrideCoverageNV: return "OverrideCoverageNV"; + case Decoration::PassthroughNV: return "PassthroughNV"; + case Decoration::ViewportRelativeNV: return "ViewportRelativeNV"; + case Decoration::SecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; + case Decoration::PerPrimitiveEXT: return "PerPrimitiveEXT"; + case Decoration::PerViewNV: return "PerViewNV"; + case Decoration::PerTaskNV: return "PerTaskNV"; + case Decoration::PerVertexKHR: return "PerVertexKHR"; + case Decoration::NonUniform: return "NonUniform"; + case Decoration::RestrictPointer: return "RestrictPointer"; + case Decoration::AliasedPointer: return "AliasedPointer"; + case Decoration::HitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV"; + case Decoration::BindlessSamplerNV: return "BindlessSamplerNV"; + case Decoration::BindlessImageNV: return "BindlessImageNV"; + case Decoration::BoundSamplerNV: return "BoundSamplerNV"; + case Decoration::BoundImageNV: return "BoundImageNV"; + case Decoration::SIMTCallINTEL: return "SIMTCallINTEL"; + case Decoration::ReferencedIndirectlyINTEL: return "ReferencedIndirectlyINTEL"; + case Decoration::ClobberINTEL: return "ClobberINTEL"; + case Decoration::SideEffectsINTEL: return "SideEffectsINTEL"; + case Decoration::VectorComputeVariableINTEL: return "VectorComputeVariableINTEL"; + case Decoration::FuncParamIOKindINTEL: return "FuncParamIOKindINTEL"; + case Decoration::VectorComputeFunctionINTEL: return "VectorComputeFunctionINTEL"; + case Decoration::StackCallINTEL: return "StackCallINTEL"; + case Decoration::GlobalVariableOffsetINTEL: return "GlobalVariableOffsetINTEL"; + case Decoration::CounterBuffer: return "CounterBuffer"; + case Decoration::HlslSemanticGOOGLE: return "HlslSemanticGOOGLE"; + case Decoration::UserTypeGOOGLE: return "UserTypeGOOGLE"; + case Decoration::FunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL"; + case Decoration::FunctionDenormModeINTEL: return "FunctionDenormModeINTEL"; + case Decoration::RegisterINTEL: return "RegisterINTEL"; + case Decoration::MemoryINTEL: return "MemoryINTEL"; + case Decoration::NumbanksINTEL: return "NumbanksINTEL"; + case Decoration::BankwidthINTEL: return "BankwidthINTEL"; + case Decoration::MaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL"; + case Decoration::SinglepumpINTEL: return "SinglepumpINTEL"; + case Decoration::DoublepumpINTEL: return "DoublepumpINTEL"; + case Decoration::MaxReplicatesINTEL: return "MaxReplicatesINTEL"; + case Decoration::SimpleDualPortINTEL: return "SimpleDualPortINTEL"; + case Decoration::MergeINTEL: return "MergeINTEL"; + case Decoration::BankBitsINTEL: return "BankBitsINTEL"; + case Decoration::ForcePow2DepthINTEL: return "ForcePow2DepthINTEL"; + case Decoration::StridesizeINTEL: return "StridesizeINTEL"; + case Decoration::WordsizeINTEL: return "WordsizeINTEL"; + case Decoration::TrueDualPortINTEL: return "TrueDualPortINTEL"; + case Decoration::BurstCoalesceINTEL: return "BurstCoalesceINTEL"; + case Decoration::CacheSizeINTEL: return "CacheSizeINTEL"; + case Decoration::DontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL"; + case Decoration::PrefetchINTEL: return "PrefetchINTEL"; + case Decoration::StallEnableINTEL: return "StallEnableINTEL"; + case Decoration::FuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL"; + case Decoration::MathOpDSPModeINTEL: return "MathOpDSPModeINTEL"; + case Decoration::AliasScopeINTEL: return "AliasScopeINTEL"; + case Decoration::NoAliasINTEL: return "NoAliasINTEL"; + case Decoration::InitiationIntervalINTEL: return "InitiationIntervalINTEL"; + case Decoration::MaxConcurrencyINTEL: return "MaxConcurrencyINTEL"; + case Decoration::PipelineEnableINTEL: return "PipelineEnableINTEL"; + case Decoration::BufferLocationINTEL: return "BufferLocationINTEL"; + case Decoration::IOPipeStorageINTEL: return "IOPipeStorageINTEL"; + case Decoration::FunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL"; + case Decoration::SingleElementVectorINTEL: return "SingleElementVectorINTEL"; + case Decoration::VectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL"; + case Decoration::MediaBlockIOINTEL: return "MediaBlockIOINTEL"; + case Decoration::StallFreeINTEL: return "StallFreeINTEL"; + case Decoration::FPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL"; + case Decoration::LatencyControlLabelINTEL: return "LatencyControlLabelINTEL"; + case Decoration::LatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL"; + case Decoration::ConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL"; + case Decoration::RegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL"; + case Decoration::MMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL"; + case Decoration::MMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL"; + case Decoration::MMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL"; + case Decoration::MMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL"; + case Decoration::MMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL"; + case Decoration::MMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL"; + case Decoration::StableKernelArgumentINTEL: return "StableKernelArgumentINTEL"; + case Decoration::HostAccessINTEL: return "HostAccessINTEL"; + case Decoration::InitModeINTEL: return "InitModeINTEL"; + case Decoration::ImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL"; + case Decoration::CacheControlLoadINTEL: return "CacheControlLoadINTEL"; + case Decoration::CacheControlStoreINTEL: return "CacheControlStoreINTEL"; + default: return "Unknown"; + } +} + +inline const char* BuiltInToString(BuiltIn value) { + switch (value) { + case BuiltIn::Position: return "Position"; + case BuiltIn::PointSize: return "PointSize"; + case BuiltIn::ClipDistance: return "ClipDistance"; + case BuiltIn::CullDistance: return "CullDistance"; + case BuiltIn::VertexId: return "VertexId"; + case BuiltIn::InstanceId: return "InstanceId"; + case BuiltIn::PrimitiveId: return "PrimitiveId"; + case BuiltIn::InvocationId: return "InvocationId"; + case BuiltIn::Layer: return "Layer"; + case BuiltIn::ViewportIndex: return "ViewportIndex"; + case BuiltIn::TessLevelOuter: return "TessLevelOuter"; + case BuiltIn::TessLevelInner: return "TessLevelInner"; + case BuiltIn::TessCoord: return "TessCoord"; + case BuiltIn::PatchVertices: return "PatchVertices"; + case BuiltIn::FragCoord: return "FragCoord"; + case BuiltIn::PointCoord: return "PointCoord"; + case BuiltIn::FrontFacing: return "FrontFacing"; + case BuiltIn::SampleId: return "SampleId"; + case BuiltIn::SamplePosition: return "SamplePosition"; + case BuiltIn::SampleMask: return "SampleMask"; + case BuiltIn::FragDepth: return "FragDepth"; + case BuiltIn::HelperInvocation: return "HelperInvocation"; + case BuiltIn::NumWorkgroups: return "NumWorkgroups"; + case BuiltIn::WorkgroupSize: return "WorkgroupSize"; + case BuiltIn::WorkgroupId: return "WorkgroupId"; + case BuiltIn::LocalInvocationId: return "LocalInvocationId"; + case BuiltIn::GlobalInvocationId: return "GlobalInvocationId"; + case BuiltIn::LocalInvocationIndex: return "LocalInvocationIndex"; + case BuiltIn::WorkDim: return "WorkDim"; + case BuiltIn::GlobalSize: return "GlobalSize"; + case BuiltIn::EnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case BuiltIn::GlobalOffset: return "GlobalOffset"; + case BuiltIn::GlobalLinearId: return "GlobalLinearId"; + case BuiltIn::SubgroupSize: return "SubgroupSize"; + case BuiltIn::SubgroupMaxSize: return "SubgroupMaxSize"; + case BuiltIn::NumSubgroups: return "NumSubgroups"; + case BuiltIn::NumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case BuiltIn::SubgroupId: return "SubgroupId"; + case BuiltIn::SubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + case BuiltIn::VertexIndex: return "VertexIndex"; + case BuiltIn::InstanceIndex: return "InstanceIndex"; + case BuiltIn::CoreIDARM: return "CoreIDARM"; + case BuiltIn::CoreCountARM: return "CoreCountARM"; + case BuiltIn::CoreMaxIDARM: return "CoreMaxIDARM"; + case BuiltIn::WarpIDARM: return "WarpIDARM"; + case BuiltIn::WarpMaxIDARM: return "WarpMaxIDARM"; + case BuiltIn::SubgroupEqMask: return "SubgroupEqMask"; + case BuiltIn::SubgroupGeMask: return "SubgroupGeMask"; + case BuiltIn::SubgroupGtMask: return "SubgroupGtMask"; + case BuiltIn::SubgroupLeMask: return "SubgroupLeMask"; + case BuiltIn::SubgroupLtMask: return "SubgroupLtMask"; + case BuiltIn::BaseVertex: return "BaseVertex"; + case BuiltIn::BaseInstance: return "BaseInstance"; + case BuiltIn::DrawIndex: return "DrawIndex"; + case BuiltIn::PrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + case BuiltIn::DeviceIndex: return "DeviceIndex"; + case BuiltIn::ViewIndex: return "ViewIndex"; + case BuiltIn::ShadingRateKHR: return "ShadingRateKHR"; + case BuiltIn::TileOffsetQCOM: return "TileOffsetQCOM"; + case BuiltIn::TileDimensionQCOM: return "TileDimensionQCOM"; + case BuiltIn::TileApronSizeQCOM: return "TileApronSizeQCOM"; + case BuiltIn::BaryCoordNoPerspAMD: return "BaryCoordNoPerspAMD"; + case BuiltIn::BaryCoordNoPerspCentroidAMD: return "BaryCoordNoPerspCentroidAMD"; + case BuiltIn::BaryCoordNoPerspSampleAMD: return "BaryCoordNoPerspSampleAMD"; + case BuiltIn::BaryCoordSmoothAMD: return "BaryCoordSmoothAMD"; + case BuiltIn::BaryCoordSmoothCentroidAMD: return "BaryCoordSmoothCentroidAMD"; + case BuiltIn::BaryCoordSmoothSampleAMD: return "BaryCoordSmoothSampleAMD"; + case BuiltIn::BaryCoordPullModelAMD: return "BaryCoordPullModelAMD"; + case BuiltIn::FragStencilRefEXT: return "FragStencilRefEXT"; + case BuiltIn::RemainingRecursionLevelsAMDX: return "RemainingRecursionLevelsAMDX"; + case BuiltIn::ShaderIndexAMDX: return "ShaderIndexAMDX"; + case BuiltIn::ViewportMaskNV: return "ViewportMaskNV"; + case BuiltIn::SecondaryPositionNV: return "SecondaryPositionNV"; + case BuiltIn::SecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case BuiltIn::PositionPerViewNV: return "PositionPerViewNV"; + case BuiltIn::ViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case BuiltIn::FullyCoveredEXT: return "FullyCoveredEXT"; + case BuiltIn::TaskCountNV: return "TaskCountNV"; + case BuiltIn::PrimitiveCountNV: return "PrimitiveCountNV"; + case BuiltIn::PrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case BuiltIn::ClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case BuiltIn::CullDistancePerViewNV: return "CullDistancePerViewNV"; + case BuiltIn::LayerPerViewNV: return "LayerPerViewNV"; + case BuiltIn::MeshViewCountNV: return "MeshViewCountNV"; + case BuiltIn::MeshViewIndicesNV: return "MeshViewIndicesNV"; + case BuiltIn::BaryCoordKHR: return "BaryCoordKHR"; + case BuiltIn::BaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR"; + case BuiltIn::FragSizeEXT: return "FragSizeEXT"; + case BuiltIn::FragInvocationCountEXT: return "FragInvocationCountEXT"; + case BuiltIn::PrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case BuiltIn::PrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case BuiltIn::PrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case BuiltIn::CullPrimitiveEXT: return "CullPrimitiveEXT"; + case BuiltIn::LaunchIdKHR: return "LaunchIdKHR"; + case BuiltIn::LaunchSizeKHR: return "LaunchSizeKHR"; + case BuiltIn::WorldRayOriginKHR: return "WorldRayOriginKHR"; + case BuiltIn::WorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case BuiltIn::ObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case BuiltIn::ObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case BuiltIn::RayTminKHR: return "RayTminKHR"; + case BuiltIn::RayTmaxKHR: return "RayTmaxKHR"; + case BuiltIn::InstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case BuiltIn::ObjectToWorldKHR: return "ObjectToWorldKHR"; + case BuiltIn::WorldToObjectKHR: return "WorldToObjectKHR"; + case BuiltIn::HitTNV: return "HitTNV"; + case BuiltIn::HitKindKHR: return "HitKindKHR"; + case BuiltIn::CurrentRayTimeNV: return "CurrentRayTimeNV"; + case BuiltIn::HitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR"; + case BuiltIn::HitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV"; + case BuiltIn::HitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV"; + case BuiltIn::IncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case BuiltIn::RayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case BuiltIn::HitIsSphereNV: return "HitIsSphereNV"; + case BuiltIn::HitIsLSSNV: return "HitIsLSSNV"; + case BuiltIn::HitSpherePositionNV: return "HitSpherePositionNV"; + case BuiltIn::WarpsPerSMNV: return "WarpsPerSMNV"; + case BuiltIn::SMCountNV: return "SMCountNV"; + case BuiltIn::WarpIDNV: return "WarpIDNV"; + case BuiltIn::SMIDNV: return "SMIDNV"; + case BuiltIn::HitLSSPositionsNV: return "HitLSSPositionsNV"; + case BuiltIn::HitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case BuiltIn::HitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; + case BuiltIn::HitSphereRadiusNV: return "HitSphereRadiusNV"; + case BuiltIn::HitLSSRadiiNV: return "HitLSSRadiiNV"; + case BuiltIn::ClusterIDNV: return "ClusterIDNV"; + case BuiltIn::CullMaskKHR: return "CullMaskKHR"; + default: return "Unknown"; + } +} + +inline const char* ScopeToString(Scope value) { + switch (value) { + case Scope::CrossDevice: return "CrossDevice"; + case Scope::Device: return "Device"; + case Scope::Workgroup: return "Workgroup"; + case Scope::Subgroup: return "Subgroup"; + case Scope::Invocation: return "Invocation"; + case Scope::QueueFamily: return "QueueFamily"; + case Scope::ShaderCallKHR: return "ShaderCallKHR"; + default: return "Unknown"; + } +} + +inline const char* GroupOperationToString(GroupOperation value) { + switch (value) { + case GroupOperation::Reduce: return "Reduce"; + case GroupOperation::InclusiveScan: return "InclusiveScan"; + case GroupOperation::ExclusiveScan: return "ExclusiveScan"; + case GroupOperation::ClusteredReduce: return "ClusteredReduce"; + case GroupOperation::PartitionedReduceNV: return "PartitionedReduceNV"; + case GroupOperation::PartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; + case GroupOperation::PartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; + default: return "Unknown"; + } +} + +inline const char* KernelEnqueueFlagsToString(KernelEnqueueFlags value) { + switch (value) { + case KernelEnqueueFlags::NoWait: return "NoWait"; + case KernelEnqueueFlags::WaitKernel: return "WaitKernel"; + case KernelEnqueueFlags::WaitWorkGroup: return "WaitWorkGroup"; + default: return "Unknown"; + } +} + +inline const char* CapabilityToString(Capability value) { + switch (value) { + case Capability::Matrix: return "Matrix"; + case Capability::Shader: return "Shader"; + case Capability::Geometry: return "Geometry"; + case Capability::Tessellation: return "Tessellation"; + case Capability::Addresses: return "Addresses"; + case Capability::Linkage: return "Linkage"; + case Capability::Kernel: return "Kernel"; + case Capability::Vector16: return "Vector16"; + case Capability::Float16Buffer: return "Float16Buffer"; + case Capability::Float16: return "Float16"; + case Capability::Float64: return "Float64"; + case Capability::Int64: return "Int64"; + case Capability::Int64Atomics: return "Int64Atomics"; + case Capability::ImageBasic: return "ImageBasic"; + case Capability::ImageReadWrite: return "ImageReadWrite"; + case Capability::ImageMipmap: return "ImageMipmap"; + case Capability::Pipes: return "Pipes"; + case Capability::Groups: return "Groups"; + case Capability::DeviceEnqueue: return "DeviceEnqueue"; + case Capability::LiteralSampler: return "LiteralSampler"; + case Capability::AtomicStorage: return "AtomicStorage"; + case Capability::Int16: return "Int16"; + case Capability::TessellationPointSize: return "TessellationPointSize"; + case Capability::GeometryPointSize: return "GeometryPointSize"; + case Capability::ImageGatherExtended: return "ImageGatherExtended"; + case Capability::StorageImageMultisample: return "StorageImageMultisample"; + case Capability::UniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; + case Capability::SampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; + case Capability::StorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; + case Capability::StorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; + case Capability::ClipDistance: return "ClipDistance"; + case Capability::CullDistance: return "CullDistance"; + case Capability::ImageCubeArray: return "ImageCubeArray"; + case Capability::SampleRateShading: return "SampleRateShading"; + case Capability::ImageRect: return "ImageRect"; + case Capability::SampledRect: return "SampledRect"; + case Capability::GenericPointer: return "GenericPointer"; + case Capability::Int8: return "Int8"; + case Capability::InputAttachment: return "InputAttachment"; + case Capability::SparseResidency: return "SparseResidency"; + case Capability::MinLod: return "MinLod"; + case Capability::Sampled1D: return "Sampled1D"; + case Capability::Image1D: return "Image1D"; + case Capability::SampledCubeArray: return "SampledCubeArray"; + case Capability::SampledBuffer: return "SampledBuffer"; + case Capability::ImageBuffer: return "ImageBuffer"; + case Capability::ImageMSArray: return "ImageMSArray"; + case Capability::StorageImageExtendedFormats: return "StorageImageExtendedFormats"; + case Capability::ImageQuery: return "ImageQuery"; + case Capability::DerivativeControl: return "DerivativeControl"; + case Capability::InterpolationFunction: return "InterpolationFunction"; + case Capability::TransformFeedback: return "TransformFeedback"; + case Capability::GeometryStreams: return "GeometryStreams"; + case Capability::StorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; + case Capability::StorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; + case Capability::MultiViewport: return "MultiViewport"; + case Capability::SubgroupDispatch: return "SubgroupDispatch"; + case Capability::NamedBarrier: return "NamedBarrier"; + case Capability::PipeStorage: return "PipeStorage"; + case Capability::GroupNonUniform: return "GroupNonUniform"; + case Capability::GroupNonUniformVote: return "GroupNonUniformVote"; + case Capability::GroupNonUniformArithmetic: return "GroupNonUniformArithmetic"; + case Capability::GroupNonUniformBallot: return "GroupNonUniformBallot"; + case Capability::GroupNonUniformShuffle: return "GroupNonUniformShuffle"; + case Capability::GroupNonUniformShuffleRelative: return "GroupNonUniformShuffleRelative"; + case Capability::GroupNonUniformClustered: return "GroupNonUniformClustered"; + case Capability::GroupNonUniformQuad: return "GroupNonUniformQuad"; + case Capability::ShaderLayer: return "ShaderLayer"; + case Capability::ShaderViewportIndex: return "ShaderViewportIndex"; + case Capability::UniformDecoration: return "UniformDecoration"; + case Capability::CoreBuiltinsARM: return "CoreBuiltinsARM"; + case Capability::TileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; + case Capability::TileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; + case Capability::TileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case Capability::TensorsARM: return "TensorsARM"; + case Capability::CooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM"; + case Capability::Float8EXT: return "Float8EXT"; + case Capability::Float8CooperativeMatrixEXT: return "Float8CooperativeMatrixEXT"; + case Capability::FragmentShadingRateKHR: return "FragmentShadingRateKHR"; + case Capability::SubgroupBallotKHR: return "SubgroupBallotKHR"; + case Capability::DrawParameters: return "DrawParameters"; + case Capability::WorkgroupMemoryExplicitLayoutKHR: return "WorkgroupMemoryExplicitLayoutKHR"; + case Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR: return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; + case Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR: return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; + case Capability::SubgroupVoteKHR: return "SubgroupVoteKHR"; + case Capability::StorageBuffer16BitAccess: return "StorageBuffer16BitAccess"; + case Capability::StorageUniform16: return "StorageUniform16"; + case Capability::StoragePushConstant16: return "StoragePushConstant16"; + case Capability::StorageInputOutput16: return "StorageInputOutput16"; + case Capability::DeviceGroup: return "DeviceGroup"; + case Capability::MultiView: return "MultiView"; + case Capability::VariablePointersStorageBuffer: return "VariablePointersStorageBuffer"; + case Capability::VariablePointers: return "VariablePointers"; + case Capability::AtomicStorageOps: return "AtomicStorageOps"; + case Capability::SampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; + case Capability::StorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case Capability::UniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case Capability::StoragePushConstant8: return "StoragePushConstant8"; + case Capability::DenormPreserve: return "DenormPreserve"; + case Capability::DenormFlushToZero: return "DenormFlushToZero"; + case Capability::SignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case Capability::RoundingModeRTE: return "RoundingModeRTE"; + case Capability::RoundingModeRTZ: return "RoundingModeRTZ"; + case Capability::RayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; + case Capability::RayQueryKHR: return "RayQueryKHR"; + case Capability::UntypedPointersKHR: return "UntypedPointersKHR"; + case Capability::RayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; + case Capability::RayTracingKHR: return "RayTracingKHR"; + case Capability::TextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; + case Capability::TextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; + case Capability::TextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; + case Capability::TileShadingQCOM: return "TileShadingQCOM"; + case Capability::CooperativeMatrixConversionQCOM: return "CooperativeMatrixConversionQCOM"; + case Capability::TextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; + case Capability::Float16ImageAMD: return "Float16ImageAMD"; + case Capability::ImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; + case Capability::FragmentMaskAMD: return "FragmentMaskAMD"; + case Capability::StencilExportEXT: return "StencilExportEXT"; + case Capability::ImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case Capability::Int64ImageEXT: return "Int64ImageEXT"; + case Capability::ShaderClockKHR: return "ShaderClockKHR"; + case Capability::ShaderEnqueueAMDX: return "ShaderEnqueueAMDX"; + case Capability::QuadControlKHR: return "QuadControlKHR"; + case Capability::BFloat16TypeKHR: return "BFloat16TypeKHR"; + case Capability::BFloat16DotProductKHR: return "BFloat16DotProductKHR"; + case Capability::BFloat16CooperativeMatrixKHR: return "BFloat16CooperativeMatrixKHR"; + case Capability::SampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; + case Capability::GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case Capability::ShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; + case Capability::ShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case Capability::ShaderStereoViewNV: return "ShaderStereoViewNV"; + case Capability::PerViewAttributesNV: return "PerViewAttributesNV"; + case Capability::FragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; + case Capability::MeshShadingNV: return "MeshShadingNV"; + case Capability::ImageFootprintNV: return "ImageFootprintNV"; + case Capability::MeshShadingEXT: return "MeshShadingEXT"; + case Capability::FragmentBarycentricKHR: return "FragmentBarycentricKHR"; + case Capability::ComputeDerivativeGroupQuadsKHR: return "ComputeDerivativeGroupQuadsKHR"; + case Capability::FragmentDensityEXT: return "FragmentDensityEXT"; + case Capability::GroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; + case Capability::ShaderNonUniform: return "ShaderNonUniform"; + case Capability::RuntimeDescriptorArray: return "RuntimeDescriptorArray"; + case Capability::InputAttachmentArrayDynamicIndexing: return "InputAttachmentArrayDynamicIndexing"; + case Capability::UniformTexelBufferArrayDynamicIndexing: return "UniformTexelBufferArrayDynamicIndexing"; + case Capability::StorageTexelBufferArrayDynamicIndexing: return "StorageTexelBufferArrayDynamicIndexing"; + case Capability::UniformBufferArrayNonUniformIndexing: return "UniformBufferArrayNonUniformIndexing"; + case Capability::SampledImageArrayNonUniformIndexing: return "SampledImageArrayNonUniformIndexing"; + case Capability::StorageBufferArrayNonUniformIndexing: return "StorageBufferArrayNonUniformIndexing"; + case Capability::StorageImageArrayNonUniformIndexing: return "StorageImageArrayNonUniformIndexing"; + case Capability::InputAttachmentArrayNonUniformIndexing: return "InputAttachmentArrayNonUniformIndexing"; + case Capability::UniformTexelBufferArrayNonUniformIndexing: return "UniformTexelBufferArrayNonUniformIndexing"; + case Capability::StorageTexelBufferArrayNonUniformIndexing: return "StorageTexelBufferArrayNonUniformIndexing"; + case Capability::RayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR"; + case Capability::RayTracingNV: return "RayTracingNV"; + case Capability::RayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; + case Capability::VulkanMemoryModel: return "VulkanMemoryModel"; + case Capability::VulkanMemoryModelDeviceScope: return "VulkanMemoryModelDeviceScope"; + case Capability::PhysicalStorageBufferAddresses: return "PhysicalStorageBufferAddresses"; + case Capability::ComputeDerivativeGroupLinearKHR: return "ComputeDerivativeGroupLinearKHR"; + case Capability::RayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case Capability::CooperativeMatrixNV: return "CooperativeMatrixNV"; + case Capability::FragmentShaderSampleInterlockEXT: return "FragmentShaderSampleInterlockEXT"; + case Capability::FragmentShaderShadingRateInterlockEXT: return "FragmentShaderShadingRateInterlockEXT"; + case Capability::ShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + case Capability::FragmentShaderPixelInterlockEXT: return "FragmentShaderPixelInterlockEXT"; + case Capability::DemoteToHelperInvocation: return "DemoteToHelperInvocation"; + case Capability::DisplacementMicromapNV: return "DisplacementMicromapNV"; + case Capability::RayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT"; + case Capability::ShaderInvocationReorderNV: return "ShaderInvocationReorderNV"; + case Capability::BindlessTextureNV: return "BindlessTextureNV"; + case Capability::RayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR"; + case Capability::CooperativeVectorNV: return "CooperativeVectorNV"; + case Capability::AtomicFloat16VectorNV: return "AtomicFloat16VectorNV"; + case Capability::RayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV"; + case Capability::RawAccessChainsNV: return "RawAccessChainsNV"; + case Capability::RayTracingSpheresGeometryNV: return "RayTracingSpheresGeometryNV"; + case Capability::RayTracingLinearSweptSpheresGeometryNV: return "RayTracingLinearSweptSpheresGeometryNV"; + case Capability::CooperativeMatrixReductionsNV: return "CooperativeMatrixReductionsNV"; + case Capability::CooperativeMatrixConversionsNV: return "CooperativeMatrixConversionsNV"; + case Capability::CooperativeMatrixPerElementOperationsNV: return "CooperativeMatrixPerElementOperationsNV"; + case Capability::CooperativeMatrixTensorAddressingNV: return "CooperativeMatrixTensorAddressingNV"; + case Capability::CooperativeMatrixBlockLoadsNV: return "CooperativeMatrixBlockLoadsNV"; + case Capability::CooperativeVectorTrainingNV: return "CooperativeVectorTrainingNV"; + case Capability::RayTracingClusterAccelerationStructureNV: return "RayTracingClusterAccelerationStructureNV"; + case Capability::TensorAddressingNV: return "TensorAddressingNV"; + case Capability::SubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; + case Capability::SubgroupBufferBlockIOINTEL: return "SubgroupBufferBlockIOINTEL"; + case Capability::SubgroupImageBlockIOINTEL: return "SubgroupImageBlockIOINTEL"; + case Capability::SubgroupImageMediaBlockIOINTEL: return "SubgroupImageMediaBlockIOINTEL"; + case Capability::RoundToInfinityINTEL: return "RoundToInfinityINTEL"; + case Capability::FloatingPointModeINTEL: return "FloatingPointModeINTEL"; + case Capability::IntegerFunctions2INTEL: return "IntegerFunctions2INTEL"; + case Capability::FunctionPointersINTEL: return "FunctionPointersINTEL"; + case Capability::IndirectReferencesINTEL: return "IndirectReferencesINTEL"; + case Capability::AsmINTEL: return "AsmINTEL"; + case Capability::AtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; + case Capability::AtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; + case Capability::AtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; + case Capability::VectorComputeINTEL: return "VectorComputeINTEL"; + case Capability::VectorAnyINTEL: return "VectorAnyINTEL"; + case Capability::ExpectAssumeKHR: return "ExpectAssumeKHR"; + case Capability::SubgroupAvcMotionEstimationINTEL: return "SubgroupAvcMotionEstimationINTEL"; + case Capability::SubgroupAvcMotionEstimationIntraINTEL: return "SubgroupAvcMotionEstimationIntraINTEL"; + case Capability::SubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL"; + case Capability::VariableLengthArrayINTEL: return "VariableLengthArrayINTEL"; + case Capability::FunctionFloatControlINTEL: return "FunctionFloatControlINTEL"; + case Capability::FPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL"; + case Capability::FPFastMathModeINTEL: return "FPFastMathModeINTEL"; + case Capability::ArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL"; + case Capability::ArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL"; + case Capability::UnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL"; + case Capability::FPGALoopControlsINTEL: return "FPGALoopControlsINTEL"; + case Capability::KernelAttributesINTEL: return "KernelAttributesINTEL"; + case Capability::FPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL"; + case Capability::FPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL"; + case Capability::FPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL"; + case Capability::LoopFuseINTEL: return "LoopFuseINTEL"; + case Capability::FPGADSPControlINTEL: return "FPGADSPControlINTEL"; + case Capability::MemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL"; + case Capability::FPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL"; + case Capability::FPGABufferLocationINTEL: return "FPGABufferLocationINTEL"; + case Capability::ArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL"; + case Capability::USMStorageClassesINTEL: return "USMStorageClassesINTEL"; + case Capability::RuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL"; + case Capability::IOPipesINTEL: return "IOPipesINTEL"; + case Capability::BlockingPipesINTEL: return "BlockingPipesINTEL"; + case Capability::FPGARegINTEL: return "FPGARegINTEL"; + case Capability::DotProductInputAll: return "DotProductInputAll"; + case Capability::DotProductInput4x8Bit: return "DotProductInput4x8Bit"; + case Capability::DotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked"; + case Capability::DotProduct: return "DotProduct"; + case Capability::RayCullMaskKHR: return "RayCullMaskKHR"; + case Capability::CooperativeMatrixKHR: return "CooperativeMatrixKHR"; + case Capability::ReplicatedCompositesEXT: return "ReplicatedCompositesEXT"; + case Capability::BitInstructions: return "BitInstructions"; + case Capability::GroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR"; + case Capability::FloatControls2: return "FloatControls2"; + case Capability::AtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case Capability::AtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + case Capability::LongCompositesINTEL: return "LongCompositesINTEL"; + case Capability::OptNoneEXT: return "OptNoneEXT"; + case Capability::AtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; + case Capability::DebugInfoModuleINTEL: return "DebugInfoModuleINTEL"; + case Capability::BFloat16ConversionINTEL: return "BFloat16ConversionINTEL"; + case Capability::SplitBarrierINTEL: return "SplitBarrierINTEL"; + case Capability::ArithmeticFenceEXT: return "ArithmeticFenceEXT"; + case Capability::FPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL"; + case Capability::FPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL"; + case Capability::FPMaxErrorINTEL: return "FPMaxErrorINTEL"; + case Capability::FPGALatencyControlINTEL: return "FPGALatencyControlINTEL"; + case Capability::FPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL"; + case Capability::GlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL"; + case Capability::GlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL"; + case Capability::SubgroupBufferPrefetchINTEL: return "SubgroupBufferPrefetchINTEL"; + case Capability::Subgroup2DBlockIOINTEL: return "Subgroup2DBlockIOINTEL"; + case Capability::Subgroup2DBlockTransformINTEL: return "Subgroup2DBlockTransformINTEL"; + case Capability::Subgroup2DBlockTransposeINTEL: return "Subgroup2DBlockTransposeINTEL"; + case Capability::SubgroupMatrixMultiplyAccumulateINTEL: return "SubgroupMatrixMultiplyAccumulateINTEL"; + case Capability::GroupUniformArithmeticKHR: return "GroupUniformArithmeticKHR"; + case Capability::MaskedGatherScatterINTEL: return "MaskedGatherScatterINTEL"; + case Capability::CacheControlsINTEL: return "CacheControlsINTEL"; + case Capability::RegisterLimitsINTEL: return "RegisterLimitsINTEL"; + default: return "Unknown"; + } +} + +inline const char* RayQueryIntersectionToString(RayQueryIntersection value) { + switch (value) { + case RayQueryIntersection::RayQueryCandidateIntersectionKHR: return "RayQueryCandidateIntersectionKHR"; + case RayQueryIntersection::RayQueryCommittedIntersectionKHR: return "RayQueryCommittedIntersectionKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCommittedIntersectionTypeToString(RayQueryCommittedIntersectionType value) { + switch (value) { + case RayQueryCommittedIntersectionType::RayQueryCommittedIntersectionNoneKHR: return "RayQueryCommittedIntersectionNoneKHR"; + case RayQueryCommittedIntersectionType::RayQueryCommittedIntersectionTriangleKHR: return "RayQueryCommittedIntersectionTriangleKHR"; + case RayQueryCommittedIntersectionType::RayQueryCommittedIntersectionGeneratedKHR: return "RayQueryCommittedIntersectionGeneratedKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCandidateIntersectionTypeToString(RayQueryCandidateIntersectionType value) { + switch (value) { + case RayQueryCandidateIntersectionType::RayQueryCandidateIntersectionTriangleKHR: return "RayQueryCandidateIntersectionTriangleKHR"; + case RayQueryCandidateIntersectionType::RayQueryCandidateIntersectionAABBKHR: return "RayQueryCandidateIntersectionAABBKHR"; + default: return "Unknown"; + } +} + +inline const char* FPDenormModeToString(FPDenormMode value) { + switch (value) { + case FPDenormMode::Preserve: return "Preserve"; + case FPDenormMode::FlushToZero: return "FlushToZero"; + default: return "Unknown"; + } +} + +inline const char* FPOperationModeToString(FPOperationMode value) { + switch (value) { + case FPOperationMode::IEEE: return "IEEE"; + case FPOperationMode::ALT: return "ALT"; + default: return "Unknown"; + } +} + +inline const char* QuantizationModesToString(QuantizationModes value) { + switch (value) { + case QuantizationModes::TRN: return "TRN"; + case QuantizationModes::TRN_ZERO: return "TRN_ZERO"; + case QuantizationModes::RND: return "RND"; + case QuantizationModes::RND_ZERO: return "RND_ZERO"; + case QuantizationModes::RND_INF: return "RND_INF"; + case QuantizationModes::RND_MIN_INF: return "RND_MIN_INF"; + case QuantizationModes::RND_CONV: return "RND_CONV"; + case QuantizationModes::RND_CONV_ODD: return "RND_CONV_ODD"; + default: return "Unknown"; + } +} + +inline const char* OverflowModesToString(OverflowModes value) { + switch (value) { + case OverflowModes::WRAP: return "WRAP"; + case OverflowModes::SAT: return "SAT"; + case OverflowModes::SAT_ZERO: return "SAT_ZERO"; + case OverflowModes::SAT_SYM: return "SAT_SYM"; + default: return "Unknown"; + } +} + +inline const char* PackedVectorFormatToString(PackedVectorFormat value) { + switch (value) { + case PackedVectorFormat::PackedVectorFormat4x8Bit: return "PackedVectorFormat4x8Bit"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixLayoutToString(CooperativeMatrixLayout value) { + switch (value) { + case CooperativeMatrixLayout::RowMajorKHR: return "RowMajorKHR"; + case CooperativeMatrixLayout::ColumnMajorKHR: return "ColumnMajorKHR"; + case CooperativeMatrixLayout::RowBlockedInterleavedARM: return "RowBlockedInterleavedARM"; + case CooperativeMatrixLayout::ColumnBlockedInterleavedARM: return "ColumnBlockedInterleavedARM"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixUseToString(CooperativeMatrixUse value) { + switch (value) { + case CooperativeMatrixUse::MatrixAKHR: return "MatrixAKHR"; + case CooperativeMatrixUse::MatrixBKHR: return "MatrixBKHR"; + case CooperativeMatrixUse::MatrixAccumulatorKHR: return "MatrixAccumulatorKHR"; + default: return "Unknown"; + } +} + +inline const char* TensorClampModeToString(TensorClampMode value) { + switch (value) { + case TensorClampMode::Undefined: return "Undefined"; + case TensorClampMode::Constant: return "Constant"; + case TensorClampMode::ClampToEdge: return "ClampToEdge"; + case TensorClampMode::Repeat: return "Repeat"; + case TensorClampMode::RepeatMirrored: return "RepeatMirrored"; + default: return "Unknown"; + } +} + +inline const char* InitializationModeQualifierToString(InitializationModeQualifier value) { + switch (value) { + case InitializationModeQualifier::InitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL"; + case InitializationModeQualifier::InitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL"; + default: return "Unknown"; + } +} + +inline const char* HostAccessQualifierToString(HostAccessQualifier value) { + switch (value) { + case HostAccessQualifier::NoneINTEL: return "NoneINTEL"; + case HostAccessQualifier::ReadINTEL: return "ReadINTEL"; + case HostAccessQualifier::WriteINTEL: return "WriteINTEL"; + case HostAccessQualifier::ReadWriteINTEL: return "ReadWriteINTEL"; + default: return "Unknown"; + } +} + +inline const char* LoadCacheControlToString(LoadCacheControl value) { + switch (value) { + case LoadCacheControl::UncachedINTEL: return "UncachedINTEL"; + case LoadCacheControl::CachedINTEL: return "CachedINTEL"; + case LoadCacheControl::StreamingINTEL: return "StreamingINTEL"; + case LoadCacheControl::InvalidateAfterReadINTEL: return "InvalidateAfterReadINTEL"; + case LoadCacheControl::ConstCachedINTEL: return "ConstCachedINTEL"; + default: return "Unknown"; + } +} + +inline const char* StoreCacheControlToString(StoreCacheControl value) { + switch (value) { + case StoreCacheControl::UncachedINTEL: return "UncachedINTEL"; + case StoreCacheControl::WriteThroughINTEL: return "WriteThroughINTEL"; + case StoreCacheControl::WriteBackINTEL: return "WriteBackINTEL"; + case StoreCacheControl::StreamingINTEL: return "StreamingINTEL"; + default: return "Unknown"; + } +} + +inline const char* NamedMaximumNumberOfRegistersToString(NamedMaximumNumberOfRegisters value) { + switch (value) { + case NamedMaximumNumberOfRegisters::AutoINTEL: return "AutoINTEL"; + default: return "Unknown"; + } +} + +inline const char* FPEncodingToString(FPEncoding value) { + switch (value) { + case FPEncoding::BFloat16KHR: return "BFloat16KHR"; + case FPEncoding::Float8E4M3EXT: return "Float8E4M3EXT"; + case FPEncoding::Float8E5M2EXT: return "Float8E5M2EXT"; + default: return "Unknown"; + } +} + +inline const char* CooperativeVectorMatrixLayoutToString(CooperativeVectorMatrixLayout value) { + switch (value) { + case CooperativeVectorMatrixLayout::RowMajorNV: return "RowMajorNV"; + case CooperativeVectorMatrixLayout::ColumnMajorNV: return "ColumnMajorNV"; + case CooperativeVectorMatrixLayout::InferencingOptimalNV: return "InferencingOptimalNV"; + case CooperativeVectorMatrixLayout::TrainingOptimalNV: return "TrainingOptimalNV"; + default: return "Unknown"; + } +} + +inline const char* ComponentTypeToString(ComponentType value) { + switch (value) { + case ComponentType::Float16NV: return "Float16NV"; + case ComponentType::Float32NV: return "Float32NV"; + case ComponentType::Float64NV: return "Float64NV"; + case ComponentType::SignedInt8NV: return "SignedInt8NV"; + case ComponentType::SignedInt16NV: return "SignedInt16NV"; + case ComponentType::SignedInt32NV: return "SignedInt32NV"; + case ComponentType::SignedInt64NV: return "SignedInt64NV"; + case ComponentType::UnsignedInt8NV: return "UnsignedInt8NV"; + case ComponentType::UnsignedInt16NV: return "UnsignedInt16NV"; + case ComponentType::UnsignedInt32NV: return "UnsignedInt32NV"; + case ComponentType::UnsignedInt64NV: return "UnsignedInt64NV"; + case ComponentType::SignedInt8PackedNV: return "SignedInt8PackedNV"; + case ComponentType::UnsignedInt8PackedNV: return "UnsignedInt8PackedNV"; + case ComponentType::FloatE4M3NV: return "FloatE4M3NV"; + case ComponentType::FloatE5M2NV: return "FloatE5M2NV"; + default: return "Unknown"; + } +} + +inline const char* OpToString(Op value) { + switch (value) { + case Op::OpNop: return "OpNop"; + case Op::OpUndef: return "OpUndef"; + case Op::OpSourceContinued: return "OpSourceContinued"; + case Op::OpSource: return "OpSource"; + case Op::OpSourceExtension: return "OpSourceExtension"; + case Op::OpName: return "OpName"; + case Op::OpMemberName: return "OpMemberName"; + case Op::OpString: return "OpString"; + case Op::OpLine: return "OpLine"; + case Op::OpExtension: return "OpExtension"; + case Op::OpExtInstImport: return "OpExtInstImport"; + case Op::OpExtInst: return "OpExtInst"; + case Op::OpMemoryModel: return "OpMemoryModel"; + case Op::OpEntryPoint: return "OpEntryPoint"; + case Op::OpExecutionMode: return "OpExecutionMode"; + case Op::OpCapability: return "OpCapability"; + case Op::OpTypeVoid: return "OpTypeVoid"; + case Op::OpTypeBool: return "OpTypeBool"; + case Op::OpTypeInt: return "OpTypeInt"; + case Op::OpTypeFloat: return "OpTypeFloat"; + case Op::OpTypeVector: return "OpTypeVector"; + case Op::OpTypeMatrix: return "OpTypeMatrix"; + case Op::OpTypeImage: return "OpTypeImage"; + case Op::OpTypeSampler: return "OpTypeSampler"; + case Op::OpTypeSampledImage: return "OpTypeSampledImage"; + case Op::OpTypeArray: return "OpTypeArray"; + case Op::OpTypeRuntimeArray: return "OpTypeRuntimeArray"; + case Op::OpTypeStruct: return "OpTypeStruct"; + case Op::OpTypeOpaque: return "OpTypeOpaque"; + case Op::OpTypePointer: return "OpTypePointer"; + case Op::OpTypeFunction: return "OpTypeFunction"; + case Op::OpTypeEvent: return "OpTypeEvent"; + case Op::OpTypeDeviceEvent: return "OpTypeDeviceEvent"; + case Op::OpTypeReserveId: return "OpTypeReserveId"; + case Op::OpTypeQueue: return "OpTypeQueue"; + case Op::OpTypePipe: return "OpTypePipe"; + case Op::OpTypeForwardPointer: return "OpTypeForwardPointer"; + case Op::OpConstantTrue: return "OpConstantTrue"; + case Op::OpConstantFalse: return "OpConstantFalse"; + case Op::OpConstant: return "OpConstant"; + case Op::OpConstantComposite: return "OpConstantComposite"; + case Op::OpConstantSampler: return "OpConstantSampler"; + case Op::OpConstantNull: return "OpConstantNull"; + case Op::OpSpecConstantTrue: return "OpSpecConstantTrue"; + case Op::OpSpecConstantFalse: return "OpSpecConstantFalse"; + case Op::OpSpecConstant: return "OpSpecConstant"; + case Op::OpSpecConstantComposite: return "OpSpecConstantComposite"; + case Op::OpSpecConstantOp: return "OpSpecConstantOp"; + case Op::OpFunction: return "OpFunction"; + case Op::OpFunctionParameter: return "OpFunctionParameter"; + case Op::OpFunctionEnd: return "OpFunctionEnd"; + case Op::OpFunctionCall: return "OpFunctionCall"; + case Op::OpVariable: return "OpVariable"; + case Op::OpImageTexelPointer: return "OpImageTexelPointer"; + case Op::OpLoad: return "OpLoad"; + case Op::OpStore: return "OpStore"; + case Op::OpCopyMemory: return "OpCopyMemory"; + case Op::OpCopyMemorySized: return "OpCopyMemorySized"; + case Op::OpAccessChain: return "OpAccessChain"; + case Op::OpInBoundsAccessChain: return "OpInBoundsAccessChain"; + case Op::OpPtrAccessChain: return "OpPtrAccessChain"; + case Op::OpArrayLength: return "OpArrayLength"; + case Op::OpGenericPtrMemSemantics: return "OpGenericPtrMemSemantics"; + case Op::OpInBoundsPtrAccessChain: return "OpInBoundsPtrAccessChain"; + case Op::OpDecorate: return "OpDecorate"; + case Op::OpMemberDecorate: return "OpMemberDecorate"; + case Op::OpDecorationGroup: return "OpDecorationGroup"; + case Op::OpGroupDecorate: return "OpGroupDecorate"; + case Op::OpGroupMemberDecorate: return "OpGroupMemberDecorate"; + case Op::OpVectorExtractDynamic: return "OpVectorExtractDynamic"; + case Op::OpVectorInsertDynamic: return "OpVectorInsertDynamic"; + case Op::OpVectorShuffle: return "OpVectorShuffle"; + case Op::OpCompositeConstruct: return "OpCompositeConstruct"; + case Op::OpCompositeExtract: return "OpCompositeExtract"; + case Op::OpCompositeInsert: return "OpCompositeInsert"; + case Op::OpCopyObject: return "OpCopyObject"; + case Op::OpTranspose: return "OpTranspose"; + case Op::OpSampledImage: return "OpSampledImage"; + case Op::OpImageSampleImplicitLod: return "OpImageSampleImplicitLod"; + case Op::OpImageSampleExplicitLod: return "OpImageSampleExplicitLod"; + case Op::OpImageSampleDrefImplicitLod: return "OpImageSampleDrefImplicitLod"; + case Op::OpImageSampleDrefExplicitLod: return "OpImageSampleDrefExplicitLod"; + case Op::OpImageSampleProjImplicitLod: return "OpImageSampleProjImplicitLod"; + case Op::OpImageSampleProjExplicitLod: return "OpImageSampleProjExplicitLod"; + case Op::OpImageSampleProjDrefImplicitLod: return "OpImageSampleProjDrefImplicitLod"; + case Op::OpImageSampleProjDrefExplicitLod: return "OpImageSampleProjDrefExplicitLod"; + case Op::OpImageFetch: return "OpImageFetch"; + case Op::OpImageGather: return "OpImageGather"; + case Op::OpImageDrefGather: return "OpImageDrefGather"; + case Op::OpImageRead: return "OpImageRead"; + case Op::OpImageWrite: return "OpImageWrite"; + case Op::OpImage: return "OpImage"; + case Op::OpImageQueryFormat: return "OpImageQueryFormat"; + case Op::OpImageQueryOrder: return "OpImageQueryOrder"; + case Op::OpImageQuerySizeLod: return "OpImageQuerySizeLod"; + case Op::OpImageQuerySize: return "OpImageQuerySize"; + case Op::OpImageQueryLod: return "OpImageQueryLod"; + case Op::OpImageQueryLevels: return "OpImageQueryLevels"; + case Op::OpImageQuerySamples: return "OpImageQuerySamples"; + case Op::OpConvertFToU: return "OpConvertFToU"; + case Op::OpConvertFToS: return "OpConvertFToS"; + case Op::OpConvertSToF: return "OpConvertSToF"; + case Op::OpConvertUToF: return "OpConvertUToF"; + case Op::OpUConvert: return "OpUConvert"; + case Op::OpSConvert: return "OpSConvert"; + case Op::OpFConvert: return "OpFConvert"; + case Op::OpQuantizeToF16: return "OpQuantizeToF16"; + case Op::OpConvertPtrToU: return "OpConvertPtrToU"; + case Op::OpSatConvertSToU: return "OpSatConvertSToU"; + case Op::OpSatConvertUToS: return "OpSatConvertUToS"; + case Op::OpConvertUToPtr: return "OpConvertUToPtr"; + case Op::OpPtrCastToGeneric: return "OpPtrCastToGeneric"; + case Op::OpGenericCastToPtr: return "OpGenericCastToPtr"; + case Op::OpGenericCastToPtrExplicit: return "OpGenericCastToPtrExplicit"; + case Op::OpBitcast: return "OpBitcast"; + case Op::OpSNegate: return "OpSNegate"; + case Op::OpFNegate: return "OpFNegate"; + case Op::OpIAdd: return "OpIAdd"; + case Op::OpFAdd: return "OpFAdd"; + case Op::OpISub: return "OpISub"; + case Op::OpFSub: return "OpFSub"; + case Op::OpIMul: return "OpIMul"; + case Op::OpFMul: return "OpFMul"; + case Op::OpUDiv: return "OpUDiv"; + case Op::OpSDiv: return "OpSDiv"; + case Op::OpFDiv: return "OpFDiv"; + case Op::OpUMod: return "OpUMod"; + case Op::OpSRem: return "OpSRem"; + case Op::OpSMod: return "OpSMod"; + case Op::OpFRem: return "OpFRem"; + case Op::OpFMod: return "OpFMod"; + case Op::OpVectorTimesScalar: return "OpVectorTimesScalar"; + case Op::OpMatrixTimesScalar: return "OpMatrixTimesScalar"; + case Op::OpVectorTimesMatrix: return "OpVectorTimesMatrix"; + case Op::OpMatrixTimesVector: return "OpMatrixTimesVector"; + case Op::OpMatrixTimesMatrix: return "OpMatrixTimesMatrix"; + case Op::OpOuterProduct: return "OpOuterProduct"; + case Op::OpDot: return "OpDot"; + case Op::OpIAddCarry: return "OpIAddCarry"; + case Op::OpISubBorrow: return "OpISubBorrow"; + case Op::OpUMulExtended: return "OpUMulExtended"; + case Op::OpSMulExtended: return "OpSMulExtended"; + case Op::OpAny: return "OpAny"; + case Op::OpAll: return "OpAll"; + case Op::OpIsNan: return "OpIsNan"; + case Op::OpIsInf: return "OpIsInf"; + case Op::OpIsFinite: return "OpIsFinite"; + case Op::OpIsNormal: return "OpIsNormal"; + case Op::OpSignBitSet: return "OpSignBitSet"; + case Op::OpLessOrGreater: return "OpLessOrGreater"; + case Op::OpOrdered: return "OpOrdered"; + case Op::OpUnordered: return "OpUnordered"; + case Op::OpLogicalEqual: return "OpLogicalEqual"; + case Op::OpLogicalNotEqual: return "OpLogicalNotEqual"; + case Op::OpLogicalOr: return "OpLogicalOr"; + case Op::OpLogicalAnd: return "OpLogicalAnd"; + case Op::OpLogicalNot: return "OpLogicalNot"; + case Op::OpSelect: return "OpSelect"; + case Op::OpIEqual: return "OpIEqual"; + case Op::OpINotEqual: return "OpINotEqual"; + case Op::OpUGreaterThan: return "OpUGreaterThan"; + case Op::OpSGreaterThan: return "OpSGreaterThan"; + case Op::OpUGreaterThanEqual: return "OpUGreaterThanEqual"; + case Op::OpSGreaterThanEqual: return "OpSGreaterThanEqual"; + case Op::OpULessThan: return "OpULessThan"; + case Op::OpSLessThan: return "OpSLessThan"; + case Op::OpULessThanEqual: return "OpULessThanEqual"; + case Op::OpSLessThanEqual: return "OpSLessThanEqual"; + case Op::OpFOrdEqual: return "OpFOrdEqual"; + case Op::OpFUnordEqual: return "OpFUnordEqual"; + case Op::OpFOrdNotEqual: return "OpFOrdNotEqual"; + case Op::OpFUnordNotEqual: return "OpFUnordNotEqual"; + case Op::OpFOrdLessThan: return "OpFOrdLessThan"; + case Op::OpFUnordLessThan: return "OpFUnordLessThan"; + case Op::OpFOrdGreaterThan: return "OpFOrdGreaterThan"; + case Op::OpFUnordGreaterThan: return "OpFUnordGreaterThan"; + case Op::OpFOrdLessThanEqual: return "OpFOrdLessThanEqual"; + case Op::OpFUnordLessThanEqual: return "OpFUnordLessThanEqual"; + case Op::OpFOrdGreaterThanEqual: return "OpFOrdGreaterThanEqual"; + case Op::OpFUnordGreaterThanEqual: return "OpFUnordGreaterThanEqual"; + case Op::OpShiftRightLogical: return "OpShiftRightLogical"; + case Op::OpShiftRightArithmetic: return "OpShiftRightArithmetic"; + case Op::OpShiftLeftLogical: return "OpShiftLeftLogical"; + case Op::OpBitwiseOr: return "OpBitwiseOr"; + case Op::OpBitwiseXor: return "OpBitwiseXor"; + case Op::OpBitwiseAnd: return "OpBitwiseAnd"; + case Op::OpNot: return "OpNot"; + case Op::OpBitFieldInsert: return "OpBitFieldInsert"; + case Op::OpBitFieldSExtract: return "OpBitFieldSExtract"; + case Op::OpBitFieldUExtract: return "OpBitFieldUExtract"; + case Op::OpBitReverse: return "OpBitReverse"; + case Op::OpBitCount: return "OpBitCount"; + case Op::OpDPdx: return "OpDPdx"; + case Op::OpDPdy: return "OpDPdy"; + case Op::OpFwidth: return "OpFwidth"; + case Op::OpDPdxFine: return "OpDPdxFine"; + case Op::OpDPdyFine: return "OpDPdyFine"; + case Op::OpFwidthFine: return "OpFwidthFine"; + case Op::OpDPdxCoarse: return "OpDPdxCoarse"; + case Op::OpDPdyCoarse: return "OpDPdyCoarse"; + case Op::OpFwidthCoarse: return "OpFwidthCoarse"; + case Op::OpEmitVertex: return "OpEmitVertex"; + case Op::OpEndPrimitive: return "OpEndPrimitive"; + case Op::OpEmitStreamVertex: return "OpEmitStreamVertex"; + case Op::OpEndStreamPrimitive: return "OpEndStreamPrimitive"; + case Op::OpControlBarrier: return "OpControlBarrier"; + case Op::OpMemoryBarrier: return "OpMemoryBarrier"; + case Op::OpAtomicLoad: return "OpAtomicLoad"; + case Op::OpAtomicStore: return "OpAtomicStore"; + case Op::OpAtomicExchange: return "OpAtomicExchange"; + case Op::OpAtomicCompareExchange: return "OpAtomicCompareExchange"; + case Op::OpAtomicCompareExchangeWeak: return "OpAtomicCompareExchangeWeak"; + case Op::OpAtomicIIncrement: return "OpAtomicIIncrement"; + case Op::OpAtomicIDecrement: return "OpAtomicIDecrement"; + case Op::OpAtomicIAdd: return "OpAtomicIAdd"; + case Op::OpAtomicISub: return "OpAtomicISub"; + case Op::OpAtomicSMin: return "OpAtomicSMin"; + case Op::OpAtomicUMin: return "OpAtomicUMin"; + case Op::OpAtomicSMax: return "OpAtomicSMax"; + case Op::OpAtomicUMax: return "OpAtomicUMax"; + case Op::OpAtomicAnd: return "OpAtomicAnd"; + case Op::OpAtomicOr: return "OpAtomicOr"; + case Op::OpAtomicXor: return "OpAtomicXor"; + case Op::OpPhi: return "OpPhi"; + case Op::OpLoopMerge: return "OpLoopMerge"; + case Op::OpSelectionMerge: return "OpSelectionMerge"; + case Op::OpLabel: return "OpLabel"; + case Op::OpBranch: return "OpBranch"; + case Op::OpBranchConditional: return "OpBranchConditional"; + case Op::OpSwitch: return "OpSwitch"; + case Op::OpKill: return "OpKill"; + case Op::OpReturn: return "OpReturn"; + case Op::OpReturnValue: return "OpReturnValue"; + case Op::OpUnreachable: return "OpUnreachable"; + case Op::OpLifetimeStart: return "OpLifetimeStart"; + case Op::OpLifetimeStop: return "OpLifetimeStop"; + case Op::OpGroupAsyncCopy: return "OpGroupAsyncCopy"; + case Op::OpGroupWaitEvents: return "OpGroupWaitEvents"; + case Op::OpGroupAll: return "OpGroupAll"; + case Op::OpGroupAny: return "OpGroupAny"; + case Op::OpGroupBroadcast: return "OpGroupBroadcast"; + case Op::OpGroupIAdd: return "OpGroupIAdd"; + case Op::OpGroupFAdd: return "OpGroupFAdd"; + case Op::OpGroupFMin: return "OpGroupFMin"; + case Op::OpGroupUMin: return "OpGroupUMin"; + case Op::OpGroupSMin: return "OpGroupSMin"; + case Op::OpGroupFMax: return "OpGroupFMax"; + case Op::OpGroupUMax: return "OpGroupUMax"; + case Op::OpGroupSMax: return "OpGroupSMax"; + case Op::OpReadPipe: return "OpReadPipe"; + case Op::OpWritePipe: return "OpWritePipe"; + case Op::OpReservedReadPipe: return "OpReservedReadPipe"; + case Op::OpReservedWritePipe: return "OpReservedWritePipe"; + case Op::OpReserveReadPipePackets: return "OpReserveReadPipePackets"; + case Op::OpReserveWritePipePackets: return "OpReserveWritePipePackets"; + case Op::OpCommitReadPipe: return "OpCommitReadPipe"; + case Op::OpCommitWritePipe: return "OpCommitWritePipe"; + case Op::OpIsValidReserveId: return "OpIsValidReserveId"; + case Op::OpGetNumPipePackets: return "OpGetNumPipePackets"; + case Op::OpGetMaxPipePackets: return "OpGetMaxPipePackets"; + case Op::OpGroupReserveReadPipePackets: return "OpGroupReserveReadPipePackets"; + case Op::OpGroupReserveWritePipePackets: return "OpGroupReserveWritePipePackets"; + case Op::OpGroupCommitReadPipe: return "OpGroupCommitReadPipe"; + case Op::OpGroupCommitWritePipe: return "OpGroupCommitWritePipe"; + case Op::OpEnqueueMarker: return "OpEnqueueMarker"; + case Op::OpEnqueueKernel: return "OpEnqueueKernel"; + case Op::OpGetKernelNDrangeSubGroupCount: return "OpGetKernelNDrangeSubGroupCount"; + case Op::OpGetKernelNDrangeMaxSubGroupSize: return "OpGetKernelNDrangeMaxSubGroupSize"; + case Op::OpGetKernelWorkGroupSize: return "OpGetKernelWorkGroupSize"; + case Op::OpGetKernelPreferredWorkGroupSizeMultiple: return "OpGetKernelPreferredWorkGroupSizeMultiple"; + case Op::OpRetainEvent: return "OpRetainEvent"; + case Op::OpReleaseEvent: return "OpReleaseEvent"; + case Op::OpCreateUserEvent: return "OpCreateUserEvent"; + case Op::OpIsValidEvent: return "OpIsValidEvent"; + case Op::OpSetUserEventStatus: return "OpSetUserEventStatus"; + case Op::OpCaptureEventProfilingInfo: return "OpCaptureEventProfilingInfo"; + case Op::OpGetDefaultQueue: return "OpGetDefaultQueue"; + case Op::OpBuildNDRange: return "OpBuildNDRange"; + case Op::OpImageSparseSampleImplicitLod: return "OpImageSparseSampleImplicitLod"; + case Op::OpImageSparseSampleExplicitLod: return "OpImageSparseSampleExplicitLod"; + case Op::OpImageSparseSampleDrefImplicitLod: return "OpImageSparseSampleDrefImplicitLod"; + case Op::OpImageSparseSampleDrefExplicitLod: return "OpImageSparseSampleDrefExplicitLod"; + case Op::OpImageSparseSampleProjImplicitLod: return "OpImageSparseSampleProjImplicitLod"; + case Op::OpImageSparseSampleProjExplicitLod: return "OpImageSparseSampleProjExplicitLod"; + case Op::OpImageSparseSampleProjDrefImplicitLod: return "OpImageSparseSampleProjDrefImplicitLod"; + case Op::OpImageSparseSampleProjDrefExplicitLod: return "OpImageSparseSampleProjDrefExplicitLod"; + case Op::OpImageSparseFetch: return "OpImageSparseFetch"; + case Op::OpImageSparseGather: return "OpImageSparseGather"; + case Op::OpImageSparseDrefGather: return "OpImageSparseDrefGather"; + case Op::OpImageSparseTexelsResident: return "OpImageSparseTexelsResident"; + case Op::OpNoLine: return "OpNoLine"; + case Op::OpAtomicFlagTestAndSet: return "OpAtomicFlagTestAndSet"; + case Op::OpAtomicFlagClear: return "OpAtomicFlagClear"; + case Op::OpImageSparseRead: return "OpImageSparseRead"; + case Op::OpSizeOf: return "OpSizeOf"; + case Op::OpTypePipeStorage: return "OpTypePipeStorage"; + case Op::OpConstantPipeStorage: return "OpConstantPipeStorage"; + case Op::OpCreatePipeFromPipeStorage: return "OpCreatePipeFromPipeStorage"; + case Op::OpGetKernelLocalSizeForSubgroupCount: return "OpGetKernelLocalSizeForSubgroupCount"; + case Op::OpGetKernelMaxNumSubgroups: return "OpGetKernelMaxNumSubgroups"; + case Op::OpTypeNamedBarrier: return "OpTypeNamedBarrier"; + case Op::OpNamedBarrierInitialize: return "OpNamedBarrierInitialize"; + case Op::OpMemoryNamedBarrier: return "OpMemoryNamedBarrier"; + case Op::OpModuleProcessed: return "OpModuleProcessed"; + case Op::OpExecutionModeId: return "OpExecutionModeId"; + case Op::OpDecorateId: return "OpDecorateId"; + case Op::OpGroupNonUniformElect: return "OpGroupNonUniformElect"; + case Op::OpGroupNonUniformAll: return "OpGroupNonUniformAll"; + case Op::OpGroupNonUniformAny: return "OpGroupNonUniformAny"; + case Op::OpGroupNonUniformAllEqual: return "OpGroupNonUniformAllEqual"; + case Op::OpGroupNonUniformBroadcast: return "OpGroupNonUniformBroadcast"; + case Op::OpGroupNonUniformBroadcastFirst: return "OpGroupNonUniformBroadcastFirst"; + case Op::OpGroupNonUniformBallot: return "OpGroupNonUniformBallot"; + case Op::OpGroupNonUniformInverseBallot: return "OpGroupNonUniformInverseBallot"; + case Op::OpGroupNonUniformBallotBitExtract: return "OpGroupNonUniformBallotBitExtract"; + case Op::OpGroupNonUniformBallotBitCount: return "OpGroupNonUniformBallotBitCount"; + case Op::OpGroupNonUniformBallotFindLSB: return "OpGroupNonUniformBallotFindLSB"; + case Op::OpGroupNonUniformBallotFindMSB: return "OpGroupNonUniformBallotFindMSB"; + case Op::OpGroupNonUniformShuffle: return "OpGroupNonUniformShuffle"; + case Op::OpGroupNonUniformShuffleXor: return "OpGroupNonUniformShuffleXor"; + case Op::OpGroupNonUniformShuffleUp: return "OpGroupNonUniformShuffleUp"; + case Op::OpGroupNonUniformShuffleDown: return "OpGroupNonUniformShuffleDown"; + case Op::OpGroupNonUniformIAdd: return "OpGroupNonUniformIAdd"; + case Op::OpGroupNonUniformFAdd: return "OpGroupNonUniformFAdd"; + case Op::OpGroupNonUniformIMul: return "OpGroupNonUniformIMul"; + case Op::OpGroupNonUniformFMul: return "OpGroupNonUniformFMul"; + case Op::OpGroupNonUniformSMin: return "OpGroupNonUniformSMin"; + case Op::OpGroupNonUniformUMin: return "OpGroupNonUniformUMin"; + case Op::OpGroupNonUniformFMin: return "OpGroupNonUniformFMin"; + case Op::OpGroupNonUniformSMax: return "OpGroupNonUniformSMax"; + case Op::OpGroupNonUniformUMax: return "OpGroupNonUniformUMax"; + case Op::OpGroupNonUniformFMax: return "OpGroupNonUniformFMax"; + case Op::OpGroupNonUniformBitwiseAnd: return "OpGroupNonUniformBitwiseAnd"; + case Op::OpGroupNonUniformBitwiseOr: return "OpGroupNonUniformBitwiseOr"; + case Op::OpGroupNonUniformBitwiseXor: return "OpGroupNonUniformBitwiseXor"; + case Op::OpGroupNonUniformLogicalAnd: return "OpGroupNonUniformLogicalAnd"; + case Op::OpGroupNonUniformLogicalOr: return "OpGroupNonUniformLogicalOr"; + case Op::OpGroupNonUniformLogicalXor: return "OpGroupNonUniformLogicalXor"; + case Op::OpGroupNonUniformQuadBroadcast: return "OpGroupNonUniformQuadBroadcast"; + case Op::OpGroupNonUniformQuadSwap: return "OpGroupNonUniformQuadSwap"; + case Op::OpCopyLogical: return "OpCopyLogical"; + case Op::OpPtrEqual: return "OpPtrEqual"; + case Op::OpPtrNotEqual: return "OpPtrNotEqual"; + case Op::OpPtrDiff: return "OpPtrDiff"; + case Op::OpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT"; + case Op::OpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT"; + case Op::OpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT"; + case Op::OpTypeTensorARM: return "OpTypeTensorARM"; + case Op::OpTensorReadARM: return "OpTensorReadARM"; + case Op::OpTensorWriteARM: return "OpTensorWriteARM"; + case Op::OpTensorQuerySizeARM: return "OpTensorQuerySizeARM"; + case Op::OpTerminateInvocation: return "OpTerminateInvocation"; + case Op::OpTypeUntypedPointerKHR: return "OpTypeUntypedPointerKHR"; + case Op::OpUntypedVariableKHR: return "OpUntypedVariableKHR"; + case Op::OpUntypedAccessChainKHR: return "OpUntypedAccessChainKHR"; + case Op::OpUntypedInBoundsAccessChainKHR: return "OpUntypedInBoundsAccessChainKHR"; + case Op::OpSubgroupBallotKHR: return "OpSubgroupBallotKHR"; + case Op::OpSubgroupFirstInvocationKHR: return "OpSubgroupFirstInvocationKHR"; + case Op::OpUntypedPtrAccessChainKHR: return "OpUntypedPtrAccessChainKHR"; + case Op::OpUntypedInBoundsPtrAccessChainKHR: return "OpUntypedInBoundsPtrAccessChainKHR"; + case Op::OpUntypedArrayLengthKHR: return "OpUntypedArrayLengthKHR"; + case Op::OpUntypedPrefetchKHR: return "OpUntypedPrefetchKHR"; + case Op::OpSubgroupAllKHR: return "OpSubgroupAllKHR"; + case Op::OpSubgroupAnyKHR: return "OpSubgroupAnyKHR"; + case Op::OpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR"; + case Op::OpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR"; + case Op::OpSubgroupReadInvocationKHR: return "OpSubgroupReadInvocationKHR"; + case Op::OpExtInstWithForwardRefsKHR: return "OpExtInstWithForwardRefsKHR"; + case Op::OpTraceRayKHR: return "OpTraceRayKHR"; + case Op::OpExecuteCallableKHR: return "OpExecuteCallableKHR"; + case Op::OpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR"; + case Op::OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case Op::OpTerminateRayKHR: return "OpTerminateRayKHR"; + case Op::OpSDot: return "OpSDot"; + case Op::OpUDot: return "OpUDot"; + case Op::OpSUDot: return "OpSUDot"; + case Op::OpSDotAccSat: return "OpSDotAccSat"; + case Op::OpUDotAccSat: return "OpUDotAccSat"; + case Op::OpSUDotAccSat: return "OpSUDotAccSat"; + case Op::OpTypeCooperativeMatrixKHR: return "OpTypeCooperativeMatrixKHR"; + case Op::OpCooperativeMatrixLoadKHR: return "OpCooperativeMatrixLoadKHR"; + case Op::OpCooperativeMatrixStoreKHR: return "OpCooperativeMatrixStoreKHR"; + case Op::OpCooperativeMatrixMulAddKHR: return "OpCooperativeMatrixMulAddKHR"; + case Op::OpCooperativeMatrixLengthKHR: return "OpCooperativeMatrixLengthKHR"; + case Op::OpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT"; + case Op::OpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT"; + case Op::OpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT"; + case Op::OpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; + case Op::OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case Op::OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case Op::OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case Op::OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case Op::OpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case Op::OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case Op::OpImageSampleWeightedQCOM: return "OpImageSampleWeightedQCOM"; + case Op::OpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; + case Op::OpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + case Op::OpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; + case Op::OpBitCastArrayQCOM: return "OpBitCastArrayQCOM"; + case Op::OpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM"; + case Op::OpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM"; + case Op::OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; + case Op::OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; + case Op::OpCompositeConstructCoopMatQCOM: return "OpCompositeConstructCoopMatQCOM"; + case Op::OpCompositeExtractCoopMatQCOM: return "OpCompositeExtractCoopMatQCOM"; + case Op::OpExtractSubArrayQCOM: return "OpExtractSubArrayQCOM"; + case Op::OpGroupIAddNonUniformAMD: return "OpGroupIAddNonUniformAMD"; + case Op::OpGroupFAddNonUniformAMD: return "OpGroupFAddNonUniformAMD"; + case Op::OpGroupFMinNonUniformAMD: return "OpGroupFMinNonUniformAMD"; + case Op::OpGroupUMinNonUniformAMD: return "OpGroupUMinNonUniformAMD"; + case Op::OpGroupSMinNonUniformAMD: return "OpGroupSMinNonUniformAMD"; + case Op::OpGroupFMaxNonUniformAMD: return "OpGroupFMaxNonUniformAMD"; + case Op::OpGroupUMaxNonUniformAMD: return "OpGroupUMaxNonUniformAMD"; + case Op::OpGroupSMaxNonUniformAMD: return "OpGroupSMaxNonUniformAMD"; + case Op::OpFragmentMaskFetchAMD: return "OpFragmentMaskFetchAMD"; + case Op::OpFragmentFetchAMD: return "OpFragmentFetchAMD"; + case Op::OpReadClockKHR: return "OpReadClockKHR"; + case Op::OpAllocateNodePayloadsAMDX: return "OpAllocateNodePayloadsAMDX"; + case Op::OpEnqueueNodePayloadsAMDX: return "OpEnqueueNodePayloadsAMDX"; + case Op::OpTypeNodePayloadArrayAMDX: return "OpTypeNodePayloadArrayAMDX"; + case Op::OpFinishWritingNodePayloadAMDX: return "OpFinishWritingNodePayloadAMDX"; + case Op::OpNodePayloadArrayLengthAMDX: return "OpNodePayloadArrayLengthAMDX"; + case Op::OpIsNodePayloadValidAMDX: return "OpIsNodePayloadValidAMDX"; + case Op::OpConstantStringAMDX: return "OpConstantStringAMDX"; + case Op::OpSpecConstantStringAMDX: return "OpSpecConstantStringAMDX"; + case Op::OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; + case Op::OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; + case Op::OpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; + case Op::OpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; + case Op::OpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; + case Op::OpHitObjectGetWorldToObjectNV: return "OpHitObjectGetWorldToObjectNV"; + case Op::OpHitObjectGetObjectToWorldNV: return "OpHitObjectGetObjectToWorldNV"; + case Op::OpHitObjectGetObjectRayDirectionNV: return "OpHitObjectGetObjectRayDirectionNV"; + case Op::OpHitObjectGetObjectRayOriginNV: return "OpHitObjectGetObjectRayOriginNV"; + case Op::OpHitObjectTraceRayMotionNV: return "OpHitObjectTraceRayMotionNV"; + case Op::OpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV"; + case Op::OpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV"; + case Op::OpHitObjectRecordEmptyNV: return "OpHitObjectRecordEmptyNV"; + case Op::OpHitObjectTraceRayNV: return "OpHitObjectTraceRayNV"; + case Op::OpHitObjectRecordHitNV: return "OpHitObjectRecordHitNV"; + case Op::OpHitObjectRecordHitWithIndexNV: return "OpHitObjectRecordHitWithIndexNV"; + case Op::OpHitObjectRecordMissNV: return "OpHitObjectRecordMissNV"; + case Op::OpHitObjectExecuteShaderNV: return "OpHitObjectExecuteShaderNV"; + case Op::OpHitObjectGetCurrentTimeNV: return "OpHitObjectGetCurrentTimeNV"; + case Op::OpHitObjectGetAttributesNV: return "OpHitObjectGetAttributesNV"; + case Op::OpHitObjectGetHitKindNV: return "OpHitObjectGetHitKindNV"; + case Op::OpHitObjectGetPrimitiveIndexNV: return "OpHitObjectGetPrimitiveIndexNV"; + case Op::OpHitObjectGetGeometryIndexNV: return "OpHitObjectGetGeometryIndexNV"; + case Op::OpHitObjectGetInstanceIdNV: return "OpHitObjectGetInstanceIdNV"; + case Op::OpHitObjectGetInstanceCustomIndexNV: return "OpHitObjectGetInstanceCustomIndexNV"; + case Op::OpHitObjectGetWorldRayDirectionNV: return "OpHitObjectGetWorldRayDirectionNV"; + case Op::OpHitObjectGetWorldRayOriginNV: return "OpHitObjectGetWorldRayOriginNV"; + case Op::OpHitObjectGetRayTMaxNV: return "OpHitObjectGetRayTMaxNV"; + case Op::OpHitObjectGetRayTMinNV: return "OpHitObjectGetRayTMinNV"; + case Op::OpHitObjectIsEmptyNV: return "OpHitObjectIsEmptyNV"; + case Op::OpHitObjectIsHitNV: return "OpHitObjectIsHitNV"; + case Op::OpHitObjectIsMissNV: return "OpHitObjectIsMissNV"; + case Op::OpReorderThreadWithHitObjectNV: return "OpReorderThreadWithHitObjectNV"; + case Op::OpReorderThreadWithHintNV: return "OpReorderThreadWithHintNV"; + case Op::OpTypeHitObjectNV: return "OpTypeHitObjectNV"; + case Op::OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; + case Op::OpTypeCooperativeVectorNV: return "OpTypeCooperativeVectorNV"; + case Op::OpCooperativeVectorMatrixMulNV: return "OpCooperativeVectorMatrixMulNV"; + case Op::OpCooperativeVectorOuterProductAccumulateNV: return "OpCooperativeVectorOuterProductAccumulateNV"; + case Op::OpCooperativeVectorReduceSumAccumulateNV: return "OpCooperativeVectorReduceSumAccumulateNV"; + case Op::OpCooperativeVectorMatrixMulAddNV: return "OpCooperativeVectorMatrixMulAddNV"; + case Op::OpCooperativeMatrixConvertNV: return "OpCooperativeMatrixConvertNV"; + case Op::OpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT"; + case Op::OpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT"; + case Op::OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; + case Op::OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case Op::OpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV"; + case Op::OpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV"; + case Op::OpCooperativeVectorLoadNV: return "OpCooperativeVectorLoadNV"; + case Op::OpCooperativeVectorStoreNV: return "OpCooperativeVectorStoreNV"; + case Op::OpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case Op::OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case Op::OpTerminateRayNV: return "OpTerminateRayNV"; + case Op::OpTraceNV: return "OpTraceNV"; + case Op::OpTraceMotionNV: return "OpTraceMotionNV"; + case Op::OpTraceRayMotionNV: return "OpTraceRayMotionNV"; + case Op::OpRayQueryGetIntersectionTriangleVertexPositionsKHR: return "OpRayQueryGetIntersectionTriangleVertexPositionsKHR"; + case Op::OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case Op::OpExecuteCallableNV: return "OpExecuteCallableNV"; + case Op::OpRayQueryGetClusterIdNV: return "OpRayQueryGetClusterIdNV"; + case Op::OpHitObjectGetClusterIdNV: return "OpHitObjectGetClusterIdNV"; + case Op::OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case Op::OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case Op::OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case Op::OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case Op::OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case Op::OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case Op::OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + case Op::OpCooperativeMatrixReduceNV: return "OpCooperativeMatrixReduceNV"; + case Op::OpCooperativeMatrixLoadTensorNV: return "OpCooperativeMatrixLoadTensorNV"; + case Op::OpCooperativeMatrixStoreTensorNV: return "OpCooperativeMatrixStoreTensorNV"; + case Op::OpCooperativeMatrixPerElementOpNV: return "OpCooperativeMatrixPerElementOpNV"; + case Op::OpTypeTensorLayoutNV: return "OpTypeTensorLayoutNV"; + case Op::OpTypeTensorViewNV: return "OpTypeTensorViewNV"; + case Op::OpCreateTensorLayoutNV: return "OpCreateTensorLayoutNV"; + case Op::OpTensorLayoutSetDimensionNV: return "OpTensorLayoutSetDimensionNV"; + case Op::OpTensorLayoutSetStrideNV: return "OpTensorLayoutSetStrideNV"; + case Op::OpTensorLayoutSliceNV: return "OpTensorLayoutSliceNV"; + case Op::OpTensorLayoutSetClampValueNV: return "OpTensorLayoutSetClampValueNV"; + case Op::OpCreateTensorViewNV: return "OpCreateTensorViewNV"; + case Op::OpTensorViewSetDimensionNV: return "OpTensorViewSetDimensionNV"; + case Op::OpTensorViewSetStrideNV: return "OpTensorViewSetStrideNV"; + case Op::OpDemoteToHelperInvocation: return "OpDemoteToHelperInvocation"; + case Op::OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + case Op::OpTensorViewSetClipNV: return "OpTensorViewSetClipNV"; + case Op::OpTensorLayoutSetBlockSizeNV: return "OpTensorLayoutSetBlockSizeNV"; + case Op::OpCooperativeMatrixTransposeNV: return "OpCooperativeMatrixTransposeNV"; + case Op::OpConvertUToImageNV: return "OpConvertUToImageNV"; + case Op::OpConvertUToSamplerNV: return "OpConvertUToSamplerNV"; + case Op::OpConvertImageToUNV: return "OpConvertImageToUNV"; + case Op::OpConvertSamplerToUNV: return "OpConvertSamplerToUNV"; + case Op::OpConvertUToSampledImageNV: return "OpConvertUToSampledImageNV"; + case Op::OpConvertSampledImageToUNV: return "OpConvertSampledImageToUNV"; + case Op::OpSamplerImageAddressingModeNV: return "OpSamplerImageAddressingModeNV"; + case Op::OpRawAccessChainNV: return "OpRawAccessChainNV"; + case Op::OpRayQueryGetIntersectionSpherePositionNV: return "OpRayQueryGetIntersectionSpherePositionNV"; + case Op::OpRayQueryGetIntersectionSphereRadiusNV: return "OpRayQueryGetIntersectionSphereRadiusNV"; + case Op::OpRayQueryGetIntersectionLSSPositionsNV: return "OpRayQueryGetIntersectionLSSPositionsNV"; + case Op::OpRayQueryGetIntersectionLSSRadiiNV: return "OpRayQueryGetIntersectionLSSRadiiNV"; + case Op::OpRayQueryGetIntersectionLSSHitValueNV: return "OpRayQueryGetIntersectionLSSHitValueNV"; + case Op::OpHitObjectGetSpherePositionNV: return "OpHitObjectGetSpherePositionNV"; + case Op::OpHitObjectGetSphereRadiusNV: return "OpHitObjectGetSphereRadiusNV"; + case Op::OpHitObjectGetLSSPositionsNV: return "OpHitObjectGetLSSPositionsNV"; + case Op::OpHitObjectGetLSSRadiiNV: return "OpHitObjectGetLSSRadiiNV"; + case Op::OpHitObjectIsSphereHitNV: return "OpHitObjectIsSphereHitNV"; + case Op::OpHitObjectIsLSSHitNV: return "OpHitObjectIsLSSHitNV"; + case Op::OpRayQueryIsSphereHitNV: return "OpRayQueryIsSphereHitNV"; + case Op::OpRayQueryIsLSSHitNV: return "OpRayQueryIsLSSHitNV"; + case Op::OpSubgroupShuffleINTEL: return "OpSubgroupShuffleINTEL"; + case Op::OpSubgroupShuffleDownINTEL: return "OpSubgroupShuffleDownINTEL"; + case Op::OpSubgroupShuffleUpINTEL: return "OpSubgroupShuffleUpINTEL"; + case Op::OpSubgroupShuffleXorINTEL: return "OpSubgroupShuffleXorINTEL"; + case Op::OpSubgroupBlockReadINTEL: return "OpSubgroupBlockReadINTEL"; + case Op::OpSubgroupBlockWriteINTEL: return "OpSubgroupBlockWriteINTEL"; + case Op::OpSubgroupImageBlockReadINTEL: return "OpSubgroupImageBlockReadINTEL"; + case Op::OpSubgroupImageBlockWriteINTEL: return "OpSubgroupImageBlockWriteINTEL"; + case Op::OpSubgroupImageMediaBlockReadINTEL: return "OpSubgroupImageMediaBlockReadINTEL"; + case Op::OpSubgroupImageMediaBlockWriteINTEL: return "OpSubgroupImageMediaBlockWriteINTEL"; + case Op::OpUCountLeadingZerosINTEL: return "OpUCountLeadingZerosINTEL"; + case Op::OpUCountTrailingZerosINTEL: return "OpUCountTrailingZerosINTEL"; + case Op::OpAbsISubINTEL: return "OpAbsISubINTEL"; + case Op::OpAbsUSubINTEL: return "OpAbsUSubINTEL"; + case Op::OpIAddSatINTEL: return "OpIAddSatINTEL"; + case Op::OpUAddSatINTEL: return "OpUAddSatINTEL"; + case Op::OpIAverageINTEL: return "OpIAverageINTEL"; + case Op::OpUAverageINTEL: return "OpUAverageINTEL"; + case Op::OpIAverageRoundedINTEL: return "OpIAverageRoundedINTEL"; + case Op::OpUAverageRoundedINTEL: return "OpUAverageRoundedINTEL"; + case Op::OpISubSatINTEL: return "OpISubSatINTEL"; + case Op::OpUSubSatINTEL: return "OpUSubSatINTEL"; + case Op::OpIMul32x16INTEL: return "OpIMul32x16INTEL"; + case Op::OpUMul32x16INTEL: return "OpUMul32x16INTEL"; + case Op::OpConstantFunctionPointerINTEL: return "OpConstantFunctionPointerINTEL"; + case Op::OpFunctionPointerCallINTEL: return "OpFunctionPointerCallINTEL"; + case Op::OpAsmTargetINTEL: return "OpAsmTargetINTEL"; + case Op::OpAsmINTEL: return "OpAsmINTEL"; + case Op::OpAsmCallINTEL: return "OpAsmCallINTEL"; + case Op::OpAtomicFMinEXT: return "OpAtomicFMinEXT"; + case Op::OpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; + case Op::OpAssumeTrueKHR: return "OpAssumeTrueKHR"; + case Op::OpExpectKHR: return "OpExpectKHR"; + case Op::OpDecorateString: return "OpDecorateString"; + case Op::OpMemberDecorateString: return "OpMemberDecorateString"; + case Op::OpVmeImageINTEL: return "OpVmeImageINTEL"; + case Op::OpTypeVmeImageINTEL: return "OpTypeVmeImageINTEL"; + case Op::OpTypeAvcImePayloadINTEL: return "OpTypeAvcImePayloadINTEL"; + case Op::OpTypeAvcRefPayloadINTEL: return "OpTypeAvcRefPayloadINTEL"; + case Op::OpTypeAvcSicPayloadINTEL: return "OpTypeAvcSicPayloadINTEL"; + case Op::OpTypeAvcMcePayloadINTEL: return "OpTypeAvcMcePayloadINTEL"; + case Op::OpTypeAvcMceResultINTEL: return "OpTypeAvcMceResultINTEL"; + case Op::OpTypeAvcImeResultINTEL: return "OpTypeAvcImeResultINTEL"; + case Op::OpTypeAvcImeResultSingleReferenceStreamoutINTEL: return "OpTypeAvcImeResultSingleReferenceStreamoutINTEL"; + case Op::OpTypeAvcImeResultDualReferenceStreamoutINTEL: return "OpTypeAvcImeResultDualReferenceStreamoutINTEL"; + case Op::OpTypeAvcImeSingleReferenceStreaminINTEL: return "OpTypeAvcImeSingleReferenceStreaminINTEL"; + case Op::OpTypeAvcImeDualReferenceStreaminINTEL: return "OpTypeAvcImeDualReferenceStreaminINTEL"; + case Op::OpTypeAvcRefResultINTEL: return "OpTypeAvcRefResultINTEL"; + case Op::OpTypeAvcSicResultINTEL: return "OpTypeAvcSicResultINTEL"; + case Op::OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL"; + case Op::OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL"; + case Op::OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL"; + case Op::OpSubgroupAvcMceSetInterShapePenaltyINTEL: return "OpSubgroupAvcMceSetInterShapePenaltyINTEL"; + case Op::OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL"; + case Op::OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL"; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL"; + case Op::OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: return "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL"; + case Op::OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL"; + case Op::OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL"; + case Op::OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL"; + case Op::OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: return "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL"; + case Op::OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL"; + case Op::OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL"; + case Op::OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL"; + case Op::OpSubgroupAvcMceSetAcOnlyHaarINTEL: return "OpSubgroupAvcMceSetAcOnlyHaarINTEL"; + case Op::OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL"; + case Op::OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL"; + case Op::OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL"; + case Op::OpSubgroupAvcMceConvertToImePayloadINTEL: return "OpSubgroupAvcMceConvertToImePayloadINTEL"; + case Op::OpSubgroupAvcMceConvertToImeResultINTEL: return "OpSubgroupAvcMceConvertToImeResultINTEL"; + case Op::OpSubgroupAvcMceConvertToRefPayloadINTEL: return "OpSubgroupAvcMceConvertToRefPayloadINTEL"; + case Op::OpSubgroupAvcMceConvertToRefResultINTEL: return "OpSubgroupAvcMceConvertToRefResultINTEL"; + case Op::OpSubgroupAvcMceConvertToSicPayloadINTEL: return "OpSubgroupAvcMceConvertToSicPayloadINTEL"; + case Op::OpSubgroupAvcMceConvertToSicResultINTEL: return "OpSubgroupAvcMceConvertToSicResultINTEL"; + case Op::OpSubgroupAvcMceGetMotionVectorsINTEL: return "OpSubgroupAvcMceGetMotionVectorsINTEL"; + case Op::OpSubgroupAvcMceGetInterDistortionsINTEL: return "OpSubgroupAvcMceGetInterDistortionsINTEL"; + case Op::OpSubgroupAvcMceGetBestInterDistortionsINTEL: return "OpSubgroupAvcMceGetBestInterDistortionsINTEL"; + case Op::OpSubgroupAvcMceGetInterMajorShapeINTEL: return "OpSubgroupAvcMceGetInterMajorShapeINTEL"; + case Op::OpSubgroupAvcMceGetInterMinorShapeINTEL: return "OpSubgroupAvcMceGetInterMinorShapeINTEL"; + case Op::OpSubgroupAvcMceGetInterDirectionsINTEL: return "OpSubgroupAvcMceGetInterDirectionsINTEL"; + case Op::OpSubgroupAvcMceGetInterMotionVectorCountINTEL: return "OpSubgroupAvcMceGetInterMotionVectorCountINTEL"; + case Op::OpSubgroupAvcMceGetInterReferenceIdsINTEL: return "OpSubgroupAvcMceGetInterReferenceIdsINTEL"; + case Op::OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL"; + case Op::OpSubgroupAvcImeInitializeINTEL: return "OpSubgroupAvcImeInitializeINTEL"; + case Op::OpSubgroupAvcImeSetSingleReferenceINTEL: return "OpSubgroupAvcImeSetSingleReferenceINTEL"; + case Op::OpSubgroupAvcImeSetDualReferenceINTEL: return "OpSubgroupAvcImeSetDualReferenceINTEL"; + case Op::OpSubgroupAvcImeRefWindowSizeINTEL: return "OpSubgroupAvcImeRefWindowSizeINTEL"; + case Op::OpSubgroupAvcImeAdjustRefOffsetINTEL: return "OpSubgroupAvcImeAdjustRefOffsetINTEL"; + case Op::OpSubgroupAvcImeConvertToMcePayloadINTEL: return "OpSubgroupAvcImeConvertToMcePayloadINTEL"; + case Op::OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: return "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL"; + case Op::OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: return "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL"; + case Op::OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: return "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL"; + case Op::OpSubgroupAvcImeSetWeightedSadINTEL: return "OpSubgroupAvcImeSetWeightedSadINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL"; + case Op::OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL"; + case Op::OpSubgroupAvcImeConvertToMceResultINTEL: return "OpSubgroupAvcImeConvertToMceResultINTEL"; + case Op::OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL"; + case Op::OpSubgroupAvcImeGetDualReferenceStreaminINTEL: return "OpSubgroupAvcImeGetDualReferenceStreaminINTEL"; + case Op::OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL"; + case Op::OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL"; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL"; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL"; + case Op::OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL"; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL"; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL"; + case Op::OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL"; + case Op::OpSubgroupAvcImeGetBorderReachedINTEL: return "OpSubgroupAvcImeGetBorderReachedINTEL"; + case Op::OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: return "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL"; + case Op::OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: return "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL"; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL"; + case Op::OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL"; + case Op::OpSubgroupAvcFmeInitializeINTEL: return "OpSubgroupAvcFmeInitializeINTEL"; + case Op::OpSubgroupAvcBmeInitializeINTEL: return "OpSubgroupAvcBmeInitializeINTEL"; + case Op::OpSubgroupAvcRefConvertToMcePayloadINTEL: return "OpSubgroupAvcRefConvertToMcePayloadINTEL"; + case Op::OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: return "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL"; + case Op::OpSubgroupAvcRefSetBilinearFilterEnableINTEL: return "OpSubgroupAvcRefSetBilinearFilterEnableINTEL"; + case Op::OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL"; + case Op::OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL"; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL"; + case Op::OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL"; + case Op::OpSubgroupAvcRefConvertToMceResultINTEL: return "OpSubgroupAvcRefConvertToMceResultINTEL"; + case Op::OpSubgroupAvcSicInitializeINTEL: return "OpSubgroupAvcSicInitializeINTEL"; + case Op::OpSubgroupAvcSicConfigureSkcINTEL: return "OpSubgroupAvcSicConfigureSkcINTEL"; + case Op::OpSubgroupAvcSicConfigureIpeLumaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaINTEL"; + case Op::OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL"; + case Op::OpSubgroupAvcSicGetMotionVectorMaskINTEL: return "OpSubgroupAvcSicGetMotionVectorMaskINTEL"; + case Op::OpSubgroupAvcSicConvertToMcePayloadINTEL: return "OpSubgroupAvcSicConvertToMcePayloadINTEL"; + case Op::OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL"; + case Op::OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL"; + case Op::OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL"; + case Op::OpSubgroupAvcSicSetBilinearFilterEnableINTEL: return "OpSubgroupAvcSicSetBilinearFilterEnableINTEL"; + case Op::OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: return "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL"; + case Op::OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: return "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL"; + case Op::OpSubgroupAvcSicEvaluateIpeINTEL: return "OpSubgroupAvcSicEvaluateIpeINTEL"; + case Op::OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL"; + case Op::OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL"; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL"; + case Op::OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL"; + case Op::OpSubgroupAvcSicConvertToMceResultINTEL: return "OpSubgroupAvcSicConvertToMceResultINTEL"; + case Op::OpSubgroupAvcSicGetIpeLumaShapeINTEL: return "OpSubgroupAvcSicGetIpeLumaShapeINTEL"; + case Op::OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL"; + case Op::OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL"; + case Op::OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: return "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL"; + case Op::OpSubgroupAvcSicGetIpeChromaModeINTEL: return "OpSubgroupAvcSicGetIpeChromaModeINTEL"; + case Op::OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL"; + case Op::OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL"; + case Op::OpSubgroupAvcSicGetInterRawSadsINTEL: return "OpSubgroupAvcSicGetInterRawSadsINTEL"; + case Op::OpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL"; + case Op::OpSaveMemoryINTEL: return "OpSaveMemoryINTEL"; + case Op::OpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL"; + case Op::OpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL"; + case Op::OpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL"; + case Op::OpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL"; + case Op::OpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL"; + case Op::OpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL"; + case Op::OpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL"; + case Op::OpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL"; + case Op::OpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL"; + case Op::OpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL"; + case Op::OpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL"; + case Op::OpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL"; + case Op::OpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL"; + case Op::OpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL"; + case Op::OpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL"; + case Op::OpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL"; + case Op::OpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL"; + case Op::OpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL"; + case Op::OpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL"; + case Op::OpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL"; + case Op::OpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL"; + case Op::OpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL"; + case Op::OpArbitraryFloatLog1pINTEL: return "OpArbitraryFloatLog1pINTEL"; + case Op::OpArbitraryFloatExpINTEL: return "OpArbitraryFloatExpINTEL"; + case Op::OpArbitraryFloatExp2INTEL: return "OpArbitraryFloatExp2INTEL"; + case Op::OpArbitraryFloatExp10INTEL: return "OpArbitraryFloatExp10INTEL"; + case Op::OpArbitraryFloatExpm1INTEL: return "OpArbitraryFloatExpm1INTEL"; + case Op::OpArbitraryFloatSinINTEL: return "OpArbitraryFloatSinINTEL"; + case Op::OpArbitraryFloatCosINTEL: return "OpArbitraryFloatCosINTEL"; + case Op::OpArbitraryFloatSinCosINTEL: return "OpArbitraryFloatSinCosINTEL"; + case Op::OpArbitraryFloatSinPiINTEL: return "OpArbitraryFloatSinPiINTEL"; + case Op::OpArbitraryFloatCosPiINTEL: return "OpArbitraryFloatCosPiINTEL"; + case Op::OpArbitraryFloatASinINTEL: return "OpArbitraryFloatASinINTEL"; + case Op::OpArbitraryFloatASinPiINTEL: return "OpArbitraryFloatASinPiINTEL"; + case Op::OpArbitraryFloatACosINTEL: return "OpArbitraryFloatACosINTEL"; + case Op::OpArbitraryFloatACosPiINTEL: return "OpArbitraryFloatACosPiINTEL"; + case Op::OpArbitraryFloatATanINTEL: return "OpArbitraryFloatATanINTEL"; + case Op::OpArbitraryFloatATanPiINTEL: return "OpArbitraryFloatATanPiINTEL"; + case Op::OpArbitraryFloatATan2INTEL: return "OpArbitraryFloatATan2INTEL"; + case Op::OpArbitraryFloatPowINTEL: return "OpArbitraryFloatPowINTEL"; + case Op::OpArbitraryFloatPowRINTEL: return "OpArbitraryFloatPowRINTEL"; + case Op::OpArbitraryFloatPowNINTEL: return "OpArbitraryFloatPowNINTEL"; + case Op::OpLoopControlINTEL: return "OpLoopControlINTEL"; + case Op::OpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL"; + case Op::OpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL"; + case Op::OpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL"; + case Op::OpFixedSqrtINTEL: return "OpFixedSqrtINTEL"; + case Op::OpFixedRecipINTEL: return "OpFixedRecipINTEL"; + case Op::OpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL"; + case Op::OpFixedSinINTEL: return "OpFixedSinINTEL"; + case Op::OpFixedCosINTEL: return "OpFixedCosINTEL"; + case Op::OpFixedSinCosINTEL: return "OpFixedSinCosINTEL"; + case Op::OpFixedSinPiINTEL: return "OpFixedSinPiINTEL"; + case Op::OpFixedCosPiINTEL: return "OpFixedCosPiINTEL"; + case Op::OpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL"; + case Op::OpFixedLogINTEL: return "OpFixedLogINTEL"; + case Op::OpFixedExpINTEL: return "OpFixedExpINTEL"; + case Op::OpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL"; + case Op::OpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL"; + case Op::OpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL"; + case Op::OpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL"; + case Op::OpFPGARegINTEL: return "OpFPGARegINTEL"; + case Op::OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case Op::OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case Op::OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case Op::OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case Op::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case Op::OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case Op::OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case Op::OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case Op::OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case Op::OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case Op::OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case Op::OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case Op::OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case Op::OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case Op::OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case Op::OpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case Op::OpTypeBufferSurfaceINTEL: return "OpTypeBufferSurfaceINTEL"; + case Op::OpTypeStructContinuedINTEL: return "OpTypeStructContinuedINTEL"; + case Op::OpConstantCompositeContinuedINTEL: return "OpConstantCompositeContinuedINTEL"; + case Op::OpSpecConstantCompositeContinuedINTEL: return "OpSpecConstantCompositeContinuedINTEL"; + case Op::OpCompositeConstructContinuedINTEL: return "OpCompositeConstructContinuedINTEL"; + case Op::OpConvertFToBF16INTEL: return "OpConvertFToBF16INTEL"; + case Op::OpConvertBF16ToFINTEL: return "OpConvertBF16ToFINTEL"; + case Op::OpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL"; + case Op::OpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL"; + case Op::OpArithmeticFenceEXT: return "OpArithmeticFenceEXT"; + case Op::OpSubgroupBlockPrefetchINTEL: return "OpSubgroupBlockPrefetchINTEL"; + case Op::OpSubgroup2DBlockLoadINTEL: return "OpSubgroup2DBlockLoadINTEL"; + case Op::OpSubgroup2DBlockLoadTransformINTEL: return "OpSubgroup2DBlockLoadTransformINTEL"; + case Op::OpSubgroup2DBlockLoadTransposeINTEL: return "OpSubgroup2DBlockLoadTransposeINTEL"; + case Op::OpSubgroup2DBlockPrefetchINTEL: return "OpSubgroup2DBlockPrefetchINTEL"; + case Op::OpSubgroup2DBlockStoreINTEL: return "OpSubgroup2DBlockStoreINTEL"; + case Op::OpSubgroupMatrixMultiplyAccumulateINTEL: return "OpSubgroupMatrixMultiplyAccumulateINTEL"; + case Op::OpGroupIMulKHR: return "OpGroupIMulKHR"; + case Op::OpGroupFMulKHR: return "OpGroupFMulKHR"; + case Op::OpGroupBitwiseAndKHR: return "OpGroupBitwiseAndKHR"; + case Op::OpGroupBitwiseOrKHR: return "OpGroupBitwiseOrKHR"; + case Op::OpGroupBitwiseXorKHR: return "OpGroupBitwiseXorKHR"; + case Op::OpGroupLogicalAndKHR: return "OpGroupLogicalAndKHR"; + case Op::OpGroupLogicalOrKHR: return "OpGroupLogicalOrKHR"; + case Op::OpGroupLogicalXorKHR: return "OpGroupLogicalXorKHR"; + case Op::OpMaskedGatherINTEL: return "OpMaskedGatherINTEL"; + case Op::OpMaskedScatterINTEL: return "OpMaskedScatterINTEL"; + default: return "Unknown"; + } +} + +#endif /* SPV_ENABLE_UTILITY_CODE */ + +// Overload bitwise operators for mask bit combining + +constexpr ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +constexpr ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); } +constexpr ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); } +constexpr FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +constexpr FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); } +constexpr FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); } +constexpr FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); } +constexpr SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +constexpr SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); } +constexpr SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); } +constexpr SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); } +constexpr LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +constexpr LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); } +constexpr LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); } +constexpr LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); } +constexpr FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +constexpr FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); } +constexpr FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); } +constexpr FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); } +constexpr MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +constexpr MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); } +constexpr MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); } +constexpr MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); } +constexpr MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +constexpr MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); } +constexpr MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); } +constexpr MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); } +constexpr KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +constexpr KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); } +constexpr KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); } +constexpr KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); } +constexpr RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +constexpr RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); } +constexpr RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); } +constexpr RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); } +constexpr FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } +constexpr FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); } +constexpr FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); } +constexpr FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); } +constexpr CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); } +constexpr CooperativeMatrixReduceMask operator|(CooperativeMatrixReduceMask a, CooperativeMatrixReduceMask b) { return CooperativeMatrixReduceMask(unsigned(a) | unsigned(b)); } +constexpr CooperativeMatrixReduceMask operator&(CooperativeMatrixReduceMask a, CooperativeMatrixReduceMask b) { return CooperativeMatrixReduceMask(unsigned(a) & unsigned(b)); } +constexpr CooperativeMatrixReduceMask operator^(CooperativeMatrixReduceMask a, CooperativeMatrixReduceMask b) { return CooperativeMatrixReduceMask(unsigned(a) ^ unsigned(b)); } +constexpr CooperativeMatrixReduceMask operator~(CooperativeMatrixReduceMask a) { return CooperativeMatrixReduceMask(~unsigned(a)); } +constexpr TensorAddressingOperandsMask operator|(TensorAddressingOperandsMask a, TensorAddressingOperandsMask b) { return TensorAddressingOperandsMask(unsigned(a) | unsigned(b)); } +constexpr TensorAddressingOperandsMask operator&(TensorAddressingOperandsMask a, TensorAddressingOperandsMask b) { return TensorAddressingOperandsMask(unsigned(a) & unsigned(b)); } +constexpr TensorAddressingOperandsMask operator^(TensorAddressingOperandsMask a, TensorAddressingOperandsMask b) { return TensorAddressingOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr TensorAddressingOperandsMask operator~(TensorAddressingOperandsMask a) { return TensorAddressingOperandsMask(~unsigned(a)); } +constexpr TensorOperandsMask operator|(TensorOperandsMask a, TensorOperandsMask b) { return TensorOperandsMask(unsigned(a) | unsigned(b)); } +constexpr TensorOperandsMask operator&(TensorOperandsMask a, TensorOperandsMask b) { return TensorOperandsMask(unsigned(a) & unsigned(b)); } +constexpr TensorOperandsMask operator^(TensorOperandsMask a, TensorOperandsMask b) { return TensorOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr TensorOperandsMask operator~(TensorOperandsMask a) { return TensorOperandsMask(~unsigned(a)); } +constexpr MatrixMultiplyAccumulateOperandsMask operator|(MatrixMultiplyAccumulateOperandsMask a, MatrixMultiplyAccumulateOperandsMask b) { return MatrixMultiplyAccumulateOperandsMask(unsigned(a) | unsigned(b)); } +constexpr MatrixMultiplyAccumulateOperandsMask operator&(MatrixMultiplyAccumulateOperandsMask a, MatrixMultiplyAccumulateOperandsMask b) { return MatrixMultiplyAccumulateOperandsMask(unsigned(a) & unsigned(b)); } +constexpr MatrixMultiplyAccumulateOperandsMask operator^(MatrixMultiplyAccumulateOperandsMask a, MatrixMultiplyAccumulateOperandsMask b) { return MatrixMultiplyAccumulateOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr MatrixMultiplyAccumulateOperandsMask operator~(MatrixMultiplyAccumulateOperandsMask a) { return MatrixMultiplyAccumulateOperandsMask(~unsigned(a)); } +constexpr RawAccessChainOperandsMask operator|(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) | unsigned(b)); } +constexpr RawAccessChainOperandsMask operator&(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) & unsigned(b)); } +constexpr RawAccessChainOperandsMask operator^(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr RawAccessChainOperandsMask operator~(RawAccessChainOperandsMask a) { return RawAccessChainOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/thirdparty/headers/glslang/include/glslang/build_info.h b/thirdparty/headers/glslang/include/glslang/build_info.h new file mode 100644 index 000000000..d8f2a74ce --- /dev/null +++ b/thirdparty/headers/glslang/include/glslang/build_info.h @@ -0,0 +1,62 @@ +// Copyright (C) 2020 The Khronos Group Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of The Khronos Group Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef GLSLANG_BUILD_INFO +#define GLSLANG_BUILD_INFO + +#define GLSLANG_VERSION_MAJOR 16 +#define GLSLANG_VERSION_MINOR 0 +#define GLSLANG_VERSION_PATCH 0 +#define GLSLANG_VERSION_FLAVOR "" + +#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \ + ((GLSLANG_VERSION_MAJOR) > (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) > (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH) > (patch))))) + +#define GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch) \ + ((GLSLANG_VERSION_MAJOR) > (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) > (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH >= (patch)))))) + +#define GLSLANG_VERSION_LESS_THAN(major, minor, patch) \ + ((GLSLANG_VERSION_MAJOR) < (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) < (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH) < (patch))))) + +#define GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch) \ + ((GLSLANG_VERSION_MAJOR) < (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) < (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH <= (patch)))))) + +#endif // GLSLANG_BUILD_INFO diff --git a/thirdparty/headers/glslang/include/spirv-tools/libspirv.h b/thirdparty/headers/glslang/include/spirv-tools/libspirv.h new file mode 100644 index 000000000..0cd717e59 --- /dev/null +++ b/thirdparty/headers/glslang/include/spirv-tools/libspirv.h @@ -0,0 +1,1071 @@ +// Copyright (c) 2015-2020 The Khronos Group Inc. +// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights +// reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_LIBSPIRV_H_ +#define INCLUDE_SPIRV_TOOLS_LIBSPIRV_H_ + +#ifdef __cplusplus +extern "C" { +#else +#include +#endif + +#include +#include + +#if defined(SPIRV_TOOLS_SHAREDLIB) +#if defined(_WIN32) +#if defined(SPIRV_TOOLS_IMPLEMENTATION) +#define SPIRV_TOOLS_EXPORT __declspec(dllexport) +#else +#define SPIRV_TOOLS_EXPORT __declspec(dllimport) +#endif +#define SPIRV_TOOLS_LOCAL +#else +#if defined(SPIRV_TOOLS_IMPLEMENTATION) +#define SPIRV_TOOLS_EXPORT __attribute__((visibility("default"))) +#define SPIRV_TOOLS_LOCAL __attribute__((visibility("hidden"))) +#else +#define SPIRV_TOOLS_EXPORT +#define SPIRV_TOOLS_LOCAL +#endif +#endif +#else +#define SPIRV_TOOLS_EXPORT +#define SPIRV_TOOLS_LOCAL +#endif + +// Helpers + +#define SPV_BIT(shift) (1 << (shift)) + +#define SPV_FORCE_16_BIT_ENUM(name) SPV_FORCE_16BIT_##name = 0x7fff +#define SPV_FORCE_32_BIT_ENUM(name) SPV_FORCE_32BIT_##name = 0x7fffffff + +// Enumerations + +typedef enum spv_result_t { + SPV_SUCCESS = 0, + SPV_UNSUPPORTED = 1, + SPV_END_OF_STREAM = 2, + SPV_WARNING = 3, + SPV_FAILED_MATCH = 4, + SPV_REQUESTED_TERMINATION = 5, // Success, but signals early termination. + SPV_ERROR_INTERNAL = -1, + SPV_ERROR_OUT_OF_MEMORY = -2, + SPV_ERROR_INVALID_POINTER = -3, + SPV_ERROR_INVALID_BINARY = -4, + SPV_ERROR_INVALID_TEXT = -5, + SPV_ERROR_INVALID_TABLE = -6, + SPV_ERROR_INVALID_VALUE = -7, + SPV_ERROR_INVALID_DIAGNOSTIC = -8, + SPV_ERROR_INVALID_LOOKUP = -9, + SPV_ERROR_INVALID_ID = -10, + SPV_ERROR_INVALID_CFG = -11, + SPV_ERROR_INVALID_LAYOUT = -12, + SPV_ERROR_INVALID_CAPABILITY = -13, + SPV_ERROR_INVALID_DATA = -14, // Indicates data rules validation failure. + SPV_ERROR_MISSING_EXTENSION = -15, + SPV_ERROR_WRONG_VERSION = -16, // Indicates wrong SPIR-V version + SPV_ERROR_FNVAR = + -17, // Error related to SPV_INTEL_function_variants extension + SPV_FORCE_32_BIT_ENUM(spv_result_t) +} spv_result_t; + +// Severity levels of messages communicated to the consumer. +typedef enum spv_message_level_t { + SPV_MSG_FATAL, // Unrecoverable error due to environment. + // Will exit the program immediately. E.g., + // out of memory. + SPV_MSG_INTERNAL_ERROR, // Unrecoverable error due to SPIRV-Tools + // internals. + // Will exit the program immediately. E.g., + // unimplemented feature. + SPV_MSG_ERROR, // Normal error due to user input. + SPV_MSG_WARNING, // Warning information. + SPV_MSG_INFO, // General information. + SPV_MSG_DEBUG, // Debug information. +} spv_message_level_t; + +typedef enum spv_endianness_t { + SPV_ENDIANNESS_LITTLE, + SPV_ENDIANNESS_BIG, + SPV_FORCE_32_BIT_ENUM(spv_endianness_t) +} spv_endianness_t; + +// The kinds of operands that an instruction may have. +// +// Some operand types are "concrete". The binary parser uses a concrete +// operand type to describe an operand of a parsed instruction. +// +// The assembler uses all operand types. In addition to determining what +// kind of value an operand may be, non-concrete operand types capture the +// fact that an operand might be optional (may be absent, or present exactly +// once), or might occur zero or more times. +// +// Sometimes we also need to be able to express the fact that an operand +// is a member of an optional tuple of values. In that case the first member +// would be optional, and the subsequent members would be required. +// +// NOTE: Although we don't promise binary compatibility, as a courtesy, please +// add new enum values at the end. +typedef enum spv_operand_type_t { + // A sentinel value. + SPV_OPERAND_TYPE_NONE = 0, + + // Set 1: Operands that are IDs. + SPV_OPERAND_TYPE_ID, + SPV_OPERAND_TYPE_TYPE_ID, + SPV_OPERAND_TYPE_RESULT_ID, + SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, // SPIR-V Sec 3.25 + SPV_OPERAND_TYPE_SCOPE_ID, // SPIR-V Sec 3.27 + + // Set 2: Operands that are literal numbers. + SPV_OPERAND_TYPE_LITERAL_INTEGER, // Always unsigned 32-bits. + // The Instruction argument to OpExtInst. It's an unsigned 32-bit literal + // number indicating which instruction to use from an extended instruction + // set. + SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + // The Opcode argument to OpSpecConstantOp. It determines the operation + // to be performed on constant operands to compute a specialization constant + // result. + SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, + // A literal number whose format and size are determined by a previous operand + // in the same instruction. It's a signed integer, an unsigned integer, or a + // floating point number. It also has a specified bit width. The width + // may be larger than 32, which would require such a typed literal value to + // occupy multiple SPIR-V words. + SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, + SPV_OPERAND_TYPE_LITERAL_FLOAT, // Always 32-bit float. + + // Set 3: The literal string operand type. + SPV_OPERAND_TYPE_LITERAL_STRING, + + // Set 4: Operands that are a single word enumerated value. + SPV_OPERAND_TYPE_SOURCE_LANGUAGE, // SPIR-V Sec 3.2 + SPV_OPERAND_TYPE_EXECUTION_MODEL, // SPIR-V Sec 3.3 + SPV_OPERAND_TYPE_ADDRESSING_MODEL, // SPIR-V Sec 3.4 + SPV_OPERAND_TYPE_MEMORY_MODEL, // SPIR-V Sec 3.5 + SPV_OPERAND_TYPE_EXECUTION_MODE, // SPIR-V Sec 3.6 + SPV_OPERAND_TYPE_STORAGE_CLASS, // SPIR-V Sec 3.7 + SPV_OPERAND_TYPE_DIMENSIONALITY, // SPIR-V Sec 3.8 + SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, // SPIR-V Sec 3.9 + SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE, // SPIR-V Sec 3.10 + SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT, // SPIR-V Sec 3.11 + SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, // SPIR-V Sec 3.12 + SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, // SPIR-V Sec 3.13 + SPV_OPERAND_TYPE_FP_ROUNDING_MODE, // SPIR-V Sec 3.16 + SPV_OPERAND_TYPE_LINKAGE_TYPE, // SPIR-V Sec 3.17 + SPV_OPERAND_TYPE_ACCESS_QUALIFIER, // SPIR-V Sec 3.18 + SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, // SPIR-V Sec 3.19 + SPV_OPERAND_TYPE_DECORATION, // SPIR-V Sec 3.20 + SPV_OPERAND_TYPE_BUILT_IN, // SPIR-V Sec 3.21 + SPV_OPERAND_TYPE_GROUP_OPERATION, // SPIR-V Sec 3.28 + SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS, // SPIR-V Sec 3.29 + SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, // SPIR-V Sec 3.30 + SPV_OPERAND_TYPE_CAPABILITY, // SPIR-V Sec 3.31 + SPV_OPERAND_TYPE_FPENCODING, // SPIR-V Sec 3.51 + + // NOTE: New concrete enum values should be added at the end. + + // Set 5: Operands that are a single word bitmask. + // Sometimes a set bit indicates the instruction requires still more operands. + SPV_OPERAND_TYPE_IMAGE, // SPIR-V Sec 3.14 + SPV_OPERAND_TYPE_FP_FAST_MATH_MODE, // SPIR-V Sec 3.15 + SPV_OPERAND_TYPE_SELECTION_CONTROL, // SPIR-V Sec 3.22 + SPV_OPERAND_TYPE_LOOP_CONTROL, // SPIR-V Sec 3.23 + SPV_OPERAND_TYPE_FUNCTION_CONTROL, // SPIR-V Sec 3.24 + SPV_OPERAND_TYPE_MEMORY_ACCESS, // SPIR-V Sec 3.26 + SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, // SPIR-V Sec 3.FSR + + // NOTE: New concrete enum values should be added at the end. + + // The "optional" and "variable" operand types are only used internally by + // the assembler and the binary parser. + // There are two categories: + // Optional : expands to 0 or 1 operand, like ? in regular expressions. + // Variable : expands to 0, 1 or many operands or pairs of operands. + // This is similar to * in regular expressions. + + // Use characteristic function spvOperandIsConcrete to classify the + // operand types; when it returns false, the operand is optional or variable. + // + // Any variable operand type is also optional. + + // An optional operand represents zero or one logical operands. + // In an instruction definition, this may only appear at the end of the + // operand types. + SPV_OPERAND_TYPE_OPTIONAL_ID, + // An optional image operand type. + SPV_OPERAND_TYPE_OPTIONAL_IMAGE, + // An optional memory access type. + SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, + // An optional literal integer. + SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, + // An optional literal number, which may be either integer or floating point. + SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER, + // Like SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, but optional, and integral. + SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER, + // An optional literal string. + SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING, + // An optional access qualifier + SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, + // An optional context-independent value, or CIV. CIVs are tokens that we can + // assemble regardless of where they occur -- literals, IDs, immediate + // integers, etc. + SPV_OPERAND_TYPE_OPTIONAL_CIV, + // An optional floating point encoding enum + SPV_OPERAND_TYPE_OPTIONAL_FPENCODING, + + // A variable operand represents zero or more logical operands. + // In an instruction definition, this may only appear at the end of the + // operand types. + SPV_OPERAND_TYPE_VARIABLE_ID, + SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER, + // A sequence of zero or more pairs of (typed literal integer, Id). + // Expands to zero or more: + // (SPV_OPERAND_TYPE_TYPED_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID) + // where the literal number must always be an integer of some sort. + SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID, + // A sequence of zero or more pairs of (Id, Literal integer) + SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER, + + // The following are concrete enum types from the DebugInfo extended + // instruction set. + SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, // DebugInfo Sec 3.2. A mask. + SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, // DebugInfo Sec 3.3 + SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, // DebugInfo Sec 3.4 + SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, // DebugInfo Sec 3.5 + SPV_OPERAND_TYPE_DEBUG_OPERATION, // DebugInfo Sec 3.6 + + // The following are concrete enum types from the OpenCL.DebugInfo.100 + // extended instruction set. + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, // Sec 3.2. A Mask + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, // Sec 3.3 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, // Sec 3.4 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, // Sec 3.5 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, // Sec 3.6 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, // Sec 3.7 + + // The following are concrete enum types from SPV_INTEL_float_controls2 + // https://github.com/intel/llvm/blob/39fa9b0cbfbae88327118990a05c5b387b56d2ef/sycl/doc/extensions/SPIRV/SPV_INTEL_float_controls2.asciidoc + SPV_OPERAND_TYPE_FPDENORM_MODE, // Sec 3.17 FP Denorm Mode + SPV_OPERAND_TYPE_FPOPERATION_MODE, // Sec 3.18 FP Operation Mode + // A value enum from https://github.com/KhronosGroup/SPIRV-Headers/pull/177 + SPV_OPERAND_TYPE_QUANTIZATION_MODES, + // A value enum from https://github.com/KhronosGroup/SPIRV-Headers/pull/177 + SPV_OPERAND_TYPE_OVERFLOW_MODES, + + // Concrete operand types for the provisional Vulkan ray tracing feature. + SPV_OPERAND_TYPE_RAY_FLAGS, // SPIR-V Sec 3.RF + SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION, // SPIR-V Sec 3.RQIntersection + SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE, // SPIR-V Sec + // 3.RQCommitted + SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE, // SPIR-V Sec + // 3.RQCandidate + + // Concrete operand types for integer dot product. + // Packed vector format + SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT, // SPIR-V Sec 3.x + // An optional packed vector format + SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT, + + // Concrete operand types for cooperative matrix. + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, + // An optional cooperative matrix operands + SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS, + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, + + // Enum type from SPV_INTEL_global_variable_fpga_decorations + SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER, + // Enum type from SPV_INTEL_global_variable_host_access + SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER, + // Enum type from SPV_INTEL_cache_controls + SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL, + // Enum type from SPV_INTEL_cache_controls + SPV_OPERAND_TYPE_STORE_CACHE_CONTROL, + // Enum type from SPV_INTEL_maximum_registers + SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS, + // Enum type from SPV_NV_raw_access_chains + SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, + // Optional enum type from SPV_NV_raw_access_chains + SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS, + // Enum type from SPV_NV_tensor_addressing + SPV_OPERAND_TYPE_TENSOR_CLAMP_MODE, + // Enum type from SPV_NV_cooperative_matrix2 + SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE, + // Enum type from SPV_NV_cooperative_matrix2 + SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS, + // Optional types from SPV_INTEL_subgroup_matrix_multiply_accumulate + SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, + SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, + + SPV_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT, + SPV_OPERAND_TYPE_COMPONENT_TYPE, + + // From nonesmantic.clspvreflection + SPV_OPERAND_TYPE_KERNEL_PROPERTY_FLAGS, + + // From nonesmantic.shader.debuginfo.100 + SPV_OPERAND_TYPE_SHDEBUG100_BUILD_IDENTIFIER_FLAGS, + SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, + SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_COMPOSITE_TYPE, + SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_IMPORTED_ENTITY, + SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_INFO_FLAGS, + SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_OPERATION, + SPV_OPERAND_TYPE_SHDEBUG100_DEBUG_TYPE_QUALIFIER, + + // SPV_ARM_tensors + SPV_OPERAND_TYPE_TENSOR_OPERANDS, + SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS, + + // SPV_INTEL_function_variants + SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY, + SPV_OPERAND_TYPE_VARIABLE_CAPABILITY, + + // This is a sentinel value, and does not represent an operand type. + // It should come last. + SPV_OPERAND_TYPE_NUM_OPERAND_TYPES, + + SPV_FORCE_32_BIT_ENUM(spv_operand_type_t) +} spv_operand_type_t; + +// Returns true if the given type is concrete. +bool spvOperandIsConcrete(spv_operand_type_t type); + +// Returns true if the given type is concrete and also a mask. +bool spvOperandIsConcreteMask(spv_operand_type_t type); + +typedef enum spv_ext_inst_type_t { + SPV_EXT_INST_TYPE_NONE = 0, + SPV_EXT_INST_TYPE_GLSL_STD_450, + SPV_EXT_INST_TYPE_OPENCL_STD, + SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER, + SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX, + SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER, + SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT, + SPV_EXT_INST_TYPE_DEBUGINFO, + SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100, + SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, + SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100, + SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION, + SPV_EXT_INST_TYPE_TOSA_001000_1, + + // Multiple distinct extended instruction set types could return this + // value, if they are prefixed with NonSemantic. and are otherwise + // unrecognised + SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN, + + SPV_FORCE_32_BIT_ENUM(spv_ext_inst_type_t) +} spv_ext_inst_type_t; + +// This determines at a high level the kind of a binary-encoded literal +// number, but not the bit width. +// In principle, these could probably be folded into new entries in +// spv_operand_type_t. But then we'd have some special case differences +// between the assembler and disassembler. +typedef enum spv_number_kind_t { + SPV_NUMBER_NONE = 0, // The default for value initialization. + SPV_NUMBER_UNSIGNED_INT, + SPV_NUMBER_SIGNED_INT, + SPV_NUMBER_FLOATING, +} spv_number_kind_t; + +// Represent the encoding of floating point values +typedef enum spv_fp_encoding_t { + SPV_FP_ENCODING_UNKNOWN = + 0, // The encoding is not specified. Has to be deduced from bitwidth + SPV_FP_ENCODING_IEEE754_BINARY16, // half float + SPV_FP_ENCODING_IEEE754_BINARY32, // single float + SPV_FP_ENCODING_IEEE754_BINARY64, // double float + SPV_FP_ENCODING_BFLOAT16, + SPV_FP_ENCODING_FLOAT8_E4M3, + SPV_FP_ENCODING_FLOAT8_E5M2, +} spv_fp_encoding_t; + +typedef enum spv_text_to_binary_options_t { + SPV_TEXT_TO_BINARY_OPTION_NONE = SPV_BIT(0), + // Numeric IDs in the binary will have the same values as in the source. + // Non-numeric IDs are allocated by filling in the gaps, starting with 1 + // and going up. + SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS = SPV_BIT(1), + SPV_FORCE_32_BIT_ENUM(spv_text_to_binary_options_t) +} spv_text_to_binary_options_t; + +typedef enum spv_binary_to_text_options_t { + SPV_BINARY_TO_TEXT_OPTION_NONE = SPV_BIT(0), + SPV_BINARY_TO_TEXT_OPTION_PRINT = SPV_BIT(1), + SPV_BINARY_TO_TEXT_OPTION_COLOR = SPV_BIT(2), + SPV_BINARY_TO_TEXT_OPTION_INDENT = SPV_BIT(3), + SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET = SPV_BIT(4), + // Do not output the module header as leading comments in the assembly. + SPV_BINARY_TO_TEXT_OPTION_NO_HEADER = SPV_BIT(5), + // Use friendly names where possible. The heuristic may expand over + // time, but will use common names for scalar types, and debug names from + // OpName instructions. + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES = SPV_BIT(6), + // Add some comments to the generated assembly + SPV_BINARY_TO_TEXT_OPTION_COMMENT = SPV_BIT(7), + // Use nested indentation for more readable SPIR-V + SPV_BINARY_TO_TEXT_OPTION_NESTED_INDENT = SPV_BIT(8), + // Reorder blocks to match the structured control flow of SPIR-V to increase + // readability. + SPV_BINARY_TO_TEXT_OPTION_REORDER_BLOCKS = SPV_BIT(9), + SPV_FORCE_32_BIT_ENUM(spv_binary_to_text_options_t) +} spv_binary_to_text_options_t; + +// Constants + +// The default id bound is to the minimum value for the id limit +// in the spir-v specification under the section "Universal Limits". +const static uint32_t kDefaultMaxIdBound = 0x3FFFFF; + +// Structures + +// Information about an operand parsed from a binary SPIR-V module. +// Note that the values are not included. You still need access to the binary +// to extract the values. +typedef struct spv_parsed_operand_t { + // Location of the operand, in words from the start of the instruction. + uint16_t offset; + // Number of words occupied by this operand. + uint16_t num_words; + // The "concrete" operand type. See the definition of spv_operand_type_t + // for details. + spv_operand_type_t type; + // If type is a literal number type, then number_kind says whether it's + // a signed integer, an unsigned integer, or a floating point number. + spv_number_kind_t number_kind; + // The number of bits for a literal number type. + uint32_t number_bit_width; + // The encoding used for floating point values + spv_fp_encoding_t fp_encoding; +} spv_parsed_operand_t; + +// An instruction parsed from a binary SPIR-V module. +typedef struct spv_parsed_instruction_t { + // An array of words for this instruction, in native endianness. + const uint32_t* words; + // The number of words in this instruction. + uint16_t num_words; + uint16_t opcode; + // The extended instruction type, if opcode is OpExtInst. Otherwise + // this is the "none" value. + spv_ext_inst_type_t ext_inst_type; + // The type id, or 0 if this instruction doesn't have one. + uint32_t type_id; + // The result id, or 0 if this instruction doesn't have one. + uint32_t result_id; + // The array of parsed operands. + const spv_parsed_operand_t* operands; + uint16_t num_operands; +} spv_parsed_instruction_t; + +typedef struct spv_parsed_header_t { + // The magic number of the SPIR-V module. + uint32_t magic; + // Version number. + uint32_t version; + // Generator's magic number. + uint32_t generator; + // IDs bound for this module (0 < id < bound). + uint32_t bound; + // reserved. + uint32_t reserved; +} spv_parsed_header_t; + +typedef struct spv_const_binary_t { + const uint32_t* code; + const size_t wordCount; +} spv_const_binary_t; + +typedef struct spv_binary_t { + uint32_t* code; + size_t wordCount; +} spv_binary_t; + +typedef struct spv_text_t { + const char* str; + size_t length; +} spv_text_t; + +typedef struct spv_position_t { + size_t line; + size_t column; + size_t index; +} spv_position_t; + +typedef struct spv_diagnostic_t { + spv_position_t position; + char* error; + bool isTextSource; +} spv_diagnostic_t; + +// Opaque struct containing the context used to operate on a SPIR-V module. +// Its object is used by various translation API functions. +typedef struct spv_context_t spv_context_t; + +typedef struct spv_validator_options_t spv_validator_options_t; + +typedef struct spv_optimizer_options_t spv_optimizer_options_t; + +typedef struct spv_reducer_options_t spv_reducer_options_t; + +typedef struct spv_fuzzer_options_t spv_fuzzer_options_t; + +typedef struct spv_optimizer_t spv_optimizer_t; + +// Type Definitions + +typedef spv_const_binary_t* spv_const_binary; +typedef spv_binary_t* spv_binary; +typedef spv_text_t* spv_text; +typedef spv_position_t* spv_position; +typedef spv_diagnostic_t* spv_diagnostic; +typedef const spv_context_t* spv_const_context; +typedef spv_context_t* spv_context; +typedef spv_validator_options_t* spv_validator_options; +typedef const spv_validator_options_t* spv_const_validator_options; +typedef spv_optimizer_options_t* spv_optimizer_options; +typedef const spv_optimizer_options_t* spv_const_optimizer_options; +typedef spv_reducer_options_t* spv_reducer_options; +typedef const spv_reducer_options_t* spv_const_reducer_options; +typedef spv_fuzzer_options_t* spv_fuzzer_options; +typedef const spv_fuzzer_options_t* spv_const_fuzzer_options; + +// Platform API + +// Returns the SPIRV-Tools software version as a null-terminated string. +// The contents of the underlying storage is valid for the remainder of +// the process. +SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionString(void); +// Returns a null-terminated string containing the name of the project, +// the software version string, and commit details. +// The contents of the underlying storage is valid for the remainder of +// the process. +SPIRV_TOOLS_EXPORT const char* spvSoftwareVersionDetailsString(void); + +// Certain target environments impose additional restrictions on SPIR-V, so it's +// often necessary to specify which one applies. SPV_ENV_UNIVERSAL_* implies an +// environment-agnostic SPIR-V. +// +// When an API method needs to derive a SPIR-V version from a target environment +// (from the spv_context object), the method will choose the highest version of +// SPIR-V supported by the target environment. Examples: +// SPV_ENV_VULKAN_1_0 -> SPIR-V 1.0 +// SPV_ENV_VULKAN_1_1 -> SPIR-V 1.3 +// SPV_ENV_VULKAN_1_1_SPIRV_1_4 -> SPIR-V 1.4 +// SPV_ENV_VULKAN_1_2 -> SPIR-V 1.5 +// SPV_ENV_VULKAN_1_3 -> SPIR-V 1.6 +// SPV_ENV_VULKAN_1_4 -> SPIR-V 1.6 +// Consult the description of API entry points for specific rules. +typedef enum { + SPV_ENV_UNIVERSAL_1_0, // SPIR-V 1.0 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_0, // Vulkan 1.0 latest revision. + SPV_ENV_UNIVERSAL_1_1, // SPIR-V 1.1 latest revision, no other restrictions. + SPV_ENV_OPENCL_2_1, // OpenCL Full Profile 2.1 latest revision. + SPV_ENV_OPENCL_2_2, // OpenCL Full Profile 2.2 latest revision. + SPV_ENV_OPENGL_4_0, // OpenGL 4.0 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_OPENGL_4_1, // OpenGL 4.1 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_OPENGL_4_2, // OpenGL 4.2 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_OPENGL_4_3, // OpenGL 4.3 plus GL_ARB_gl_spirv, latest revisions. + // There is no variant for OpenGL 4.4. + SPV_ENV_OPENGL_4_5, // OpenGL 4.5 plus GL_ARB_gl_spirv, latest revisions. + SPV_ENV_UNIVERSAL_1_2, // SPIR-V 1.2, latest revision, no other restrictions. + SPV_ENV_OPENCL_1_2, // OpenCL Full Profile 1.2 plus cl_khr_il_program, + // latest revision. + SPV_ENV_OPENCL_EMBEDDED_1_2, // OpenCL Embedded Profile 1.2 plus + // cl_khr_il_program, latest revision. + SPV_ENV_OPENCL_2_0, // OpenCL Full Profile 2.0 plus cl_khr_il_program, + // latest revision. + SPV_ENV_OPENCL_EMBEDDED_2_0, // OpenCL Embedded Profile 2.0 plus + // cl_khr_il_program, latest revision. + SPV_ENV_OPENCL_EMBEDDED_2_1, // OpenCL Embedded Profile 2.1 latest revision. + SPV_ENV_OPENCL_EMBEDDED_2_2, // OpenCL Embedded Profile 2.2 latest revision. + SPV_ENV_UNIVERSAL_1_3, // SPIR-V 1.3 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_1, // Vulkan 1.1 latest revision. + SPV_ENV_WEBGPU_0, // DEPRECATED, may be removed in the future. + SPV_ENV_UNIVERSAL_1_4, // SPIR-V 1.4 latest revision, no other restrictions. + + // Vulkan 1.1 with VK_KHR_spirv_1_4, i.e. SPIR-V 1.4 binary. + SPV_ENV_VULKAN_1_1_SPIRV_1_4, + + SPV_ENV_UNIVERSAL_1_5, // SPIR-V 1.5 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_2, // Vulkan 1.2 latest revision. + + SPV_ENV_UNIVERSAL_1_6, // SPIR-V 1.6 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_3, // Vulkan 1.3 latest revision. + SPV_ENV_VULKAN_1_4, // Vulkan 1.4 latest revision. + + SPV_ENV_MAX // Keep this as the last enum value. +} spv_target_env; + +// SPIR-V Validator can be parameterized with the following Universal Limits. +typedef enum { + spv_validator_limit_max_struct_members, + spv_validator_limit_max_struct_depth, + spv_validator_limit_max_local_variables, + spv_validator_limit_max_global_variables, + spv_validator_limit_max_switch_branches, + spv_validator_limit_max_function_args, + spv_validator_limit_max_control_flow_nesting_depth, + spv_validator_limit_max_access_chain_indexes, + spv_validator_limit_max_id_bound, +} spv_validator_limit; + +// Returns a string describing the given SPIR-V target environment. +SPIRV_TOOLS_EXPORT const char* spvTargetEnvDescription(spv_target_env env); + +// Parses s into *env and returns true if successful. If unparsable, returns +// false and sets *env to SPV_ENV_UNIVERSAL_1_0. +SPIRV_TOOLS_EXPORT bool spvParseTargetEnv(const char* s, spv_target_env* env); + +// Determines the target env value with the least features but which enables +// the given Vulkan and SPIR-V versions. If such a target is supported, returns +// true and writes the value to |env|, otherwise returns false. +// +// The Vulkan version is given as an unsigned 32-bit number as specified in +// Vulkan section "29.2.1 Version Numbers": the major version number appears +// in bits 22 to 21, and the minor version is in bits 12 to 21. The SPIR-V +// version is given in the SPIR-V version header word: major version in bits +// 16 to 23, and minor version in bits 8 to 15. +SPIRV_TOOLS_EXPORT bool spvParseVulkanEnv(uint32_t vulkan_ver, + uint32_t spirv_ver, + spv_target_env* env); + +// Creates a context object for most of the SPIRV-Tools API. +// Returns null if env is invalid. +// +// See specific API calls for how the target environment is interpreted +// (particularly assembly and validation). +SPIRV_TOOLS_EXPORT spv_context spvContextCreate(spv_target_env env); + +// Destroys the given context object. +SPIRV_TOOLS_EXPORT void spvContextDestroy(spv_context context); + +// Creates a Validator options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// spvValidatorOptionsDestroy. +SPIRV_TOOLS_EXPORT spv_validator_options spvValidatorOptionsCreate(void); + +// Destroys the given Validator options object. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsDestroy( + spv_validator_options options); + +// Records the maximum Universal Limit that is considered valid in the given +// Validator options object. argument must be a valid options object. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetUniversalLimit( + spv_validator_options options, spv_validator_limit limit_type, + uint32_t limit); + +// Record whether or not the validator should relax the rules on types for +// stores to structs. When relaxed, it will allow a type mismatch as long as +// the types are structs with the same layout. Two structs have the same layout +// if +// +// 1) the members of the structs are either the same type or are structs with +// same layout, and +// +// 2) the decorations that affect the memory layout are identical for both +// types. Other decorations are not relevant. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxStoreStruct( + spv_validator_options options, bool val); + +// Records whether or not the validator should relax the rules on pointer usage +// in logical addressing mode. +// +// When relaxed, it will allow the following usage cases of pointers: +// 1) OpVariable allocating an object whose type is a pointer type +// 2) OpReturnValue returning a pointer value +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxLogicalPointer( + spv_validator_options options, bool val); + +// Records whether or not the validator should relax the rules because it is +// expected that the optimizations will make the code legal. +// +// When relaxed, it will allow the following: +// 1) It will allow relaxed logical pointers. Setting this option will also +// set that option. +// 2) Pointers that are pass as parameters to function calls do not have to +// match the storage class of the formal parameter. +// 3) Pointers that are actual parameters on function calls do not have to point +// to the same type pointed as the formal parameter. The types just need to +// logically match. +// 4) GLSLstd450 Interpolate* instructions can have a load of an interpolant +// for a first argument. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetBeforeHlslLegalization( + spv_validator_options options, bool val); + +// Records whether the validator should use "relaxed" block layout rules. +// Relaxed layout rules are described by Vulkan extension +// VK_KHR_relaxed_block_layout, and they affect uniform blocks, storage blocks, +// and push constants. +// +// This is enabled by default when targeting Vulkan 1.1 or later. +// Relaxed layout is more permissive than the default rules in Vulkan 1.0. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetRelaxBlockLayout( + spv_validator_options options, bool val); + +// Records whether the validator should use standard block layout rules for +// uniform blocks. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetUniformBufferStandardLayout( + spv_validator_options options, bool val); + +// Records whether the validator should use "scalar" block layout rules. +// Scalar layout rules are more permissive than relaxed block layout. +// +// See Vulkan extension VK_EXT_scalar_block_layout. The scalar alignment is +// defined as follows: +// - scalar alignment of a scalar is the scalar size +// - scalar alignment of a vector is the scalar alignment of its component +// - scalar alignment of a matrix is the scalar alignment of its component +// - scalar alignment of an array is the scalar alignment of its element +// - scalar alignment of a struct is the max scalar alignment among its +// members +// +// For a struct in Uniform, StorageClass, or PushConstant: +// - a member Offset must be a multiple of the member's scalar alignment +// - ArrayStride or MatrixStride must be a multiple of the array or matrix +// scalar alignment +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetScalarBlockLayout( + spv_validator_options options, bool val); + +// Records whether the validator should use "scalar" block layout +// rules (as defined above) for Workgroup blocks. See Vulkan +// extension VK_KHR_workgroup_memory_explicit_layout. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetWorkgroupScalarBlockLayout( + spv_validator_options options, bool val); + +// Records whether or not the validator should skip validating standard +// uniform/storage block layout. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetSkipBlockLayout( + spv_validator_options options, bool val); + +// Records whether or not the validator should allow the LocalSizeId +// decoration where the environment otherwise would not allow it. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowLocalSizeId( + spv_validator_options options, bool val); + +// Allow Offset (in addition to ConstOffset) for texture operations. +// Was added for VK_KHR_maintenance8 +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowOffsetTextureOperand( + spv_validator_options options, bool val); + +// Allow base operands of some bit operations to be non-32-bit wide. +// Was added for VK_KHR_maintenance9 +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowVulkan32BitBitwise( + spv_validator_options options, bool val); + +// Whether friendly names should be used in validation error messages. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetFriendlyNames( + spv_validator_options options, bool val); + +// Creates an optimizer options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// |spvOptimizerOptionsDestroy|. +SPIRV_TOOLS_EXPORT spv_optimizer_options spvOptimizerOptionsCreate(void); + +// Destroys the given optimizer options object. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsDestroy( + spv_optimizer_options options); + +// Records whether or not the optimizer should run the validator before +// optimizing. If |val| is true, the validator will be run. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetRunValidator( + spv_optimizer_options options, bool val); + +// Records the validator options that should be passed to the validator if it is +// run. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetValidatorOptions( + spv_optimizer_options options, spv_validator_options val); + +// Records the maximum possible value for the id bound. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetMaxIdBound( + spv_optimizer_options options, uint32_t val); + +// Records whether all bindings within the module should be preserved. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetPreserveBindings( + spv_optimizer_options options, bool val); + +// Records whether all specialization constants within the module +// should be preserved. +SPIRV_TOOLS_EXPORT void spvOptimizerOptionsSetPreserveSpecConstants( + spv_optimizer_options options, bool val); + +// Creates a reducer options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// |spvReducerOptionsDestroy|. +SPIRV_TOOLS_EXPORT spv_reducer_options spvReducerOptionsCreate(void); + +// Destroys the given reducer options object. +SPIRV_TOOLS_EXPORT void spvReducerOptionsDestroy(spv_reducer_options options); + +// Sets the maximum number of reduction steps that should run before the reducer +// gives up. +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetStepLimit( + spv_reducer_options options, uint32_t step_limit); + +// Sets the fail-on-validation-error option; if true, the reducer will return +// kStateInvalid if a reduction step yields a state that fails SPIR-V +// validation. Otherwise, an invalid state is treated as uninteresting and the +// reduction backtracks and continues. +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetFailOnValidationError( + spv_reducer_options options, bool fail_on_validation_error); + +// Sets the function that the reducer should target. If set to zero the reducer +// will target all functions as well as parts of the module that lie outside +// functions. Otherwise the reducer will restrict reduction to the function +// with result id |target_function|, which is required to exist. +SPIRV_TOOLS_EXPORT void spvReducerOptionsSetTargetFunction( + spv_reducer_options options, uint32_t target_function); + +// Creates a fuzzer options object with default options. Returns a valid +// options object. The object remains valid until it is passed into +// |spvFuzzerOptionsDestroy|. +SPIRV_TOOLS_EXPORT spv_fuzzer_options spvFuzzerOptionsCreate(void); + +// Destroys the given fuzzer options object. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsDestroy(spv_fuzzer_options options); + +// Enables running the validator after every transformation is applied during +// a replay. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableReplayValidation( + spv_fuzzer_options options); + +// Sets the seed with which the random number generator used by the fuzzer +// should be initialized. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetRandomSeed( + spv_fuzzer_options options, uint32_t seed); + +// Sets the range of transformations that should be applied during replay: 0 +// means all transformations, +N means the first N transformations, -N means all +// except the final N transformations. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetReplayRange( + spv_fuzzer_options options, int32_t replay_range); + +// Sets the maximum number of steps that the shrinker should take before giving +// up. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsSetShrinkerStepLimit( + spv_fuzzer_options options, uint32_t shrinker_step_limit); + +// Enables running the validator after every pass is applied during a fuzzing +// run. +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableFuzzerPassValidation( + spv_fuzzer_options options); + +// Enables all fuzzer passes during a fuzzing run (instead of a random subset +// of passes). +SPIRV_TOOLS_EXPORT void spvFuzzerOptionsEnableAllPasses( + spv_fuzzer_options options); + +// Encodes the given SPIR-V assembly text to its binary representation. The +// length parameter specifies the number of bytes for text. Encoded binary will +// be stored into *binary. Any error will be written into *diagnostic if +// diagnostic is non-null, otherwise the context's message consumer will be +// used. The generated binary is independent of the context and may outlive it. +// The SPIR-V binary version is set to the highest version of SPIR-V supported +// by the context's target environment. +SPIRV_TOOLS_EXPORT spv_result_t spvTextToBinary(const spv_const_context context, + const char* text, + const size_t length, + spv_binary* binary, + spv_diagnostic* diagnostic); + +// Encodes the given SPIR-V assembly text to its binary representation. Same as +// spvTextToBinary but with options. The options parameter is a bit field of +// spv_text_to_binary_options_t. +SPIRV_TOOLS_EXPORT spv_result_t spvTextToBinaryWithOptions( + const spv_const_context context, const char* text, const size_t length, + const uint32_t options, spv_binary* binary, spv_diagnostic* diagnostic); + +// Frees an allocated text stream. This is a no-op if the text parameter +// is a null pointer. +SPIRV_TOOLS_EXPORT void spvTextDestroy(spv_text text); + +// Decodes the given SPIR-V binary representation to its assembly text. The +// word_count parameter specifies the number of words for binary. The options +// parameter is a bit field of spv_binary_to_text_options_t. Decoded text will +// be stored into *text. Any error will be written into *diagnostic if +// diagnostic is non-null, otherwise the context's message consumer will be +// used. +SPIRV_TOOLS_EXPORT spv_result_t spvBinaryToText(const spv_const_context context, + const uint32_t* binary, + const size_t word_count, + const uint32_t options, + spv_text* text, + spv_diagnostic* diagnostic); + +// Frees a binary stream from memory. This is a no-op if binary is a null +// pointer. +SPIRV_TOOLS_EXPORT void spvBinaryDestroy(spv_binary binary); + +// Validates a SPIR-V binary for correctness. Any errors will be written into +// *diagnostic if diagnostic is non-null, otherwise the context's message +// consumer will be used. +// +// Validate for SPIR-V spec rules for the SPIR-V version named in the +// binary's header (at word offset 1). Additionally, if the context target +// environment is a client API (such as Vulkan 1.1), then validate for that +// client API version, to the extent that it is verifiable from data in the +// binary itself. +SPIRV_TOOLS_EXPORT spv_result_t spvValidate(const spv_const_context context, + const spv_const_binary binary, + spv_diagnostic* diagnostic); + +// Validates a SPIR-V binary for correctness. Uses the provided Validator +// options. Any errors will be written into *diagnostic if diagnostic is +// non-null, otherwise the context's message consumer will be used. +// +// Validate for SPIR-V spec rules for the SPIR-V version named in the +// binary's header (at word offset 1). Additionally, if the context target +// environment is a client API (such as Vulkan 1.1), then validate for that +// client API version, to the extent that it is verifiable from data in the +// binary itself, or in the validator options. +SPIRV_TOOLS_EXPORT spv_result_t spvValidateWithOptions( + const spv_const_context context, const spv_const_validator_options options, + const spv_const_binary binary, spv_diagnostic* diagnostic); + +// Validates a raw SPIR-V binary for correctness. Any errors will be written +// into *diagnostic if diagnostic is non-null, otherwise the context's message +// consumer will be used. +SPIRV_TOOLS_EXPORT spv_result_t +spvValidateBinary(const spv_const_context context, const uint32_t* words, + const size_t num_words, spv_diagnostic* diagnostic); + +// Creates a diagnostic object. The position parameter specifies the location in +// the text/binary stream. The message parameter, copied into the diagnostic +// object, contains the error message to display. +SPIRV_TOOLS_EXPORT spv_diagnostic +spvDiagnosticCreate(const spv_position position, const char* message); + +// Destroys a diagnostic object. This is a no-op if diagnostic is a null +// pointer. +SPIRV_TOOLS_EXPORT void spvDiagnosticDestroy(spv_diagnostic diagnostic); + +// Prints the diagnostic to stderr. +SPIRV_TOOLS_EXPORT spv_result_t +spvDiagnosticPrint(const spv_diagnostic diagnostic); + +// Gets the name of an instruction, without the "Op" prefix. +SPIRV_TOOLS_EXPORT const char* spvOpcodeString(const uint32_t opcode); + +// The binary parser interface. + +// A pointer to a function that accepts a parsed SPIR-V header. +// The integer arguments are the 32-bit words from the header, as specified +// in SPIR-V 1.0 Section 2.3 Table 1. +// The function should return SPV_SUCCESS if parsing should continue. +typedef spv_result_t (*spv_parsed_header_fn_t)( + void* user_data, spv_endianness_t endian, uint32_t magic, uint32_t version, + uint32_t generator, uint32_t id_bound, uint32_t reserved); + +// A pointer to a function that accepts a parsed SPIR-V instruction. +// The parsed_instruction value is transient: it may be overwritten +// or released immediately after the function has returned. That also +// applies to the words array member of the parsed instruction. The +// function should return SPV_SUCCESS if and only if parsing should +// continue. +typedef spv_result_t (*spv_parsed_instruction_fn_t)( + void* user_data, const spv_parsed_instruction_t* parsed_instruction); + +// Parses a SPIR-V binary, specified as counted sequence of 32-bit words. +// Parsing feedback is provided via two callbacks provided as function +// pointers. Each callback function pointer can be a null pointer, in +// which case it is never called. Otherwise, in a valid parse the +// parsed-header callback is called once, and then the parsed-instruction +// callback once for each instruction in the stream. The user_data parameter +// is supplied as context to the callbacks. Returns SPV_SUCCESS on successful +// parse where the callbacks always return SPV_SUCCESS. For an invalid parse, +// returns a status code other than SPV_SUCCESS, and if diagnostic is non-null +// also emits a diagnostic. If diagnostic is null the context's message consumer +// will be used to emit any errors. If a callback returns anything other than +// SPV_SUCCESS, then that status code is returned, no further callbacks are +// issued, and no additional diagnostics are emitted. +SPIRV_TOOLS_EXPORT spv_result_t spvBinaryParse( + const spv_const_context context, void* user_data, const uint32_t* words, + const size_t num_words, spv_parsed_header_fn_t parse_header, + spv_parsed_instruction_fn_t parse_instruction, spv_diagnostic* diagnostic); + +// The optimizer interface. + +// A pointer to a function that accepts a log message from an optimizer. +typedef void (*spv_message_consumer)( + spv_message_level_t, const char*, const spv_position_t*, const char*); + +// Creates and returns an optimizer object. This object must be passed to +// optimizer APIs below and is valid until passed to spvOptimizerDestroy. +SPIRV_TOOLS_EXPORT spv_optimizer_t* spvOptimizerCreate(spv_target_env env); + +// Destroys the given optimizer object. +SPIRV_TOOLS_EXPORT void spvOptimizerDestroy(spv_optimizer_t* optimizer); + +// Sets an spv_message_consumer on an optimizer object. +SPIRV_TOOLS_EXPORT void spvOptimizerSetMessageConsumer( + spv_optimizer_t* optimizer, spv_message_consumer consumer); + +// Registers passes that attempt to legalize the generated code. +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterLegalizationPasses( + spv_optimizer_t* optimizer); + +// Registers passes that attempt to improve performance of generated code. +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterPerformancePasses( + spv_optimizer_t* optimizer); + +// Registers passes that attempt to improve the size of generated code. +SPIRV_TOOLS_EXPORT void spvOptimizerRegisterSizePasses( + spv_optimizer_t* optimizer); + +// Registers a pass specified by a flag in an optimizer object. +SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag( + spv_optimizer_t* optimizer, const char* flag); + +// Registers passes specified by length number of flags in an optimizer object. +// Passes may remove interface variables that are unused. +SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags( + spv_optimizer_t* optimizer, const char** flags, const size_t flag_count); + +// Registers passes specified by length number of flags in an optimizer object. +// Passes will not remove interface variables. +SPIRV_TOOLS_EXPORT bool +spvOptimizerRegisterPassesFromFlagsWhilePreservingTheInterface( + spv_optimizer_t* optimizer, const char** flags, const size_t flag_count); + +// Optimizes the SPIR-V code of size |word_count| pointed to by |binary| and +// returns an optimized spv_binary in |optimized_binary|. +// +// Returns SPV_SUCCESS on successful optimization, whether or not the module is +// modified. Returns an SPV_ERROR_* if the module fails to validate or if +// errors occur when processing using any of the registered passes. In that +// case, no further passes are executed and the |optimized_binary| contents may +// be invalid. +// +// By default, the binary is validated before any transforms are performed, +// and optionally after each transform. Validation uses SPIR-V spec rules +// for the SPIR-V version named in the binary's header (at word offset 1). +// Additionally, if the target environment is a client API (such as +// Vulkan 1.1), then validate for that client API version, to the extent +// that it is verifiable from data in the binary itself, or from the +// validator options set on the optimizer options. +SPIRV_TOOLS_EXPORT spv_result_t spvOptimizerRun( + spv_optimizer_t* optimizer, const uint32_t* binary, const size_t word_count, + spv_binary* optimized_binary, const spv_optimizer_options options); + +#ifdef __cplusplus +} +#endif + +#endif // INCLUDE_SPIRV_TOOLS_LIBSPIRV_H_ diff --git a/thirdparty/headers/glslang/include/spirv-tools/libspirv.hpp b/thirdparty/headers/glslang/include/spirv-tools/libspirv.hpp new file mode 100644 index 000000000..1b3ed86a8 --- /dev/null +++ b/thirdparty/headers/glslang/include/spirv-tools/libspirv.hpp @@ -0,0 +1,410 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ +#define INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ + +#include +#include +#include +#include + +#include "libspirv.h" + +namespace spvtools { + +// Message consumer. The C strings for source and message are only alive for the +// specific invocation. +using MessageConsumer = std::function; + +using HeaderParser = std::function; +using InstructionParser = + std::function; + +// C++ RAII wrapper around the C context object spv_context. +class SPIRV_TOOLS_EXPORT Context { + public: + // Constructs a context targeting the given environment |env|. + // + // See specific API calls for how the target environment is interpreted + // (particularly assembly and validation). + // + // The constructed instance will have an empty message consumer, which just + // ignores all messages from the library. Use SetMessageConsumer() to supply + // one if messages are of concern. + explicit Context(spv_target_env env); + + // Enables move constructor/assignment operations. + Context(Context&& other); + Context& operator=(Context&& other); + + // Disables copy constructor/assignment operations. + Context(const Context&) = delete; + Context& operator=(const Context&) = delete; + + // Destructs this instance. + ~Context(); + + // Sets the message consumer to the given |consumer|. The |consumer| will be + // invoked once for each message communicated from the library. + void SetMessageConsumer(MessageConsumer consumer); + + // Returns the underlying spv_context. + spv_context& CContext(); + const spv_context& CContext() const; + + private: + spv_context context_; +}; + +// A RAII wrapper around a validator options object. +class SPIRV_TOOLS_EXPORT ValidatorOptions { + public: + ValidatorOptions() : options_(spvValidatorOptionsCreate()) {} + ~ValidatorOptions() { spvValidatorOptionsDestroy(options_); } + // Allow implicit conversion to the underlying object. + operator spv_validator_options() const { return options_; } + + // Sets a limit. + void SetUniversalLimit(spv_validator_limit limit_type, uint32_t limit) { + spvValidatorOptionsSetUniversalLimit(options_, limit_type, limit); + } + + void SetRelaxStructStore(bool val) { + spvValidatorOptionsSetRelaxStoreStruct(options_, val); + } + + // Enables VK_KHR_relaxed_block_layout when validating standard + // uniform/storage buffer/push-constant layout. If true, disables + // scalar block layout rules. + void SetRelaxBlockLayout(bool val) { + spvValidatorOptionsSetRelaxBlockLayout(options_, val); + } + + // Enables VK_KHR_uniform_buffer_standard_layout when validating standard + // uniform layout. If true, disables scalar block layout rules. + void SetUniformBufferStandardLayout(bool val) { + spvValidatorOptionsSetUniformBufferStandardLayout(options_, val); + } + + // Enables VK_EXT_scalar_block_layout when validating standard + // uniform/storage buffer/push-constant layout. If true, disables + // relaxed block layout rules. + void SetScalarBlockLayout(bool val) { + spvValidatorOptionsSetScalarBlockLayout(options_, val); + } + + // Enables scalar layout when validating Workgroup blocks. See + // VK_KHR_workgroup_memory_explicit_layout. + void SetWorkgroupScalarBlockLayout(bool val) { + spvValidatorOptionsSetWorkgroupScalarBlockLayout(options_, val); + } + + // Skips validating standard uniform/storage buffer/push-constant layout. + void SetSkipBlockLayout(bool val) { + spvValidatorOptionsSetSkipBlockLayout(options_, val); + } + + // Enables LocalSizeId decorations where the environment would not otherwise + // allow them. + void SetAllowLocalSizeId(bool val) { + spvValidatorOptionsSetAllowLocalSizeId(options_, val); + } + + // Allow Offset (in addition to ConstOffset) for texture + // operations. Was added for VK_KHR_maintenance8 + void SetAllowOffsetTextureOperand(bool val) { + spvValidatorOptionsSetAllowOffsetTextureOperand(options_, val); + } + + // Allow base operands of some bit operations to be non-32-bit wide. + // Was added for VK_KHR_maintenance9 + void SetAllowVulkan32BitBitwise(bool val) { + spvValidatorOptionsSetAllowVulkan32BitBitwise(options_, val); + } + + // Records whether or not the validator should relax the rules on pointer + // usage in logical addressing mode. + // + // When relaxed, it will allow the following usage cases of pointers: + // 1) OpVariable allocating an object whose type is a pointer type + // 2) OpReturnValue returning a pointer value + void SetRelaxLogicalPointer(bool val) { + spvValidatorOptionsSetRelaxLogicalPointer(options_, val); + } + + // Records whether or not the validator should relax the rules because it is + // expected that the optimizations will make the code legal. + // + // When relaxed, it will allow the following: + // 1) It will allow relaxed logical pointers. Setting this option will also + // set that option. + // 2) Pointers that are pass as parameters to function calls do not have to + // match the storage class of the formal parameter. + // 3) Pointers that are actual parameters on function calls do not have to + // point to the same type pointed as the formal parameter. The types just + // need to logically match. + // 4) GLSLstd450 Interpolate* instructions can have a load of an interpolant + // for a first argument. + void SetBeforeHlslLegalization(bool val) { + spvValidatorOptionsSetBeforeHlslLegalization(options_, val); + } + + // Whether friendly names should be used in validation error messages. + void SetFriendlyNames(bool val) { + spvValidatorOptionsSetFriendlyNames(options_, val); + } + + private: + spv_validator_options options_; +}; + +// A C++ wrapper around an optimization options object. +class SPIRV_TOOLS_EXPORT OptimizerOptions { + public: + OptimizerOptions() : options_(spvOptimizerOptionsCreate()) {} + ~OptimizerOptions() { spvOptimizerOptionsDestroy(options_); } + + // Allow implicit conversion to the underlying object. + operator spv_optimizer_options() const { return options_; } + + // Records whether or not the optimizer should run the validator before + // optimizing. If |run| is true, the validator will be run. + void set_run_validator(bool run) { + spvOptimizerOptionsSetRunValidator(options_, run); + } + + // Records the validator options that should be passed to the validator if it + // is run. + void set_validator_options(const ValidatorOptions& val_options) { + spvOptimizerOptionsSetValidatorOptions(options_, val_options); + } + + // Records the maximum possible value for the id bound. + void set_max_id_bound(uint32_t new_bound) { + spvOptimizerOptionsSetMaxIdBound(options_, new_bound); + } + + // Records whether all bindings within the module should be preserved. + void set_preserve_bindings(bool preserve_bindings) { + spvOptimizerOptionsSetPreserveBindings(options_, preserve_bindings); + } + + // Records whether all specialization constants within the module + // should be preserved. + void set_preserve_spec_constants(bool preserve_spec_constants) { + spvOptimizerOptionsSetPreserveSpecConstants(options_, + preserve_spec_constants); + } + + private: + spv_optimizer_options options_; +}; + +// A C++ wrapper around a reducer options object. +class SPIRV_TOOLS_EXPORT ReducerOptions { + public: + ReducerOptions() : options_(spvReducerOptionsCreate()) {} + ~ReducerOptions() { spvReducerOptionsDestroy(options_); } + + // Allow implicit conversion to the underlying object. + operator spv_reducer_options() const { // NOLINT(google-explicit-constructor) + return options_; + } + + // See spvReducerOptionsSetStepLimit. + void set_step_limit(uint32_t step_limit) { + spvReducerOptionsSetStepLimit(options_, step_limit); + } + + // See spvReducerOptionsSetFailOnValidationError. + void set_fail_on_validation_error(bool fail_on_validation_error) { + spvReducerOptionsSetFailOnValidationError(options_, + fail_on_validation_error); + } + + // See spvReducerOptionsSetTargetFunction. + void set_target_function(uint32_t target_function) { + spvReducerOptionsSetTargetFunction(options_, target_function); + } + + private: + spv_reducer_options options_; +}; + +// A C++ wrapper around a fuzzer options object. +class SPIRV_TOOLS_EXPORT FuzzerOptions { + public: + FuzzerOptions() : options_(spvFuzzerOptionsCreate()) {} + ~FuzzerOptions() { spvFuzzerOptionsDestroy(options_); } + + // Allow implicit conversion to the underlying object. + operator spv_fuzzer_options() const { // NOLINT(google-explicit-constructor) + return options_; + } + + // See spvFuzzerOptionsEnableReplayValidation. + void enable_replay_validation() { + spvFuzzerOptionsEnableReplayValidation(options_); + } + + // See spvFuzzerOptionsSetRandomSeed. + void set_random_seed(uint32_t seed) { + spvFuzzerOptionsSetRandomSeed(options_, seed); + } + + // See spvFuzzerOptionsSetReplayRange. + void set_replay_range(int32_t replay_range) { + spvFuzzerOptionsSetReplayRange(options_, replay_range); + } + + // See spvFuzzerOptionsSetShrinkerStepLimit. + void set_shrinker_step_limit(uint32_t shrinker_step_limit) { + spvFuzzerOptionsSetShrinkerStepLimit(options_, shrinker_step_limit); + } + + // See spvFuzzerOptionsEnableFuzzerPassValidation. + void enable_fuzzer_pass_validation() { + spvFuzzerOptionsEnableFuzzerPassValidation(options_); + } + + // See spvFuzzerOptionsEnableAllPasses. + void enable_all_passes() { spvFuzzerOptionsEnableAllPasses(options_); } + + private: + spv_fuzzer_options options_; +}; + +// C++ interface for SPIRV-Tools functionalities. It wraps the context +// (including target environment and the corresponding SPIR-V grammar) and +// provides methods for assembling, disassembling, and validating. +// +// Instances of this class provide basic thread-safety guarantee. +class SPIRV_TOOLS_EXPORT SpirvTools { + public: + enum { + // Default assembling option used by assemble(): + kDefaultAssembleOption = SPV_TEXT_TO_BINARY_OPTION_NONE, + + // Default disassembling option used by Disassemble(): + // * Avoid prefix comments from decoding the SPIR-V module header, and + // * Use friendly names for variables. + kDefaultDisassembleOption = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER | + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES + }; + + // Constructs an instance targeting the given environment |env|. + // + // The constructed instance will have an empty message consumer, which just + // ignores all messages from the library. Use SetMessageConsumer() to supply + // one if messages are of concern. + explicit SpirvTools(spv_target_env env); + + // Disables copy/move constructor/assignment operations. + SpirvTools(const SpirvTools&) = delete; + SpirvTools(SpirvTools&&) = delete; + SpirvTools& operator=(const SpirvTools&) = delete; + SpirvTools& operator=(SpirvTools&&) = delete; + + // Destructs this instance. + ~SpirvTools(); + + // Sets the message consumer to the given |consumer|. The |consumer| will be + // invoked once for each message communicated from the library. + void SetMessageConsumer(MessageConsumer consumer); + + // Assembles the given assembly |text| and writes the result to |binary|. + // Returns true on successful assembling. |binary| will be kept untouched if + // assembling is unsuccessful. + // The SPIR-V binary version is set to the highest version of SPIR-V supported + // by the target environment with which this SpirvTools object was created. + bool Assemble(const std::string& text, std::vector* binary, + uint32_t options = kDefaultAssembleOption) const; + // |text_size| specifies the number of bytes in |text|. A terminating null + // character is not required to present in |text| as long as |text| is valid. + // The SPIR-V binary version is set to the highest version of SPIR-V supported + // by the target environment with which this SpirvTools object was created. + bool Assemble(const char* text, size_t text_size, + std::vector* binary, + uint32_t options = kDefaultAssembleOption) const; + + // Disassembles the given SPIR-V |binary| with the given |options| and writes + // the assembly to |text|. Returns true on successful disassembling. |text| + // will be kept untouched if diassembling is unsuccessful. + bool Disassemble(const std::vector& binary, std::string* text, + uint32_t options = kDefaultDisassembleOption) const; + // |binary_size| specifies the number of words in |binary|. + bool Disassemble(const uint32_t* binary, size_t binary_size, + std::string* text, + uint32_t options = kDefaultDisassembleOption) const; + + // Parses a SPIR-V binary, specified as counted sequence of 32-bit words. + // Parsing feedback is provided via two callbacks provided as std::function. + // In a valid parse the parsed-header callback is called once, and + // then the parsed-instruction callback is called once for each instruction + // in the stream. + // Returns true on successful parsing. + // If diagnostic is non-null, a diagnostic is emitted on failed parsing. + // If diagnostic is null the context's message consumer + // will be used to emit any errors. If a callback returns anything other than + // SPV_SUCCESS, then that status code is returned, no further callbacks are + // issued, and no additional diagnostics are emitted. + // This is a wrapper around the C API spvBinaryParse. + bool Parse(const std::vector& binary, + const HeaderParser& header_parser, + const InstructionParser& instruction_parser, + spv_diagnostic* diagnostic = nullptr); + + // Validates the given SPIR-V |binary|. Returns true if no issues are found. + // Otherwise, returns false and communicates issues via the message consumer + // registered. + // Validates for SPIR-V spec rules for the SPIR-V version named in the + // binary's header (at word offset 1). Additionally, if the target + // environment is a client API (such as Vulkan 1.1), then validate for that + // client API version, to the extent that it is verifiable from data in the + // binary itself. + bool Validate(const std::vector& binary) const; + // Like the previous overload, but provides the binary as a pointer and size: + // |binary_size| specifies the number of words in |binary|. + // Validates for SPIR-V spec rules for the SPIR-V version named in the + // binary's header (at word offset 1). Additionally, if the target + // environment is a client API (such as Vulkan 1.1), then validate for that + // client API version, to the extent that it is verifiable from data in the + // binary itself. + bool Validate(const uint32_t* binary, size_t binary_size) const; + // Like the previous overload, but takes an options object. + // Validates for SPIR-V spec rules for the SPIR-V version named in the + // binary's header (at word offset 1). Additionally, if the target + // environment is a client API (such as Vulkan 1.1), then validate for that + // client API version, to the extent that it is verifiable from data in the + // binary itself, or in the validator options. + bool Validate(const uint32_t* binary, size_t binary_size, + spv_validator_options options) const; + + // Was this object successfully constructed. + bool IsValid() const; + + private: + struct SPIRV_TOOLS_LOCAL + Impl; // Opaque struct for holding the data fields used by this class. + std::unique_ptr impl_; // Unique pointer to implementation data. +}; + +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_LIBSPIRV_HPP_ diff --git a/thirdparty/headers/glslang/include/spirv-tools/linker.hpp b/thirdparty/headers/glslang/include/spirv-tools/linker.hpp new file mode 100644 index 000000000..99527ed6d --- /dev/null +++ b/thirdparty/headers/glslang/include/spirv-tools/linker.hpp @@ -0,0 +1,128 @@ +// Copyright (c) 2017 Pierre Moreau +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_LINKER_HPP_ +#define INCLUDE_SPIRV_TOOLS_LINKER_HPP_ + +#include +#include +#include + +#include "libspirv.hpp" + +namespace spvtools { + +class SPIRV_TOOLS_EXPORT LinkerOptions { + public: + // Returns whether a library or an executable should be produced by the + // linking phase. + // + // All exported symbols are kept when creating a library, whereas they will + // be removed when creating an executable. + // The returned value will be true if creating a library, and false if + // creating an executable. + bool GetCreateLibrary() const { return create_library_; } + + // Sets whether a library or an executable should be produced. + void SetCreateLibrary(bool create_library) { + create_library_ = create_library; + } + + // Returns whether to verify the uniqueness of the unique ids in the merged + // context. + bool GetVerifyIds() const { return verify_ids_; } + + // Sets whether to verify the uniqueness of the unique ids in the merged + // context. + void SetVerifyIds(bool verify_ids) { verify_ids_ = verify_ids; } + + // Returns whether to allow for imported symbols to have no corresponding + // exported symbols + bool GetAllowPartialLinkage() const { return allow_partial_linkage_; } + + // Sets whether to allow for imported symbols to have no corresponding + // exported symbols + void SetAllowPartialLinkage(bool allow_partial_linkage) { + allow_partial_linkage_ = allow_partial_linkage; + } + + bool GetUseHighestVersion() const { return use_highest_version_; } + void SetUseHighestVersion(bool use_highest_vers) { + use_highest_version_ = use_highest_vers; + } + + bool GetAllowPtrTypeMismatch() const { return allow_ptr_type_mismatch_; } + void SetAllowPtrTypeMismatch(bool allow_ptr_type_mismatch) { + allow_ptr_type_mismatch_ = allow_ptr_type_mismatch; + } + + std::string GetFnVarTargetsCsv() const { return fnvar_targets_csv_; } + void SetFnVarTargetsCsv(std::string fnvar_targets_csv) { + fnvar_targets_csv_ = fnvar_targets_csv; + } + + std::string GetFnVarArchitecturesCsv() const { + return fnvar_architectures_csv_; + } + void SetFnVarArchitecturesCsv(std::string fnvar_architectures_csv) { + fnvar_architectures_csv_ = fnvar_architectures_csv; + } + + bool GetHasFnVarCapabilities() const { return has_fnvar_capabilities_; } + void SetHasFnVarCapabilities(bool fnvar_capabilities) { + has_fnvar_capabilities_ = fnvar_capabilities; + } + + std::vector GetInFiles() const { return in_files_; } + void SetInFiles(std::vector in_files) { in_files_ = in_files; } + + private: + bool create_library_{false}; + bool verify_ids_{false}; + bool allow_partial_linkage_{false}; + bool use_highest_version_{false}; + bool allow_ptr_type_mismatch_{false}; + std::string fnvar_targets_csv_{""}; + std::string fnvar_architectures_csv_{""}; + bool has_fnvar_capabilities_ = false; + std::vector in_files_{{}}; +}; + +// Links one or more SPIR-V modules into a new SPIR-V module. That is, combine +// several SPIR-V modules into one, resolving link dependencies between them. +// +// At least one binary has to be provided in |binaries|. Those binaries do not +// have to be valid, but they should be at least parseable. +// The functions can fail due to the following: +// * The given context was not initialised using `spvContextCreate()`; +// * No input modules were given; +// * One or more of those modules were not parseable; +// * The input modules used different addressing or memory models; +// * The ID or global variable number limit were exceeded; +// * Some entry points were defined multiple times; +// * Some imported symbols did not have an exported counterpart; +// * Possibly other reasons. +SPIRV_TOOLS_EXPORT spv_result_t +Link(const Context& context, const std::vector>& binaries, + std::vector* linked_binary, + const LinkerOptions& options = LinkerOptions()); +SPIRV_TOOLS_EXPORT spv_result_t +Link(const Context& context, const uint32_t* const* binaries, + const size_t* binary_sizes, size_t num_binaries, + std::vector* linked_binary, + const LinkerOptions& options = LinkerOptions()); + +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_LINKER_HPP_ diff --git a/thirdparty/headers/glslang/include/spirv-tools/optimizer.hpp b/thirdparty/headers/glslang/include/spirv-tools/optimizer.hpp new file mode 100644 index 000000000..b25ad47ec --- /dev/null +++ b/thirdparty/headers/glslang/include/spirv-tools/optimizer.hpp @@ -0,0 +1,1037 @@ +// Copyright (c) 2016 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ +#define INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ + +#include +#include +#include +#include +#include +#include +#include + +#include "libspirv.hpp" + +namespace spvtools { + +namespace opt { +class Pass; +struct DescriptorSetAndBinding; +} // namespace opt + +// C++ interface for SPIR-V optimization functionalities. It wraps the context +// (including target environment and the corresponding SPIR-V grammar) and +// provides methods for registering optimization passes and optimizing. +// +// Instances of this class provides basic thread-safety guarantee. +class SPIRV_TOOLS_EXPORT Optimizer { + public: + // The token for an optimization pass. It is returned via one of the + // Create*Pass() standalone functions at the end of this header file and + // consumed by the RegisterPass() method. Tokens are one-time objects that + // only support move; copying is not allowed. + struct PassToken { + struct SPIRV_TOOLS_LOCAL Impl; // Opaque struct for holding internal data. + + PassToken(std::unique_ptr); + + // Tokens for built-in passes should be created using Create*Pass functions + // below; for out-of-tree passes, use this constructor instead. + // Note that this API isn't guaranteed to be stable and may change without + // preserving source or binary compatibility in the future. + PassToken(std::unique_ptr&& pass); + + // Tokens can only be moved. Copying is disabled. + PassToken(const PassToken&) = delete; + PassToken(PassToken&&); + PassToken& operator=(const PassToken&) = delete; + PassToken& operator=(PassToken&&); + + ~PassToken(); + + std::unique_ptr impl_; // Unique pointer to internal data. + }; + + // Constructs an instance with the given target |env|, which is used to decode + // the binaries to be optimized later. + // + // The instance will have an empty message consumer, which ignores all + // messages from the library. Use SetMessageConsumer() to supply a consumer + // if messages are of concern. + explicit Optimizer(spv_target_env env); + + // Disables copy/move constructor/assignment operations. + Optimizer(const Optimizer&) = delete; + Optimizer(Optimizer&&) = delete; + Optimizer& operator=(const Optimizer&) = delete; + Optimizer& operator=(Optimizer&&) = delete; + + // Destructs this instance. + ~Optimizer(); + + // Sets the message consumer to the given |consumer|. The |consumer| will be + // invoked once for each message communicated from the library. + void SetMessageConsumer(MessageConsumer consumer); + + // Returns a reference to the registered message consumer. + const MessageConsumer& consumer() const; + + // Registers the given |pass| to this optimizer. Passes will be run in the + // exact order of registration. The token passed in will be consumed by this + // method. + Optimizer& RegisterPass(PassToken&& pass); + + // Registers passes that attempt to improve performance of generated code. + // This sequence of passes is subject to constant review and will change + // from time to time. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + Optimizer& RegisterPerformancePasses(); + Optimizer& RegisterPerformancePasses(bool preserve_interface); + + // Registers passes that attempt to improve the size of generated code. + // This sequence of passes is subject to constant review and will change + // from time to time. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + Optimizer& RegisterSizePasses(); + Optimizer& RegisterSizePasses(bool preserve_interface); + + // Registers passes that attempt to legalize the generated code. + // + // Note: this recipe is specially designed for legalizing SPIR-V. It should be + // used by compilers after translating HLSL source code literally. It should + // *not* be used by general workloads for performance or size improvement. + // + // This sequence of passes is subject to constant review and will change + // from time to time. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + Optimizer& RegisterLegalizationPasses(); + Optimizer& RegisterLegalizationPasses(bool preserve_interface); + + // Register passes specified in the list of |flags|. Each flag must be a + // string of a form accepted by Optimizer::FlagHasValidForm(). + // + // If the list of flags contains an invalid entry, it returns false and an + // error message is emitted to the MessageConsumer object (use + // Optimizer::SetMessageConsumer to define a message consumer, if needed). + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + // + // If all the passes are registered successfully, it returns true. + bool RegisterPassesFromFlags(const std::vector& flags); + bool RegisterPassesFromFlags(const std::vector& flags, + bool preserve_interface); + + // Registers the optimization pass associated with |flag|. This only accepts + // |flag| values of the form "--pass_name[=pass_args]". If no such pass + // exists, it returns false. Otherwise, the pass is registered and it returns + // true. + // + // The following flags have special meaning: + // + // -O: Registers all performance optimization passes + // (Optimizer::RegisterPerformancePasses) + // + // -Os: Registers all size optimization passes + // (Optimizer::RegisterSizePasses). + // + // --legalize-hlsl: Registers all passes that legalize SPIR-V generated by an + // HLSL front-end. + // + // If |preserve_interface| is true, all non-io variables in the entry point + // interface are considered live and are not eliminated. + bool RegisterPassFromFlag(const std::string& flag); + bool RegisterPassFromFlag(const std::string& flag, bool preserve_interface); + + // Validates that |flag| has a valid format. Strings accepted: + // + // --pass_name[=pass_args] + // -O + // -Os + // + // If |flag| takes one of the forms above, it returns true. Otherwise, it + // returns false. + bool FlagHasValidForm(const std::string& flag) const; + + // Allows changing, after creation time, the target environment to be + // optimized for and validated. Should be called before calling Run(). + void SetTargetEnv(const spv_target_env env); + + // Optimizes the given SPIR-V module |original_binary| and writes the + // optimized binary into |optimized_binary|. The optimized binary uses + // the same SPIR-V version as the original binary. + // + // Returns true on successful optimization, whether or not the module is + // modified. Returns false if |original_binary| fails to validate or if errors + // occur when processing |original_binary| using any of the registered passes. + // In that case, no further passes are executed and the contents in + // |optimized_binary| may be invalid. + // + // By default, the binary is validated before any transforms are performed, + // and optionally after each transform. Validation uses SPIR-V spec rules + // for the SPIR-V version named in the binary's header (at word offset 1). + // Additionally, if the target environment is a client API (such as + // Vulkan 1.1), then validate for that client API version, to the extent + // that it is verifiable from data in the binary itself. + // + // It's allowed to alias |original_binary| to the start of |optimized_binary|. + bool Run(const uint32_t* original_binary, size_t original_binary_size, + std::vector* optimized_binary) const; + + // DEPRECATED: Same as above, except passes |options| to the validator when + // trying to validate the binary. If |skip_validation| is true, then the + // caller is guaranteeing that |original_binary| is valid, and the validator + // will not be run. The |max_id_bound| is the limit on the max id in the + // module. + bool Run(const uint32_t* original_binary, const size_t original_binary_size, + std::vector* optimized_binary, + const ValidatorOptions& options, bool skip_validation) const; + + // Same as above, except it takes an options object. See the documentation + // for |OptimizerOptions| to see which options can be set. + // + // By default, the binary is validated before any transforms are performed, + // and optionally after each transform. Validation uses SPIR-V spec rules + // for the SPIR-V version named in the binary's header (at word offset 1). + // Additionally, if the target environment is a client API (such as + // Vulkan 1.1), then validate for that client API version, to the extent + // that it is verifiable from data in the binary itself, or from the + // validator options set on the optimizer options. + bool Run(const uint32_t* original_binary, const size_t original_binary_size, + std::vector* optimized_binary, + const spv_optimizer_options opt_options) const; + + // Returns a vector of strings with all the pass names added to this + // optimizer's pass manager. These strings are valid until the associated + // pass manager is destroyed. + std::vector GetPassNames() const; + + // Sets the option to print the disassembly before each pass and after the + // last pass. If |out| is null, then no output is generated. Otherwise, + // output is sent to the |out| output stream. + Optimizer& SetPrintAll(std::ostream* out); + + // Sets the option to print the resource utilization of each pass. If |out| + // is null, then no output is generated. Otherwise, output is sent to the + // |out| output stream. + Optimizer& SetTimeReport(std::ostream* out); + + // Sets the option to validate the module after each pass. + Optimizer& SetValidateAfterAll(bool validate); + + private: + struct SPIRV_TOOLS_LOCAL Impl; // Opaque struct for holding internal data. + std::unique_ptr impl_; // Unique pointer to internal data. +}; + +// Creates a null pass. +// A null pass does nothing to the SPIR-V module to be optimized. +Optimizer::PassToken CreateNullPass(); + +// Creates a strip-debug-info pass. +// A strip-debug-info pass removes all debug instructions (as documented in +// Section 3.42.2 of the SPIR-V spec) of the SPIR-V module to be optimized. +Optimizer::PassToken CreateStripDebugInfoPass(); + +// [Deprecated] This will create a strip-nonsemantic-info pass. See below. +Optimizer::PassToken CreateStripReflectInfoPass(); + +// Creates a strip-nonsemantic-info pass. +// A strip-nonsemantic-info pass removes all reflections and explicitly +// non-semantic instructions. +Optimizer::PassToken CreateStripNonSemanticInfoPass(); + +// Creates an eliminate-dead-functions pass. +// An eliminate-dead-functions pass will remove all functions that are not in +// the call trees rooted at entry points and exported functions. These +// functions are not needed because they will never be called. +Optimizer::PassToken CreateEliminateDeadFunctionsPass(); + +// Creates an eliminate-dead-members pass. +// An eliminate-dead-members pass will remove all unused members of structures. +// This will not affect the data layout of the remaining members. +Optimizer::PassToken CreateEliminateDeadMembersPass(); + +// Creates a set-spec-constant-default-value pass from a mapping from spec-ids +// to the default values in the form of string. +// A set-spec-constant-default-value pass sets the default values for the +// spec constants that have SpecId decorations (i.e., those defined by +// OpSpecConstant{|True|False} instructions). +Optimizer::PassToken CreateSetSpecConstantDefaultValuePass( + const std::unordered_map& id_value_map); + +// Creates a set-spec-constant-default-value pass from a mapping from spec-ids +// to the default values in the form of bit pattern. +// A set-spec-constant-default-value pass sets the default values for the +// spec constants that have SpecId decorations (i.e., those defined by +// OpSpecConstant{|True|False} instructions). +Optimizer::PassToken CreateSetSpecConstantDefaultValuePass( + const std::unordered_map>& id_value_map); + +// Creates a flatten-decoration pass. +// A flatten-decoration pass replaces grouped decorations with equivalent +// ungrouped decorations. That is, it replaces each OpDecorationGroup +// instruction and associated OpGroupDecorate and OpGroupMemberDecorate +// instructions with equivalent OpDecorate and OpMemberDecorate instructions. +// The pass does not attempt to preserve debug information for instructions +// it removes. +Optimizer::PassToken CreateFlattenDecorationPass(); + +// Creates a freeze-spec-constant-value pass. +// A freeze-spec-constant pass specializes the value of spec constants to +// their default values. This pass only processes the spec constants that have +// SpecId decorations (defined by OpSpecConstant, OpSpecConstantTrue, or +// OpSpecConstantFalse instructions) and replaces them with their normal +// counterparts (OpConstant, OpConstantTrue, or OpConstantFalse). The +// corresponding SpecId annotation instructions will also be removed. This +// pass does not fold the newly added normal constants and does not process +// other spec constants defined by OpSpecConstantComposite or +// OpSpecConstantOp. +Optimizer::PassToken CreateFreezeSpecConstantValuePass(); + +// Creates a fold-spec-constant-op-and-composite pass. +// A fold-spec-constant-op-and-composite pass folds spec constants defined by +// OpSpecConstantOp or OpSpecConstantComposite instruction, to normal Constants +// defined by OpConstantTrue, OpConstantFalse, OpConstant, OpConstantNull, or +// OpConstantComposite instructions. Note that spec constants defined with +// OpSpecConstant, OpSpecConstantTrue, or OpSpecConstantFalse instructions are +// not handled, as these instructions indicate their value are not determined +// and can be changed in future. A spec constant is foldable if all of its +// value(s) can be determined from the module. E.g., an integer spec constant +// defined with OpSpecConstantOp instruction can be folded if its value won't +// change later. This pass will replace the original OpSpecConstantOp +// instruction with an OpConstant instruction. When folding composite spec +// constants, new instructions may be inserted to define the components of the +// composite constant first, then the original spec constants will be replaced +// by OpConstantComposite instructions. +// +// There are some operations not supported yet: +// OpSConvert, OpFConvert, OpQuantizeToF16 and +// all the operations under Kernel capability. +// TODO(qining): Add support for the operations listed above. +Optimizer::PassToken CreateFoldSpecConstantOpAndCompositePass(); + +// Creates a unify-constant pass. +// A unify-constant pass de-duplicates the constants. Constants with the exact +// same value and identical form will be unified and only one constant will +// be kept for each unique pair of type and value. +// There are several cases not handled by this pass: +// 1) Constants defined by OpConstantNull instructions (null constants) and +// constants defined by OpConstantFalse, OpConstant or OpConstantComposite +// with value 0 (zero-valued normal constants) are not considered equivalent. +// So null constants won't be used to replace zero-valued normal constants, +// vice versa. +// 2) Whenever there are decorations to the constant's result id id, the +// constant won't be handled, which means, it won't be used to replace any +// other constants, neither can other constants replace it. +// 3) NaN in float point format with different bit patterns are not unified. +Optimizer::PassToken CreateUnifyConstantPass(); + +// Creates a eliminate-dead-constant pass. +// A eliminate-dead-constant pass removes dead constants, including normal +// constants defined by OpConstant, OpConstantComposite, OpConstantTrue, or +// OpConstantFalse and spec constants defined by OpSpecConstant, +// OpSpecConstantComposite, OpSpecConstantTrue, OpSpecConstantFalse or +// OpSpecConstantOp. +Optimizer::PassToken CreateEliminateDeadConstantPass(); + +// Creates a strength-reduction pass. +// A strength-reduction pass will look for opportunities to replace an +// instruction with an equivalent and less expensive one. For example, +// multiplying by a power of 2 can be replaced by a bit shift. +Optimizer::PassToken CreateStrengthReductionPass(); + +// Creates a block merge pass. +// This pass searches for blocks with a single Branch to a block with no +// other predecessors and merges the blocks into a single block. Continue +// blocks and Merge blocks are not candidates for the second block. +// +// The pass is most useful after Dead Branch Elimination, which can leave +// such sequences of blocks. Merging them makes subsequent passes more +// effective, such as single block local store-load elimination. +// +// While this pass reduces the number of occurrences of this sequence, at +// this time it does not guarantee all such sequences are eliminated. +// +// Presence of phi instructions can inhibit this optimization. Handling +// these is left for future improvements. +Optimizer::PassToken CreateBlockMergePass(); + +// Creates an exhaustive inline pass. +// An exhaustive inline pass attempts to exhaustively inline all function +// calls in all functions in an entry point call tree. The intent is to enable, +// albeit through brute force, analysis and optimization across function +// calls by subsequent optimization passes. As the inlining is exhaustive, +// there is no attempt to optimize for size or runtime performance. Functions +// that are not in the call tree of an entry point are not changed. +Optimizer::PassToken CreateInlineExhaustivePass(); + +// Creates an opaque inline pass. +// An opaque inline pass inlines all function calls in all functions in all +// entry point call trees where the called function contains an opaque type +// in either its parameter types or return type. An opaque type is currently +// defined as Image, Sampler or SampledImage. The intent is to enable, albeit +// through brute force, analysis and optimization across these function calls +// by subsequent passes in order to remove the storing of opaque types which is +// not legal in Vulkan. Functions that are not in the call tree of an entry +// point are not changed. +Optimizer::PassToken CreateInlineOpaquePass(); + +// Creates a single-block local variable load/store elimination pass. +// For every entry point function, do single block memory optimization of +// function variables referenced only with non-access-chain loads and stores. +// For each targeted variable load, if previous store to that variable in the +// block, replace the load's result id with the value id of the store. +// If previous load within the block, replace the current load's result id +// with the previous load's result id. In either case, delete the current +// load. Finally, check if any remaining stores are useless, and delete store +// and variable if possible. +// +// The presence of access chain references and function calls can inhibit +// the above optimization. +// +// Only modules with relaxed logical addressing (see opt/instruction.h) are +// currently processed. +// +// This pass is most effective if preceded by Inlining and +// LocalAccessChainConvert. This pass will reduce the work needed to be done +// by LocalSingleStoreElim and LocalMultiStoreElim. +// +// Only functions in the call tree of an entry point are processed. +Optimizer::PassToken CreateLocalSingleBlockLoadStoreElimPass(); + +// Create dead branch elimination pass. +// For each entry point function, this pass will look for SelectionMerge +// BranchConditionals with constant condition and convert to a Branch to +// the indicated label. It will delete resulting dead blocks. +// +// For all phi functions in merge block, replace all uses with the id +// corresponding to the living predecessor. +// +// Note that some branches and blocks may be left to avoid creating invalid +// control flow. Improving this is left to future work. +// +// This pass is most effective when preceded by passes which eliminate +// local loads and stores, effectively propagating constant values where +// possible. +Optimizer::PassToken CreateDeadBranchElimPass(); + +// Creates an SSA local variable load/store elimination pass. +// For every entry point function, eliminate all loads and stores of function +// scope variables only referenced with non-access-chain loads and stores. +// Eliminate the variables as well. +// +// The presence of access chain references and function calls can inhibit +// the above optimization. +// +// Only shader modules with relaxed logical addressing (see opt/instruction.h) +// are currently processed. Currently modules with any extensions enabled are +// not processed. This is left for future work. +// +// This pass is most effective if preceded by Inlining and +// LocalAccessChainConvert. LocalSingleStoreElim and LocalSingleBlockElim +// will reduce the work that this pass has to do. +Optimizer::PassToken CreateLocalMultiStoreElimPass(); + +// Creates a local access chain conversion pass. +// A local access chain conversion pass identifies all function scope +// variables which are accessed only with loads, stores and access chains +// with constant indices. It then converts all loads and stores of such +// variables into equivalent sequences of loads, stores, extracts and inserts. +// +// This pass only processes entry point functions. It currently only converts +// non-nested, non-ptr access chains. It does not process modules with +// non-32-bit integer types present. Optional memory access options on loads +// and stores are ignored as we are only processing function scope variables. +// +// This pass unifies access to these variables to a single mode and simplifies +// subsequent analysis and elimination of these variables along with their +// loads and stores allowing values to propagate to their points of use where +// possible. +Optimizer::PassToken CreateLocalAccessChainConvertPass(); + +// Creates a local single store elimination pass. +// For each entry point function, this pass eliminates loads and stores for +// function scope variable that are stored to only once, where possible. Only +// whole variable loads and stores are eliminated; access-chain references are +// not optimized. Replace all loads of such variables with the value that is +// stored and eliminate any resulting dead code. +// +// Currently, the presence of access chains and function calls can inhibit this +// pass, however the Inlining and LocalAccessChainConvert passes can make it +// more effective. In additional, many non-load/store memory operations are +// not supported and will prohibit optimization of a function. Support of +// these operations are future work. +// +// Only shader modules with relaxed logical addressing (see opt/instruction.h) +// are currently processed. +// +// This pass will reduce the work needed to be done by LocalSingleBlockElim +// and LocalMultiStoreElim and can improve the effectiveness of other passes +// such as DeadBranchElimination which depend on values for their analysis. +Optimizer::PassToken CreateLocalSingleStoreElimPass(); + +// Creates an insert/extract elimination pass. +// This pass processes each entry point function in the module, searching for +// extracts on a sequence of inserts. It further searches the sequence for an +// insert with indices identical to the extract. If such an insert can be +// found before hitting a conflicting insert, the extract's result id is +// replaced with the id of the values from the insert. +// +// Besides removing extracts this pass enables subsequent dead code elimination +// passes to delete the inserts. This pass performs best after access chains are +// converted to inserts and extracts and local loads and stores are eliminated. +Optimizer::PassToken CreateInsertExtractElimPass(); + +// Creates a dead insert elimination pass. +// This pass processes each entry point function in the module, searching for +// unreferenced inserts into composite types. These are most often unused +// stores to vector components. They are unused because they are never +// referenced, or because there is another insert to the same component between +// the insert and the reference. After removing the inserts, dead code +// elimination is attempted on the inserted values. +// +// This pass performs best after access chains are converted to inserts and +// extracts and local loads and stores are eliminated. While executing this +// pass can be advantageous on its own, it is also advantageous to execute +// this pass after CreateInsertExtractPass() as it will remove any unused +// inserts created by that pass. +Optimizer::PassToken CreateDeadInsertElimPass(); + +// Create aggressive dead code elimination pass +// This pass eliminates unused code from the module. In addition, +// it detects and eliminates code which may have spurious uses but which do +// not contribute to the output of the function. The most common cause of +// such code sequences is summations in loops whose result is no longer used +// due to dead code elimination. This optimization has additional compile +// time cost over standard dead code elimination. +// +// This pass only processes entry point functions. It also only processes +// shaders with relaxed logical addressing (see opt/instruction.h). It +// currently will not process functions with function calls. Unreachable +// functions are deleted. +// +// This pass will be made more effective by first running passes that remove +// dead control flow and inlines function calls. +// +// This pass can be especially useful after running Local Access Chain +// Conversion, which tends to cause cycles of dead code to be left after +// Store/Load elimination passes are completed. These cycles cannot be +// eliminated with standard dead code elimination. +// +// If |preserve_interface| is true, all non-io variables in the entry point +// interface are considered live and are not eliminated. This mode is needed +// by GPU-Assisted validation instrumentation, where a change in the interface +// is not allowed. +// +// If |remove_outputs| is true, allow outputs to be removed from the interface. +// This is only safe if the caller knows that there is no corresponding input +// variable in the following shader. It is false by default. +Optimizer::PassToken CreateAggressiveDCEPass(); +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface); +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface, + bool remove_outputs); + +// Creates a remove-unused-interface-variables pass. +// Removes variables referenced on the |OpEntryPoint| instruction that are not +// referenced in the entry point function or any function in its call tree. Note +// that this could cause the shader interface to no longer match other shader +// stages. +Optimizer::PassToken CreateRemoveUnusedInterfaceVariablesPass(); + +// Creates an empty pass. +// This is deprecated and will be removed. +// TODO(jaebaek): remove this pass after handling glslang's broken unit tests. +// https://github.com/KhronosGroup/glslang/pull/2440 +Optimizer::PassToken CreatePropagateLineInfoPass(); + +// Creates an empty pass. +// This is deprecated and will be removed. +// TODO(jaebaek): remove this pass after handling glslang's broken unit tests. +// https://github.com/KhronosGroup/glslang/pull/2440 +Optimizer::PassToken CreateRedundantLineInfoElimPass(); + +// Creates a compact ids pass. +// The pass remaps result ids to a compact and gapless range starting from %1. +Optimizer::PassToken CreateCompactIdsPass(); + +// Creates a remove duplicate pass. +// This pass removes various duplicates: +// * duplicate capabilities; +// * duplicate extended instruction imports; +// * duplicate types; +// * duplicate decorations. +Optimizer::PassToken CreateRemoveDuplicatesPass(); + +// Creates a CFG cleanup pass. +// This pass removes cruft from the control flow graph of functions that are +// reachable from entry points and exported functions. It currently includes the +// following functionality: +// +// - Removal of unreachable basic blocks. +Optimizer::PassToken CreateCFGCleanupPass(); + +// Create dead variable elimination pass. +// This pass will delete module scope variables, along with their decorations, +// that are not referenced. +Optimizer::PassToken CreateDeadVariableEliminationPass(); + +// create merge return pass. +// changes functions that have multiple return statements so they have a single +// return statement. +// +// for structured control flow it is assumed that the only unreachable blocks in +// the function are trivial merge and continue blocks. +// +// a trivial merge block contains the label and an opunreachable instructions, +// nothing else. a trivial continue block contain a label and an opbranch to +// the header, nothing else. +// +// these conditions are guaranteed to be met after running dead-branch +// elimination. +Optimizer::PassToken CreateMergeReturnPass(); + +// Create value numbering pass. +// This pass will look for instructions in the same basic block that compute the +// same value, and remove the redundant ones. +Optimizer::PassToken CreateLocalRedundancyEliminationPass(); + +// Create LICM pass. +// This pass will look for invariant instructions inside loops and hoist them to +// the loops preheader. +Optimizer::PassToken CreateLoopInvariantCodeMotionPass(); + +// Creates a loop fission pass. +// This pass will split all top level loops whose register pressure exceedes the +// given |threshold|. +Optimizer::PassToken CreateLoopFissionPass(size_t threshold); + +// Creates a loop fusion pass. +// This pass will look for adjacent loops that are compatible and legal to be +// fused. The fuse all such loops as long as the register usage for the fused +// loop stays under the threshold defined by |max_registers_per_loop|. +Optimizer::PassToken CreateLoopFusionPass(size_t max_registers_per_loop); + +// Creates a loop peeling pass. +// This pass will look for conditions inside a loop that are true or false only +// for the N first or last iteration. For loop with such condition, those N +// iterations of the loop will be executed outside of the main loop. +// To limit code size explosion, the loop peeling can only happen if the code +// size growth for each loop is under |code_growth_threshold|. +Optimizer::PassToken CreateLoopPeelingPass(); + +// Creates a loop unswitch pass. +// This pass will look for loop independent branch conditions and move the +// condition out of the loop and version the loop based on the taken branch. +// Works best after LICM and local multi store elimination pass. +Optimizer::PassToken CreateLoopUnswitchPass(); + +// Create global value numbering pass. +// This pass will look for instructions where the same value is computed on all +// paths leading to the instruction. Those instructions are deleted. +Optimizer::PassToken CreateRedundancyEliminationPass(); + +// Create scalar replacement pass. +// This pass replaces composite function scope variables with variables for each +// element if those elements are accessed individually. The parameter is a +// limit on the number of members in the composite variable that the pass will +// consider replacing. +Optimizer::PassToken CreateScalarReplacementPass(uint32_t size_limit = 0); + +// Create a private to local pass. +// This pass looks for variables declared in the private storage class that are +// used in only one function. Those variables are moved to the function storage +// class in the function that they are used. +Optimizer::PassToken CreatePrivateToLocalPass(); + +// Creates a conditional constant propagation (CCP) pass. +// This pass implements the SSA-CCP algorithm in +// +// Constant propagation with conditional branches, +// Wegman and Zadeck, ACM TOPLAS 13(2):181-210. +// +// Constant values in expressions and conditional jumps are folded and +// simplified. This may reduce code size by removing never executed jump targets +// and computations with constant operands. +Optimizer::PassToken CreateCCPPass(); + +// Creates a workaround driver bugs pass. This pass attempts to work around +// a known driver bug (issue #1209) by identifying the bad code sequences and +// rewriting them. +// +// Current workaround: Avoid OpUnreachable instructions in loops. +Optimizer::PassToken CreateWorkaround1209Pass(); + +// Creates a pass that converts if-then-else like assignments into OpSelect. +Optimizer::PassToken CreateIfConversionPass(); + +// Creates a pass that will replace instructions that are not valid for the +// current shader stage by constants. Has no effect on non-shader modules. +Optimizer::PassToken CreateReplaceInvalidOpcodePass(); + +// Creates a pass that simplifies instructions using the instruction folder. +Optimizer::PassToken CreateSimplificationPass(); + +// Create loop unroller pass. +// Creates a pass to unroll loops which have the "Unroll" loop control +// mask set. The loops must meet a specific criteria in order to be unrolled +// safely this criteria is checked before doing the unroll by the +// LoopUtils::CanPerformUnroll method. Any loop that does not meet the criteria +// won't be unrolled. See CanPerformUnroll LoopUtils.h for more information. +Optimizer::PassToken CreateLoopUnrollPass(bool fully_unroll, int factor = 0); + +// Create the SSA rewrite pass. +// This pass converts load/store operations on function local variables into +// operations on SSA IDs. This allows SSA optimizers to act on these variables. +// Only variables that are local to the function and of supported types are +// processed (see IsSSATargetVar for details). +Optimizer::PassToken CreateSSARewritePass(); + +// Create pass to convert relaxed precision instructions to half precision. +// This pass converts as many relaxed float32 arithmetic operations to half as +// possible. It converts any float32 operands to half if needed. It converts +// any resulting half precision values back to float32 as needed. No variables +// are changed. No image operations are changed. +// +// Best if run after function scope store/load and composite operation +// eliminations are run. Also best if followed by instruction simplification, +// redundancy elimination and DCE. +Optimizer::PassToken CreateConvertRelaxedToHalfPass(); + +// Create relax float ops pass. +// This pass decorates all float32 result instructions with RelaxedPrecision +// if not already so decorated. +Optimizer::PassToken CreateRelaxFloatOpsPass(); + +// Create copy propagate arrays pass. +// This pass looks to copy propagate memory references for arrays. It looks +// for specific code patterns to recognize array copies. +Optimizer::PassToken CreateCopyPropagateArraysPass(); + +// Create a vector dce pass. +// This pass looks for components of vectors that are unused, and removes them +// from the vector. Note this would still leave around lots of dead code that +// a pass of ADCE will be able to remove. +Optimizer::PassToken CreateVectorDCEPass(); + +// Create a pass to reduce the size of loads. +// This pass looks for loads of structures where only a few of its members are +// used. It replaces the loads feeding an OpExtract with an OpAccessChain and +// a load of the specific elements. The parameter is a threshold to determine +// whether we have to replace the load or not. If the ratio of the used +// components of the load is less than the threshold, we replace the load. +Optimizer::PassToken CreateReduceLoadSizePass( + double load_replacement_threshold = 0.9); + +// Create a pass to combine chained access chains. +// This pass looks for access chains fed by other access chains and combines +// them into a single instruction where possible. +Optimizer::PassToken CreateCombineAccessChainsPass(); + +// Create a pass to upgrade to the VulkanKHR memory model. +// This pass upgrades the Logical GLSL450 memory model to Logical VulkanKHR. +// Additionally, it modifies memory, image, atomic and barrier operations to +// conform to that model's requirements. +Optimizer::PassToken CreateUpgradeMemoryModelPass(); + +// Create a pass to do code sinking. Code sinking is a transformation +// where an instruction is moved into a more deeply nested construct. +Optimizer::PassToken CreateCodeSinkingPass(); + +// Create a pass to fix incorrect storage classes. In order to make code +// generation simpler, DXC may generate code where the storage classes do not +// match up correctly. This pass will fix the errors that it can. +Optimizer::PassToken CreateFixStorageClassPass(); + +// Creates a graphics robust access pass. +// +// This pass injects code to clamp indexed accesses to buffers and internal +// arrays, providing guarantees satisfying Vulkan's robustBufferAccess rules. +// +// TODO(dneto): Clamps coordinates and sample index for pointer calculations +// into storage images (OpImageTexelPointer). For an cube array image, it +// assumes the maximum layer count times 6 is at most 0xffffffff. +// +// NOTE: This pass will fail with a message if: +// - The module is not a Shader module. +// - The module declares VariablePointers, VariablePointersStorageBuffer, or +// RuntimeDescriptorArrayEXT capabilities. +// - The module uses an addressing model other than Logical +// - Access chain indices are wider than 64 bits. +// - Access chain index for a struct is not an OpConstant integer or is out +// of range. (The module is already invalid if that is the case.) +// - TODO(dneto): The OpImageTexelPointer coordinate component is not 32-bits +// wide. +// +// NOTE: Access chain indices are always treated as signed integers. So +// if an array has a fixed size of more than 2^31 elements, then elements +// from 2^31 and above are never accessible with a 32-bit index, +// signed or unsigned. For this case, this pass will clamp the index +// between 0 and at 2^31-1, inclusive. +// Similarly, if an array has more then 2^15 element and is accessed with +// a 16-bit index, then elements from 2^15 and above are not accessible. +// In this case, the pass will clamp the index between 0 and 2^15-1 +// inclusive. +Optimizer::PassToken CreateGraphicsRobustAccessPass(); + +// Create a pass to spread Volatile semantics to variables with SMIDNV, +// WarpIDNV, SubgroupSize, SubgroupLocalInvocationId, SubgroupEqMask, +// SubgroupGeMask, SubgroupGtMask, SubgroupLeMask, or SubgroupLtMask BuiltIn +// decorations or OpLoad for them when the shader model is the ray generation, +// closest hit, miss, intersection, or callable. This pass can be used for +// VUID-StandaloneSpirv-VulkanMemoryModel-04678 and +// VUID-StandaloneSpirv-VulkanMemoryModel-04679 (See "Standalone SPIR-V +// Validation" section of Vulkan spec "Appendix A: Vulkan Environment for +// SPIR-V"). When the SPIR-V version is 1.6 or above, the pass also spreads +// the Volatile semantics to a variable with HelperInvocation BuiltIn decoration +// in the fragement shader. +Optimizer::PassToken CreateSpreadVolatileSemanticsPass(); + +// Create a pass to replace a descriptor access using variable index. +// This pass replaces every access using a variable index to array variable +// |desc| that has a DescriptorSet and Binding decorations with a constant +// element of the array. In order to replace the access using a variable index +// with the constant element, it uses a switch statement. +Optimizer::PassToken CreateReplaceDescArrayAccessUsingVarIndexPass(); + +// Create descriptor scalar replacement pass. +// This pass replaces every array variable |desc| that has a DescriptorSet and +// Binding decorations with a new variable for each element of the +// array/composite. Suppose |desc| was bound at binding |b|. Then the variable +// corresponding to |desc[i]| will have binding |b+i|. The descriptor set will +// be the same. It is assumed that no other variable already has a binding that +// will used by one of the new variables. If not, the pass will generate +// invalid Spir-V. All accesses to |desc| must be OpAccessChain instructions +// with a literal index for the first index. This variant flattens both +// composites and arrays. +Optimizer::PassToken CreateDescriptorScalarReplacementPass(); +// This variant flattens only composites. +Optimizer::PassToken CreateDescriptorCompositeScalarReplacementPass(); +// This variant flattens only arrays. +Optimizer::PassToken CreateDescriptorArrayScalarReplacementPass(); + +// Create a pass to replace each OpKill instruction with a function call to a +// function that has a single OpKill. Also replace each OpTerminateInvocation +// instruction with a function call to a function that has a single +// OpTerminateInvocation. This allows more code to be inlined. +Optimizer::PassToken CreateWrapOpKillPass(); + +// Replaces the extensions VK_AMD_shader_ballot,VK_AMD_gcn_shader, and +// VK_AMD_shader_trinary_minmax with equivalent code using core instructions and +// capabilities. +Optimizer::PassToken CreateAmdExtToKhrPass(); + +// Replaces the internal version of GLSLstd450 InterpolateAt* extended +// instructions with the externally valid version. The internal version allows +// an OpLoad of the interpolant for the first argument. This pass removes the +// OpLoad and replaces it with its pointer. glslang and possibly other +// frontends will create the internal version for HLSL. This pass will be part +// of HLSL legalization and should be called after interpolants have been +// propagated into their final positions. +Optimizer::PassToken CreateInterpolateFixupPass(); + +// Replace OpExtInst instructions with OpExtInstWithForwardRefsKHR when +// the instruction contains a forward reference to another debug instuction. +// Replace OpExtInstWithForwardRefsKHR with OpExtInst when there are no forward +// reference to another debug instruction. +Optimizer::PassToken CreateOpExtInstWithForwardReferenceFixupPass(); + +// Removes unused components from composite input variables. Current +// implementation just removes trailing unused components from input arrays +// and structs. The pass performs best after maximizing dead code removal. +// A subsequent dead code elimination pass would be beneficial in removing +// newly unused component types. +// +// WARNING: This pass can only be safely applied standalone to vertex shaders +// as it can otherwise cause interface incompatibilities with the preceding +// shader in the pipeline. If applied to non-vertex shaders, the user should +// follow by applying EliminateDeadOutputStores and +// EliminateDeadOutputComponents to the preceding shader. +Optimizer::PassToken CreateEliminateDeadInputComponentsPass(); + +// Removes unused components from composite output variables. Current +// implementation just removes trailing unused components from output arrays +// and structs. The pass performs best after eliminating dead output stores. +// A subsequent dead code elimination pass would be beneficial in removing +// newly unused component types. Currently only supports vertex and fragment +// shaders. +// +// WARNING: This pass cannot be safely applied standalone as it can cause +// interface incompatibility with the following shader in the pipeline. The +// user should first apply EliminateDeadInputComponents to the following +// shader, then apply EliminateDeadOutputStores to this shader. +Optimizer::PassToken CreateEliminateDeadOutputComponentsPass(); + +// Removes unused components from composite input variables. This safe +// version will not cause interface incompatibilities since it only changes +// vertex shaders. The current implementation just removes trailing unused +// components from input structs and input arrays. The pass performs best +// after maximizing dead code removal. A subsequent dead code elimination +// pass would be beneficial in removing newly unused component types. +Optimizer::PassToken CreateEliminateDeadInputComponentsSafePass(); + +// Analyzes shader and populates |live_locs| and |live_builtins|. Best results +// will be obtained if shader has all dead code eliminated first. |live_locs| +// and |live_builtins| are subsequently used when calling +// CreateEliminateDeadOutputStoresPass on the preceding shader. Currently only +// supports tesc, tese, geom, and frag shaders. +Optimizer::PassToken CreateAnalyzeLiveInputPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins); + +// Removes stores to output locations not listed in |live_locs| or +// |live_builtins|. Best results are obtained if constant propagation is +// performed first. A subsequent call to ADCE will eliminate any dead code +// created by the removal of the stores. A subsequent call to +// CreateEliminateDeadOutputComponentsPass will eliminate any dead output +// components created by the elimination of the stores. Currently only supports +// vert, tesc, tese, and geom shaders. +Optimizer::PassToken CreateEliminateDeadOutputStoresPass( + std::unordered_set* live_locs, + std::unordered_set* live_builtins); + +// Creates a convert-to-sampled-image pass to convert images and/or +// samplers with given pairs of descriptor set and binding to sampled image. +// If a pair of an image and a sampler have the same pair of descriptor set and +// binding that is one of the given pairs, they will be converted to a sampled +// image. In addition, if only an image has the descriptor set and binding that +// is one of the given pairs, it will be converted to a sampled image as well. +Optimizer::PassToken CreateConvertToSampledImagePass( + const std::vector& + descriptor_set_binding_pairs); + +// Create an interface-variable-scalar-replacement pass that replaces array or +// matrix interface variables with a series of scalar or vector interface +// variables. For example, it replaces `float3 foo[2]` with `float3 foo0, foo1`. +Optimizer::PassToken CreateInterfaceVariableScalarReplacementPass(); + +// Creates a remove-dont-inline pass to remove the |DontInline| function control +// from every function in the module. This is useful if you want the inliner to +// inline these functions some reason. +Optimizer::PassToken CreateRemoveDontInlinePass(); +// Create a fix-func-call-param pass to fix non memory argument for the function +// call, as spirv-validation requires function parameters to be an memory +// object, currently the pass would remove accesschain pointer argument passed +// to the function +Optimizer::PassToken CreateFixFuncCallArgumentsPass(); + +// Creates a trim-capabilities pass. +// This pass removes unused capabilities for a given module, and if possible, +// associated extensions. +// See `trim_capabilities.h` for the list of supported capabilities. +// +// If the module contains unsupported capabilities, this pass will ignore them. +// This should be fine in most cases, but could yield to incorrect results if +// the unknown capability interacts with one of the trimmed capabilities. +Optimizer::PassToken CreateTrimCapabilitiesPass(); + +// Creates a struct-packing pass. +// This pass re-assigns all offset layout decorators to tightly pack +// the struct with OpName matching `structToPack` according to the given packing +// rule. Accepted packing rules are: std140, std140EnhancedLayout, std430, +// std430EnhancedLayout, hlslCbuffer, hlslCbufferPackOffset, scalar, +// scalarEnhancedLayout. +Optimizer::PassToken CreateStructPackingPass(const char* structToPack, + const char* packingRule); + +// Creates a switch-descriptorset pass. +// This pass changes any DescriptorSet decorations with the value |ds_from| to +// use the new value |ds_to|. +Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t ds_from, + uint32_t ds_to); + +// Creates an invocation interlock placement pass. +// This pass ensures that an entry point will have at most one +// OpBeginInterlockInvocationEXT and one OpEndInterlockInvocationEXT, in that +// order. +Optimizer::PassToken CreateInvocationInterlockPlacementPass(); + +// Creates a pass to add/remove maximal reconvergence execution mode. +// This pass either adds or removes maximal reconvergence from all entry points. +Optimizer::PassToken CreateModifyMaximalReconvergencePass(bool add); + +// Creates a pass to split combined image+sampler variables and function +// parameters into separate image and sampler parts. Binding numbers and +// other decorations are copied. +Optimizer::PassToken CreateSplitCombinedImageSamplerPass(); + +// Creates a pass to remap bindings to avoid conflicts, assuming the module +// is valid for Vulkan. A conflict exits when an entry point uses two distinct +// variables with the same descriptor set and binding. Vulkan allows one kind +// of conflict: when one varible is an image (or array of images), and the +// other is a sampler (or an array of samplers). + +// Conflicts are eliminated by incrementing the binding number of the sampler +// part, and then propagating that increment through variables with +// higher-numbered bindings until no conflict remains. This handles the case +// when multiple shaders may share the same resource variables; this can +// introduce holes in binding slots. +// +// Here's an example where shaders Alpha, Beta, Gamma, Delta collectively use +// resource variables %100, %101, %102, %103, %104 all with the same +// DescriptorSet and with Bindings as in the following table: +// +// Before: +// +// Binding: 0 1 2 3 +// Alpha: %100,%101 +// Beta: %100 %102 +// Gamma: %102 %103 +// Delta: %103 %104 +// +// The Alpha shader has a conflict where variables %100, %101 have the same +// descriptor set and binding. If %100 is a sampler resource variable, then +// the conflict is resolved by incrementing the binding number on %100 from 0 +// to 1. But this causes a new confict for shader Beta because it now uses +// both %100 and %102 with binding number 1. That conflict is resolved by +// incrementing the binding number on its variable that originally appeared +// second (i.e. %102), so %102 gets binding 2. This now produces a conflict +// for Gamma between %102 and %103 using binding number 2. Since %103 originally +// appeared second (in the view from Gamma), the algorithm bumps %103 to binding +// number %103. Now Delta has a conflict between %103 and %104, resulting in +// %104 getting the next binding number, 4. The picture afterward is: +// +// After: +// +// Binding: 0 1 2 3 4 +// Alpha: %101 %100 +// Beta: %100 %102 +// Gamma: %102 %103 +// Delta: %103 %104 +// +// +// This pass assumes binding numbers are not applid via decoration groups +// (OpDecorationGroup). +Optimizer::PassToken CreateResolveBindingConflictsPass(); + +// Create a pass to canonicalize IDs to improve compression of SPIR-V binary +// files. The resulting modules have an increased ID range (IDs are not as +// tightly packed around zero), but will compress better when multiple modules +// are compressed together, since the compressor's dictionary can find better +// cross module commonality. This pass should be run after most optimization +// passes except for +// --strip-debug because this pass will use OpName to canonicalize IDs. i.e. Run +// --strip-debug after this pass. +Optimizer::PassToken CreateCanonicalizeIdsPass(); +} // namespace spvtools + +#endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_ diff --git a/thirdparty/libs/Darwin/lib/glslang/libGenericCodeGen.a b/thirdparty/libs/Darwin/lib/glslang/libGenericCodeGen.a new file mode 100644 index 0000000000000000000000000000000000000000..5646f89f215ddbc5a2aac698d7568f13de8a025f GIT binary patch literal 608 zcmY$iNi0gvu;WrT)HgCvKmbE?Gea{|0~1T2ps9f&Py!-tXkcJwVxpj6W&u;1z!e{_ z7aZy9;_9Xl>>m{3>cRj793TP+I)GRKh~wjSnW5qFf}m7Zoi445!3+*Tp(lhk_!s-^1()diSxhS{^Ma_U<7eM1Pc&LfEWru z3yNZbJ^0b(ZrX$>F^QV{^eAOO+>!zgxuWr-ykf(|gpUy}tY Y=K~oA1t2Cr5+84b=9J_X7(g@v0I6L?NB{r; literal 0 HcmV?d00001 diff --git a/thirdparty/libs/Darwin/lib/glslang/libMachineIndependent.a b/thirdparty/libs/Darwin/lib/glslang/libMachineIndependent.a new file mode 100644 index 0000000000000000000000000000000000000000..5646f89f215ddbc5a2aac698d7568f13de8a025f GIT binary patch literal 608 zcmY$iNi0gvu;WrT)HgCvKmbE?Gea{|0~1T2ps9f&Py!-tXkcJwVxpj6W&u;1z!e{_ z7aZy9;_9Xl>>m{3>cRj793TP+I)GRKh~wjSnW5qFf}m7Zoi445!3+*Tp(lhk_!s-^1()diSxhS{^Ma_U<7eM1Pc&LfEWru z3yNZbJ^0b(ZrX$>F^QV{^eAOO+>!zgxuWr-ykf(|gpUy}tY Y=K~oA1t2Cr5+84b=9J_X7(g@v0I6L?NB{r; literal 0 HcmV?d00001 diff --git a/thirdparty/libs/Darwin/lib/glslang/libOSDependent.a b/thirdparty/libs/Darwin/lib/glslang/libOSDependent.a new file mode 100644 index 0000000000000000000000000000000000000000..5646f89f215ddbc5a2aac698d7568f13de8a025f GIT binary patch literal 608 zcmY$iNi0gvu;WrT)HgCvKmbE?Gea{|0~1T2ps9f&Py!-tXkcJwVxpj6W&u;1z!e{_ z7aZy9;_9Xl>>m{3>cRj793TP+I)GRKh~wjSnW5qFf}m7Zoi445!3+*Tp(lhk_!s-^1()diSxhS{^Ma_U<7eM1Pc&LfEWru z3yNZbJ^0b(ZrX$>F^QV{^eAOO+>!zgxuWr-ykf(|gpUy}tY Y=K~oA1t2Cr5+84b=9J_X7(g@v0I6L?NB{r; literal 0 HcmV?d00001 diff --git a/thirdparty/libs/Darwin/lib/glslang/libSPIRV.a b/thirdparty/libs/Darwin/lib/glslang/libSPIRV.a new file mode 100644 index 0000000000000000000000000000000000000000..602ae0c531a0a1785fa7bb15afb1608defff0bb1 GIT binary patch literal 608 zcmY$iNi0gvu;WrT)HgCvKmbE?Gea|D3o|2A1qD+BL!bmi+R(tj%)~@N!OQ}tHi0WX zUN1P(*TvOMA=p1C#MOlX2sl6l5Oe^s0uaZ?M;RFwmy{;O=VT@oB^Fi2rucL7;xBcYH5VseiK8W1Q;Z6fsEBlE-28;2O9+@&i{J*kB5PQ5ySxzEI=#)VkiJH z5J&>?3@{5j0dv0v*aU=s*n!GH7%B|(S4nC`3Bru{_z>5K5Ck8_LN<>HCJ3Tg7#fhd zMnH}P5JSx82D13T(jYw`aR;CTh@AkWHGnioMF0?k07wrEqu2qKC6;IiI=~!%O%|w} X4`dh=fSCM9e7q5wQ<7U?0MQ5l#N|a+ literal 0 HcmV?d00001 diff --git a/thirdparty/libs/Darwin/lib/glslang/libglslang-default-resource-limits.a b/thirdparty/libs/Darwin/lib/glslang/libglslang-default-resource-limits.a new file mode 100644 index 0000000000000000000000000000000000000000..95f6a1c26327c9269aee0a1b6884354382afe5c0 GIT binary patch literal 43784 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 |B0O$x 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 literal 0 HcmV?d00001 diff --git a/thirdparty/libs/Darwin/lib/glslang/libglslang.a b/thirdparty/libs/Darwin/lib/glslang/libglslang.a new file mode 100644 index 0000000000000000000000000000000000000000..6ede0cc27c95fe738d349852518e8f66d4f6dfb6 GIT binary patch literal 4963096 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%0De=%JL3DnFNpO`yq*4diTI?6^-a77{H9pn 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

U;}jPd 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 z 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≺%RT!PE`-aFdwmr{cFoGBV&eT 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

rsx>FHL(RamC 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

(r3+p%b=XmT5*6+!9 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� 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

QJNF>ZIkh`!9EVxh%ZgD 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


1>yWjOQYJ}{Eu%=ghoc^d!c+y_QD^SNhT7vaq3 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

X4n44nF3(Hfi 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

$8*HHWwIBNyk92X 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 z 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 z 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 z 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 z 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 literal 0 HcmV?d00001 From c1f4c1486568835b0786c30429d4afbfc9139d6a Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 29 Oct 2025 22:18:38 +0800 Subject: [PATCH 02/37] fix --- src/client/graphics/webgl_context.cpp | 1 - src/client/graphics/webgl_context.hpp | 488 ++++++-------------------- src/client/graphics/webgl_shader.cpp | 2 +- src/common/command_buffers/shared.cpp | 182 +++++++++- src/common/command_buffers/shared.hpp | 17 +- src/renderer/content_renderer.cpp | 2 +- src/renderer/render_api_opengles.cpp | 73 ++-- 7 files changed, 340 insertions(+), 425 deletions(-) diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index c65f0a510..9e60d485b 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -322,7 +322,6 @@ namespace endor auto buffer = make_shared(); auto req = CreateBufferCommandBufferRequest(buffer->id); sendCommandBufferRequest(req); - cerr << "Created buffer with id: " << buffer->id << endl; return buffer; } diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index 8573532a6..32567de43 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -283,66 +284,14 @@ namespace endor ~WebGLContext(); public: // graphics methods - /** - * It creates and initializes a WebGLProgram object. - * - * @returns The created WebGLProgram object. - */ std::shared_ptr createProgram(); - /** - * It deletes a given WebGLProgram object, and this method has no effect if the program has already been deleted. - * - * @param program The WebGLProgram object to delete. - */ void deleteProgram(std::shared_ptr program); - /** - * It links a given `WebGLProgram`, completing the process of preparing the GPU code for the program's fragment and - * vertex shaders. - * - * @param program The WebGLProgram object to link. - */ void linkProgram(std::shared_ptr program); - /** - * It validates a program. It checks if a program can execute given the current WebGL state. The information - * generated by the validation process will be stored in the program's information log. The validation - * information may consist of an empty string, or it may be a string containing information about how the - * current program might execute given the current WebGL state. This information could be useful during - * program development. - * - * @param program The WebGLProgram object to validate. - */ void validateProgram(std::shared_ptr program); - /** - * It sets the specified WebGLProgram as part of the current rendering state. - * - * @param program The WebGLProgram object to use. - */ void useProgram(std::shared_ptr program); - /** - * It binds a generic vertex index to an attribute variable. - * - * @param program The WebGLProgram object to bind the attribute to. - * @param index The index of the generic vertex to bind. - * @param name A string specifying the name of the variable to bind to the generic vertex index. This name cannot start - * with "webgl_" or "_webgl_", as these are reserved for use by WebGL. - */ void bindAttribLocation(std::shared_ptr program, uint32_t index, const std::string &name); - /** - * It returns information about the given program. - * - * @param program The WebGLProgram object to get information from. - * @param pname A GLenum specifying the information to query. - * @returns the requested program information (as specified with pname). - */ + int getProgramParameter(std::shared_ptr program, int pname); - /** - * It returns the information log for the specified `WebGLProgram` object. It contains errors that occurred during failed - * linking or validation of `WebGLProgram` objects. - * - * @param program The WebGLProgram object to get the information log from. - * @returns A string that contains diagnostic messages, warning messages, and other information about the last linking or - * validation operation. - */ std::string getProgramInfoLog(std::shared_ptr program); std::shared_ptr createShader(WebGLShaderType type); void deleteShader(std::shared_ptr shader); @@ -353,6 +302,7 @@ namespace endor std::string getShaderSource(std::shared_ptr shader); int getShaderParameter(std::shared_ptr shader, int pname); std::string getShaderInfoLog(std::shared_ptr shader); + std::shared_ptr createBuffer(); void deleteBuffer(std::shared_ptr buffer); void bindBuffer(WebGLBufferBindingTarget target, std::shared_ptr buffer); @@ -374,10 +324,12 @@ namespace endor std::shared_ptr texture, int level); uint32_t checkFramebufferStatus(WebGLFramebufferBindingTarget target); + std::shared_ptr createRenderbuffer(); void deleteRenderbuffer(std::shared_ptr renderbuffer); void bindRenderbuffer(WebGLRenderbufferBindingTarget target, std::shared_ptr renderbuffer); void renderbufferStorage(WebGLRenderbufferBindingTarget target, int internalformat, int width, int height); + std::shared_ptr createTexture(); void deleteTexture(std::shared_ptr texture); void bindTexture(WebGLTextureTarget target, std::shared_ptr texture); @@ -425,6 +377,7 @@ namespace endor void texParameteriv(WebGLTextureTarget target, WebGLTextureParameterName pname, const std::vector params); void activeTexture(WebGLTextureUnit texture); void generateMipmap(WebGLTextureTarget target); + void enableVertexAttribArray(const WebGLAttribLocation &); void enableVertexAttribArray(int index); void disableVertexAttribArray(const WebGLAttribLocation &); @@ -443,6 +396,7 @@ namespace endor std::optional getActiveUniform(std::shared_ptr program, unsigned int index); std::optional getAttribLocation(std::shared_ptr program, const std::string &name); std::optional getUniformLocation(std::shared_ptr program, const std::string &name); + void uniform1f(WebGLUniformLocation location, float v0); void uniform1fv(WebGLUniformLocation location, const std::vector value); void uniform1i(WebGLUniformLocation location, int v0); @@ -468,8 +422,10 @@ namespace endor void uniformMatrix4fv(WebGLUniformLocation location, bool transpose, glm::mat4 m); void uniformMatrix4fv(WebGLUniformLocation location, bool transpose, std::vector values); void uniformMatrix4fv(WebGLUniformLocation location, bool transpose, MatrixComputationGraph &graphToValues); + void drawArrays(WebGLDrawMode mode, int first, int count); void drawElements(WebGLDrawMode mode, int count, int type, int offset); + void hint(WebGLHintTargetBehavior target, WebGLHintBehaviorMode mode); void lineWidth(float width); void pixelStorei(WebGLPixelStorageParameterName pname, int param); @@ -499,47 +455,14 @@ namespace endor void frontFace(int mode); void enable(int cap); void disable(int cap); - /** - * @param pname The parameter name that returns a boolean value. - * @returns The boolean value for the parameter name. - */ + bool getParameter(WebGLBooleanParameterName pname); - /** - * @param pname The parameter name that returns a float value. - * @returns The float value for the parameter name. - */ float getParameter(WebGLFloatParameterName pname); - /** - * @param pname The parameter name that returns a float array value. - * @returns The float array value for the parameter name. - */ std::vector getParameter(WebGLFloatArrayParameterName pname); - /** - * @param pname The parameter name that returns an integer value. - * @returns The integer value for the parameter name. - */ int getParameter(WebGLIntegerParameterName pname); - /** - * @param pname The parameter name that returns a 64-bit integer value. - * @returns The 64-bit integer value for the parameter name. - */ int64_t getParameter(WebGLInteger64ParameterName pname); - /** - * @param pname The parameter name that returns a boolean value. - * @param index The index of the parameter. - * @returns The boolean value for the parameter name. - */ bool getParameter(WebGLBooleanIndexedParameterName pname, int index); - /** - * @param pname The parameter name that returns a float value. - * @param index The index of the parameter. - * @returns The float value for the parameter name. - */ float getParameter(WebGLFloatArrayParameterName pname, int index); - /** - * @param pname The parameter name that returns a string. - * @returns The string value for the parameter name, such as `renderer`, `vendor` or others. - */ std::string getParameter(WebGLStringParameterName pname); WebGLShaderPrecisionFormat getShaderPrecisionFormat(int shadertype, int precisiontype); int getError(); @@ -605,37 +528,38 @@ namespace endor protected: /** - * It sends a command buffer request directly to the client context, it only updates the command buffer's context id before - * sending. - * - * @param commandBuffer - * @param followsFlush - if true, the command buffer will be executed in the default queue. - * @returns if the command buffer request is sent successfully. - */ + * It sends a command buffer request directly to the client context, it only updates the command buffer's context id before + * sending. + * + * @param commandBuffer + * @param followsFlush - if true, the command buffer will be executed in the default queue. + * @returns if the command buffer request is sent successfully. + */ inline bool sendCommandBufferRequestDirectly(commandbuffers::TrCommandBufferBase &commandBuffer, bool followsFlush = false) { commandBuffer.contextId = id; - return clientContext_->sendCommandBufferRequest(commandBuffer, followsFlush); + bool r = clientContext_->sendCommandBufferRequest(commandBuffer, followsFlush); + return r; } /** - * It sends a command buffer request to the server. - * - * @param commandBuffer - * @param followsFlush - if true, the command buffer will be executed in the default queue. - * @returns if the command buffer request is sent successfully. - */ + * It sends a command buffer request to the server. + * + * @param commandBuffer + * @param followsFlush - if true, the command buffer will be executed in the default queue. + * @returns if the command buffer request is sent successfully. + */ bool sendCommandBufferRequest(commandbuffers::TrCommandBufferBase &commandBuffer, bool followsFlush = false); /** - * Receives a command buffer response from the server, and returns the response as a pointer to the specified type. - * - * @param responseType The type of the response command buffer, that is used to check the response type. - * @param req The request command buffer that is used to match the response. - * @param timeout The timeout in milliseconds to wait for the response, default is 1000ms. - * @returns A pointer to the response command buffer of the specified type, or nullptr if the response is not - * received within the timeout or if the response type does not match. - */ + * Receives a command buffer response from the server, and returns the response as a pointer to the specified type. + * + * @param responseType The type of the response command buffer, that is used to check the response type. + * @param req The request command buffer that is used to match the response. + * @param timeout The timeout in milliseconds to wait for the response, default is 1000ms. + * @returns A pointer to the response command buffer of the specified type, or nullptr if the response is not + * received within the timeout or if the response type does not match. + */ template R *recvResponse(commandbuffers::CommandBufferType responseType, const commandbuffers::TrCommandBufferBase &req, @@ -656,12 +580,12 @@ namespace endor } /** - * It receives a command buffer response **asynchronously**, and calls the callback function with the response. - * - * @param responseType The type of the response command buffer, that is used to check the response type. - * @param req The request command buffer that is used to match the response. - * @param callback The callback function that is called with the response command buffer of the specified type. - */ + * It receives a command buffer response **asynchronously**, and calls the callback function with the response. + * + * @param responseType The type of the response command buffer, that is used to check the response type. + * @param req The request command buffer that is used to match the response. + * @param callback The callback function that is called with the response command buffer of the specified type. + */ template void recvResponseAsync(commandbuffers::CommandBufferType responseType, const commandbuffers::TrCommandBufferBase &req, @@ -685,16 +609,16 @@ namespace endor void sendFirstContentfulPaintMetrics(); /** - * It unpacks the pixels from the source buffer to the destination buffer. - * - * @param type The pixel type. - * @param format The pixel format. - * @param width The width of the image. - * @param height The height of the image. - * @param srcPixels The source pixels buffer. - * @param dstPixels The destination pixels buffer, if it is null, a new buffer will be created. - * @returns The destination pixels buffer. - */ + * It unpacks the pixels from the source buffer to the destination buffer. + * + * @param type The pixel type. + * @param format The pixel format. + * @param width The width of the image. + * @param height The height of the image. + * @param srcPixels The source pixels buffer. + * @param dstPixels The destination pixels buffer, if it is null, a new buffer will be created. + * @returns The destination pixels buffer. + */ unsigned char *unpackPixels( WebGLPixelType type, WebGLTextureFormat format, @@ -802,28 +726,28 @@ namespace endor private: /** - * @returns the client state of the WebGL context. - */ + * @returns the client state of the WebGL context. + */ WebGLState &clientState() { return clientState_; } /** - * an XR-compatible WebGL context could be configured as an `XRWebGLLayer` object and be connected to a specific WebXR - * session. At the same time, each WebXR session could own 1 base layer, thus the XR-compatible WebGL context to a WebXR - * session is a one-to-one relationship. - * - * @returns the current connected WebXR session, or `nullptr` if it is not connected. - */ + * an XR-compatible WebGL context could be configured as an `XRWebGLLayer` object and be connected to a specific WebXR + * session. At the same time, each WebXR session could own 1 base layer, thus the XR-compatible WebGL context to a WebXR + * session is a one-to-one relationship. + * + * @returns the current connected WebXR session, or `nullptr` if it is not connected. + */ inline std::shared_ptr connectedXRSession() { return isXRCompatible() ? connectedXRSession_.lock() : nullptr; } /** - * It connects the current WebGL context to a WebXR session. - * - * @param session The WebXR session to connect. - */ + * It connects the current WebGL context to a WebXR session. + * + * @param session The WebXR session to connect. + */ inline void connectXRSession(std::shared_ptr session) { connectedXRSession_ = session; @@ -845,9 +769,7 @@ namespace endor std::string vendor; std::string version; std::string renderer; - /** - * The default handedness of the coordinate system to use. - */ + // The default handedness of the coordinate system to use. commandbuffers::MatrixHandedness defaultCoordHandedness = commandbuffers::MatrixHandedness::MATRIX_RIGHT_HANDED; protected: @@ -867,8 +789,8 @@ namespace endor int clearStencil_ = 0; glm::vec4 blendColor_ = {0.0f, 0.0f, 0.0f, 1.0f}; /** - * TODO: Read the value from the host - */ + * TODO: Read the value from the host + */ uint32_t unpackAlignment_ = 4; private: @@ -879,12 +801,6 @@ namespace endor class WebGL2Context final : public WebGLContext { public: - /** - * It creates a new `WebGL2Context` object. - * - * @param attrs The context attributes. - * @returns The created `WebGL2Context` object. - */ static inline std::shared_ptr Make(ContextAttributes &attrs) { return std::make_shared(attrs); @@ -924,16 +840,6 @@ namespace endor WebGLBufferUsage usage, std::optional srcOffset = 0, std::optional length = 0); - /** - * It updates a subset of a buffer object's data store. - * - * @param target The binding point (target). - * @param dstByteOffset An offset in bytes where the data replacement will start. - * @param srcSize The size of the source data. - * @param srcData The source data to copy from. - * @param srcOffset The element index offset where to start reading the buffer. - * @param length A `uint` defaulting to 0, where 0 means bufferSubData should calculate the length. - */ void bufferSubData( WebGLBufferBindingTarget target, int dstByteOffset, @@ -994,29 +900,14 @@ namespace endor void drawElementsInstanced(WebGLDrawMode mode, int count, int type, int offset, int instanceCount); void drawRangeElements(WebGLDrawMode mode, int start, int end, int count, int type, int offset); void endQuery(WebGLQueryTarget target); - /** - * It attaches a single layer of a texture to a framebuffer. - */ void framebufferTextureLayer( WebGLFramebufferBindingTarget target, WebGLFramebufferAttachment attachment, std::shared_ptr texture, int level, int layer); - /** - * @returns A string indicating the active uniform block name. - */ + std::string getActiveUniformBlockName(std::shared_ptr program, int uniformBlockIndex); - /** - * It reads data from a buffer binding point and writes them to the destination buffer. - * - * @param target The binding point (target). - * @param srcByteOffset The byte offset from which to start reading from the buffer. - * @param dstSize The size of the destination buffer. - * @param dstData A data storage to copy the data to, if it is null, will throw an exception. - * @param dstOffset The element index offset to start writing in `dstData`. - * @param length the number of elements to copy. If this is 0 or nullopt, it will copy util the end of `dstData`. - */ void getBufferSubData( WebGLBufferBindingTarget target, int srcByteOffset, @@ -1027,31 +918,9 @@ namespace endor int getFragDataLocation(std::shared_ptr program, const std::string &name); int getParameterV2(WebGL2IntegerParameterName pname); std::shared_ptr getQuery(WebGLQueryTarget target, int pname); - /** - * It retrieves the index of a uniform block within a WebGLProgram. - * - * @param program The program to query. - * @param uniformBlockName The name of the uniform block. - * @returns The index of the uniform block. - */ int getUniformBlockIndex(std::shared_ptr program, const std::string &uniformBlockName); - /** - * It invalidates the contents of attachments in a framebuffer. - * - * @param target The target to which the framebuffer is attached. - * @param attachments The list of attachments to invalidate. - */ + void invalidateFramebuffer(WebGLFramebufferBindingTarget target, const std::vector attachments); - /** - * It invalidates portions of the contents of attachments in a framebuffer. - * - * @param target The target to which the framebuffer is attached. - * @param attachments The list of attachments to invalidate. - * @param x The x offset of the region to invalidate. - * @param y The y offset of the region to invalidate. - * @param width The width of the region to invalidate. - * @param height The height of the region to invalidate. - */ void invalidateSubFramebuffer( WebGLFramebufferBindingTarget target, const std::vector attachments, @@ -1059,210 +928,69 @@ namespace endor int y, size_t width, size_t height); - /** - * @returns `true` if the passed object is a valid `WebGLQuery` object. - */ + bool isQuery(std::shared_ptr query); - /** - * @returns `true` if the passed object is a valid `WebGLSampler` object. - */ bool isSampler(std::shared_ptr sampler); - /** - * @returns `true` if the passed object is a valid `WebGLVertexArray` object. - */ bool isVertexArray(std::shared_ptr vertexArray); - /** - * It selects a color buffer as the source for pixels for subsequent calls to `copyTexImage2D`, `copyTexSubImage2D`, - * `copyTexSubImage3D` or `readPixels`. - * - * @param src The color buffer to select. - */ + void readBuffer(int src); - /** - * It returns creates and initializes a renderbuffer object's data store and allows specifying a number of samples to - * be used. - * - * @param target The target to which the renderbuffer is attached. - * @param samples The number of samples to be used. - * @param internalformat The internal format of the renderbuffer. - * @param width The width of the renderbuffer. - * @param height The height of the renderbuffer. - */ - void renderbufferStorageMultisample( - WebGLRenderbufferBindingTarget target, - int samples, - int internalformat, - int width, - int height); - /** - * It specifies a three-dimensional texture image. - * - * @param target The target to which the texture is bound. - * @param level The level of detail. Level 0 is the base image level. - * @param internalformat The color components in the texture. - * @param width The width of the texture image. - * @param height The height of the texture image. - * @param depth The depth of the texture image. - * @param border The width of the border. Must be 0. - * @param format The format of the pixel data. - * @param type The data type of the pixel data. - * @param pixels The pixel data. - */ - void texImage3D( - WebGLTexture3DTarget target, - int level, - int internalformat, - size_t width, - size_t height, - size_t depth, - int border, - WebGLTextureFormat format, - WebGLPixelType type, - unsigned char *pixels); - /** - * It specifies all levels of two-dimensional texture storage. - * - * @param target The target to which the texture is bound. - * @param levels The number of texture levels. - * @param internalformat The color components in the texture. - * @param width The width of the texture image. - * @param height The height of the texture image. - */ - void texStorage2D( - WebGLTexture2DTarget target, - int levels, - int internalformat, - size_t width, - size_t height); - /** - * It specifies all levels of three-dimensional texture storage. - * - * @param target The target to which the texture is bound. - * @param levels The number of texture levels. - * @param internalformat The color components in the texture. - * @param width The width of the texture image. - * @param height The height of the texture image. - * @param depth The depth of the texture image. - */ - void texStorage3D( - WebGLTexture3DTarget target, - int levels, - int internalformat, - size_t width, - size_t height, - size_t depth); - /** - * It specifies a sub-rectangle of a three-dimensional texture image. - * - * @param target The target to which the texture is bound. - * @param level The level of detail. Level 0 is the base image level. - * @param xoffset The x offset of the sub-rectangle. - * @param yoffset The y offset of the sub-rectangle. - * @param zoffset The z offset of the sub-rectangle. - * @param width The width of the sub-rectangle. - * @param height The height of the sub-rectangle. - * @param depth The depth of the sub-rectangle. - * @param format The format of the pixel data. - * @param type The data type of the pixel data. - * @param pixels The pixel data. - */ - void texSubImage3D( - WebGLTexture3DTarget target, - int level, - int xoffset, - int yoffset, - int zoffset, - size_t width, - size_t height, - size_t depth, - WebGLTextureFormat format, - WebGLPixelType type, - unsigned char *pixels); - /** - * It assigns binding points for active uniform blocks. - */ + void renderbufferStorageMultisample(WebGLRenderbufferBindingTarget target, + int samples, + int internalformat, + int width, + int height); + + void texImage3D(WebGLTexture3DTarget target, + int level, + int internalformat, + size_t width, + size_t height, + size_t depth, + int border, + WebGLTextureFormat format, + WebGLPixelType type, + unsigned char *pixels); + void texStorage2D(WebGLTexture2DTarget target, + int levels, + int internalformat, + size_t width, + size_t height); + void texStorage3D(WebGLTexture3DTarget target, + int levels, + int internalformat, + size_t width, + size_t height, + size_t depth); + void texSubImage3D(WebGLTexture3DTarget target, + int level, + int xoffset, + int yoffset, + int zoffset, + size_t width, + size_t height, + size_t depth, + WebGLTextureFormat format, + WebGLPixelType type, + unsigned char *pixels); + void uniformBlockBinding(std::shared_ptr program, int uniformBlockIndex, uint32_t uniformBlockBinding); - /** - * It specifies 3x2 matrix values for uniform variables. - */ void uniformMatrix3x2fv(WebGLUniformLocation location, bool transpose, std::vector values); - /** - * It specifies 4x2 matrix values for uniform variables. - */ void uniformMatrix4x2fv(WebGLUniformLocation location, bool transpose, std::vector values); - /** - * It specifies 2x3 matrix values for uniform variables. - */ void uniformMatrix2x3fv(WebGLUniformLocation location, bool transpose, std::vector values); - /** - * It specifies 4x3 matrix values for uniform variables. - */ void uniformMatrix4x3fv(WebGLUniformLocation location, bool transpose, std::vector values); - /** - * It specifies 2x4 matrix values for uniform variables. - */ void uniformMatrix2x4fv(WebGLUniformLocation location, bool transpose, std::vector values); - /** - * It specifies 3x4 matrix values for uniform variables. - */ void uniformMatrix3x4fv(WebGLUniformLocation location, bool transpose, std::vector values); - /** - * It modifies the rate at which generic vertex attributes advance when rendering multiple instances of primitives with - * `gl.drawArraysInstanced()` and `gl.drawElementsInstanced()`. - * - * @param index The index of the vertex attribute. - * @param divisor The number of instances that will pass between updates of the generic attribute. - */ + void vertexAttribDivisor(const WebGLAttribLocation &, uint32_t divisor); void vertexAttribDivisor(int index, uint32_t divisor); - /** - * It specify integer values for generic vertex attributes. - * - * @param index The index of the vertex attribute. - * @param v0 The first value to set. - * @param v1 The second value to set. - * @param v2 The third value to set. - * @param v3 The fourth value to set. - */ void vertexAttribI4i(const WebGLAttribLocation &, int v0, int v1, int v2, int v3); void vertexAttribI4i(int index, int v0, int v1, int v2, int v3); - /** - * It specify unsigned integer values for generic vertex attributes. - * - * @param index The index of the vertex attribute. - * @param v0 The first value to set. - * @param v1 The second value to set. - * @param v2 The third value to set. - * @param v3 The fourth value to set. - */ void vertexAttribI4ui(const WebGLAttribLocation &, uint v0, uint v1, uint v2, uint v3); void vertexAttribI4ui(int index, uint v0, uint v1, uint v2, uint v3); - /** - * It specify integer values for generic vertex attributes from a vector. - * - * @param index The index of the vertex attribute. - * @param values The values to set. - */ void vertexAttribI4iv(const WebGLAttribLocation &, const std::vector values); void vertexAttribI4iv(int index, const std::vector values); - /** - * It specify unsigned integer values for generic vertex attributes from a vector. - * - * @param index The index of the vertex attribute. - * @param values The values to set. - */ void vertexAttribI4uiv(const WebGLAttribLocation &, const std::vector values); void vertexAttribI4uiv(int index, const std::vector values); - /** - * It specifies integer data formats and locations of vertex attributes in a vertex attributes array. - * - * @param index The index of the vertex attribute that is to be modified. - * @param size The number of components per vertex attribute. Must be 1, 2, 3, or 4. - * @param type The data type of each component in the array. Must be one of: `gl.BYTE`, `gl.UNSIGNED_BYTE`, - * `gl.SHORT`, `gl.UNSIGNED_SHORT`, `gl.INT`, or `gl.UNSIGNED_INT`. - * @param stride The offset in bytes between the beginning of consecutive vertex attributes. - * @param offset An offset in bytes of the first component in the vertex attribute array. Must be a multiple of type. - */ void vertexAttribIPointer(const WebGLAttribLocation &, int size, int type, diff --git a/src/client/graphics/webgl_shader.cpp b/src/client/graphics/webgl_shader.cpp index cb657a4dd..5679d3ad9 100644 --- a/src/client/graphics/webgl_shader.cpp +++ b/src/client/graphics/webgl_shader.cpp @@ -1,4 +1,4 @@ - +#include #include #include "./webgl_shader.hpp" diff --git a/src/common/command_buffers/shared.cpp b/src/common/command_buffers/shared.cpp index d18a1eb58..b4637dde1 100644 --- a/src/common/command_buffers/shared.cpp +++ b/src/common/command_buffers/shared.cpp @@ -1,9 +1,11 @@ #include "./shared.hpp" #include "./macros.hpp" +using namespace std; + namespace commandbuffers { - std::string commandTypeToStr(CommandBufferType type) + string commandTypeToStr(CommandBufferType type) { switch (type) { @@ -31,4 +33,182 @@ namespace commandbuffers return "Unknown"; } } + + // static + bool CommandTypes::IsXRFrameControl(CommandBufferType type) + { + return type == COMMAND_BUFFER_XRFRAME_START_REQ || + type == COMMAND_BUFFER_XRFRAME_FLUSH_REQ || + type == COMMAND_BUFFER_XRFRAME_END_REQ; + } + + // static + bool CommandTypes::IsFramebufferDependentCommand(CommandBufferType type) + { + switch (type) + { + // --- Framebuffer binding & attachment --- + case COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ: + case COMMAND_BUFFER_FRAMEBUFFER_RENDERBUFFER_REQ: + case COMMAND_BUFFER_FRAMEBUFFER_TEXTURE2D_REQ: + case COMMAND_BUFFER_CHECK_FRAMEBUFFER_STATUS_REQ: + case COMMAND_BUFFER_CHECK_FRAMEBUFFER_STATUS_RES: + case COMMAND_BUFFER_READ_BUFFER_REQ: + case COMMAND_BUFFER_BLIT_FRAMEBUFFER_REQ: + case COMMAND_BUFFER_RENDERBUFFER_STORAGE_REQ: + case COMMAND_BUFFER_RENDERBUFFER_STORAGE_MULTISAMPLE_REQ: + case COMMAND_BUFFER_BIND_RENDERBUFFER_REQ: + return true; + + // --- Program / Shader states --- + case COMMAND_BUFFER_USE_PROGRAM_REQ: + return true; + + // --- Vertex Inputs --- + case COMMAND_BUFFER_BIND_VERTEX_ARRAY_REQ: + case COMMAND_BUFFER_BIND_BUFFER_REQ: + case COMMAND_BUFFER_BUFFER_DATA_REQ: + case COMMAND_BUFFER_BUFFER_SUB_DATA_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_POINTER_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_IPOINTER_REQ: + case COMMAND_BUFFER_ENABLE_VERTEX_ATTRIB_ARRAY_REQ: + case COMMAND_BUFFER_DISABLE_VERTEX_ATTRIB_ARRAY_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_DIVISOR_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_1F_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_2F_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_3F_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_4F_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_I4I_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_I4UI_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_I4IV_REQ: + case COMMAND_BUFFER_VERTEX_ATTRIB_I4UIV_REQ: + return true; + + // --- Texture / Sampler --- + case COMMAND_BUFFER_ACTIVE_TEXTURE_REQ: + case COMMAND_BUFFER_BIND_TEXTURE_REQ: + case COMMAND_BUFFER_BIND_SAMPLER_REQ: + case COMMAND_BUFFER_TEXTURE_PARAMETERI_REQ: + case COMMAND_BUFFER_TEXTURE_PARAMETERF_REQ: + case COMMAND_BUFFER_SAMPLER_PARAMETERI_REQ: + case COMMAND_BUFFER_SAMPLER_PARAMETERF_REQ: + case COMMAND_BUFFER_TEXTURE_IMAGE_2D_REQ: + case COMMAND_BUFFER_TEXTURE_IMAGE_3D_REQ: + case COMMAND_BUFFER_TEXTURE_SUB_IMAGE_2D_REQ: + case COMMAND_BUFFER_TEXTURE_SUB_IMAGE_3D_REQ: + case COMMAND_BUFFER_GENERATE_MIPMAP_REQ: + return true; + + // --- Uniforms --- + case COMMAND_BUFFER_UNIFORM1F_REQ: + case COMMAND_BUFFER_UNIFORM1FV_REQ: + case COMMAND_BUFFER_UNIFORM1I_REQ: + case COMMAND_BUFFER_UNIFORM1IV_REQ: + case COMMAND_BUFFER_UNIFORM2F_REQ: + case COMMAND_BUFFER_UNIFORM2FV_REQ: + case COMMAND_BUFFER_UNIFORM2I_REQ: + case COMMAND_BUFFER_UNIFORM2IV_REQ: + case COMMAND_BUFFER_UNIFORM3F_REQ: + case COMMAND_BUFFER_UNIFORM3FV_REQ: + case COMMAND_BUFFER_UNIFORM3I_REQ: + case COMMAND_BUFFER_UNIFORM3IV_REQ: + case COMMAND_BUFFER_UNIFORM4F_REQ: + case COMMAND_BUFFER_UNIFORM4FV_REQ: + case COMMAND_BUFFER_UNIFORM4I_REQ: + case COMMAND_BUFFER_UNIFORM4IV_REQ: + case COMMAND_BUFFER_UNIFORM_MATRIX2FV_REQ: + case COMMAND_BUFFER_UNIFORM_MATRIX3FV_REQ: + case COMMAND_BUFFER_UNIFORM_MATRIX4FV_REQ: + return true; + + // --- Draw calls (write to framebuffer) --- + case COMMAND_BUFFER_DRAW_ARRAYS_REQ: + case COMMAND_BUFFER_DRAW_ARRAYS_INSTANCED_REQ: + case COMMAND_BUFFER_DRAW_ELEMENTS_REQ: + case COMMAND_BUFFER_DRAW_ELEMENTS_INSTANCED_REQ: + case COMMAND_BUFFER_DRAW_RANGE_ELEMENTS_REQ: + case COMMAND_BUFFER_DRAW_BUFFERS_REQ: + return true; + + // --- Clear (modify framebuffer attachments) --- + case COMMAND_BUFFER_CLEAR_REQ: + case COMMAND_BUFFER_CLEAR_COLOR_REQ: + case COMMAND_BUFFER_CLEAR_DEPTH_REQ: + case COMMAND_BUFFER_CLEAR_STENCIL_REQ: + case COMMAND_BUFFER_CLEAR_BUFFERFV_REQ: + case COMMAND_BUFFER_CLEAR_BUFFERIV_REQ: + case COMMAND_BUFFER_CLEAR_BUFFERUIV_REQ: + case COMMAND_BUFFER_CLEAR_BUFFERFI_REQ: + return true; + + // --- Framebuffer size/region dependent states --- + case COMMAND_BUFFER_SET_VIEWPORT_REQ: + case COMMAND_BUFFER_SET_SCISSOR_REQ: + case COMMAND_BUFFER_DEPTH_FUNC_REQ: + case COMMAND_BUFFER_DEPTH_MASK_REQ: + case COMMAND_BUFFER_STENCIL_FUNC_REQ: + case COMMAND_BUFFER_STENCIL_FUNC_SEPARATE_REQ: + case COMMAND_BUFFER_STENCIL_MASK_REQ: + case COMMAND_BUFFER_STENCIL_MASK_SEPARATE_REQ: + case COMMAND_BUFFER_STENCIL_OP_REQ: + case COMMAND_BUFFER_STENCIL_OP_SEPARATE_REQ: + case COMMAND_BUFFER_BLEND_COLOR_REQ: + case COMMAND_BUFFER_BLEND_EQUATION_REQ: + case COMMAND_BUFFER_BLEND_EQUATION_SEPARATE_REQ: + case COMMAND_BUFFER_BLEND_FUNC_REQ: + case COMMAND_BUFFER_BLEND_FUNC_SEPARATE_REQ: + case COMMAND_BUFFER_COLOR_MASK_REQ: + case COMMAND_BUFFER_POLYGON_OFFSET_REQ: + case COMMAND_BUFFER_CULL_FACE_REQ: + case COMMAND_BUFFER_FRONT_FACE_REQ: + case COMMAND_BUFFER_ENABLE_REQ: + case COMMAND_BUFFER_DISABLE_REQ: + case COMMAND_BUFFER_LINE_WIDTH_REQ: + return true; + + default: + return false; + } + } + + // static + bool CommandTypes::IsResourceCreatingCommand(CommandBufferType type) + { + switch (type) + { + // --- Shader / Program --- + case COMMAND_BUFFER_CREATE_SHADER_REQ: + case COMMAND_BUFFER_CREATE_PROGRAM_REQ: + return true; + + // --- Buffer objects --- + case COMMAND_BUFFER_CREATE_BUFFER_REQ: + return true; + + // --- Framebuffer / Renderbuffer --- + case COMMAND_BUFFER_CREATE_FRAMEBUFFER_REQ: + case COMMAND_BUFFER_CREATE_RENDERBUFFER_REQ: + return true; + + // --- Vertex Array --- + case COMMAND_BUFFER_CREATE_VERTEX_ARRAY_REQ: + return true; + + // --- Texture objects --- + case COMMAND_BUFFER_CREATE_TEXTURE_REQ: + return true; + + // --- Sampler objects --- + case COMMAND_BUFFER_CREATE_SAMPLER_REQ: + return true; + + // --- Transform Feedback --- + case COMMAND_BUFFER_CREATE_TRANSFORM_FEEDBACK_REQ: + return true; + + default: + return false; + } + } + } diff --git a/src/common/command_buffers/shared.hpp b/src/common/command_buffers/shared.hpp index 375e9e038..edf0e7874 100644 --- a/src/common/command_buffers/shared.hpp +++ b/src/common/command_buffers/shared.hpp @@ -244,15 +244,16 @@ namespace commandbuffers std::string commandTypeToStr(CommandBufferType type); - /** - * Check this command type is a XRFrame control. - */ - inline bool isXRFrameControlCommandType(CommandBufferType type) + class CommandTypes { - return type == COMMAND_BUFFER_XRFRAME_START_REQ || - type == COMMAND_BUFFER_XRFRAME_FLUSH_REQ || - type == COMMAND_BUFFER_XRFRAME_END_REQ; - } + public: + // Check this command type is a XRFrame control. + static bool IsXRFrameControl(CommandBufferType); + // Check this command type is a framebuffer dependent command, such as draw calls, read pixels, etc. + static bool IsFramebufferDependentCommand(CommandBufferType); + // Check this command type is a resource creating command. + static bool IsResourceCreatingCommand(CommandBufferType); + }; // Check this command type is a request type. template diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index 7e950c8eb..bade263c3 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -166,7 +166,7 @@ namespace renderer // such as `defaultCommandBufferRequests` or `stereoFramesList`, otherwise it will be deleted in this function. void TrContentRenderer::onCommandBufferRequestReceived(TrCommandBufferBase *req) { - if (!req->renderingInfo.isValid() && !commandbuffers::isXRFrameControlCommandType(req->type)) + if (!req->renderingInfo.isValid() && !commandbuffers::CommandTypes::IsXRFrameControl(req->type)) { unique_lock lock(commandBufferRequestsMutex); defaultCommandBufferRequests.push_back(req); diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 4071bc27a..3f882a33a 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -510,15 +510,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface for (const auto &attrib : req->attribLocations) { if (attrib.name.rfind("gl_", 0) != 0) - { glBindAttribLocation(program, attrib.location, attrib.name.c_str()); - DEBUG(LOG_TAG_RENDERER, - "[%d] GL::BindAttribLocation(program=%d, location=%d, name=%s)", - options.isDefaultQueue(), - program, - attrib.location, - attrib.name.c_str()); - } } glLinkProgram(program); reqContentRenderer->getContextGL()->MarkAsDirty(); @@ -2198,6 +2190,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto type = req->indicesType; auto indices = reinterpret_cast(req->indicesOffset); + PrintDebugInfo(req, nullptr, nullptr, options); + DumpDrawCallInfo(DEBUG_TAG, "DrawElements", options.isDefaultQueue(), mode, count, type, indices); + reqContentRenderer->getContextGL()->drawElements(mode, count, type, indices); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { @@ -2814,35 +2809,47 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectortype; - // if (commandType == COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ) - // { - // auto req = dynamic_cast(commandbuffer); - // assert(req != nullptr); - - // if (pass_type == ExecutingPassType::kXRFrame && - // (req->target == GL_FRAMEBUFFER || - // req->target == GL_DRAW_FRAMEBUFFER)) - // { - // if (req->isBindToDefault()) // Stop copying commandbuffers into offscreen pass if it is to bind to default. - // should_move_to_offscreen_pass = false; - // else - // { - // GLuint framebuffer = contentGlContext->ObjectManagerRef().FindFramebuffer(req->framebuffer); - // should_move_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); - // if (should_move_to_offscreen_pass == true) - // content_renderer->resetOffscreenPassGLContext(framebuffer); - // } - // } - // } + + // Determine if we need to move this command buffer to other passes such as offscreen pass. + if (commandType == COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ) + { + auto req = dynamic_cast(commandbuffer); + assert(req != nullptr); + + if (pass_type == ExecutingPassType::kXRFrame && + (req->target == GL_FRAMEBUFFER || + req->target == GL_DRAW_FRAMEBUFFER)) + { + if (req->isBindToDefault()) // Stop copying commandbuffers into offscreen pass if it is to bind to default. + should_move_to_offscreen_pass = false; + else + { + GLuint framebuffer = contentGlContext->ObjectManagerRef().FindFramebuffer(req->framebuffer); + should_move_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); + if (should_move_to_offscreen_pass == true) + content_renderer->resetOffscreenPassGLContext(framebuffer); + } + } + } // Move the command buffers to offscreen pass if needed - if (pass_type == ExecutingPassType::kXRFrame && should_move_to_offscreen_pass == true) + if (pass_type == ExecutingPassType::kXRFrame && + should_move_to_offscreen_pass == true) { - content_renderer->scheduleCommandBufferAtOffscreenPass(commandbuffer); - it = list.erase(it); // Remove this command buffer from the original list - continue; // Skip to the next command buffer + // Move only framebuffer dependent command buffers + if (CommandTypes::IsFramebufferDependentCommand(commandType)) + { + content_renderer->scheduleCommandBufferAtOffscreenPass(commandbuffer); + it = list.erase(it); // Remove this command buffer from the original list + continue; // Skip to the next command buffer + } + else + { + DEBUG(DEBUG_TAG, + "Executing resource creation command for offscreen pass in advance: %s.", + commandTypeToStr(commandType).c_str()); + } } // Move to the next command buffer From 77ba6dd94a4fa886b49f69d9a16b25789f01ce92 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 30 Oct 2025 18:32:32 +0800 Subject: [PATCH 03/37] update --- cmake/TransmuteCommon.cmake | 3 +- src/common/command_buffers/gpu/gpu_base.hpp | 36 +++ .../command_buffers/gpu/gpu_bind_group.hpp | 55 +--- .../gpu/gpu_bind_group_layout.hpp | 63 +++++ src/common/command_buffers/gpu/gpu_buffer.hpp | 58 ++++- .../gpu/gpu_command_buffer.hpp | 216 +--------------- .../gpu/gpu_command_encoder.hpp | 13 +- .../command_buffers/gpu/gpu_commands.hpp | 237 ++++++++++++++++++ src/common/command_buffers/gpu/gpu_device.hpp | 10 +- .../gpu/gpu_pass_encoder_base.cpp | 26 ++ .../gpu/gpu_pass_encoder_base.hpp | 25 +- .../command_buffers/gpu/gpu_pipeline.hpp | 10 +- .../gpu/gpu_renderpass_encoder.hpp | 18 +- .../command_buffers/gpu/gpu_texture_view.hpp | 2 +- src/renderer/gles/gpu_command_buffer_impl.cpp | 6 +- src/renderer/gles/gpu_command_buffer_impl.hpp | 2 +- .../gles/gpu_command_encoder_impl.hpp | 10 +- src/renderer/gles/gpu_device_impl.cpp | 10 +- src/renderer/gles/gpu_device_impl.hpp | 8 +- .../gles/gpu_renderpass_encoder_impl.hpp | 2 +- 20 files changed, 483 insertions(+), 327 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_bind_group_layout.hpp create mode 100644 src/common/command_buffers/gpu/gpu_commands.hpp create mode 100644 src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp diff --git a/cmake/TransmuteCommon.cmake b/cmake/TransmuteCommon.cmake index 5116c1e37..482e28345 100644 --- a/cmake/TransmuteCommon.cmake +++ b/cmake/TransmuteCommon.cmake @@ -1,7 +1,6 @@ # Set the common source files. -file(GLOB TR_COMMON_SOURCE +file(GLOB_RECURSE TR_COMMON_SOURCE "src/common/*.cpp" - "src/common/**/*.cpp" ) # Set the common include directories diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 9ed377959..fadd7e175 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -5,6 +5,40 @@ namespace commandbuffers { + enum class GPUHandleType : uint32_t + { + kAdapter, + kBindGroup, + kBindGroupLayout, + kBuffer, + kCommandBuffer, + kCommandEncoder, + kComputePassEncoder, + kComputePipeline, + kDevice, + kExternalTexture, + kInstance, + kPipelineLayout, + kQuerySet, + kQueue, + kRenderBundle, + kRenderBundleEncoder, + kRenderPassEncoder, + kRenderPipeline, + kSampler, + kShaderModule, + kSharedBufferMemory, + kSharedFence, + kSharedTextureMemory, + kSurface, + kTexelBufferView, + kTexture, + kTextureView, + + // Additional internal object types. Keep kExtraObjectTypes in sync when updating. + kBindGroupLayoutInternal, + }; + enum class GPUShaderStage { kVertex, @@ -52,6 +86,8 @@ namespace commandbuffers { } + virtual GPUHandleType type() const = 0; + public: const std::string label = ""; const GPUIdentifier id; diff --git a/src/common/command_buffers/gpu/gpu_bind_group.hpp b/src/common/command_buffers/gpu/gpu_bind_group.hpp index aa14ce744..8be2b63a0 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group.hpp +++ b/src/common/command_buffers/gpu/gpu_bind_group.hpp @@ -5,63 +5,16 @@ #include #include "./gpu_base.hpp" -#include "./gpu_texture.hpp" +#include "./gpu_bind_group_layout.hpp" namespace commandbuffers { - class GPUBindGroupLayout : public GPUHandle + class GPUBindGroupBase : public GPUHandle { public: - class BufferLayout - { - public: - GPUBufferType type; - bool hasDynamicOffset = false; - uint32_t minBindingSize = 0; // in bytes - }; - - class TextureLayout - { - public: - bool multisampled = false; - }; - - class StorageTextureLayout - { - public: - GPUStorageAccess access; - GPUTextureFormat format; - std::optional viewDimension; - }; - - class ExternalTextureLayout - { - }; - - class SamplerLayout - { - public: - GPUSamplerType type; - }; - - using ResourceLayout = std::variant; - class Entry - { - public: - uint32_t binding; - GPUShaderStage visibility; - ResourceLayout layout; - }; + virtual ~GPUBindGroupBase() = default; private: - std::vector entries_; - }; - - class GPUBindGroup : public GPUHandle - { + std::shared_ptr *layout_ = nullptr; }; } diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp b/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp new file mode 100644 index 000000000..32686c33c --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include + +#include "./gpu_base.hpp" +#include "./gpu_texture.hpp" + +namespace commandbuffers +{ + class GPUBindGroupLayoutBase : public GPUHandle + { + public: + class BufferLayout + { + public: + GPUBufferType type; + bool hasDynamicOffset = false; + uint32_t minBindingSize = 0; // in bytes + }; + + class TextureLayout + { + public: + bool multisampled = false; + }; + + class StorageTextureLayout + { + public: + GPUStorageAccess access; + GPUTextureFormat format; + std::optional viewDimension; + }; + + class ExternalTextureLayout + { + }; + + class SamplerLayout + { + public: + GPUSamplerType type; + }; + + using ResourceLayout = std::variant; + class Entry + { + public: + uint32_t binding; + GPUShaderStage visibility; + ResourceLayout layout; + }; + + private: + std::vector entries_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_buffer.hpp b/src/common/command_buffers/gpu/gpu_buffer.hpp index e969351f4..846d59d7b 100644 --- a/src/common/command_buffers/gpu/gpu_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_buffer.hpp @@ -1,12 +1,66 @@ #pragma once +#include #include "./gpu_base.hpp" namespace commandbuffers { - class GPUBuffer : public GPUHandle + enum class BufferUsage : uint64_t { + None, + MapRead, + MapWrite, + CopySrc, + CopyDst, + Index, + Vertex, + Uniform, + Storage, + Indirect, + QueryResolve, + TexelBuffer, + }; + + class GPUBufferBase : public GPUHandle + { + public: + enum class BufferState + { + Unmapped, + PendingMap, + Mapped, + MappedAtCreation, + HostMappedPersistent, + SharedMemoryNoAccess, + Destroyed, + }; + static bool IsMappedState(BufferState state) + { + return state == BufferState::Mapped || + state == BufferState::MappedAtCreation || + state == BufferState::HostMappedPersistent; + } + + public: + virtual ~GPUBufferBase() = default; + public: - ~GPUBuffer() = default; + size_t size() const + { + return size_; + } + BufferUsage usage() const + { + return usage_; + } + BufferState mapState() const + { + return map_state_.load(); + } + + private: + size_t size_ = 0; + BufferUsage usage_ = BufferUsage::None; + std::atomic map_state_ = BufferState::Unmapped; }; } diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.hpp b/src/common/command_buffers/gpu/gpu_command_buffer.hpp index fd3d0a280..84fa186ba 100644 --- a/src/common/command_buffers/gpu/gpu_command_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_command_buffer.hpp @@ -6,229 +6,27 @@ #include "./gpu_base.hpp" #include "./gpu_buffer.hpp" #include "./gpu_pipeline.hpp" +#include "./gpu_commands.hpp" namespace commandbuffers { - class GPUCommand + class GPUCommandBufferBase : public GPUHandle { - public: - enum GPUCommandType : uint8_t - { - kDraw = 0, - kDrawIndexed, - kDrawIndirect, - kDrawIndexedIndirect, - kSetViewport, - kSetScissor, - kSetRenderPipeline, - kSetIndexBuffer, - kSetVertexBuffer, - kSetBindGroup, - kSetBlendConstant, - kSetStencilReference, - }; - - public: - const GPUCommandType type; - - GPUCommand(GPUCommandType type) - : type(type) - { - } - virtual ~GPUCommand() = default; - }; - - class GPUDrawCommand : public GPUCommand - { - public: - const uint32_t vertexCount; - const uint32_t instanceCount; - const uint32_t firstVertex; - const uint32_t firstInstance; - - GPUDrawCommand(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) - : GPUCommand(kDraw) - , vertexCount(vertex_count) - , instanceCount(instance_count) - , firstVertex(first_vertex) - , firstInstance(first_instance) - { - } - }; - - class GPUDrawIndexedCommand : public GPUCommand - { - public: - const uint32_t indexCount; - const uint32_t instanceCount; - const uint32_t firstIndex; - const int32_t baseVertex; - const uint32_t firstInstance; - - GPUDrawIndexedCommand(uint32_t index_count, - uint32_t instance_count, - uint32_t first_index, - int32_t base_vertex, - uint32_t first_instance) - : GPUCommand(kDrawIndexed) - , indexCount(index_count) - , instanceCount(instance_count) - , firstIndex(first_index) - , baseVertex(base_vertex) - , firstInstance(first_instance) - { - } - }; - - class GPUSetViewportCommand : public GPUCommand - { - public: - const float x; - const float y; - const float width; - const float height; - const float minDepth; - const float maxDepth; - - GPUSetViewportCommand(float x, float y, float width, float height, float min_depth, float max_depth) - : GPUCommand(kSetViewport) - , x(x) - , y(y) - , width(width) - , height(height) - , minDepth(min_depth) - , maxDepth(max_depth) - { - } - }; - - class GPUSetScissorCommand : public GPUCommand - { - public: - const float x; - const float y; - const float width; - const float height; - - GPUSetScissorCommand(float x, float y, float width, float height) - : GPUCommand(kSetScissor) - , x(x) - , y(y) - , width(width) - , height(height) - { - } - }; - - class GPUSetRenderPipelineCommand : public GPUCommand - { - public: - const GPUIdentifier pipelineId; - - GPUSetRenderPipelineCommand(const GPURenderPipeline &pipeline) - : GPUCommand(kSetRenderPipeline) - , pipelineId(pipeline.id) - { - } - }; - - class GPUSetIndexBufferCommand : public GPUCommand - { - public: - const GPUIdentifier bufferId; - const GPUIndexFormat indexFormat; - const uint32_t offset; - const uint32_t size; - - GPUSetIndexBufferCommand(const GPUBuffer &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) - : GPUCommand(kSetIndexBuffer) - , bufferId(buffer.id) - , indexFormat(index_format) - , offset(offset) - , size(size) - { - } - }; - - class GPUSetVertexBufferCommand : public GPUCommand - { - public: - const uint32_t slot; - const GPUIdentifier bufferId; - const uint32_t offset; - const uint32_t size; - - GPUSetVertexBufferCommand(const uint32_t slot, const GPUBuffer &buffer, uint64_t offset, uint32_t size) - : GPUCommand(kSetVertexBuffer) - , slot(slot) - , bufferId(buffer.id) - , offset(offset) - , size(size) - { - } - }; - - class GPUSetBindGroupCommand : public GPUCommand - { - public: - const GPUIdentifier bindGroupId; - const uint32_t index; - - GPUSetBindGroupCommand(const GPUBindGroup &bindGroup, uint32_t index) - : GPUCommand(kSetBindGroup) - , bindGroupId(bindGroup.id) - , index(index) - { - } - }; - - class GPUSetBlendConstantCommand : public GPUCommand - { - public: - const float r; - const float g; - const float b; - const float a; - - GPUSetBlendConstantCommand(float r, float g, float b, float a) - : GPUCommand(kSetBlendConstant) - , r(r) - , g(g) - , b(b) - , a(a) - { - } - }; - - class GPUSetStencilReferenceCommand : public GPUCommand - { - public: - const uint32_t reference; - - GPUSetStencilReferenceCommand(uint32_t reference) - : GPUCommand(kSetStencilReference) - , reference(reference) - { - } - }; - - class GPUCommandBuffer : public GPUHandle - { - friend class GPUComputePassEncoder; - friend class GPURenderPassEncoder; + friend class GPUComputePassEncoderBase; + friend class GPURenderPassEncoderBase; public: - GPUCommandBuffer(std::optional label) + GPUCommandBufferBase(std::optional label) : GPUHandle(label.value_or("GPUCommandBuffer")) , commands_() { } - GPUCommandBuffer(std::optional label, const GPUCommandBuffer &source) + GPUCommandBufferBase(std::optional label, const GPUCommandBufferBase &source) : GPUHandle(label.value_or("GPUCommandBuffer")) , commands_(source.commands_) { } - virtual ~GPUCommandBuffer() = default; + virtual ~GPUCommandBufferBase() = default; public: virtual void execute() = 0; diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index 78e1971d0..c03b12bd4 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -9,17 +9,22 @@ namespace commandbuffers { - class GPUCommandEncoder : public GPUHandle + class GPUCommandEncoderBase : public GPUHandle { using GPUHandle::GPUHandle; public: - virtual ~GPUCommandEncoder() = default; + virtual ~GPUCommandEncoderBase() = default; + + GPUHandleType type() const override + { + return GPUHandleType::kCommandEncoder; + } public: // TODO(yorkie): begineComputePass - virtual GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor &) = 0; - virtual std::unique_ptr finish(std::optional label = std::nullopt) const = 0; + virtual GPURenderPassEncoderBase beginRenderPass(GPURenderPassDescriptor &) = 0; + virtual std::unique_ptr finish(std::optional label = std::nullopt) const = 0; protected: std::shared_ptr current_pass_encoder_; diff --git a/src/common/command_buffers/gpu/gpu_commands.hpp b/src/common/command_buffers/gpu/gpu_commands.hpp new file mode 100644 index 000000000..71eae1585 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_commands.hpp @@ -0,0 +1,237 @@ +#pragma once + +#include +#include + +#include "./gpu_base.hpp" +#include "./gpu_buffer.hpp" +#include "./gpu_pipeline.hpp" + +namespace commandbuffers +{ + class GPUCommand + { + public: + enum CommandType + { + kBeginComputePass, + kBeginOcclusionQuery, + kBeginRenderPass, + kClearBuffer, + kCopyBufferToBuffer, + kCopyBufferToTexture, + kCopyTextureToBuffer, + kCopyTextureToTexture, + kDispatch, + kDispatchIndirect, + kDraw, + kDrawIndexed, + kDrawIndirect, + kDrawIndexedIndirect, + kMultiDrawIndirect, + kMultiDrawIndexedIndirect, + kEndComputePass, + kEndOcclusionQuery, + kEndRenderPass, + kExecuteBundles, + kInsertDebugMarker, + kPixelLocalStorageBarrier, + kPopDebugGroup, + kPushDebugGroup, + kResolveQuerySet, + kSetComputePipeline, + kSetRenderPipeline, + kSetStencilReference, + kSetViewport, + kSetScissorRect, + kSetBlendConstant, + kSetBindGroup, + kSetImmediateData, + kSetIndexBuffer, + kSetVertexBuffer, + kWriteBuffer, + kWriteTimestamp, + }; + const CommandType type; + + GPUCommand(CommandType type) + : type(type) + { + } + virtual ~GPUCommand() = default; + }; + + class GPUDrawCommand : public GPUCommand + { + public: + const uint32_t vertexCount; + const uint32_t instanceCount; + const uint32_t firstVertex; + const uint32_t firstInstance; + + GPUDrawCommand(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) + : GPUCommand(kDraw) + , vertexCount(vertex_count) + , instanceCount(instance_count) + , firstVertex(first_vertex) + , firstInstance(first_instance) + { + } + }; + + class GPUDrawIndexedCommand : public GPUCommand + { + public: + const uint32_t indexCount; + const uint32_t instanceCount; + const uint32_t firstIndex; + const int32_t baseVertex; + const uint32_t firstInstance; + + GPUDrawIndexedCommand(uint32_t index_count, + uint32_t instance_count, + uint32_t first_index, + int32_t base_vertex, + uint32_t first_instance) + : GPUCommand(kDrawIndexed) + , indexCount(index_count) + , instanceCount(instance_count) + , firstIndex(first_index) + , baseVertex(base_vertex) + , firstInstance(first_instance) + { + } + }; + + class GPUSetViewportCommand : public GPUCommand + { + public: + const float x; + const float y; + const float width; + const float height; + const float minDepth; + const float maxDepth; + + GPUSetViewportCommand(float x, float y, float width, float height, float min_depth, float max_depth) + : GPUCommand(kSetViewport) + , x(x) + , y(y) + , width(width) + , height(height) + , minDepth(min_depth) + , maxDepth(max_depth) + { + } + }; + + class GPUSetScissorCommand : public GPUCommand + { + public: + const float x; + const float y; + const float width; + const float height; + + GPUSetScissorCommand(float x, float y, float width, float height) + : GPUCommand(kSetScissorRect) + , x(x) + , y(y) + , width(width) + , height(height) + { + } + }; + + class GPUSetRenderPipelineCommand : public GPUCommand + { + public: + const GPUIdentifier pipelineId; + + GPUSetRenderPipelineCommand(const GPURenderPipelineBase &pipeline) + : GPUCommand(kSetRenderPipeline) + , pipelineId(pipeline.id) + { + } + }; + + class GPUSetIndexBufferCommand : public GPUCommand + { + public: + const GPUIdentifier bufferId; + const GPUIndexFormat indexFormat; + const uint32_t offset; + const uint32_t size; + + GPUSetIndexBufferCommand(const GPUBufferBase &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) + : GPUCommand(kSetIndexBuffer) + , bufferId(buffer.id) + , indexFormat(index_format) + , offset(offset) + , size(size) + { + } + }; + + class GPUSetVertexBufferCommand : public GPUCommand + { + public: + const uint32_t slot; + const GPUIdentifier bufferId; + const uint32_t offset; + const uint32_t size; + + GPUSetVertexBufferCommand(const uint32_t slot, const GPUBufferBase &buffer, uint64_t offset, uint32_t size) + : GPUCommand(kSetVertexBuffer) + , slot(slot) + , bufferId(buffer.id) + , offset(offset) + , size(size) + { + } + }; + + class GPUSetBindGroupCommand : public GPUCommand + { + public: + const GPUIdentifier bindGroupId; + const uint32_t index; + + GPUSetBindGroupCommand(const GPUBindGroupBase &bindGroup, uint32_t index) + : GPUCommand(kSetBindGroup) + , bindGroupId(bindGroup.id) + , index(index) + { + } + }; + + class GPUSetBlendConstantCommand : public GPUCommand + { + public: + const float r; + const float g; + const float b; + const float a; + + GPUSetBlendConstantCommand(float r, float g, float b, float a) + : GPUCommand(kSetBlendConstant) + , r(r) + , g(g) + , b(b) + , a(a) + { + } + }; + + class GPUSetStencilReferenceCommand : public GPUCommand + { + public: + const uint32_t reference; + + GPUSetStencilReferenceCommand(uint32_t reference) + : GPUCommand(kSetStencilReference) + , reference(reference) + { + } + }; +} diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index 991888ce7..a5f4c832a 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -9,7 +9,7 @@ #include "./gpu_command_buffer.hpp" #include "./gpu_command_encoder.hpp" -namespace commandbuffers +namespace commandbuffers::gpu { class GPUQueue : public GPUHandle { @@ -17,7 +17,7 @@ namespace commandbuffers virtual ~GPUQueue() = default; public: - virtual void submit(const std::vector> &) = 0; + virtual void submit(const std::vector> &) = 0; }; /** @@ -27,10 +27,10 @@ namespace commandbuffers * `GPUCommandBuffer` to the renderer. And at server-side's renderer, it implements the same `GPUDevice` interface to * execute the `GPUCommandBuffer` on the corresponding graphics API (e.g. OpenGL, Vulkan, etc.) via RHI. */ - class GPUDevice : public GPUHandle + class GPUDeviceBase : public GPUHandle { public: - virtual ~GPUDevice() = default; + virtual ~GPUDeviceBase() = default; public: const GPUAdapterInfo &adapterInfo() const @@ -51,7 +51,7 @@ namespace commandbuffers return *queue_; } - virtual std::unique_ptr createCommandEncoder(std::optional label) = 0; + virtual std::unique_ptr createCommandEncoder(std::optional label) = 0; protected: GPUAdapterInfo adapter_info_; diff --git a/src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp b/src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp new file mode 100644 index 000000000..9b55f6835 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp @@ -0,0 +1,26 @@ +#include + +namespace commandbuffers +{ + GPUPassEncoderBase::GPUPassEncoderBase() + : ended_(false) + { + } + + void GPUPassEncoderBase::begin() + { + ended_ = false; + assert(command_buffer_ != nullptr && "Command buffer must be initialized before beginning pass encoder."); + } + + void GPUPassEncoderBase::end() + { + ended_ = true; + } + + const GPUCommandBufferBase &GPUPassEncoderBase::commandBuffer() const + { + assert(command_buffer_ != nullptr && "Command buffer is not initialized."); + return *command_buffer_; + } +} diff --git a/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp b/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp index 7e7ec9715..bbf8b4eb7 100644 --- a/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp +++ b/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp @@ -9,10 +9,7 @@ namespace commandbuffers class GPUPassEncoderBase { public: - GPUPassEncoderBase() - : ended_(false) - { - } + GPUPassEncoderBase(); virtual ~GPUPassEncoderBase() = default; public: @@ -25,24 +22,12 @@ namespace commandbuffers return false; } - virtual void begin() - { - ended_ = false; - assert(command_buffer_ != nullptr && "Command buffer must be initialized before beginning pass encoder."); - } - virtual void end() - { - ended_ = true; - } - - const GPUCommandBuffer &commandBuffer() const - { - assert(command_buffer_ != nullptr && "Command buffer is not initialized."); - return *command_buffer_; - } + virtual void begin(); + virtual void end(); + const GPUCommandBufferBase &commandBuffer() const; protected: - std::unique_ptr command_buffer_; + std::unique_ptr command_buffer_; bool ended_ = false; }; } diff --git a/src/common/command_buffers/gpu/gpu_pipeline.hpp b/src/common/command_buffers/gpu/gpu_pipeline.hpp index a6bcdc46c..4d1c6a58a 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_pipeline.hpp @@ -9,10 +9,10 @@ namespace commandbuffers { - class GPUPipelineLayout : public GPUHandle + class GPUPipelineLayoutBase : public GPUHandle { private: - std::vector bind_group_layouts_; + std::vector bind_group_layouts_; }; class GPURenderPipelineDescriptor @@ -21,12 +21,12 @@ namespace commandbuffers std::optional label; }; - class GPURenderPipeline : public GPUHandle + class GPURenderPipelineBase : public GPUHandle { using GPUHandle::GPUHandle; public: - GPUBindGroupLayout &getBindGroupLayout(size_t index) + GPUBindGroupLayoutBase &getBindGroupLayout(size_t index) { if (index < bind_group_layouts_.size()) return bind_group_layouts_[index]; @@ -34,6 +34,6 @@ namespace commandbuffers } private: - std::vector bind_group_layouts_; + std::vector bind_group_layouts_; }; } diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp index 04305f4c6..459d153f9 100644 --- a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp @@ -32,8 +32,8 @@ namespace commandbuffers float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; LoadOp loadOp; StoreOp storeOp; - std::optional resolveTarget; - GPUTextureView view; + std::weak_ptr resolveTarget; + std::weak_ptr view; }; class DepthStencilAttachment @@ -47,7 +47,7 @@ namespace commandbuffers std::optional stencilReadOnly; std::optional stencilLoadOp; std::optional stencilStoreOp; - GPUTextureView view; + std::weak_ptr view; }; public: @@ -57,11 +57,11 @@ namespace commandbuffers std::optional depthStencilAttachment; }; - class GPURenderPassEncoder : public GPUPassEncoderBase, - public GPUHandle + class GPURenderPassEncoderBase : public GPUPassEncoderBase, + public GPUHandle { public: - GPURenderPassEncoder(std::string label) + GPURenderPassEncoderBase(std::string label) : GPUPassEncoderBase() , GPUHandle(label) { @@ -107,17 +107,17 @@ namespace commandbuffers if (!ended_) [[likely]] command_buffer_->addCommand(x, y, width, height); } - void setPipeline(const GPURenderPipeline &pipeline) + void setPipeline(const GPURenderPipelineBase &pipeline) { if (!ended_) [[likely]] command_buffer_->addCommand(pipeline); } - void setIndexBuffer(const GPUBuffer &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) + void setIndexBuffer(const GPUBufferBase &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) { if (!ended_) [[likely]] command_buffer_->addCommand(buffer, index_format, offset, size); } - void setVertexBuffer(uint32_t slot, const GPUBuffer &buffer, uint32_t offset = 0, uint32_t size = 0) + void setVertexBuffer(uint32_t slot, const GPUBufferBase &buffer, uint32_t offset = 0, uint32_t size = 0) { if (!ended_) [[likely]] command_buffer_->addCommand(slot, buffer, offset, size); diff --git a/src/common/command_buffers/gpu/gpu_texture_view.hpp b/src/common/command_buffers/gpu/gpu_texture_view.hpp index 557402b71..a3a1a1526 100644 --- a/src/common/command_buffers/gpu/gpu_texture_view.hpp +++ b/src/common/command_buffers/gpu/gpu_texture_view.hpp @@ -7,7 +7,7 @@ namespace commandbuffers { - class GPUTextureView : public GPUHandle + class GPUTextureViewBase : public GPUHandle { public: const GPUTexture &textureRef() const diff --git a/src/renderer/gles/gpu_command_buffer_impl.cpp b/src/renderer/gles/gpu_command_buffer_impl.cpp index 2a9692e3d..63894facb 100644 --- a/src/renderer/gles/gpu_command_buffer_impl.cpp +++ b/src/renderer/gles/gpu_command_buffer_impl.cpp @@ -8,13 +8,13 @@ namespace gles using namespace commandbuffers; GPUCommandBufferImpl::GPUCommandBufferImpl(optional label) - : GPUCommandBuffer(move(label)) + : GPUCommandBufferBase(move(label)) , framebuffer_(0) { } GPUCommandBufferImpl::GPUCommandBufferImpl(optional label, const GPURenderPassEncoderImpl &renderpass_encoder) - : GPUCommandBuffer(move(label), renderpass_encoder.commandBuffer()) + : GPUCommandBufferBase(move(label), renderpass_encoder.commandBuffer()) , framebuffer_(renderpass_encoder.framebuffer_) { assert(framebuffer_ > 0 && "Framebuffer must be bound before creating GPUCommandBufferImpl"); @@ -39,7 +39,7 @@ namespace gles case GPUCommand::kSetViewport: setViewport(*dynamic_pointer_cast(command)); break; - case GPUCommand::kSetScissor: + case GPUCommand::kSetScissorRect: setScissorRect(*dynamic_pointer_cast(command)); break; default: diff --git a/src/renderer/gles/gpu_command_buffer_impl.hpp b/src/renderer/gles/gpu_command_buffer_impl.hpp index 5a147498b..35e3fc496 100644 --- a/src/renderer/gles/gpu_command_buffer_impl.hpp +++ b/src/renderer/gles/gpu_command_buffer_impl.hpp @@ -10,7 +10,7 @@ namespace gles { - class GPUCommandBufferImpl : public commandbuffers::GPUCommandBuffer + class GPUCommandBufferImpl : public commandbuffers::GPUCommandBufferBase { public: GPUCommandBufferImpl(std::optional label); diff --git a/src/renderer/gles/gpu_command_encoder_impl.hpp b/src/renderer/gles/gpu_command_encoder_impl.hpp index 188883daa..21faf4ece 100644 --- a/src/renderer/gles/gpu_command_encoder_impl.hpp +++ b/src/renderer/gles/gpu_command_encoder_impl.hpp @@ -8,17 +8,17 @@ namespace gles { - class GPUCommandEncoderImpl : public commandbuffers::GPUCommandEncoder + class GPUCommandEncoderImpl : public commandbuffers::gpu::GPUCommandEncoderBase { friend class GPUDeviceImpl; - using commandbuffers::GPUCommandEncoder::GPUCommandEncoder; + using commandbuffers::gpu::GPUCommandEncoderBase::GPUCommandEncoderBase; public: - commandbuffers::GPURenderPassEncoder beginRenderPass(commandbuffers::GPURenderPassDescriptor &) override; - std::unique_ptr finish(std::optional label = std::nullopt) const override; + commandbuffers::gpu::GPURenderPassEncoderBase beginRenderPass(commandbuffers::gpu::GPURenderPassDescriptor &) override; + std::unique_ptr finish(std::optional label = std::nullopt) const override; public: - commandbuffers::GPURenderPassEncoder &getOrStartRecordingRenderPass(); + commandbuffers::gpu::GPURenderPassEncoderBase &getOrStartRecordingRenderPass(); bool isRenderPassWith(GLuint target_framebuffer) const; }; } diff --git a/src/renderer/gles/gpu_device_impl.cpp b/src/renderer/gles/gpu_device_impl.cpp index e453a664d..457dd2082 100644 --- a/src/renderer/gles/gpu_device_impl.cpp +++ b/src/renderer/gles/gpu_device_impl.cpp @@ -9,7 +9,7 @@ namespace gles { using namespace std; - using namespace commandbuffers; + using namespace commandbuffers::gpu; GPUQueueImpl::GPUQueueImpl() : GPUQueue() @@ -18,14 +18,14 @@ namespace gles // For GLES, this might not require any specific initialization. } - void GPUQueueImpl::submit(const vector> &command_buffers) + void GPUQueueImpl::submit(const vector> &command_buffers) { for (const auto &command_buffer : command_buffers) command_buffer->execute(); } GPUDeviceImpl::GPUDeviceImpl() - : GPUDevice() + : GPUDeviceBase() { queue_ = make_unique(); @@ -65,8 +65,8 @@ namespace gles DEBUG(LOG_TAG_RENDERER, "GPU Device Info: %s", adapter_info_.toString().c_str()); } - unique_ptr GPUDeviceImpl::createCommandEncoder(optional label) + unique_ptr GPUDeviceImpl::createCommandEncoder(optional label) { - return unique_ptr(new GPUCommandEncoderImpl(label.value_or(""))); + return unique_ptr(new GPUCommandEncoderImpl(label.value_or(""))); } } diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp index 81d1317e7..1eecb6990 100644 --- a/src/renderer/gles/gpu_device_impl.hpp +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -5,19 +5,19 @@ namespace gles { - class GPUQueueImpl : public commandbuffers::GPUQueue + class GPUQueueImpl : public commandbuffers::gpu::GPUQueue { public: GPUQueueImpl(); - void submit(const std::vector> &) override; + void submit(const std::vector> &) override; }; - class GPUDeviceImpl : public commandbuffers::GPUDevice + class GPUDeviceImpl : public commandbuffers::gpu::GPUDeviceBase { public: GPUDeviceImpl(); public: - std::unique_ptr createCommandEncoder(std::optional label) override; + std::unique_ptr createCommandEncoder(std::optional label) override; }; } diff --git a/src/renderer/gles/gpu_renderpass_encoder_impl.hpp b/src/renderer/gles/gpu_renderpass_encoder_impl.hpp index edba7a185..3f04a72cd 100644 --- a/src/renderer/gles/gpu_renderpass_encoder_impl.hpp +++ b/src/renderer/gles/gpu_renderpass_encoder_impl.hpp @@ -6,7 +6,7 @@ namespace gles { - class GPURenderPassEncoderImpl : public commandbuffers::GPURenderPassEncoder + class GPURenderPassEncoderImpl : public commandbuffers::GPURenderPassEncoderBase { friend class GPUCommandBufferImpl; From d5f215ce8566f07b92b9bdef9e630312a62209e3 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 31 Oct 2025 21:48:59 +0800 Subject: [PATCH 04/37] update --- src/common/assert.cpp | 57 ++ src/common/assert.hpp | 10 + .../command_buffers/gpu/command_allocator.cpp | 281 ++++++ .../command_buffers/gpu/command_allocator.hpp | 270 ++++++ .../command_buffers/gpu/encoding_context.cpp | 101 ++ .../command_buffers/gpu/encoding_context.hpp | 80 ++ src/common/command_buffers/gpu/error_data.cpp | 134 +++ src/common/command_buffers/gpu/error_data.hpp | 57 ++ .../command_buffers/gpu/gpu_adapter.cpp | 84 ++ .../command_buffers/gpu/gpu_adapter.hpp | 82 +- src/common/command_buffers/gpu/gpu_base.cpp | 131 +++ src/common/command_buffers/gpu/gpu_base.hpp | 389 +++++++- .../gpu/gpu_bind_group_layout.cpp | 37 + .../gpu/gpu_bind_group_layout.hpp | 67 +- .../gpu/gpu_bind_group_layout_base.hpp | 58 ++ .../gpu/gpu_bind_group_layout_internal.cpp | 96 ++ .../gpu/gpu_bind_group_layout_internal.hpp | 86 ++ .../command_buffers/gpu/gpu_binding_info.cpp | 5 + .../command_buffers/gpu/gpu_binding_info.hpp | 151 +++ src/common/command_buffers/gpu/gpu_buffer.cpp | 5 + src/common/command_buffers/gpu/gpu_buffer.hpp | 111 ++- .../gpu/gpu_command_buffer.cpp | 39 + .../gpu/gpu_command_buffer.hpp | 62 +- .../gpu/gpu_command_encoder.hpp | 33 +- .../command_buffers/gpu/gpu_constants.hpp | 46 + src/common/command_buffers/gpu/gpu_device.cpp | 28 + src/common/command_buffers/gpu/gpu_device.hpp | 77 +- src/common/command_buffers/gpu/gpu_error.cpp | 5 + src/common/command_buffers/gpu/gpu_error.hpp | 10 + src/common/command_buffers/gpu/gpu_info.cpp | 900 ++++++++++++++++++ src/common/command_buffers/gpu/gpu_info.hpp | 192 ++++ .../command_buffers/gpu/gpu_instance.cpp | 40 + .../command_buffers/gpu/gpu_instance.hpp | 39 + .../command_buffers/gpu/gpu_per_stage.cpp | 21 + .../command_buffers/gpu/gpu_per_stage.hpp | 115 +++ .../gpu/gpu_physical_device.cpp | 5 + .../gpu/gpu_physical_device.hpp | 61 ++ .../command_buffers/gpu/gpu_texture.hpp | 2 +- .../gpu/indirect_draw_metadata.hpp | 9 + .../gpu/pass_resource_usage.hpp | 69 ++ .../gpu/pass_resource_usage_tracker.cpp | 1 + .../gpu/pass_resource_usage_tracker.hpp | 16 + src/common/compiler.hpp | 124 +++ src/common/math_utils.hpp | 47 + src/common/non_copyable.hpp | 44 + src/common/non_movable.hpp | 42 + src/common/platform.hpp | 320 +++++++ src/common/utility.hpp | 17 + src/renderer/gles/gpu_device_impl.hpp | 17 +- 49 files changed, 4448 insertions(+), 225 deletions(-) create mode 100644 src/common/assert.cpp create mode 100644 src/common/assert.hpp create mode 100644 src/common/command_buffers/gpu/command_allocator.cpp create mode 100644 src/common/command_buffers/gpu/command_allocator.hpp create mode 100644 src/common/command_buffers/gpu/encoding_context.cpp create mode 100644 src/common/command_buffers/gpu/encoding_context.hpp create mode 100644 src/common/command_buffers/gpu/error_data.cpp create mode 100644 src/common/command_buffers/gpu/error_data.hpp create mode 100644 src/common/command_buffers/gpu/gpu_adapter.cpp create mode 100644 src/common/command_buffers/gpu/gpu_base.cpp create mode 100644 src/common/command_buffers/gpu/gpu_bind_group_layout.cpp create mode 100644 src/common/command_buffers/gpu/gpu_bind_group_layout_base.hpp create mode 100644 src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp create mode 100644 src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp create mode 100644 src/common/command_buffers/gpu/gpu_binding_info.cpp create mode 100644 src/common/command_buffers/gpu/gpu_binding_info.hpp create mode 100644 src/common/command_buffers/gpu/gpu_buffer.cpp create mode 100644 src/common/command_buffers/gpu/gpu_command_buffer.cpp create mode 100644 src/common/command_buffers/gpu/gpu_constants.hpp create mode 100644 src/common/command_buffers/gpu/gpu_device.cpp create mode 100644 src/common/command_buffers/gpu/gpu_error.cpp create mode 100644 src/common/command_buffers/gpu/gpu_error.hpp create mode 100644 src/common/command_buffers/gpu/gpu_info.cpp create mode 100644 src/common/command_buffers/gpu/gpu_info.hpp create mode 100644 src/common/command_buffers/gpu/gpu_instance.cpp create mode 100644 src/common/command_buffers/gpu/gpu_instance.hpp create mode 100644 src/common/command_buffers/gpu/gpu_per_stage.cpp create mode 100644 src/common/command_buffers/gpu/gpu_per_stage.hpp create mode 100644 src/common/command_buffers/gpu/gpu_physical_device.cpp create mode 100644 src/common/command_buffers/gpu/gpu_physical_device.hpp create mode 100644 src/common/command_buffers/gpu/indirect_draw_metadata.hpp create mode 100644 src/common/command_buffers/gpu/pass_resource_usage.hpp create mode 100644 src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp create mode 100644 src/common/command_buffers/gpu/pass_resource_usage_tracker.hpp create mode 100644 src/common/compiler.hpp create mode 100644 src/common/non_copyable.hpp create mode 100644 src/common/non_movable.hpp create mode 100644 src/common/platform.hpp diff --git a/src/common/assert.cpp b/src/common/assert.cpp new file mode 100644 index 000000000..9b2c46261 --- /dev/null +++ b/src/common/assert.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +namespace transmute::common +{ +#if TR_COMPILER_IS(CLANG) || TR_COMPILER_IS(GCC) + void BreakPoint() + { +#if TR_PLATFORM_IS(X86) + __asm__ __volatile__("int $3\n\t"); +#elif TR_PLATFORM_IS(ARM32) + __asm__ __volatile__("bkpt 0"); +#elif TR_PLATFORM_IS(ARM64) + __asm__ __volatile__("brk 0xf000"); +#elif TR_PLATFORM_IS(LOONGARCH) + __asm__ __volatile__("break 0"); +#elif TR_PLATFORM_IS(RISCV) + __asm__ __volatile__("ebreak"); +#elif TR_PLATFORM_IS(MIPS) + __asm__ __volatile__("break"); +#elif TR_PLATFORM_IS(S390) || TR_PLATFORM_IS(S390X) + __asm__ __volatile__(".word 0x0001"); +#elif TR_PLATFORM_IS(PPC) || TR_PLATFORM_IS(PPC64) + __asm__ __volatile__("twge 2,2"); +#elif TR_PLATFORM_IS(WASM32) || TR_PLATFORM_IS(WASM64) + EM_ASM(debugger;); +#else +#error "Unsupported platform" +#endif + } + +#elif TR_COMPILER_IS(MSVC) + void BreakPoint() + { + __debugbreak(); + } + +#else +#error "Unsupported compiler" +#endif + + void HandleAssertionFailure(const char *file, + const char *function, + int line, + const char *condition) + { + std::cerr << "Assertion failure at " << file << ":" << line << " (" << function + << "): " << condition; +#if defined(TR_ABORT_ON_ASSERT) + abort(); +#else + BreakPoint(); +#endif + } +} diff --git a/src/common/assert.hpp b/src/common/assert.hpp new file mode 100644 index 000000000..f30888b82 --- /dev/null +++ b/src/common/assert.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace transmute::common +{ + void BreakPoint(); + void HandleAssertionFailure(const char *file, + const char *function, + int line, + const char *condition); +} diff --git a/src/common/command_buffers/gpu/command_allocator.cpp b/src/common/command_buffers/gpu/command_allocator.cpp new file mode 100644 index 000000000..02174770b --- /dev/null +++ b/src/common/command_buffers/gpu/command_allocator.cpp @@ -0,0 +1,281 @@ +// Copyright 2017 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include +#include +#include + +#include + +using namespace std; + +namespace commandbuffers::gpu +{ + // TODO(cwallez@chromium.org): figure out a way to have more type safety for the iterator + + CommandIterator::CommandIterator() + { + reset(); + } + + CommandIterator::~CommandIterator() + { + assert(isEmpty()); + } + + CommandIterator::CommandIterator(CommandIterator &&other) + { + if (!other.isEmpty()) + { + blocks_ = std::move(other.blocks_); + other.reset(); + } + reset(); + } + + CommandIterator &CommandIterator::operator=(CommandIterator &&other) + { + assert(isEmpty()); + if (!other.isEmpty()) + { + blocks_ = std::move(other.blocks_); + other.reset(); + } + reset(); + return *this; + } + + CommandIterator::CommandIterator(CommandAllocator allocator) + : blocks_(allocator.acquireBlocks()) + { + reset(); + } + + void CommandIterator::acquireCommandBlocks(std::vector allocators) + { + assert(isEmpty()); + blocks_.clear(); + + size_t totalBlocksCount = 0; + for (CommandAllocator &allocator : allocators) + { + totalBlocksCount += allocator.getCommandBlocksCount(); + } + + blocks_.reserve(totalBlocksCount); + for (CommandAllocator &allocator : allocators) + { + CommandBlocks blocks = allocator.acquireBlocks(); + if (!blocks.empty()) + { + for (BlockDef &block : blocks) + { + blocks_.push_back(std::move(block)); + } + } + } + reset(); + } + + bool CommandIterator::nextCommandIdInNewBlock(uint32_t *commandId) + { + current_block_++; + if (current_block_ >= blocks_.size()) + { + reset(); + *commandId = detail::kEndOfBlock; + return false; + } + current_ptr_ = transmute::common::AlignPtr(blocks_[current_block_].block.get(), alignof(uint32_t)); + return nextCommandId(commandId); + } + + void CommandIterator::reset() + { + current_block_ = 0; + + if (blocks_.empty()) + { + // This will case the first NextCommandId call to try to move to the next block and stop + // the iteration immediately, without special casing the initialization. + current_ptr_ = reinterpret_cast(&end_of_block_); + } + else + { + current_ptr_ = transmute::common::AlignPtr(blocks_[0].block.get(), alignof(uint32_t)); + } + } + + void CommandIterator::makeEmptyAsDataWasDestroyed() + { + if (isEmpty()) + { + return; + } + + current_ptr_ = reinterpret_cast(&end_of_block_); + blocks_.clear(); + reset(); + assert(isEmpty()); + } + + bool CommandIterator::isEmpty() const + { + return blocks_.empty(); + } + + // Potential TODO(crbug.com/dawn/835): + // - Host the size and pointer to next block in the block itself to avoid having an allocation + // in the vector + // - Assume T's alignof is, say 64bits, static assert it, and make commandAlignment a constant + // in Allocate + // - Be able to optimize allocation to one block, for command buffers expected to live long to + // avoid cache misses + // - Better block allocation, maybe have Dawn API to say command buffer is going to have size + // close to another + + CommandAllocator::CommandAllocator() + { + resetPointers(); + } + + CommandAllocator::~CommandAllocator() + { + reset(); + } + + CommandAllocator::CommandAllocator(CommandAllocator &&other) + : blocks_(std::move(other.blocks_)) + , last_allocation_size_(other.last_allocation_size_) + { + other.blocks_.clear(); + if (!other.isEmpty()) + { + current_ptr_ = other.current_ptr_; + end_ptr_ = other.end_ptr_; + } + else + { + resetPointers(); + } + other.reset(); + } + + CommandAllocator &CommandAllocator::operator=(CommandAllocator &&other) + { + reset(); + if (!other.isEmpty()) + { + std::swap(blocks_, other.blocks_); + last_allocation_size_ = other.last_allocation_size_; + current_ptr_ = other.current_ptr_; + end_ptr_ = other.end_ptr_; + } + other.reset(); + return *this; + } + + void CommandAllocator::reset() + { + resetPointers(); + blocks_.clear(); + last_allocation_size_ = kDefaultBaseAllocationSize; + } + + bool CommandAllocator::isEmpty() const + { + return current_ptr_ == reinterpret_cast(&placeholder_space_[0]); + } + + size_t CommandAllocator::getCommandBlocksCount() const + { + return blocks_.size(); + } + + CommandBlocks &&CommandAllocator::acquireBlocks() + { + assert(current_ptr_ != nullptr && end_ptr_ != nullptr); + assert(transmute::common::IsPtrAligned(current_ptr_, alignof(uint32_t))); + assert(current_ptr_ + sizeof(uint32_t) <= end_ptr_); + *reinterpret_cast(current_ptr_) = detail::kEndOfBlock; + + current_ptr_ = nullptr; + end_ptr_ = nullptr; + return std::move(blocks_); + } + + char *CommandAllocator::allocateInNewBlock(uint32_t commandId, + size_t commandSize, + size_t commandAlignment) + { + // When there is not enough space, we signal the kEndOfBlock, so that the iterator knows + // to move to the next one. kEndOfBlock on the last block means the end of the commands. + uint32_t *idAlloc = reinterpret_cast(current_ptr_); + *idAlloc = detail::kEndOfBlock; + + // We'll request a block that can contain at least the command ID, the command and an + // additional ID to contain the kEndOfBlock tag. + size_t requestedBlockSize = commandSize + kWorstCaseAdditionalSize; + + // The computation of the request could overflow. + if (requestedBlockSize <= commandSize) [[unlikely]] + { + return nullptr; + } + + if (!getNewBlock(requestedBlockSize)) [[unlikely]] + { + return nullptr; + } + return allocate(commandId, commandSize, commandAlignment); + } + + bool CommandAllocator::getNewBlock(size_t minimumSize) + { + // Allocate blocks doubling sizes each time, to a maximum of 16k (or at least minimumSize). + last_allocation_size_ = std::max(minimumSize, std::min(last_allocation_size_ * 2, size_t(16384))); + + auto block = std::unique_ptr(new (std::nothrow) char[last_allocation_size_]); + if (block == nullptr) [[unlikely]] + { + return false; + } + + current_ptr_ = transmute::common::AlignPtr(block.get(), alignof(uint32_t)); + end_ptr_ = block.get() + last_allocation_size_; + blocks_.push_back({last_allocation_size_, std::move(block)}); + return true; + } + + void CommandAllocator::resetPointers() + { + current_ptr_ = reinterpret_cast(&placeholder_space_[0]); + end_ptr_ = reinterpret_cast(&placeholder_space_[1]); + } +} diff --git a/src/common/command_buffers/gpu/command_allocator.hpp b/src/common/command_buffers/gpu/command_allocator.hpp new file mode 100644 index 000000000..49be244c5 --- /dev/null +++ b/src/common/command_buffers/gpu/command_allocator.hpp @@ -0,0 +1,270 @@ +// Copyright 2017 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace commandbuffers::gpu +{ + // These are the lists of blocks, should not be used directly, only through CommandAllocator + // and CommandIterator + struct BlockDef + { + size_t size; + std::unique_ptr block; + }; + using CommandBlocks = std::vector; + + namespace detail + { + constexpr uint32_t kEndOfBlock = std::numeric_limits::max(); + constexpr uint32_t kAdditionalData = std::numeric_limits::max() - 1; + } + + class CommandAllocator; + + class CommandIterator : public NonCopyable + { + public: + CommandIterator(); + ~CommandIterator(); + + CommandIterator(CommandIterator &&other); + CommandIterator &operator=(CommandIterator &&other); + + // Shorthand constructor for acquiring CommandBlocks from a single CommandAllocator. + explicit CommandIterator(CommandAllocator allocator); + + void acquireCommandBlocks(std::vector allocators); + + template + bool nextCommandId(E *commandId) + { + return nextCommandId(reinterpret_cast(commandId)); + } + template + T *nextCommand() + { + return static_cast(nextCommand(sizeof(T), alignof(T))); + } + template + T *nextData(size_t count) + { + return static_cast(nextData(sizeof(T) * count, alignof(T))); + } + + // Sets iterator to the beginning of the commands without emptying the list. This method can + // be used if iteration was stopped early and the iterator needs to be restarted. + void reset(); + + // This method must to be called after commands have been deleted. This indicates that the + // commands have been submitted and they are no longer valid. + void makeEmptyAsDataWasDestroyed(); + + private: + bool isEmpty() const; + + inline bool nextCommandId(uint32_t *commandId) + { + char *idPtr = transmute::common::AlignPtr(current_ptr_, alignof(uint32_t)); + assert(idPtr == reinterpret_cast(&end_of_block_) || + idPtr + sizeof(uint32_t) <= blocks_[current_block_].block.get() + blocks_[current_block_].size); + + uint32_t id = *reinterpret_cast(idPtr); + if (id != detail::kEndOfBlock) + { + current_ptr_ = idPtr + sizeof(uint32_t); + *commandId = id; + return true; + } + return nextCommandIdInNewBlock(commandId); + } + + bool nextCommandIdInNewBlock(uint32_t *commandId); + + inline void *nextCommand(size_t commandSize, size_t commandAlignment) + { + char *commandPtr = transmute::common::AlignPtr(current_ptr_, commandAlignment); + assert(commandPtr + sizeof(commandSize) <= + blocks_[current_block_].block.get() + blocks_[current_block_].size); + + current_ptr_ = commandPtr + commandSize; + return commandPtr; + } + + inline void *nextData(size_t dataSize, size_t dataAlignment) + { + uint32_t id; + bool hasId = nextCommandId(&id); + assert(hasId); + assert(id == detail::kAdditionalData); + + return nextCommand(dataSize, dataAlignment); + } + + CommandBlocks blocks_; + char *current_ptr_ = nullptr; + size_t current_block_ = 0; + // Used to avoid a special case for empty iterators. + uint32_t end_of_block_ = detail::kEndOfBlock; + }; + + class CommandAllocator : public NonCopyable + { + public: + CommandAllocator(); + ~CommandAllocator(); + + // NOTE: A moved-from CommandAllocator is reset to its initial empty state. + CommandAllocator(CommandAllocator &&); + CommandAllocator &operator=(CommandAllocator &&); + + // Frees all blocks held by the allocator and restores it to its initial empty state. + void reset(); + + bool isEmpty() const; + + template + T *allocate(E commandId) + { + static_assert(sizeof(E) == sizeof(uint32_t)); + static_assert(alignof(E) == alignof(uint32_t)); + static_assert(alignof(T) <= kMaxSupportedAlignment); + T *result = reinterpret_cast(allocate(static_cast(commandId), sizeof(T), alignof(T))); + if (!result) + { + return nullptr; + } + new (result) T; + return result; + } + + template + T *allocateData(size_t count) + { + static_assert(alignof(T) <= kMaxSupportedAlignment); + T *result = reinterpret_cast(allocateData(sizeof(T) * count, alignof(T))); + if (!result) + { + return nullptr; + } + for (size_t i = 0; i < count; i++) + { + new (result + i) T; + } + return result; + } + + size_t getCommandBlocksCount() const; + + private: + // This is used for some internal computations and can be any power of two as long as code + // using the CommandAllocator passes the static_asserts. + static constexpr size_t kMaxSupportedAlignment = 8; + + // To avoid checking for overflows at every step of the computations we compute an upper + // bound of the space that will be needed in addition to the command data. + static constexpr size_t kWorstCaseAdditionalSize = + sizeof(uint32_t) + kMaxSupportedAlignment + alignof(uint32_t) + sizeof(uint32_t); + + // The default value of mLastAllocationSize. + static constexpr size_t kDefaultBaseAllocationSize = 2048; + + friend CommandIterator; + CommandBlocks &&acquireBlocks(); + + inline char *allocate(uint32_t commandId, + size_t commandSize, + size_t commandAlignment) + { + assert(current_ptr_ != nullptr); + assert(end_ptr_ != nullptr); + assert(commandId != detail::kEndOfBlock); + + // It should always be possible to allocate one id, for kEndOfBlock tagging, + assert(transmute::common::IsPtrAligned(current_ptr_, alignof(uint32_t))); + assert(end_ptr_ >= current_ptr_); + assert(static_cast(end_ptr_ - current_ptr_) >= sizeof(uint32_t)); + + // The memory after the ID will contain the following: + // - the current ID + // - padding to align the command, maximum kMaxSupportedAlignment + // - the command of size commandSize + // - padding to align the next ID, maximum alignof(uint32_t) + // - the next ID of size sizeof(uint32_t) + + // This can't overflow because by construction current_ptr_ always has space for the next + // ID. + size_t remainingSize = static_cast(end_ptr_ - current_ptr_); + + // The good case were we have enough space for the command data and upper bound of the + // extra required space. + if ((remainingSize >= kWorstCaseAdditionalSize) && + (remainingSize - kWorstCaseAdditionalSize >= commandSize)) + { + uint32_t *idAlloc = reinterpret_cast(current_ptr_); + *idAlloc = commandId; + + char *commandAlloc = transmute::common::AlignPtr(current_ptr_ + sizeof(uint32_t), commandAlignment); + current_ptr_ = transmute::common::AlignPtr(commandAlloc + commandSize, alignof(uint32_t)); + + return commandAlloc; + } + return allocateInNewBlock(commandId, commandSize, commandAlignment); + } + + char *allocateInNewBlock(uint32_t commandId, size_t commandSize, size_t commandAlignment); + + inline char *allocateData(size_t commandSize, size_t commandAlignment) + { + return allocate(detail::kAdditionalData, commandSize, commandAlignment); + } + + bool getNewBlock(size_t minimumSize); + + void resetPointers(); + + CommandBlocks blocks_; + size_t last_allocation_size_ = kDefaultBaseAllocationSize; + + // Data used for the block range at initialization so that the first call to Allocate sees + // there is not enough space and calls GetNewBlock. This avoids having to special case the + // initialization in Allocate. + uint32_t placeholder_space_[1] = {0}; + char *current_ptr_ = nullptr; + char *end_ptr_ = nullptr; + }; +} diff --git a/src/common/command_buffers/gpu/encoding_context.cpp b/src/common/command_buffers/gpu/encoding_context.cpp new file mode 100644 index 000000000..2ee01c71b --- /dev/null +++ b/src/common/command_buffers/gpu/encoding_context.cpp @@ -0,0 +1,101 @@ +#include +#include + +namespace commandbuffers::gpu +{ + EncodingContext::EncodingContext(std::shared_ptr device, std::shared_ptr initialEncoder) + : device_(device.get()) + , top_level_encoder_(initialEncoder.get()) + , current_encoder_(initialEncoder.get()) + , status_(Status::kOpen) + { + assert(!initialEncoder->isError()); + } + + EncodingContext::EncodingContext(std::shared_ptr device, GPUHandle::ErrorTag tag) + : device_(device.get()) + , top_level_encoder_(nullptr) + , current_encoder_(nullptr) + , status_(Status::kErrorAtCreation) + { + } + + EncodingContext::~EncodingContext() + { + destroy(); + } + + void EncodingContext::destroy() + { + debug_group_labels_.clear(); + + if (!were_commands_acquired_) + { + // mIndirectDrawMetadata.clear(); + } + // if (!mWereCommandsAcquired) + // { + // CommandIterator commands = AcquireCommands(); + // FreeCommands(&commands); + // } + + closeWithStatus(Status::kDestroyed); + } + + CommandIterator EncodingContext::acquireCommands() + { + assert(!were_commands_acquired_); + were_commands_acquired_ = true; + + commitCommands(std::move(pending_commands_)); + + CommandIterator commands; + commands.acquireCommandBlocks(std::move(allocators_)); + return commands; + } + + void EncodingContext::willBeginRenderPass() + { + assert(current_encoder_ == top_level_encoder_); + if (device_->isValidationEnabled() || device_->mayRequireDuplicationOfIndirectParameters()) + { + // When validation is enabled or indirect parameters require duplication, we are going + // to want to capture all commands encoded between and including BeginRenderPassCmd and + // EndRenderPassCmd, and defer their sequencing util after we have a chance to insert + // any necessary validation or duplication commands. To support this we commit any + // current commands now, so that the impending BeginRenderPassCmd starts in a fresh + // CommandAllocator. + commitCommands(std::move(pending_commands_)); + } + } + + void EncodingContext::enterPass(const GPUHandle *passEncoder) + { + // Assert we're at the top level. + assert(current_encoder_ == top_level_encoder_); + assert(passEncoder != nullptr); + + current_encoder_ = passEncoder; + } + + void EncodingContext::exitComputePass(const GPUHandle *passEncoder, + ComputePassResourceUsage usages) + { + assert(current_encoder_ != top_level_encoder_); + assert(current_encoder_ == passEncoder); + + current_encoder_ = top_level_encoder_; + // mComputePassUsages.push_back(std::move(usages)); + } + + void EncodingContext::ensurePassExited(const GPUHandle *passEncoder) + { + if (current_encoder_ != top_level_encoder_ && current_encoder_ == passEncoder) + { + // The current pass encoder is being deleted. Implicitly end the pass with an error. + current_encoder_ = top_level_encoder_; + // HandleError(DAWN_VALIDATION_ERROR("Command buffer recording ended before %s was ended.", + // passEncoder)); + } + } +} diff --git a/src/common/command_buffers/gpu/encoding_context.hpp b/src/common/command_buffers/gpu/encoding_context.hpp new file mode 100644 index 000000000..c1e6d57d2 --- /dev/null +++ b/src/common/command_buffers/gpu/encoding_context.hpp @@ -0,0 +1,80 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + class GPUCommandEncoder; + + namespace gpu + { + class EncodingContext + { + public: + EncodingContext(std::shared_ptr device, std::shared_ptr initialEncoder); + EncodingContext(std::shared_ptr device, GPUHandle::ErrorTag tag); + ~EncodingContext(); + + // Marks the encoding context as destroyed so that any future encodes will fail, and all + // encoded commands are released. + void destroy(); + CommandIterator acquireCommands(); + + // Must be called prior to encoding a BeginRenderPassCmd. Note that it's OK to call this + // and then not actually call EnterPass+ExitRenderPass, for example if some other pass setup + // failed validation before the BeginRenderPassCmd could be encoded. + void willBeginRenderPass(); + + // Functions to set current encoder state + void enterPass(const GPUHandle *passEncoder); + bool exitRenderPass(const GPUHandle *passEncoder, + RenderPassResourceUsageTracker usageTracker, + GPUCommandEncoder *commandEncoder, + gpu::IndirectDrawMetadata indirectDrawMetadata); + void exitComputePass(const GPUHandle *passEncoder, ComputePassResourceUsage usages); + bool finish(); + + // Called when a pass encoder is deleted. Provides an opportunity to clean up if it's the + // mCurrentEncoder. + void ensurePassExited(const GPUHandle *passEncoder); + + void pushDebugGroupLabel(std::string_view groupLabel); + void popDebugGroupLabel(); + + private: + enum class Status + { + kOpen, + kFinished, + kErrorAtCreation, + kErrorInRecording, + kDestroyed, + }; + + void commitCommands(CommandAllocator allocator); + void closeWithStatus(Status status); + + GPUDeviceBase *device_; + const GPUHandle *top_level_encoder_; + const GPUHandle *current_encoder_; + + CommandAllocator pending_commands_; + std::vector allocators_; + bool were_commands_acquired_ = false; + + // Contains pointers to strings allocated inside the command allocators. + std::vector debug_group_labels_; + + Status status_; + std::unique_ptr error_; + }; + } +} diff --git a/src/common/command_buffers/gpu/error_data.cpp b/src/common/command_buffers/gpu/error_data.cpp new file mode 100644 index 000000000..f8596d1c5 --- /dev/null +++ b/src/common/command_buffers/gpu/error_data.cpp @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include + +using namespace std; + +namespace commandbuffers::gpu +{ + unique_ptr ErrorData::Create(InternalErrorType type, + string message, + const char *file, + const char *function, + int line) + { + unique_ptr error = make_unique(type, move(message)); + error->appendBacktrace(file, function, line); + + auto [var, present] = transmute::common::GetEnvironmentVar("DAWN_DEBUG_BREAK_ON_ERROR"); + if (present && !var.empty() && var != "0") + { + cerr << error->message() << endl; + transmute::common::BreakPoint(); + } + return error; + } + + ErrorData::ErrorData(InternalErrorType type, string message) + : type_(type) + , message_(move(message)) + { + } + + void ErrorData::appendBacktrace(const char *file, const char *function, int line) + { + BacktraceRecord record; + record.file = file; + record.function = function; + record.line = line; + + backtrace_.push_back(move(record)); + } + + void ErrorData::appendContext(string context) + { + contexts_.push_back(move(context)); + } + + void ErrorData::appendDebugGroup(string_view label) + { + debug_groups_.push_back(string(label)); + } + + void ErrorData::appendBackendMessage(string message) + { + backend_messages_.push_back(move(message)); + } + + InternalErrorType ErrorData::type() const + { + return type_; + } + + const string &ErrorData::message() const + { + return message_; + } + + const vector &ErrorData::backtrace() const + { + return backtrace_; + } + + const vector &ErrorData::contexts() const + { + return contexts_; + } + + const vector &ErrorData::debugGroups() const + { + return debug_groups_; + } + + const vector &ErrorData::backendMessages() const + { + return backend_messages_; + } + + string ErrorData::getFormattedMessage() const + { + ostringstream ss; + ss << message_ << "\n"; + + if (!contexts_.empty()) + { + for (auto context : contexts_) + { + ss << " - While " << context << "\n"; + } + } + + // For non-validation errors, or errors that lack a context include the + // stack trace for debugging purposes. + if (contexts_.empty() || type_ != InternalErrorType::kValidation) + { + for (const auto &callsite : backtrace_) + { + ss << " at " << callsite.function << " (" << callsite.file << ":" << callsite.line + << ")\n"; + } + } + + if (!debug_groups_.empty()) + { + ss << "\nDebug group stack:\n"; + for (auto label : debug_groups_) + { + ss << " > \"" << label << "\"\n"; + } + } + + if (!backend_messages_.empty()) + { + ss << "\nBackend messages:\n"; + for (auto message : backend_messages_) + { + ss << " * " << message << "\n"; + } + } + + return ss.str(); + } +} \ No newline at end of file diff --git a/src/common/command_buffers/gpu/error_data.hpp b/src/common/command_buffers/gpu/error_data.hpp new file mode 100644 index 000000000..431ff12cf --- /dev/null +++ b/src/common/command_buffers/gpu/error_data.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include + +namespace commandbuffers::gpu +{ + enum class InternalErrorType : uint32_t + { + kNone = 0, + kValidation = 1, + kDeviceLost = 2, + kInternal = 4, + kOutOfMemory = 8 + }; + + class [[nodiscard]] ErrorData + { + public: + [[nodiscard]] static std::unique_ptr Create(InternalErrorType type, + std::string message, + const char *file, + const char *function, + int line); + ErrorData(InternalErrorType type, std::string message); + + struct BacktraceRecord + { + const char *file; + const char *function; + int line; + }; + void appendBacktrace(const char *file, const char *function, int line); + void appendContext(std::string context); + void appendDebugGroup(std::string_view label); + void appendBackendMessage(std::string message); + + InternalErrorType type() const; + const std::string &message() const; + const std::vector &backtrace() const; + const std::vector &contexts() const; + const std::vector &debugGroups() const; + const std::vector &backendMessages() const; + + std::string getFormattedMessage() const; + + private: + InternalErrorType type_; + std::string message_; + std::vector backtrace_; + std::vector contexts_; + std::vector debug_groups_; + std::vector backend_messages_; + }; +} \ No newline at end of file diff --git a/src/common/command_buffers/gpu/gpu_adapter.cpp b/src/common/command_buffers/gpu/gpu_adapter.cpp new file mode 100644 index 000000000..831b88fea --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_adapter.cpp @@ -0,0 +1,84 @@ +#include +#include +#include + +using namespace std; + +namespace commandbuffers +{ + bool GPUSupportedLimits::operator==(const GPUSupportedLimits &rhs) const + { + const auto &lhs = std::tie(maxTextureDimension1D, + maxTextureDimension2D, + maxTextureDimension3D, + maxTextureArrayLayers, + maxBindGroups, + maxBindingsPerBindGroup, + maxDynamicUniformBuffersPerPipelineLayout, + maxDynamicStorageBuffersPerPipelineLayout, + maxSampledTexturesPerShaderStage, + maxSamplersPerShaderStage, + maxStorageBuffersPerShaderStage, + maxStorageTexturesPerShaderStage, + maxUniformBuffersPerShaderStage, + maxUniformBufferBindingSize, + maxStorageBufferBindingSize, + minUniformBufferOffsetAlignment, + minStorageBufferOffsetAlignment, + maxVertexBuffers, + maxBufferSize, + maxVertexAttributes, + maxVertexBufferArrayStride, + maxInterStageShaderVariables, + maxColorAttachments, + maxColorAttachmentBytesPerSample, + maxComputeWorkgroupStorageSize, + maxComputeInvocationsPerWorkgroup, + maxComputeWorkgroupSizeX, + maxComputeWorkgroupSizeY, + maxComputeWorkgroupSizeZ, + maxComputeWorkgroupsPerDimension); + return lhs == std::tie(rhs.maxTextureDimension1D, + rhs.maxTextureDimension2D, + rhs.maxTextureDimension3D, + rhs.maxTextureArrayLayers, + rhs.maxBindGroups, + rhs.maxBindingsPerBindGroup, + rhs.maxDynamicUniformBuffersPerPipelineLayout, + rhs.maxDynamicStorageBuffersPerPipelineLayout, + rhs.maxSampledTexturesPerShaderStage, + rhs.maxSamplersPerShaderStage, + rhs.maxStorageBuffersPerShaderStage, + rhs.maxStorageTexturesPerShaderStage, + rhs.maxUniformBuffersPerShaderStage, + rhs.maxUniformBufferBindingSize, + rhs.maxStorageBufferBindingSize, + rhs.minUniformBufferOffsetAlignment, + rhs.minStorageBufferOffsetAlignment, + rhs.maxVertexBuffers, + rhs.maxBufferSize, + rhs.maxVertexAttributes, + rhs.maxVertexBufferArrayStride, + rhs.maxInterStageShaderVariables, + rhs.maxColorAttachments, + rhs.maxColorAttachmentBytesPerSample, + rhs.maxComputeWorkgroupStorageSize, + rhs.maxComputeInvocationsPerWorkgroup, + rhs.maxComputeWorkgroupSizeX, + rhs.maxComputeWorkgroupSizeY, + rhs.maxComputeWorkgroupSizeZ, + rhs.maxComputeWorkgroupsPerDimension); + } + + GPUAdapterBase::GPUAdapterBase(shared_ptr instance, + shared_ptr physicalDevice, + GPUFeatureLevel level, + GPUPowerPreference powerPreference) + : ErrorMonad() + , instance_(instance) + , physical_device_(physicalDevice) + , feature_level_(level) + , power_preference_(powerPreference) + { + } +} diff --git a/src/common/command_buffers/gpu/gpu_adapter.hpp b/src/common/command_buffers/gpu/gpu_adapter.hpp index 8e37a08e7..89cfb8a9b 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.hpp +++ b/src/common/command_buffers/gpu/gpu_adapter.hpp @@ -1,14 +1,17 @@ #pragma once +#include +#include +#include #include #include -#include -#include - -#include "./gpu_base.hpp" +#include namespace commandbuffers { + class GPUInstanceBase; + class GPUPhysicalDeviceBase; + class GPUAdapterInfo { public: @@ -40,52 +43,37 @@ namespace commandbuffers } }; - class GPUSupportedFeatures : public std::unordered_set + class GPUAdapterBase : ErrorMonad { public: - GPUSupportedFeatures() - { - // TODO(yorkie): add required features - } - }; + GPUAdapterBase(std::shared_ptr instance, + std::shared_ptr physicalDevice, + GPUFeatureLevel level, + GPUPowerPreference powerPreference); - class GPUSupportedLimits : public std::unordered_map - { - public: - GPUSupportedLimits() - { - insert({"maxTextureDimension1D", 8192}); - insert({"maxTextureDimension2D", 8192}); - insert({"maxTextureDimension3D", 2048}); - insert({"maxTextureArrayLayers", 256}); - insert({"maxBindGroups", 4}); - insert({"maxBindGroupEntries", 640}); - } + GPUInstanceBase *instance() const; + const GPUAdapterInfo &info() const; + bool hasFeature(GPUFeatureName) const; + void requestDevice(const GPUDeviceDescriptor *descriptor, + std::function)> callback); + std::unique_ptr createDevice(const GPUDeviceDescriptor *descriptor = nullptr); - public: - uint32_t maxTextureDimension1D() const - { - return at("maxTextureDimension1D"); - } - uint32_t maxTextureDimension2D() const - { - return at("maxTextureDimension2D"); - } - uint32_t maxTextureDimension3D() const - { - return at("maxTextureDimension3D"); - } - uint32_t maxTextureArrayLayers() const - { - return at("maxTextureArrayLayers"); - } - uint32_t maxBindGroups() const - { - return at("maxBindGroups"); - } - uint32_t maxBindGroupEntries() const - { - return at("maxBindGroupEntries"); - } + GPUPhysicalDeviceBase *physicalDevice(); + const GPUPhysicalDeviceBase *physicalDevice() const; + GPUFeatureLevel featureLevel() const; + + const std::string &name() const; + + private: + std::shared_ptr instance_; + std::shared_ptr physical_device_; + GPUFeatureLevel feature_level_; + GPUPowerPreference power_preference_; + + bool use_tiered_limits = false; + + // The adapter becomes "consumed" once it has successfully been used to + // create a device. + bool adapter_is_consumed = false; }; } diff --git a/src/common/command_buffers/gpu/gpu_base.cpp b/src/common/command_buffers/gpu/gpu_base.cpp new file mode 100644 index 000000000..c8568bf45 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_base.cpp @@ -0,0 +1,131 @@ +#include +#include +#include + +using namespace std; + +namespace commandbuffers +{ + // + // ErrorMonad Implementation + // + + ErrorMonad::ErrorMonad() + : tag_payload_(kInitializedNoErrorPayload) + { + } + + ErrorMonad::ErrorMonad(ErrorTag) + : tag_payload_(kInitializedErrorPayload) + { + } + ErrorMonad::ErrorMonad(DelayedInitializationTag) + : tag_payload_(kNotInitializedPayload) + { + } + + bool ErrorMonad::initialized() const + { + return (tag_payload_ & kInitializedMask) == kInitialized; + } + + bool ErrorMonad::isError() const + { + assert((tag_payload_ & kInitializedMask) == kInitialized); + return tag_payload_ != kInitializedNoErrorPayload; + } + + void ErrorMonad::setInitializedError() + { + uint64_t previousPayload = fetchAnd(kInitializedErrorPayload); + assert(previousPayload == kNotInitializedPayload); + } + + void ErrorMonad::setInitializedNoError() + { + uint64_t previousPayload = fetchAnd(kInitializedNoErrorPayload); + assert(previousPayload == kNotInitializedPayload); + } + + uint64_t ErrorMonad::fetchAnd(uint64_t arg) + { + return tag_payload_.exchange(arg, memory_order_acq_rel); + } + + // + // GPUObject Implementation + // + + GPUObject::GPUObject(shared_ptr device) + : ErrorMonad() + , device_(device) + { + } + + GPUObject::GPUObject(shared_ptr device, ErrorTag) + : ErrorMonad(kError) + , device_(device) + { + } + + GPUObject::GPUObject(shared_ptr device, DelayedInitializationTag) + : ErrorMonad(kDelayedInitialization) + , device_(device) + { + } + + GPUInstanceBase *GPUObject::instance() const + { + return device_->instance(); + } + + shared_ptr GPUObject::device() const + { + return device_; + } + + // + // GPUHandle Implementation + // + + GPUHandle::GPUHandle(shared_ptr device, string_view label) + : GPUObject(device) + , id_(Ids.get()) + , label_(string(label)) + { + } + + GPUHandle::GPUHandle(shared_ptr device, + ErrorTag tag, + string_view label) + : GPUObject(device, tag) + , id_(Ids.get()) + , label_(string(label)) + { + } + + GPUHandle::GPUHandle(shared_ptr device, + DelayedInitializationTag tag, + string_view label) + : GPUObject(device, tag) + , id_(Ids.get()) + , label_(string(label)) + { + } + + GPUHandle::GPUHandle(shared_ptr device, LabelNotImplementedTag tag) + : GPUObject(device) + , id_(Ids.get()) + { + } + + void GPUHandle::setLabel(std::string label) + { + label_ = move(label); + } + + const std::string &GPUHandle::getLabel() const + { + return label_; + } +} diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index fadd7e175..692c0812a 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -1,10 +1,52 @@ +// Copyright 2018 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #pragma once +#include #include +#include +#include +#include + #include +#include namespace commandbuffers { + using GPUBindingNumber = uint32_t; + constexpr GPUBindingNumber kMaxBindingsPerBindGroupTyped = GPUBindingNumber(gpu_constants::kMaxBindingsPerBindGroup); + + using GPUClientBindingIndex = uint32_t; + using GPUBindingIndex = uint32_t; + + using GPUBindGroupIndex = uint32_t; + constexpr GPUBindGroupIndex kMaxBindGroupsTyped = GPUBindGroupIndex(gpu_constants::kMaxBindGroups); + enum class GPUHandleType : uint32_t { kAdapter, @@ -39,18 +81,80 @@ namespace commandbuffers kBindGroupLayoutInternal, }; - enum class GPUShaderStage + enum class GPUBackendType : uint32_t { - kVertex, - kFragment, - kCompute, + kUndefined, + kNull, + kWebGPU, + kD3D11, + kD3D12, + kMetal, + kVulkan, + kOpenGL, + kOpenGLES, }; - enum class GPUBufferType + enum class GPUAdapterType : uint32_t { - kReadOnlyStorage, - kStorage, + kDiscreteGPU, + kIntegratedGPU, + kCPU, + kUnknown, + }; + + enum class GPUShaderStage : uint64_t + { + kNone = 0x0000000000000000, + kVertex = 0x0000000000000001, + kFragment = 0x0000000000000002, + kCompute = 0x0000000000000004, + }; + + enum class GPUMapMode : uint64_t + { + kNone = 0x0000000000000000, + kRead = 0x0000000000000001, + kWrite = 0x0000000000000002, + }; + + enum class GPUBufferBindingType : uint32_t + { + kBindingNotUsed, + kUndefined, kUniform, + kStorage, + kReadOnlyStorage, + }; + + enum class GPUSamplerBindingType : uint32_t + { + kBindingNotUsed, + kUndefined, + kFiltering, + kNonFiltering, + kComparison, + }; + + enum class GPUTextureSampleType : uint32_t + { + kBindingNotUsed, + kUndefined, + kFloat, + kUnfilterableFloat, + kDepth, + kSint, + kUint, + }; + + enum class GPUTextureViewDimension : uint32_t + { + kUndefined, + k1D, + k2D, + k2DArray, + kCube, + kCubeArray, + k3D, }; enum class GPUIndexFormat @@ -59,37 +163,280 @@ namespace commandbuffers kUint32, }; - enum class GPUStorageAccess + enum class GPUTextureFormat : uint32_t + { + kUndefined, + kR8Unorm, + kR8Snorm, + kR8Uint, + kR8Sint, + kR16Unorm, + kR16Snorm, + kR16Uint, + kR16Sint, + kR16Float, + kRG8Unorm, + kRG8Snorm, + kRG8Uint, + kRG8Sint, + kR32Float, + kR32Uint, + kR32Sint, + kRG16Unorm, + kRG16Snorm, + kRG16Uint, + kRG16Sint, + kRG16Float, + kRGBA8Unorm, + kRGBA8UnormSrgb, + kRGBA8Snorm, + kRGBA8Uint, + kRGBA8Sint, + kBGRA8Unorm, + kBGRA8UnormSrgb, + kRGB10A2Uint, + kRGB10A2Unorm, + kRG11B10Ufloat, + kRGB9E5Ufloat, + kRG32Float, + kRG32Uint, + kRG32Sint, + kRGBA16Unorm, + kRGBA16Snorm, + kRGBA16Uint, + kRGBA16Sint, + kRGBA16Float, + kRGBA32Float, + kRGBA32Uint, + kRGBA32Sint, + kStencil8, + kDepth16Unorm, + kDepth24Plus, + kDepth24PlusStencil8, + kDepth32Float, + kDepth32FloatStencil8, + kBC1RGBAUnorm, + kBC1RGBAUnormSrgb, + kBC2RGBAUnorm, + kBC2RGBAUnormSrgb, + kBC3RGBAUnorm, + kBC3RGBAUnormSrgb, + kBC4RUnorm, + kBC4RSnorm, + kBC5RGUnorm, + kBC5RGSnorm, + kBC6HRGBUfloat, + kBC6HRGBFloat, + kBC7RGBAUnorm, + kBC7RGBAUnormSrgb, + kETC2RGB8Unorm, + kETC2RGB8UnormSrgb, + kETC2RGB8A1Unorm, + kETC2RGB8A1UnormSrgb, + kETC2RGBA8Unorm, + kETC2RGBA8UnormSrgb, + kEACR11Unorm, + kEACR11Snorm, + kEACRG11Unorm, + kEACRG11Snorm, + kASTC4x4Unorm, + kASTC4x4UnormSrgb, + kASTC5x4Unorm, + kASTC5x4UnormSrgb, + kASTC5x5Unorm, + kASTC5x5UnormSrgb, + kASTC6x5Unorm, + kASTC6x5UnormSrgb, + kASTC6x6Unorm, + kASTC6x6UnormSrgb, + kASTC8x5Unorm, + kASTC8x5UnormSrgb, + kASTC8x6Unorm, + kASTC8x6UnormSrgb, + kASTC8x8Unorm, + kASTC8x8UnormSrgb, + kASTC10x5Unorm, + kASTC10x5UnormSrgb, + kASTC10x6Unorm, + kASTC10x6UnormSrgb, + kASTC10x8Unorm, + kASTC10x8UnormSrgb, + kASTC10x10Unorm, + kASTC10x10UnormSrgb, + kASTC12x10Unorm, + kASTC12x10UnormSrgb, + kASTC12x12Unorm, + kASTC12x12UnormSrgb, + kR8BG8Biplanar420Unorm, + kR10X6BG10X6Biplanar420Unorm, + kR8BG8A8Triplanar420Unorm, + kR8BG8Biplanar422Unorm, + kR8BG8Biplanar444Unorm, + kR10X6BG10X6Biplanar422Unorm, + kR10X6BG10X6Biplanar444Unorm, + kExternal, + }; + + enum class GPUStorageTextureAccess : uint32_t { + kBindingNotUsed, + kUndefined, + kWriteOnly, kReadOnly, kReadWrite, - kWriteOnly, }; - enum class GPUSamplerType + enum class GPUDynamicBindingKind : uint32_t { - kComparison, - kFiltering, - kNonFiltering, + kUndefined, + kSampledTexture, + }; + + enum class GPUFeatureName : uint32_t + { + kCoreFeaturesAndLimits, + kDepthClipControl, + }; + + enum class GPUFeatureLevel : uint32_t + { + kUndefined = 0x00000000, + kCompatibility = 0x00000001, + kCore = 0x00000002, + }; + + enum class GPUPowerPreference : uint32_t + { + Undefined = 0x00000000, + LowPower = 0x00000001, + HighPerformance = 0x00000002, + }; + + class GPUSupportedFeatures : public std::unordered_set + { + using std::unordered_set::unordered_set; + }; + + struct GPUSupportedLimits + { + uint32_t maxTextureDimension1D = 8192; + uint32_t maxTextureDimension2D = 8192; + uint32_t maxTextureDimension3D = 2048; + uint32_t maxTextureArrayLayers = 2048; + uint32_t maxBindGroups = 4; + uint32_t maxBindingsPerBindGroup = 640; + uint32_t maxDynamicUniformBuffersPerPipelineLayout = 8; + uint32_t maxDynamicStorageBuffersPerPipelineLayout = 4; + uint32_t maxSampledTexturesPerShaderStage = 16; + uint32_t maxSamplersPerShaderStage = 16; + uint32_t maxStorageBuffersPerShaderStage = 8; + uint32_t maxStorageTexturesPerShaderStage = 8; + uint32_t maxUniformBuffersPerShaderStage = 12; + uint64_t maxUniformBufferBindingSize = 65536; + uint64_t maxStorageBufferBindingSize = 134217728; + uint32_t minUniformBufferOffsetAlignment = 256; + uint32_t minStorageBufferOffsetAlignment = 256; + uint32_t maxVertexBuffers = 8; + uint64_t maxBufferSize = 4294967296; + uint32_t maxVertexAttributes = 16; + uint32_t maxVertexBufferArrayStride = 2048; + uint32_t maxInterStageShaderVariables = 16; + uint32_t maxColorAttachments = 8; + uint32_t maxColorAttachmentBytesPerSample = 32; + uint32_t maxComputeWorkgroupStorageSize = 16384; + uint32_t maxComputeInvocationsPerWorkgroup = 256; + uint32_t maxComputeWorkgroupSizeX = 256; + uint32_t maxComputeWorkgroupSizeY = 256; + uint32_t maxComputeWorkgroupSizeZ = 64; + uint32_t maxComputeWorkgroupsPerDimension = 65535; + + bool operator==(const GPUSupportedLimits &rhs) const; + }; + + class ErrorMonad + { + public: + struct ErrorTag + { + }; + static constexpr ErrorTag kError = {}; + + struct DelayedInitializationTag + { + }; + static constexpr DelayedInitializationTag kDelayedInitialization = {}; + + ErrorMonad(); + explicit ErrorMonad(ErrorTag tag); + explicit ErrorMonad(DelayedInitializationTag tag); + virtual ~ErrorMonad() = default; + + // Test if the error state is valid yet. It is an error to check the error state before the + // object is initialized. + bool initialized() const; + + bool isError() const; + + protected: + void setInitializedError(); + void setInitializedNoError(); + + private: + std::atomic tag_payload_; + uint64_t fetchAnd(uint64_t arg); + + static constexpr uint64_t kNotInitializedPayload = 0b11; + static constexpr uint64_t kInitializedErrorPayload = 0b00; + static constexpr uint64_t kInitializedNoErrorPayload = 0b10; + + static constexpr uint64_t kInitializedMask = 0b1; + static constexpr uint64_t kInitialized = 0b0; + }; + + class GPUDeviceBase; + class GPUInstanceBase; + + class GPUObject : public ErrorMonad + { + public: + explicit GPUObject(std::shared_ptr device); + GPUObject(std::shared_ptr device, ErrorTag tag); + GPUObject(std::shared_ptr device, DelayedInitializationTag tag); + + GPUInstanceBase *instance() const; + std::shared_ptr device() const; + + private: + std::shared_ptr device_; }; typedef uint32_t GPUIdentifier; - class GPUHandle + class GPUHandle : public GPUObject { private: static inline TrIdGeneratorBase Ids = TrIdGeneratorBase(0); public: - GPUHandle(std::string label = "") - : label(std::move(label)) - , id(Ids.get()) + struct LabelNotImplementedTag + { + }; + static constexpr LabelNotImplementedTag kLabelNotImplemented = {}; + struct UntrackedByDeviceTag { - } + }; + static constexpr UntrackedByDeviceTag kUntrackedByDevice = {}; + + GPUHandle(std::shared_ptr device, std::string_view label); + GPUHandle(std::shared_ptr device, ErrorTag tag, std::string_view label = {}); + GPUHandle(std::shared_ptr device, DelayedInitializationTag tag, std::string_view label = {}); + GPUHandle(std::shared_ptr device, LabelNotImplementedTag tag); virtual GPUHandleType type() const = 0; + void setLabel(std::string label); + const std::string &getLabel() const; - public: - const std::string label = ""; - const GPUIdentifier id; + private: + std::string label_ = ""; + const GPUIdentifier id_; }; } diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp b/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp new file mode 100644 index 000000000..75d74347a --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp @@ -0,0 +1,37 @@ +#include + +using namespace std; + +namespace commandbuffers +{ + GPUBindGroupLayoutBase::GPUBindGroupLayoutBase(shared_ptr device, + string_view label, + shared_ptr internal) + : GPUHandle(device, label) + , internal_layout_(internal) + { + } + + GPUBindGroupLayoutBase::GPUBindGroupLayoutBase(shared_ptr device, + GPUHandle::ErrorTag tag, + string_view label) + : GPUHandle(device, tag, label) + { + } + + GPUBindGroupLayoutInternalBase *GPUBindGroupLayoutBase::getInternalBindGroupLayout() const + { + return internal_layout_.get(); + } + + bool GPUBindGroupLayoutBase::equal(const GPUBindGroupLayoutBase *other, + bool excludePipelineCompatibiltyToken = false) const + { + return getInternalBindGroupLayout() == other->getInternalBindGroupLayout(); + } + + bool GPUBindGroupLayoutBase::isEmpty() const + { + return internal_layout_ == nullptr || internal_layout_->isEmpty(); + } +} diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp b/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp index 32686c33c..6ebc23de3 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp @@ -1,63 +1,38 @@ #pragma once -#include -#include -#include - -#include "./gpu_base.hpp" -#include "./gpu_texture.hpp" +#include +#include +#include +#include +#include namespace commandbuffers { class GPUBindGroupLayoutBase : public GPUHandle { public: - class BufferLayout - { - public: - GPUBufferType type; - bool hasDynamicOffset = false; - uint32_t minBindingSize = 0; // in bytes - }; - - class TextureLayout - { - public: - bool multisampled = false; - }; + GPUBindGroupLayoutBase(std::shared_ptr device, + std::string_view label, + std::shared_ptr internal); + virtual ~GPUBindGroupLayoutBase() = default; - class StorageTextureLayout + GPUHandleType type() const override { - public: - GPUStorageAccess access; - GPUTextureFormat format; - std::optional viewDimension; - }; + return GPUHandleType::kBindGroupLayout; + } - class ExternalTextureLayout - { - }; + GPUBindGroupLayoutInternalBase *getInternalBindGroupLayout() const; + bool equal(const GPUBindGroupLayoutBase *other, + bool excludePipelineCompatibiltyToken = false) const; - class SamplerLayout - { - public: - GPUSamplerType type; - }; + bool isEmpty() const; - using ResourceLayout = std::variant; - class Entry - { - public: - uint32_t binding; - GPUShaderStage visibility; - ResourceLayout layout; - }; + private: + GPUBindGroupLayoutBase(std::shared_ptr device, + GPUHandle::ErrorTag tag, + std::string_view label); private: - std::vector entries_; + std::shared_ptr internal_layout_; }; } diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout_base.hpp b/src/common/command_buffers/gpu/gpu_bind_group_layout_base.hpp new file mode 100644 index 000000000..af1c5b326 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout_base.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include +#include + +namespace commandbuffers +{ + struct GPUBufferBindingLayout + { + GPUBufferBindingType type = GPUBufferBindingType::kUniform; + bool hasDynamicOffset = false; + uint64_t minBindingSize = 0; + }; + + struct GPUSamplerBindingLayout + { + GPUSamplerBindingType type = GPUSamplerBindingType::kFiltering; + }; + + struct GPUTextureBindingLayout + { + GPUTextureSampleType sampleType = GPUTextureSampleType::kFloat; + GPUTextureViewDimension viewDimension = GPUTextureViewDimension::k2D; + bool multisampled = false; + }; + + struct GPUStorageTextureBindingLayout + { + GPUStorageTextureAccess access = GPUStorageTextureAccess::kWriteOnly; + GPUTextureFormat format = GPUTextureFormat::kUndefined; + GPUTextureViewDimension viewDimension = GPUTextureViewDimension::k2D; + }; + + struct GPUBindGroupLayoutEntry + { + uint32_t binding; + GPUShaderStage visibility = GPUShaderStage::kNone; + uint32_t bindingArraySize = 0; + + GPUBufferBindingLayout buffer = {GPUBufferBindingType::kBindingNotUsed, false, 0}; + GPUSamplerBindingLayout sampler = {GPUSamplerBindingType::kBindingNotUsed}; + GPUTextureBindingLayout texture = {GPUTextureSampleType::kBindingNotUsed, + GPUTextureViewDimension::k2D, + false}; + GPUStorageTextureBindingLayout storageTexture = {GPUStorageTextureAccess::kBindingNotUsed, + GPUTextureFormat::kUndefined, + GPUTextureViewDimension::k2D}; + }; + + struct GPUBindGroupLayoutDescriptor + { + std::string_view label; + size_t entryCount = 0; + GPUBindGroupLayoutEntry const *entries = nullptr; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp new file mode 100644 index 000000000..2c4236aa1 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp @@ -0,0 +1,96 @@ +#include + +using namespace std; + +namespace commandbuffers +{ + GPUBindGroupLayoutInternalBase::GPUBindGroupLayoutInternalBase(shared_ptr device, + const GPUBindGroupLayoutDescriptor &descriptor) + : GPUHandle(device, descriptor.label) + { + } + + GPUBindGroupLayoutInternalBase::~GPUBindGroupLayoutInternalBase() = default; + + const GPUBindingInfo &GPUBindGroupLayoutInternalBase::getBindingInfo(GPUBindingIndex bindingIndex) const + { + assert(!isError()); + // Assert that this is an internal binding. + assert(bindingIndex < getBindingCount()); + return binding_info_.at(bindingIndex); + } + + const GPUBindingInfo &GPUBindGroupLayoutInternalBase::getClientBindingInfo(GPUClientBindingIndex bindingIndex) const + { + assert(!isError()); + GPUBindingIndex index = GPUBindingIndex(uint32_t(bindingIndex)); + assert(index < binding_info_.size()); + + // Assert this is a user-facing binding and not an private internal binding. + assert(binding_map_.contains(binding_info_.at(index).binding)); + return binding_info_.at(index); + } + + const GPUBindGroupLayoutInternalBase::BindingMap &GPUBindGroupLayoutInternalBase::getBindingMap() const + { + assert(!isError()); + return binding_map_; + } + + GPUBindingIndex GPUBindGroupLayoutInternalBase::asBindingIndex(GPUClientBindingIndex bindingIndex) const + { + assert(!isError()); + // Assert this is a user-facing binding and not a private internal binding, and that it + // represents an internal bindings. + GPUBindingIndex index = GPUBindingIndex(uint32_t(bindingIndex)); + assert(index < getBindingCount()); + assert(binding_map_.contains(binding_info_.at(index).binding)); + return index; + } + + GPUClientBindingIndex GPUBindGroupLayoutInternalBase::getClientBindingIndex(GPUBindingNumber bindingNumber) const + { + assert(!isError()); + const auto &it = binding_map_.find(bindingNumber); + assert(it != binding_map_.end()); + return it->second; + } + + GPUBindingIndex GPUBindGroupLayoutInternalBase::getBindingCount() const + { + assert(!isError()); + return getBindingTypeStart(GPUBindingTypeOrder_ExternalTexture); + } + + + bool GPUBindGroupLayoutInternalBase::isEmpty() const + { + assert(!isError()); + return binding_info_.empty() && !has_dynamic_array_; + } + + string GPUBindGroupLayoutInternalBase::entriesToString() const + { + string entries = "["; + string sep = ""; + const GPUBindGroupLayoutInternalBase::BindingMap &bindingMap = getBindingMap(); + for (const auto [bindingNumber, bindingIndex] : bindingMap) + { + const GPUBindingInfo &bindingInfo = getClientBindingInfo(bindingIndex); + entries += sep + bindingInfo.toString(); + sep = ", "; + } + entries += "]"; + return entries; + } + + GPUBindingIndex GPUBindGroupLayoutInternalBase::getBindingTypeStart(GPUBindingTypeOrder type) const + { + return binding_type_start_[type]; + } + + GPUBindingIndex GPUBindGroupLayoutInternalBase::getBindingTypeEnd(GPUBindingTypeOrder type) const + { + return binding_type_start_[GPUBindingTypeOrder(static_cast(type) + 1)]; + } +} diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp new file mode 100644 index 000000000..bdf7eb70d --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + + + // In the BindGroupLayout, entries are sorted by type for more efficient lookup and iteration. + // This enum is the order that's used and can also be used to index various ranges of entries. + // The enum is public so that helper function can use it during creation of the BindGroupLayout, + // but the order is not meant to be used anywhere else. Use the accessors on the BindGroupLayout for + // logic that relies on the packing or the order. + enum GPUBindingTypeOrder : uint32_t + { + // Buffers + GPUBindingTypeOrder_DynamicBuffer, + GPUBindingTypeOrder_RegularBuffer, + // Textures + GPUBindingTypeOrder_SampledTexture, + GPUBindingTypeOrder_StorageTexture, + GPUBindingTypeOrder_InputAttachment, + // Samplers + GPUBindingTypeOrder_StaticSampler, + GPUBindingTypeOrder_RegularSampler, + // Texel Buffers + GPUBindingTypeOrder_TexelBuffer, + // Start of entries that are expanded in the frontend and aren't actually stored in the bind + // groups. + GPUBindingTypeOrder_ExternalTexture, + GPUBindingTypeOrder_Count, + }; + + class GPUBindGroupLayoutInternalBase : public GPUHandle + { + using BindingMap = std::map; + + public: + GPUBindGroupLayoutInternalBase(std::shared_ptr device, + const GPUBindGroupLayoutDescriptor &descriptor); + virtual ~GPUBindGroupLayoutInternalBase(); + + GPUHandleType type() const override + { + return GPUHandleType::kBindGroupLayoutInternal; + } + + // Getters for static bindings + const GPUBindingInfo &getBindingInfo(GPUBindingIndex bindingIndex) const; + const GPUBindingInfo &getClientBindingInfo(GPUClientBindingIndex bindingIndex) const; + const BindingMap &getBindingMap() const; + GPUBindingIndex asBindingIndex(GPUClientBindingIndex bindingIndex) const; + GPUClientBindingIndex getClientBindingIndex(GPUBindingNumber bindingNumber) const; + GPUBindingIndex getBindingCount() const; + + public: + bool isEmpty() const; + + std::string entriesToString() const; + + private: + std::unordered_map binding_info_; + GPUBindingCounts validation_binding_counts_ = {}; + + // Keep a list of the start indices for each kind of binding. Then (exclusive) end of a range + // of bindings is the start of the next range. (that's why we use count + 1 entry, to have the + // "end" of the last binding type) + GPUBindingIndex getBindingTypeStart(GPUBindingTypeOrder type) const; + GPUBindingIndex getBindingTypeEnd(GPUBindingTypeOrder type) const; + std::array binding_type_start_; + + BindingMap binding_map_; + + // Information about the dynamic binding array part of the BGL. + bool has_dynamic_array_ = false; + GPUBindingNumber client_dynamic_array_start{0}; + GPUBindingIndex dynamic_array_start{0}; + GPUBindingIndex dynamic_array_metadata_binding{0}; + GPUDynamicBindingKind dynamic_array_kind = GPUDynamicBindingKind::kUndefined; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_binding_info.cpp b/src/common/command_buffers/gpu/gpu_binding_info.cpp new file mode 100644 index 000000000..5c41068de --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_binding_info.cpp @@ -0,0 +1,5 @@ +#include + +namespace commandbuffers +{ +} diff --git a/src/common/command_buffers/gpu/gpu_binding_info.hpp b/src/common/command_buffers/gpu/gpu_binding_info.hpp new file mode 100644 index 000000000..9c24df985 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_binding_info.hpp @@ -0,0 +1,151 @@ +#pragma once + +#include +#include +#include +#include + +namespace commandbuffers +{ + enum class GPUBindingInfoType + { + Buffer, + Sampler, + Texture, + StorageTexture, + TexelBuffer, + ExternalTexture, + StaticSampler, + // Internal to vulkan only. + InputAttachment, + }; + + struct GPUBufferBindingInfo + { + GPUBufferBindingType type; + uint64_t minBindingSize{0u}; + bool hasDynamicOffset{false}; + + static GPUBufferBindingInfo From(const GPUBufferBindingLayout &); + }; + + struct GPUSamplerBindingInfo + { + GPUSamplerBindingType type; + + static GPUSamplerBindingInfo From(const GPUSamplerBindingLayout &); + }; + + struct GPUTextureBindingInfo + { + GPUTextureSampleType sampleType; + GPUTextureViewDimension viewDimension; + bool multisampled{false}; + + static GPUTextureBindingInfo From(const GPUTextureBindingLayout &); + }; + + struct GPUTexelBufferBindingInfo + { + // TODO: Add fields if needed + }; + + struct GPUStorageTextureBindingInfo + { + GPUTextureFormat format; + GPUTextureViewDimension viewDimension; + GPUStorageTextureAccess access; + + static GPUStorageTextureBindingInfo From(const GPUStorageTextureBindingLayout &); + }; + + struct GPUExternalTextureBindingInfo + { + GPUBindingIndex metadata; + GPUBindingIndex plane0; + GPUBindingIndex plane1; + }; + + struct GPUStaticSamplerBindingInfo + { + // No fields needed for static sampler + }; + + struct GPUInputAttachmentBindingInfo + { + GPUTextureSampleType type; + }; + + struct GPUBindingInfo + { + GPUBindingNumber binding; + GPUShaderStage visibility; + GPUBindingIndex arraySize{1u}; + GPUBindingIndex indexInArray{0u}; + + using BindingLayout = std::variant; + BindingLayout bindingLayout; + + bool operator==(const GPUBindingInfo &rhs) const = default; + std::string toString() const; + }; + + GPUBindingInfoType GetBindingInfoType(const GPUBindingInfo &); + + struct GPUBindingSlot + { + GPUBindGroupIndex group; + GPUBindingNumber binding; + + constexpr bool operator==(const GPUBindingSlot &rhs) const + { + return group == rhs.group && binding == rhs.binding; + } + constexpr bool operator!=(const GPUBindingSlot &rhs) const + { + return !(*this == rhs); + } + constexpr bool operator<(const GPUBindingSlot &rhs) const + { + if (group < rhs.group) + { + return true; + } + if (group > rhs.group) + { + return false; + } + return binding < rhs.binding; + } + }; + + struct GPUBindingCountsPerStage + { + uint32_t sampledTextureCount; + uint32_t samplerCount; + uint32_t storageBufferCount; + uint32_t storageTextureCount; + uint32_t texelBufferCount; + uint32_t uniformBufferCount; + uint32_t externalTextureCount; + uint32_t staticSamplerCount; + }; + + struct GPUBindingCounts + { + uint32_t totalCount; + uint32_t bufferCount; + uint32_t unverifiedBufferCount; + uint32_t dynamicUniformBufferCount; + uint32_t dynamicStorageBufferCount; + uint32_t staticSamplerCount; + GPUPerStage perStage; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_buffer.cpp b/src/common/command_buffers/gpu/gpu_buffer.cpp new file mode 100644 index 000000000..1bee3b64a --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_buffer.cpp @@ -0,0 +1,5 @@ +#include + +namespace commandbuffers +{ +} diff --git a/src/common/command_buffers/gpu/gpu_buffer.hpp b/src/common/command_buffers/gpu/gpu_buffer.hpp index 846d59d7b..b67a6e068 100644 --- a/src/common/command_buffers/gpu/gpu_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_buffer.hpp @@ -1,24 +1,37 @@ #pragma once #include -#include "./gpu_base.hpp" +#include +#include namespace commandbuffers { - enum class BufferUsage : uint64_t + enum class GPUBufferUsage : uint64_t { - None, - MapRead, - MapWrite, - CopySrc, - CopyDst, - Index, - Vertex, - Uniform, - Storage, - Indirect, - QueryResolve, - TexelBuffer, + kNone, + kMapRead, + kMapWrite, + kCopySrc, + kCopyDst, + kIndex, + kVertex, + kUniform, + kStorage, + kIndirect, + kQueryResolve, + kTexelBuffer, + }; + + struct GPUBufferDescriptor + { + std::string_view label; + GPUBufferUsage usage = GPUBufferUsage::kNone; + uint64_t size; + bool mappedAtCreation = false; + + // Equality operators, mostly for testing. Note that this tests + // strict pointer-pointer equality if the struct contains member pointers. + bool operator==(const GPUBufferDescriptor &rhs) const; }; class GPUBufferBase : public GPUHandle @@ -26,41 +39,65 @@ namespace commandbuffers public: enum class BufferState { - Unmapped, - PendingMap, - Mapped, - MappedAtCreation, - HostMappedPersistent, - SharedMemoryNoAccess, - Destroyed, + kUnmapped, + kPendingMap, + kMapped, + kMappedAtCreation, + kHostMappedPersistent, + kSharedMemoryNoAccess, + kDestroyed, }; static bool IsMappedState(BufferState state) { - return state == BufferState::Mapped || - state == BufferState::MappedAtCreation || - state == BufferState::HostMappedPersistent; + return state == BufferState::kMapped || + state == BufferState::kMappedAtCreation || + state == BufferState::kHostMappedPersistent; } public: virtual ~GPUBufferBase() = default; - public: - size_t size() const - { - return size_; - } - BufferUsage usage() const - { - return usage_; - } - BufferState mapState() const + GPUHandleType type() const override final { - return map_state_.load(); + return GPUHandleType::kBuffer; } + public: + size_t size() const; + GPUBufferUsage usage() const; + BufferState mapState() const; + void unmap(); + + protected: + GPUBufferBase(std::shared_ptr device, + const GPUBufferDescriptor &descriptor); + GPUBufferBase(std::shared_ptr device, + const GPUBufferDescriptor *descriptor, + GPUHandle::ErrorTag tag); + + bool mapAtCreationInternal(); + + BufferState state() const; + GPUMapMode mapMode() const; + size_t mapOffset() const; + size_t mapSize() const; + + uint64_t mAllocatedSize = 0; + private: size_t size_ = 0; - BufferUsage usage_ = BufferUsage::None; - std::atomic map_state_ = BufferState::Unmapped; + bool is_data_initialized = false; + + GPUBufferUsage usage_ = GPUBufferUsage::kNone; + GPUBufferUsage internal_usage_ = GPUBufferUsage::kNone; + std::atomic map_state_ = BufferState::kUnmapped; + + // A recursive buffer used to implement mappedAtCreation for buffers with non-mappable usage. + std::shared_ptr staging_buffer_ = nullptr; + + // Mapping specific states. + GPUMapMode mMapMode = GPUMapMode::kNone; + size_t mMapOffset = 0; + size_t mMapSize = 0; }; } diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.cpp b/src/common/command_buffers/gpu/gpu_command_buffer.cpp new file mode 100644 index 000000000..8501dae93 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_command_buffer.cpp @@ -0,0 +1,39 @@ +#include + +using namespace std; + +namespace commandbuffers +{ + GPUCommandBufferBase::GPUCommandBufferBase(GPUCommandEncoderBase *encoder, + const GPUCommandBufferDescriptor *descriptor) + : GPUHandle(encoder->device(), descriptor->label) + { + } + + GPUCommandBufferBase::GPUCommandBufferBase(shared_ptr device, + GPUHandle::ErrorTag tag, + string_view label) + : GPUHandle(device, tag, label) + { + } + + const string &GPUCommandBufferBase::getEncoderLabel() const + { + return encoder_label_; + } + + void GPUCommandBufferBase::setEncoderLabel(string encoderLabel) + { + encoder_label_ = move(encoderLabel); + } + + const GPUCommandBufferResourceUsage &GPUCommandBufferBase::getResourceUsages() const + { + return resource_usages_; + } + + const vector &GPUCommandBufferBase::getIndirectDrawMetadata() + { + return indirect_draw_metadata_; + } +} diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.hpp b/src/common/command_buffers/gpu/gpu_command_buffer.hpp index 84fa186ba..7ed6c2d2a 100644 --- a/src/common/command_buffers/gpu/gpu_command_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_command_buffer.hpp @@ -2,44 +2,64 @@ #include #include +#include +#include -#include "./gpu_base.hpp" -#include "./gpu_buffer.hpp" -#include "./gpu_pipeline.hpp" -#include "./gpu_commands.hpp" +#include +#include +#include +#include +#include +#include +#include +#include namespace commandbuffers { + struct GPUCommandBufferDescriptor + { + std::string_view label; + }; + class GPUCommandBufferBase : public GPUHandle { friend class GPUComputePassEncoderBase; friend class GPURenderPassEncoderBase; public: - GPUCommandBufferBase(std::optional label) - : GPUHandle(label.value_or("GPUCommandBuffer")) - , commands_() - { - } - GPUCommandBufferBase(std::optional label, const GPUCommandBufferBase &source) - : GPUHandle(label.value_or("GPUCommandBuffer")) - , commands_(source.commands_) + GPUCommandBufferBase(GPUCommandEncoderBase *encoder, + const GPUCommandBufferDescriptor *descriptor); + virtual ~GPUCommandBufferBase() = default; + + GPUHandleType type() const override final { + return GPUHandleType::kCommandBuffer; } - virtual ~GPUCommandBufferBase() = default; - public: - virtual void execute() = 0; + const std::string &getEncoderLabel() const; + void setEncoderLabel(std::string encoderLabel); - private: - template - void addCommand(Args &&...args) + const GPUCommandBufferResourceUsage &getResourceUsages() const; + const std::vector &getIndirectDrawMetadata(); + + template + auto useCommands(F func) -> auto { - auto command = std::make_shared(std::forward(args)...); - commands_.push_back(command); + auto result = func(commands_); + commands_.reset(); + return result; } protected: - std::vector> commands_; + gpu::CommandIterator commands_; + + private: + GPUCommandBufferBase(std::shared_ptr device, + GPUHandle::ErrorTag tag, + std::string_view label); + + GPUCommandBufferResourceUsage resource_usages_; + std::vector indirect_draw_metadata_; + std::string encoder_label_; }; } diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index c03b12bd4..9c3ba0792 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "./gpu_base.hpp" #include "./gpu_command_buffer.hpp" @@ -9,12 +10,21 @@ namespace commandbuffers { - class GPUCommandEncoderBase : public GPUHandle + struct GPUCommandEncoderDescriptor { - using GPUHandle::GPUHandle; + std::string_view label; + }; + + enum class GPUUsageValidationMode + { + kDefault, + kInternal, + }; + class GPUCommandEncoder final : public GPUHandle + { public: - virtual ~GPUCommandEncoderBase() = default; + virtual ~GPUCommandEncoder() = default; GPUHandleType type() const override { @@ -26,7 +36,20 @@ namespace commandbuffers virtual GPURenderPassEncoderBase beginRenderPass(GPURenderPassDescriptor &) = 0; virtual std::unique_ptr finish(std::optional label = std::nullopt) const = 0; - protected: - std::shared_ptr current_pass_encoder_; + private: + GPUCommandEncoder(std::shared_ptr device, const GPUCommandEncoderDescriptor &descriptor); + GPUCommandEncoder(std::shared_ptr device, + GPUHandle::ErrorTag tag, + std::string_view label); + + bool validateFinish() const; + + GPUEncodingContext encoding_context_; + std::unordered_set top_level_buffers_; + std::unordered_set top_level_textures_; + // std::unordered_set used_query_sets_; + + uint64_t debug_group_stack_size_ = 0; + GPUUsageValidationMode usage_validation_mode_; }; } diff --git a/src/common/command_buffers/gpu/gpu_constants.hpp b/src/common/command_buffers/gpu/gpu_constants.hpp new file mode 100644 index 000000000..144fb97a2 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_constants.hpp @@ -0,0 +1,46 @@ +// Copyright 2017 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +namespace commandbuffers::gpu_constants +{ + static constexpr uint32_t kMaxBindGroups = 4u; + static constexpr uint32_t kMaxBindingsPerBindGroup = 1000u; + static constexpr uint8_t kMaxVertexAttributes = 30u; + static constexpr uint8_t kMaxVertexBuffers = 8u; + static constexpr uint32_t kMaxVertexBufferArrayStride = 2048u; + static constexpr uint32_t kMaxBindGroupsPlusVertexBuffers = 24u; + static constexpr uint32_t kNumStages = 3; + static constexpr uint8_t kMaxColorAttachments = 8u; + static constexpr uint32_t kTextureBytesPerRowAlignment = 256u; + static constexpr uint32_t kQueryResolveAlignment = 256u; + static constexpr uint32_t kMaxInterStageShaderVariables = 16u; + static constexpr uint64_t kAssumedMaxBufferSize = 0x80000000u; // Use 2 GB when the limit is unavailable +}; diff --git a/src/common/command_buffers/gpu/gpu_device.cpp b/src/common/command_buffers/gpu/gpu_device.cpp new file mode 100644 index 000000000..2c49b14c7 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_device.cpp @@ -0,0 +1,28 @@ +#include + +namespace commandbuffers +{ + bool GPUDeviceBase::isValidationEnabled() const + { + // return !IsToggleEnabled(Toggle::SkipValidation); + return false; + } + + bool GPUDeviceBase::isRobustnessEnabled() const + { + // return !IsToggleEnabled(Toggle::DisableRobustness); + return false; + } + + bool GPUDeviceBase::isCompatibilityMode() const + { + // return !HasFeature(Feature::CoreFeaturesAndLimits); + return false; + } + + bool GPUDeviceBase::isImmediateErrorHandlingEnabled() const + { + // return mIsImmediateErrorHandlingEnabled; + return false; + } +} diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index a5f4c832a..d65d5df96 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -3,60 +3,61 @@ #include #include #include +#include +#include -#include "./gpu_base.hpp" -#include "./gpu_adapter.hpp" -#include "./gpu_command_buffer.hpp" -#include "./gpu_command_encoder.hpp" +#include +#include +#include +#include +#include +#include -namespace commandbuffers::gpu + +namespace commandbuffers { - class GPUQueue : public GPUHandle + struct GPUDeviceDescriptor { - public: - virtual ~GPUQueue() = default; - - public: - virtual void submit(const std::vector> &) = 0; + std::string_view label; + size_t requiredFeatureCount = 0; + GPUFeatureName const *requiredFeatures = nullptr; + GPUSupportedLimits *requiredLimits = nullptr; }; - /** - * The `GPUDevice` interface represents a logical GPU device. - * - * In usually, at client-side WebGPU implementation, it implements the `GPUDevice` interface to send - * `GPUCommandBuffer` to the renderer. And at server-side's renderer, it implements the same `GPUDevice` interface to - * execute the `GPUCommandBuffer` on the corresponding graphics API (e.g. OpenGL, Vulkan, etc.) via RHI. - */ class GPUDeviceBase : public GPUHandle { public: + GPUDeviceBase(GPUAdapterBase *adapter, + GPUDeviceDescriptor &descriptor); virtual ~GPUDeviceBase() = default; public: - const GPUAdapterInfo &adapterInfo() const - { - return adapter_info_; - } - const GPUSupportedFeatures &features() const - { - return features_; - } - const GPUSupportedLimits &limits() const - { - return limits_; - } - GPUQueue &queueRef() - { - assert(queue_ != nullptr); - return *queue_; - } - - virtual std::unique_ptr createCommandEncoder(std::optional label) = 0; + const GPUAdapterInfo &adapterInfo() const; + const GPUSupportedFeatures &features() const; + const GPUSupportedLimits &limits() const; + + bool validateHandle(const GPUHandle &handle) const; + + GPUInstanceBase *getInstance() const; + GPUAdapterBase *getAdapter() const; + GPUPhysicalDeviceBase *getPhysicalDevice() const; + + virtual std::unique_ptr createCommandBuffer( + GPUCommandEncoder &encoder, + const GPUCommandBufferDescriptor *descriptor = nullptr) = 0; + + std::shared_ptr GetOrCreateBindGroupLayout(); + + bool isValidationEnabled() const; + bool isRobustnessEnabled() const; + bool isCompatibilityMode() const; + bool isImmediateErrorHandlingEnabled() const; + + virtual bool mayRequireDuplicationOfIndirectParameters() const; protected: GPUAdapterInfo adapter_info_; GPUSupportedFeatures features_; GPUSupportedLimits limits_; - std::unique_ptr queue_; }; } diff --git a/src/common/command_buffers/gpu/gpu_error.cpp b/src/common/command_buffers/gpu/gpu_error.cpp new file mode 100644 index 000000000..c99710cc0 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_error.cpp @@ -0,0 +1,5 @@ +#include + +namespace commandbuffers +{ +} diff --git a/src/common/command_buffers/gpu/gpu_error.hpp b/src/common/command_buffers/gpu/gpu_error.hpp new file mode 100644 index 000000000..16711b32f --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_error.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace commandbuffers +{ + class GPUError + { + }; +} diff --git a/src/common/command_buffers/gpu/gpu_info.cpp b/src/common/command_buffers/gpu/gpu_info.cpp new file mode 100644 index 000000000..6d34783ed --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_info.cpp @@ -0,0 +1,900 @@ +#include +#include + +using namespace std; + +namespace commandbuffers::gpu_info +{ + enum class Architecture + { + Unknown, + AMD_GCN1, + AMD_GCN2, + AMD_GCN3, + AMD_GCN4, + AMD_GCN5, + AMD_RDNA1, + AMD_RDNA2, + AMD_RDNA3, + AMD_RDNA4, + AMD_CDNA1, + ARM_Midgard, + ARM_Bifrost, + ARM_Valhall, + ARM_Gen5, + Broadcom_VideoCore, + Google_Swiftshader, + ImgTec_Rogue, + ImgTec_Furian, + ImgTec_Albiorix, + Intel_Gen7, + Intel_Gen8, + Intel_Gen9, + Intel_Gen11, + Intel_Gen12LP, + Intel_Gen12HP, + Intel_XeLPG, + Intel_Xe2LPG, + Intel_Xe2HPG, + Intel_Xe3LPG, + Mesa_Software, + Microsoft_WARP, + Nvidia_Fermi, + Nvidia_Kepler, + Nvidia_Maxwell, + Nvidia_Pascal, + Nvidia_Turing, + Nvidia_Ampere, + Nvidia_Lovelace, + Nvidia_Blackwell, + Nvidia_Volta, + QualcommPCI_Adreno4xx, + QualcommPCI_Adreno5xx, + QualcommPCI_Adreno6xx, + QualcommPCI_Adreno7xx, + QualcommPCI_Adreno8xx, + QualcommACPI_Adreno6xx, + QualcommACPI_Adreno7xx, + Samsung_RDNA2, + Samsung_RDNA3, + }; + + Architecture GetArchitecture(PCIVendorID vendorId, PCIDeviceID deviceId) + { + switch (vendorId) + { + case kVendorID_AMD: + { + switch (deviceId & 0xFFF0) + { + case 0x1300: + case 0x1310: + case 0x6600: + case 0x6610: + case 0x6660: + case 0x6790: + case 0x6800: + case 0x6810: + case 0x6820: + case 0x6830: + return Architecture::AMD_GCN1; + case 0x6640: + case 0x6650: + case 0x67A0: + case 0x67B0: + case 0x9830: + case 0x9850: + return Architecture::AMD_GCN2; + case 0x6900: + case 0x6920: + case 0x6930: + case 0x7300: + case 0x9870: + case 0x98E0: + return Architecture::AMD_GCN3; + case 0x67C0: + case 0x67D0: + case 0x67E0: + case 0x67F0: + case 0x6980: + case 0x6990: + case 0x6FD0: + case 0x9920: + return Architecture::AMD_GCN4; + case 0x66A0: + case 0x6860: + case 0x6870: + case 0x6940: + case 0x69A0: + case 0x15D0: + case 0x1630: + return Architecture::AMD_GCN5; + case 0x7310: + case 0x7340: + case 0x7360: + return Architecture::AMD_RDNA1; + case 0x73A0: + case 0x73B0: + case 0x73D0: + case 0x73E0: + case 0x73F0: + case 0x7400: + case 0x7420: + case 0x7430: + case 0x1430: + case 0x1500: + case 0x15E0: + case 0x1640: + case 0x1680: + case 0x13c0: + case 0x13f0: + return Architecture::AMD_RDNA2; + case 0x7440: + case 0x7470: + case 0x7480: + case 0x15B0: + case 0x7450: + case 0x1900: + case 0x1580: + case 0x1110: + return Architecture::AMD_RDNA3; + case 0x7550: + case 0x7590: + return Architecture::AMD_RDNA4; + case 0x7380: + return Architecture::AMD_CDNA1; + } + } + break; + case kVendorID_ARM: + { + switch (deviceId & 0xF0000000) + { + case 0x00000000: + return Architecture::ARM_Midgard; + case 0x60000000: + case 0x70000000: + return Architecture::ARM_Bifrost; + case 0x90000000: + case 0xA0000000: + case 0xB0000000: + return Architecture::ARM_Valhall; + case 0xC0000000: + case 0xD0000000: + return Architecture::ARM_Gen5; + } + } + break; + case kVendorID_Broadcom: + { + switch (deviceId & 0x00000000) + { + case 0x00000000: + return Architecture::Broadcom_VideoCore; + } + } + break; + case kVendorID_Google: + { + switch (deviceId) + { + case 0xC0DE: + return Architecture::Google_Swiftshader; + } + } + break; + case kVendorID_ImgTec: + { + switch (deviceId & 0xFF000000) + { + case 0x00000000: + case 0x22000000: + case 0x24000000: + return Architecture::ImgTec_Rogue; + case 0x1b000000: + return Architecture::ImgTec_Furian; + case 0x35000000: + case 0x36000000: + return Architecture::ImgTec_Albiorix; + } + } + break; + case kVendorID_Intel: + { + switch (deviceId & 0xFF00) + { + case 0x0100: + case 0x0400: + case 0x0A00: + case 0x0D00: + case 0x0F00: + return Architecture::Intel_Gen7; + case 0x1600: + case 0x2200: + return Architecture::Intel_Gen8; + case 0x1900: + case 0x3100: + case 0x3E00: + case 0x5A00: + case 0x5900: + case 0x8700: + case 0x9B00: + return Architecture::Intel_Gen9; + case 0x8A00: + case 0x4E00: + case 0x9800: + return Architecture::Intel_Gen11; + case 0x4600: + case 0x4C00: + case 0x4900: + case 0x9A00: + case 0xA700: + return Architecture::Intel_Gen12LP; + case 0x4F00: + case 0x5600: + return Architecture::Intel_Gen12HP; + case 0x7D00: + case 0xB600: + return Architecture::Intel_XeLPG; + case 0x6400: + return Architecture::Intel_Xe2LPG; + case 0xE200: + return Architecture::Intel_Xe2HPG; + case 0xB000: + return Architecture::Intel_Xe3LPG; + } + } + break; + case kVendorID_Mesa: + { + switch (deviceId) + { + case 0x0000: + return Architecture::Mesa_Software; + } + } + break; + case kVendorID_Microsoft: + { + switch (deviceId) + { + case 0x8c: + return Architecture::Microsoft_WARP; + } + } + break; + case kVendorID_Nvidia: + { + switch (deviceId & 0xFFFFFF00) + { + case 0x0D00: + return Architecture::Nvidia_Fermi; + case 0x0F00: + case 0x1000: + case 0x1100: + case 0x1200: + return Architecture::Nvidia_Kepler; + case 0x1300: + case 0x1400: + case 0x1600: + case 0x1700: + return Architecture::Nvidia_Maxwell; + case 0x1500: + case 0x1B00: + case 0x1C00: + case 0x1D00: + return Architecture::Nvidia_Pascal; + case 0x1E00: + case 0x1F00: + case 0x2100: + return Architecture::Nvidia_Turing; + case 0x2200: + case 0x2400: + case 0x2500: + case 0x2000: + return Architecture::Nvidia_Ampere; + case 0x2600: + case 0x2700: + case 0x2800: + return Architecture::Nvidia_Lovelace; + case 0x2b00: + case 0x2c00: + case 0x2d00: + case 0x2f00: + return Architecture::Nvidia_Blackwell; + } + switch (deviceId & 0xFF000000) + { + case 0x1e000000: + return Architecture::Nvidia_Kepler; + case 0x92000000: + return Architecture::Nvidia_Maxwell; + case 0x93000000: + return Architecture::Nvidia_Pascal; + case 0x97000000: + return Architecture::Nvidia_Ampere; + case 0xa5000000: + return Architecture::Nvidia_Volta; + } + } + break; + case kVendorID_QualcommPCI: + { + switch (deviceId & 0xFF000000) + { + case 0x04000000: + return Architecture::QualcommPCI_Adreno4xx; + case 0x05000000: + return Architecture::QualcommPCI_Adreno5xx; + case 0x06000000: + return Architecture::QualcommPCI_Adreno6xx; + case 0x07000000: + case 0x43000000: + case 0x36000000: + case 0x37000000: + return Architecture::QualcommPCI_Adreno7xx; + case 0x44000000: + return Architecture::QualcommPCI_Adreno8xx; + } + } + break; + case kVendorID_QualcommACPI: + { + switch (deviceId & 0xFFFFFF00) + { + case 0x41333800: + case 0x36334100: + case 0x41333400: + case 0x36333600: + return Architecture::QualcommACPI_Adreno6xx; + case 0x37314400: + case 0x36334300: + return Architecture::QualcommACPI_Adreno7xx; + } + } + break; + case kVendorID_Samsung: + { + switch (deviceId & 0xFFFFFFFF) + { + case 0x000073A0: + case 0x01300100: + return Architecture::Samsung_RDNA2; + case 0x02600200: + return Architecture::Samsung_RDNA3; + } + } + break; + case kVendorID_Huawei: + { + switch (deviceId & 0xFFFFFFFF) + { + } + } + break; + } + + return Architecture::Unknown; + } + + bool IsAMD(PCIVendorID vendorId) + { + return vendorId == kVendorID_AMD; + } + bool IsApple(PCIVendorID vendorId) + { + return vendorId == kVendorID_Apple; + } + bool IsARM(PCIVendorID vendorId) + { + return vendorId == kVendorID_ARM; + } + bool IsBroadcom(PCIVendorID vendorId) + { + return vendorId == kVendorID_Broadcom; + } + bool IsGoogle(PCIVendorID vendorId) + { + return vendorId == kVendorID_Google; + } + bool IsImgTec(PCIVendorID vendorId) + { + return vendorId == kVendorID_ImgTec; + } + bool IsIntel(PCIVendorID vendorId) + { + return vendorId == kVendorID_Intel; + } + bool IsMesa(PCIVendorID vendorId) + { + return vendorId == kVendorID_Mesa; + } + bool IsMicrosoft(PCIVendorID vendorId) + { + return vendorId == kVendorID_Microsoft; + } + bool IsNvidia(PCIVendorID vendorId) + { + return vendorId == kVendorID_Nvidia; + } + bool IsQualcommPCI(PCIVendorID vendorId) + { + return vendorId == kVendorID_QualcommPCI; + } + bool IsQualcommACPI(PCIVendorID vendorId) + { + return vendorId == kVendorID_QualcommACPI; + } + bool IsSamsung(PCIVendorID vendorId) + { + return vendorId == kVendorID_Samsung; + } + bool IsHuawei(PCIVendorID vendorId) + { + return vendorId == kVendorID_Huawei; + } + + // Architecture checks + + // AMD architectures + bool IsAMDGCN1(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_GCN1; + } + bool IsAMDGCN2(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_GCN2; + } + bool IsAMDGCN3(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_GCN3; + } + bool IsAMDGCN4(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_GCN4; + } + bool IsAMDGCN5(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_GCN5; + } + bool IsAMDRDNA1(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_RDNA1; + } + bool IsAMDRDNA2(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_RDNA2; + } + bool IsAMDRDNA3(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_RDNA3; + } + bool IsAMDRDNA4(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_RDNA4; + } + bool IsAMDCDNA1(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::AMD_CDNA1; + } + // ARM architectures + bool IsARMMidgard(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::ARM_Midgard; + } + bool IsARMBifrost(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::ARM_Bifrost; + } + bool IsARMValhall(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::ARM_Valhall; + } + bool IsARMGen5(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::ARM_Gen5; + } + // Broadcom architectures + bool IsBroadcomVideoCore(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Broadcom_VideoCore; + } + // Google architectures + bool IsGoogleSwiftshader(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Google_Swiftshader; + } + // Img Tec architectures + bool IsImgTecRogue(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::ImgTec_Rogue; + } + bool IsImgTecFurian(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::ImgTec_Furian; + } + bool IsImgTecAlbiorix(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::ImgTec_Albiorix; + } + // Intel architectures + bool IsIntelGen7(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Gen7; + } + bool IsIntelGen8(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Gen8; + } + bool IsIntelGen9(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Gen9; + } + bool IsIntelGen11(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Gen11; + } + bool IsIntelGen12LP(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Gen12LP; + } + bool IsIntelGen12HP(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Gen12HP; + } + bool IsIntelXeLPG(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_XeLPG; + } + bool IsIntelXe2LPG(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Xe2LPG; + } + bool IsIntelXe2HPG(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Xe2HPG; + } + bool IsIntelXe3LPG(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Intel_Xe3LPG; + } + // Mesa architectures + bool IsMesaSoftware(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Mesa_Software; + } + // Microsoft architectures + bool IsMicrosoftWARP(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Microsoft_WARP; + } + // Nvidia architectures + bool IsNvidiaFermi(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Fermi; + } + bool IsNvidiaKepler(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Kepler; + } + bool IsNvidiaMaxwell(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Maxwell; + } + bool IsNvidiaPascal(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Pascal; + } + bool IsNvidiaTuring(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Turing; + } + bool IsNvidiaAmpere(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Ampere; + } + bool IsNvidiaLovelace(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Lovelace; + } + bool IsNvidiaBlackwell(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Blackwell; + } + bool IsNvidiaVolta(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Nvidia_Volta; + } + // QualcommPCI architectures + bool IsQualcommPCIAdreno4xx(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::QualcommPCI_Adreno4xx; + } + bool IsQualcommPCIAdreno5xx(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::QualcommPCI_Adreno5xx; + } + bool IsQualcommPCIAdreno6xx(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::QualcommPCI_Adreno6xx; + } + bool IsQualcommPCIAdreno7xx(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::QualcommPCI_Adreno7xx; + } + bool IsQualcommPCIAdreno8xx(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::QualcommPCI_Adreno8xx; + } + // QualcommACPI architectures + bool IsQualcommACPIAdreno6xx(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::QualcommACPI_Adreno6xx; + } + bool IsQualcommACPIAdreno7xx(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::QualcommACPI_Adreno7xx; + } + // Samsung architectures + bool IsSamsungRDNA2(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Samsung_RDNA2; + } + bool IsSamsungRDNA3(PCIVendorID vendorId, PCIDeviceID deviceId) + { + return GetArchitecture(vendorId, deviceId) == Architecture::Samsung_RDNA3; + } + + // GPUAdapterInfo fields + string GetVendorName(PCIVendorID vendorId) + { + switch (vendorId) + { + case kVendorID_AMD: + return "amd"; + case kVendorID_Apple: + return "apple"; + case kVendorID_ARM: + return "arm"; + case kVendorID_Broadcom: + return "broadcom"; + case kVendorID_Google: + return "google"; + case kVendorID_ImgTec: + return "img-tec"; + case kVendorID_Intel: + return "intel"; + case kVendorID_Mesa: + return "mesa"; + case kVendorID_Microsoft: + return "microsoft"; + case kVendorID_Nvidia: + return "nvidia"; + case kVendorID_QualcommPCI: + return "qualcomm"; + case kVendorID_QualcommACPI: + return "qualcomm"; + case kVendorID_Samsung: + return "samsung"; + case kVendorID_Huawei: + return "huawei"; + } + + return ""; + } + + string GetArchitectureName(PCIVendorID vendorId, PCIDeviceID deviceId) + { + Architecture arch = GetArchitecture(vendorId, deviceId); + switch (arch) + { + case Architecture::Unknown: + return ""; + case Architecture::AMD_GCN1: + return "gcn-1"; + case Architecture::AMD_GCN2: + return "gcn-2"; + case Architecture::AMD_GCN3: + return "gcn-3"; + case Architecture::AMD_GCN4: + return "gcn-4"; + case Architecture::AMD_GCN5: + return "gcn-5"; + case Architecture::AMD_RDNA1: + return "rdna-1"; + case Architecture::AMD_RDNA2: + return "rdna-2"; + case Architecture::AMD_RDNA3: + return "rdna-3"; + case Architecture::AMD_RDNA4: + return "rdna-4"; + case Architecture::AMD_CDNA1: + return "cdna-1"; + case Architecture::ARM_Midgard: + return "midgard"; + case Architecture::ARM_Bifrost: + return "bifrost"; + case Architecture::ARM_Valhall: + return "valhall"; + case Architecture::ARM_Gen5: + return "gen-5"; + case Architecture::Broadcom_VideoCore: + return "videocore"; + case Architecture::Google_Swiftshader: + return "swiftshader"; + case Architecture::ImgTec_Rogue: + return "rogue"; + case Architecture::ImgTec_Furian: + return "furian"; + case Architecture::ImgTec_Albiorix: + return "albiorix"; + case Architecture::Intel_Gen7: + return "gen-7"; + case Architecture::Intel_Gen8: + return "gen-8"; + case Architecture::Intel_Gen9: + return "gen-9"; + case Architecture::Intel_Gen11: + return "gen-11"; + case Architecture::Intel_Gen12LP: + return "gen-12lp"; + case Architecture::Intel_Gen12HP: + return "gen-12hp"; + case Architecture::Intel_XeLPG: + return "xe-lpg"; + case Architecture::Intel_Xe2LPG: + return "xe-2lpg"; + case Architecture::Intel_Xe2HPG: + return "xe-2hpg"; + case Architecture::Intel_Xe3LPG: + return "xe-3lpg"; + case Architecture::Mesa_Software: + return "software"; + case Architecture::Microsoft_WARP: + return "warp"; + case Architecture::Nvidia_Fermi: + return "fermi"; + case Architecture::Nvidia_Kepler: + return "kepler"; + case Architecture::Nvidia_Maxwell: + return "maxwell"; + case Architecture::Nvidia_Pascal: + return "pascal"; + case Architecture::Nvidia_Turing: + return "turing"; + case Architecture::Nvidia_Ampere: + return "ampere"; + case Architecture::Nvidia_Lovelace: + return "lovelace"; + case Architecture::Nvidia_Blackwell: + return "blackwell"; + case Architecture::Nvidia_Volta: + return "volta"; + case Architecture::QualcommPCI_Adreno4xx: + return "adreno-4xx"; + case Architecture::QualcommPCI_Adreno5xx: + return "adreno-5xx"; + case Architecture::QualcommPCI_Adreno6xx: + return "adreno-6xx"; + case Architecture::QualcommPCI_Adreno7xx: + return "adreno-7xx"; + case Architecture::QualcommPCI_Adreno8xx: + return "adreno-8xx"; + case Architecture::QualcommACPI_Adreno6xx: + return "adreno-6xx"; + case Architecture::QualcommACPI_Adreno7xx: + return "adreno-7xx"; + case Architecture::Samsung_RDNA2: + return "rdna-2"; + case Architecture::Samsung_RDNA3: + return "rdna-3"; + } + + return ""; + } + + DriverVersion::DriverVersion() = default; + + DriverVersion::DriverVersion(const std::initializer_list &version) + { + assert(version.size() <= kMaxVersionFields); + driver_version_.assign(version.begin(), version.end()); + } + + uint16_t &DriverVersion::operator[](size_t i) + { + return driver_version_.operator[](i); + } + + const uint16_t &DriverVersion::operator[](size_t i) const + { + return driver_version_.operator[](i); + } + + uint32_t DriverVersion::size() const + { + return driver_version_.size(); + } + + std::string DriverVersion::toString() const + { + std::ostringstream oss; + if (!driver_version_.empty()) + { + // Convert all but the last element to avoid a trailing "." + std::copy(driver_version_.begin(), driver_version_.end() - 1, std::ostream_iterator(oss, ".")); + // Add the last element + oss << driver_version_.back(); + } + return oss.str(); + } + + + IntelGen GetIntelGen(PCIVendorID venderId, PCIDeviceID deviceId) + { + assert(gpu_info::IsIntel(venderId)); + + if (gpu_info::IsIntelGen7(venderId, deviceId)) + { + return IntelGen::Gen7; + } + else if (gpu_info::IsIntelGen8(venderId, deviceId)) + { + return IntelGen::Gen8; + } + else if (gpu_info::IsIntelGen9(venderId, deviceId)) + { + return IntelGen::Gen9; + } + else if (gpu_info::IsIntelGen11(venderId, deviceId)) + { + return IntelGen::Gen11; + } + else if (gpu_info::IsIntelGen12LP(venderId, deviceId)) + { + return IntelGen::Xe; + } + else if (gpu_info::IsIntelGen12HP(venderId, deviceId)) + { + return IntelGen::Xe; + } + else if (gpu_info::IsIntelXeLPG(venderId, deviceId)) + { + return IntelGen::Xe; + } + else if (gpu_info::IsIntelXe2LPG(venderId, deviceId)) + { + return IntelGen::Xe2; + } + else if (gpu_info::IsIntelXe2HPG(venderId, deviceId)) + { + return IntelGen::Xe2; + } + else if (gpu_info::IsIntelXe3LPG(venderId, deviceId)) + { + return IntelGen::Xe3; + } + else + { + return IntelGen::Unknown; + } + } + + QualcommACPIGen GetQualcommACPIGen(PCIVendorID venderId, PCIDeviceID deviceId) + { + assert(gpu_info::IsQualcommACPI(venderId)); + + if (gpu_info::IsQualcommACPIAdreno6xx(venderId, deviceId)) + { + return QualcommACPIGen::Adreno6xx; + } + else if (gpu_info::IsQualcommACPIAdreno7xx(venderId, deviceId)) + { + return QualcommACPIGen::Adreno7xx; + } + else + { + return QualcommACPIGen::Unknown; + } + } +} diff --git a/src/common/command_buffers/gpu/gpu_info.hpp b/src/common/command_buffers/gpu/gpu_info.hpp new file mode 100644 index 000000000..933afa1a5 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_info.hpp @@ -0,0 +1,192 @@ +// Copyright 2019 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include + +namespace commandbuffers::gpu_info +{ + using PCIVendorID = uint32_t; + using PCIDeviceID = uint32_t; + + // Vendor IDs + static constexpr PCIVendorID kVendorID_AMD = 0x1002; + static constexpr PCIVendorID kVendorID_Apple = 0x106b; + static constexpr PCIVendorID kVendorID_ARM = 0x13B5; + static constexpr PCIVendorID kVendorID_Broadcom = 0x14e4; + static constexpr PCIVendorID kVendorID_Google = 0x1AE0; + static constexpr PCIVendorID kVendorID_ImgTec = 0x1010; + static constexpr PCIVendorID kVendorID_Intel = 0x8086; + static constexpr PCIVendorID kVendorID_Mesa = 0x10005; + static constexpr PCIVendorID kVendorID_Microsoft = 0x1414; + static constexpr PCIVendorID kVendorID_Nvidia = 0x10DE; + static constexpr PCIVendorID kVendorID_QualcommPCI = 0x5143; + static constexpr PCIVendorID kVendorID_QualcommACPI = 0x4D4F4351; + static constexpr PCIVendorID kVendorID_Samsung = 0x144d; + static constexpr PCIVendorID kVendorID_Huawei = 0x19e5; + static constexpr uint32_t kMaxVersionFields = 4; + + // Vendor checks + bool IsAMD(PCIVendorID vendorId); + bool IsApple(PCIVendorID vendorId); + bool IsARM(PCIVendorID vendorId); + bool IsBroadcom(PCIVendorID vendorId); + bool IsGoogle(PCIVendorID vendorId); + bool IsImgTec(PCIVendorID vendorId); + bool IsIntel(PCIVendorID vendorId); + bool IsMesa(PCIVendorID vendorId); + bool IsMicrosoft(PCIVendorID vendorId); + bool IsNvidia(PCIVendorID vendorId); + bool IsQualcommPCI(PCIVendorID vendorId); + bool IsQualcommACPI(PCIVendorID vendorId); + bool IsSamsung(PCIVendorID vendorId); + bool IsHuawei(PCIVendorID vendorId); + + // Architecture checks + + // AMD architectures + bool IsAMDGCN1(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDGCN2(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDGCN3(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDGCN4(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDGCN5(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDRDNA1(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDRDNA2(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDRDNA3(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDRDNA4(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsAMDCDNA1(PCIVendorID vendorId, PCIDeviceID deviceId); + + // ARM architectures + bool IsARMMidgard(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsARMBifrost(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsARMValhall(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsARMGen5(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Broadcom architectures + bool IsBroadcomVideoCore(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Google architectures + bool IsGoogleSwiftshader(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Img Tec architectures + bool IsImgTecRogue(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsImgTecFurian(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsImgTecAlbiorix(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Intel architectures + bool IsIntelGen7(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelGen8(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelGen9(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelGen11(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelGen12LP(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelGen12HP(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelXeLPG(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelXe2LPG(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelXe2HPG(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsIntelXe3LPG(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Mesa architectures + bool IsMesaSoftware(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Microsoft architectures + bool IsMicrosoftWARP(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Nvidia architectures + bool IsNvidiaFermi(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaKepler(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaMaxwell(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaPascal(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaTuring(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaAmpere(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaLovelace(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaBlackwell(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsNvidiaVolta(PCIVendorID vendorId, PCIDeviceID deviceId); + + // QualcommPCI architectures + bool IsQualcommPCIAdreno4xx(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsQualcommPCIAdreno5xx(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsQualcommPCIAdreno6xx(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsQualcommPCIAdreno7xx(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsQualcommPCIAdreno8xx(PCIVendorID vendorId, PCIDeviceID deviceId); + + // QualcommACPI architectures + bool IsQualcommACPIAdreno6xx(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsQualcommACPIAdreno7xx(PCIVendorID vendorId, PCIDeviceID deviceId); + + // Samsung architectures + bool IsSamsungRDNA2(PCIVendorID vendorId, PCIDeviceID deviceId); + bool IsSamsungRDNA3(PCIVendorID vendorId, PCIDeviceID deviceId); + + // GPUAdapterInfo fields + std::string GetVendorName(PCIVendorID vendorId); + std::string GetArchitectureName(PCIVendorID vendorId, PCIDeviceID deviceId); + + class DriverVersion + { + public: + DriverVersion(); + DriverVersion(const std::initializer_list &version); + + uint16_t &operator[](size_t i); + const uint16_t &operator[](size_t i) const; + + uint32_t size() const; + std::string toString() const; + + private: + std::vector driver_version_; + }; + + // GPU generation is an internal concept, rather than a value defined by vendors + // Intel generations + enum class IntelGen + { + Unknown = 0, + Gen7 = 7, + Gen8 = 8, + Gen9 = 9, + Gen10 = 10, + Gen11 = 11, + Xe = 12, + Xe2 = 13, + Xe3 = 14, + }; + + // Qualcomm ACPI generations + enum class QualcommACPIGen + { + Unknown = 0, + Adreno6xx = 6, + Adreno7xx = 7, + }; + + IntelGen GetIntelGen(PCIVendorID venderId, PCIDeviceID deviceId); + QualcommACPIGen GetQualcommACPIGen(PCIVendorID venderId, PCIDeviceID deviceId); +} diff --git a/src/common/command_buffers/gpu/gpu_instance.cpp b/src/common/command_buffers/gpu/gpu_instance.cpp new file mode 100644 index 000000000..8c3091ca9 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_instance.cpp @@ -0,0 +1,40 @@ +#include + +using namespace std; + +namespace commandbuffers +{ + unique_ptr GPUInstanceBase::Create(const GPUInstanceDescriptor *descriptor) + { + static constexpr GPUInstanceDescriptor kDefaultDesc = {}; + if (descriptor == nullptr) + { + descriptor = &kDefaultDesc; + } + + auto instance = make_unique(); + instance->initialize(*descriptor); + return instance; + } + + void GPUInstanceBase::addDevice(shared_ptr) + { + } + + void GPUInstanceBase::removeDevice(shared_ptr) + { + } + + bool GPUInstanceBase::hasFeature(GPUFeatureName feature) const + { + return instance_features_.find(feature) != instance_features_.end(); + } + + GPUInstanceBase::GPUInstanceBase() + { + } + + void GPUInstanceBase::initialize(const GPUInstanceDescriptor &descriptor) + { + } +} diff --git a/src/common/command_buffers/gpu/gpu_instance.hpp b/src/common/command_buffers/gpu/gpu_instance.hpp new file mode 100644 index 000000000..7dd7ea530 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_instance.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + struct GPUInstanceDescriptor + { + size_t requiredFeatureCount = 0; + GPUFeatureName const *requiredFeatures = nullptr; + GPUSupportedLimits *requiredLimits = nullptr; + }; + + class GPUInstanceBase + { + public: + static std::unique_ptr Create(const GPUInstanceDescriptor *descriptor = nullptr); + + void addDevice(std::shared_ptr); + void removeDevice(std::shared_ptr); + + bool hasFeature(GPUFeatureName feature) const; + + private: + explicit GPUInstanceBase(); + virtual ~GPUInstanceBase() = default; + + void initialize(const GPUInstanceDescriptor &descriptor); + std::shared_ptr createAdapter(); + + private: + std::unordered_set instance_features_; + std::vector> devices_list_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_per_stage.cpp b/src/common/command_buffers/gpu/gpu_per_stage.cpp new file mode 100644 index 000000000..d911d073d --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_per_stage.cpp @@ -0,0 +1,21 @@ +#include + +using namespace std; +using namespace commandbuffers::gpu_constants; + +namespace commandbuffers +{ + // static + bitset GPUStages::IterateStages(GPUShaderStage stages) + { + bitset bits(static_cast(stages)); + return bits; + } + + // static + GPUShaderStage GPUStages::StageBit(GPUSingleShaderStage stage) + { + assert(static_cast(stage) < kNumStages); + return static_cast(1 << static_cast(stage)); + } +} diff --git a/src/common/command_buffers/gpu/gpu_per_stage.hpp b/src/common/command_buffers/gpu/gpu_per_stage.hpp new file mode 100644 index 000000000..196586fbd --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_per_stage.hpp @@ -0,0 +1,115 @@ +// Copyright 2017 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + enum class GPUSingleShaderStage + { + kVertex, + kFragment, + kCompute + }; + + static_assert(static_cast(GPUSingleShaderStage::kVertex) < gpu_constants::kNumStages); + static_assert(static_cast(GPUSingleShaderStage::kFragment) < gpu_constants::kNumStages); + static_assert(static_cast(GPUSingleShaderStage::kCompute) < gpu_constants::kNumStages); + + static_assert(static_cast(GPUShaderStage::kVertex) == + (1 << static_cast(GPUSingleShaderStage::kVertex))); + static_assert(static_cast(GPUShaderStage::kFragment) == + (1 << static_cast(GPUSingleShaderStage::kFragment))); + static_assert(static_cast(GPUShaderStage::kCompute) == + (1 << static_cast(GPUSingleShaderStage::kCompute))); + + class GPUStages + { + public: + static std::bitset IterateStages(GPUShaderStage stages); + static GPUShaderStage StageBit(GPUSingleShaderStage stage); + + static constexpr GPUShaderStage kAllStages = static_cast((1 << gpu_constants::kNumStages) - 1); + }; + + template + class GPUPerStage + { + public: + GPUPerStage() = default; + explicit GPUPerStage(const T &initialValue) + { + data_.fill(initialValue); + } + + T &operator[](GPUSingleShaderStage stage) + { + assert(static_cast(stage) < gpu_constants::kNumStages); + return data_[static_cast(stage)]; + } + + const T &operator[](GPUSingleShaderStage stage) const + { + assert(static_cast(stage) < gpu_constants::kNumStages); + return data_[static_cast(stage)]; + } + + T &operator[](GPUShaderStage stageBit) + { + uint32_t bit = static_cast(stageBit); + assert(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << gpu_constants::kNumStages)); + return data_[Log2(bit)]; + } + const T &operator[](GPUShaderStage stageBit) const + { + uint32_t bit = static_cast(stageBit); + assert(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << gpu_constants::kNumStages)); + return data_[Log2(bit)]; + } + + private: + static bool IsPowerOfTwo(uint64_t n) + { + assert(n != 0); + return (n & (n - 1)) == 0; + } + static uint32_t Log2(uint32_t value) + { + assert(value != 0); + return 31 - std::countl_zero(value); + } + + private: + std::array data_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_physical_device.cpp b/src/common/command_buffers/gpu/gpu_physical_device.cpp new file mode 100644 index 000000000..f393294b8 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_physical_device.cpp @@ -0,0 +1,5 @@ +#include + +namespace commandbuffers +{ +} diff --git a/src/common/command_buffers/gpu/gpu_physical_device.hpp b/src/common/command_buffers/gpu/gpu_physical_device.hpp new file mode 100644 index 000000000..98ccda19b --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_physical_device.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUPhysicalDeviceBase + { + public: + explicit GPUPhysicalDeviceBase() = default; + + void initialize(); + std::shared_ptr createDevice(std::shared_ptr adapter, + GPUDeviceDescriptor &descriptor); + + uint32_t vendorId() const; + uint32_t deviceId() const; + const std::string &vendorName() const; + const std::string &architectureName() const; + const std::string &name() const; + const gpu_info::DriverVersion &driverVersion() const; + const std::string &driverDescription() const; + GPUAdapterType adapterType() const; + GPUBackendType backendType() const; + uint32_t subgroupMinSize() const; + uint32_t subgroupMaxSize() const; + + virtual bool supportsExternalImages() const = 0; + + protected: + void enableFeature(GPUFeatureName feature); + + private: + virtual std::unique_ptr createDeviceImpl(std::shared_ptr adapter, + GPUDeviceDescriptor &descriptor); + virtual void initializeImpl(); + virtual void initializeSupportedFeaturesImpl() = 0; + virtual void initializeVendorArchitectureImpl(); + + protected: + uint32_t vendor_id_ = 0xFFFFFFFF; + uint32_t device_id_ = 0xFFFFFFFF; + std::string vendor_name_ = "Unknown"; + std::string arch_name_ = "Unknown"; + std::string name_ = ""; + GPUAdapterType adapter_type_ = GPUAdapterType::kUnknown; + gpu_info::DriverVersion driver_version_; + std::string driver_description_ = ""; + + uint32_t subgroup_min_size_ = 4u; + uint32_t subgroup_max_size_ = 128u; + + private: + GPUBackendType backend_type_ = GPUBackendType::kUndefined; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_texture.hpp b/src/common/command_buffers/gpu/gpu_texture.hpp index 7a30052cd..fd077effc 100644 --- a/src/common/command_buffers/gpu/gpu_texture.hpp +++ b/src/common/command_buffers/gpu/gpu_texture.hpp @@ -135,7 +135,7 @@ namespace commandbuffers kTexture3D, }; - class GPUTexture : public GPUHandle + class GPUTextureBase : public GPUHandle { public: private: diff --git a/src/common/command_buffers/gpu/indirect_draw_metadata.hpp b/src/common/command_buffers/gpu/indirect_draw_metadata.hpp new file mode 100644 index 000000000..3cb5595e3 --- /dev/null +++ b/src/common/command_buffers/gpu/indirect_draw_metadata.hpp @@ -0,0 +1,9 @@ +#pragma once + +namespace commandbuffers::gpu +{ + class IndirectDrawMetadata + { + // TODO(yorkie): Implement GPUIndirectDrawMetadata class. + }; +} diff --git a/src/common/command_buffers/gpu/pass_resource_usage.hpp b/src/common/command_buffers/gpu/pass_resource_usage.hpp new file mode 100644 index 000000000..12a44ffdf --- /dev/null +++ b/src/common/command_buffers/gpu/pass_resource_usage.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace commandbuffers::gpu +{ + // Info about how a buffer is used and in which shader stages + struct BufferSyncInfo + { + GPUBufferUsage usage = GPUBufferUsage::kNone; + GPUShaderStage shaderStages = GPUShaderStage::kNone; + }; + + struct TextureSyncInfo + { + // GPUTextureUsage usage = GPUTextureUsage::None; + GPUShaderStage shaderStages = GPUShaderStage::kNone; + bool operator==(const TextureSyncInfo &b) const = default; + }; + + struct SyncScopeResourceUsage + { + std::vector buffers; + std::vector bufferSyncInfos; + + std::vector textures; + // std::vector textureSyncInfos; + + // std::vector externalTextures; + std::vector dynamicBindingArrays; + }; + + struct RenderPassResourceUsage : public SyncScopeResourceUsage + { + // Storage to track the occlusion queries used during the pass. + // std::vector querySets; + // std::vector> queryAvailabilities; + }; + + struct ComputePassResourceUsage + { + std::vector dispatchUsages; + + // All the resources referenced by this compute pass for validation in Queue::Submit. + std::unordered_set referencedBuffers; + std::unordered_set referencedTextures; + // std::unordered_set referencedExternalTextures; + std::unordered_set referencedDynamicBindingArrays; + }; + + using RenderPassUsages = std::vector; + using ComputePassUsages = std::vector; + + struct CommandBufferResourceUsage + { + RenderPassUsages renderPasses; + ComputePassUsages computePasses; + + // Resources used in commands that aren't in a pass. + std::unordered_set> topLevelBuffers; + std::unordered_set> topLevelTextures; + }; +} diff --git a/src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp b/src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp new file mode 100644 index 000000000..d75765df9 --- /dev/null +++ b/src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp @@ -0,0 +1 @@ +#include diff --git a/src/common/command_buffers/gpu/pass_resource_usage_tracker.hpp b/src/common/command_buffers/gpu/pass_resource_usage_tracker.hpp new file mode 100644 index 000000000..d86099318 --- /dev/null +++ b/src/common/command_buffers/gpu/pass_resource_usage_tracker.hpp @@ -0,0 +1,16 @@ +#pragma once + +namespace commandbuffers::gpu +{ + class SyncScopeUsageTracker + { + }; + + class ComputePassResourceUsageTracker + { + }; + + class RenderPassResourceUsageTracker : public SyncScopeUsageTracker + { + }; +} diff --git a/src/common/compiler.hpp b/src/common/compiler.hpp new file mode 100644 index 000000000..7e9e2586a --- /dev/null +++ b/src/common/compiler.hpp @@ -0,0 +1,124 @@ +#pragma once + +// Copyright 2024 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// TR_COMPILER_IS(CLANG|GCC|MSVC): Compiler detection +// +// Note: clang masquerades as GCC on POSIX and as MSVC on Windows. It must be checked first. +#if defined(__clang__) +#define TR_COMPILER_IS_CLANG 1 +#define TR_COMPILER_IS_GCC 0 +#define TR_COMPILER_IS_MSVC 0 +#elif defined(__GNUC__) +#define TR_COMPILER_IS_CLANG 0 +#define TR_COMPILER_IS_GCC 1 +#define TR_COMPILER_IS_MSVC 0 +#elif defined(_MSC_VER) +#define TR_COMPILER_IS_CLANG 0 +#define TR_COMPILER_IS_GCC 0 +#define TR_COMPILER_IS_MSVC 1 +#else +#error "Unsupported compiler" +#endif + +// Use #if TR_COMPILER_IS(XXX) for compiler specific code. +// Do not use #ifdef or the naked macro TR_COMPILER_IS_XXX. +// This can help avoid common mistakes like not including "compiler.h" and falling into unwanted +// code block as usage of undefined macro "function" will be blocked by the compiler. +#define TR_COMPILER_IS(X) (1 == TR_COMPILER_IS_##X) + +// TR_HAS_ATTRIBUTE +// +// A wrapper around `__has_attribute`. This test whether its operand is recognized by the compiler. +#if defined(__has_attribute) +#define TR_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define TR_HAS_ATTRIBUTE(x) 0 +#endif + +// TR_HAS_CPP_ATTRIBUTE +// +// A wrapper around `__has_cpp_attribute`. This test whether its operand is recognized by the +// compiler. +#if defined(__has_cpp_attribute) +#define TR_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define TR_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +// TR_BUILTIN_UNREACHABLE() +// +// Hints the compiler that a code path is unreachable. +#if TR_COMPILER_IS(MSVC) +#define TR_BUILTIN_UNREACHABLE() __assume(false) +#else +#define TR_BUILTIN_UNREACHABLE() __builtin_unreachable() +#endif + +// TR_LIKELY(EXPR) +// +// Where available, hints the compiler that the expression will be true to help it generate code +// that leads to better branch prediction. +#if TR_COMPILER_IS(GCC) || TR_COMPILER_IS(CLANG) +#define TR_LIKELY(x) __builtin_expect(!!(x), 1) +#else +#define TR_LIKELY(x) (x) +#endif + +// TR_UNLIKELY(EXPR) +// +// Where available, hints the compiler that the expression will be false to help it generate code +// that leads to better branch prediction. +#if TR_COMPILER_IS(GCC) || TR_COMPILER_IS(CLANG) +#define TR_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define TR_UNLIKELY(x) (x) +#endif + +// TR_ASAN_ENABLED() +// +// Checks whether ASan is enabled. +#if TR_COMPILER_IS(CLANG) +#define TR_ASAN_ENABLED() __has_feature(address_sanitizer) +#elif TR_COMPILER_IS(GCC) || TR_COMPILER_IS(MSVC) +#if defined(__SANITIZE_ADDRESS__) +#define TR_ASAN_ENABLED() 1 +#else +#define TR_ASAN_ENABLED() 0 +#endif +#endif + +// TR_NO_SANITIZE(instrumentation) +// +// Annotate a function or a global variable declaration to specify that a particular instrumentation +// or set of instrumentations should not be applied. +#if TR_HAS_ATTRIBUTE(no_sanitize) +#define TR_NO_SANITIZE(instrumentation) __attribute__((no_sanitize(instrumentation))) +#else +#define TR_NO_SANITIZE(instrumentation) +#endif diff --git a/src/common/math_utils.hpp b/src/common/math_utils.hpp index 533af0b1c..e6bde1b2c 100644 --- a/src/common/math_utils.hpp +++ b/src/common/math_utils.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace transmute::common @@ -44,5 +45,51 @@ namespace transmute::common { return std::fabs(a - b) <= epsilon; } + + /** + * Check if a number is a power of two. + * + * @param n The number to check, must be non-zero. + * @returns True if n is a power of two, false otherwise. + */ + static bool IsPowerOfTwo(uint64_t n) + { + assert(n != 0); + return (n & (n - 1)) == 0; + } }; + + inline bool IsPtrAligned(const void *ptr, size_t alignment) + { + assert(math_utils::IsPowerOfTwo(alignment)); + assert(alignment != 0); + return (reinterpret_cast(ptr) & (alignment - 1)) == 0; + } + + inline bool IsAligned(uint32_t value, size_t alignment) + { + assert(alignment <= UINT32_MAX); + assert(math_utils::IsPowerOfTwo(alignment)); + assert(alignment != 0); + uint32_t alignment32 = static_cast(alignment); + return (value & (alignment32 - 1)) == 0; + } + + template + inline T *AlignPtr(T *ptr, size_t alignment) + { + assert(math_utils::IsPowerOfTwo(alignment)); + assert(alignment != 0); + return reinterpret_cast((reinterpret_cast(ptr) + (alignment - 1)) & + ~(alignment - 1)); + } + + template + inline const T *AlignPtr(const T *ptr, size_t alignment) + { + assert(math_utils::IsPowerOfTwo(alignment)); + assert(alignment != 0); + return reinterpret_cast((reinterpret_cast(ptr) + (alignment - 1)) & + ~(alignment - 1)); + } } diff --git a/src/common/non_copyable.hpp b/src/common/non_copyable.hpp new file mode 100644 index 000000000..4ed3943fc --- /dev/null +++ b/src/common/non_copyable.hpp @@ -0,0 +1,44 @@ +// Copyright 2021 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +// A base class to make a class non-copyable. +class NonCopyable +{ +public: + constexpr NonCopyable() = default; + ~NonCopyable() = default; + +protected: + NonCopyable(NonCopyable &&) = default; + NonCopyable &operator=(NonCopyable &&) = default; + +private: + NonCopyable(const NonCopyable &) = delete; + void operator=(const NonCopyable &) = delete; +}; diff --git a/src/common/non_movable.hpp b/src/common/non_movable.hpp new file mode 100644 index 000000000..2ff850cec --- /dev/null +++ b/src/common/non_movable.hpp @@ -0,0 +1,42 @@ +// Copyright 2024 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +// A base class to make a class non-movable. +class NonMovable : NonCopyable +{ +protected: + constexpr NonMovable() = default; + ~NonMovable() = default; + +private: + NonMovable(NonMovable &&) = delete; + void operator=(NonMovable &&) = delete; +}; diff --git a/src/common/platform.hpp b/src/common/platform.hpp new file mode 100644 index 000000000..2fa8f1a97 --- /dev/null +++ b/src/common/platform.hpp @@ -0,0 +1,320 @@ +// Copyright 2017 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +// Use #if TR_PLATFORM_IS(X) for platform specific code. +// Do not use #ifdef or the naked macro TR_PLATFORM_IS_X. +// This can help avoid common mistakes like not including "Platform.h" and falling into unwanted +// code block as usage of undefined macro "function" will be blocked by the compiler. +#define TR_PLATFORM_IS(X) (1 == TR_PLATFORM_IS_##X) + +// Define platform macros for OSes: +// +// - WINDOWS +// - WIN32 +// - WINUWP +// - POSIX +// - LINUX +// - ANDROID +// - CHROMEOS +// - APPLE +// - IOS +// - TVOS +// - MACOS +// - FUCHSIA +// - EMSCRIPTEN +#if defined(_WIN32) || defined(_WIN64) +#include +#define TR_PLATFORM_IS_WINDOWS 1 +#if WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP +#define TR_PLATFORM_IS_WIN32 1 +#elif WINAPI_FAMILY == WINAPI_FAMILY_PC_APP +#define TR_PLATFORM_IS_WINUWP 1 +#else +#error "Unsupported Windows platform." +#endif + +#elif defined(__linux__) +#define TR_PLATFORM_IS_LINUX 1 +#define TR_PLATFORM_IS_POSIX 1 +#if defined(__ANDROID__) +#define TR_PLATFORM_IS_ANDROID 1 +#elif defined(TR_OS_CHROMEOS) +#define TR_PLATFORM_IS_CHROMEOS 1 +#else +#define TR_PLATFORM_IS_LINUX_DESKTOP 1 +#endif + +#elif defined(__APPLE__) +#define TR_PLATFORM_IS_APPLE 1 +#define TR_PLATFORM_IS_POSIX 1 +#include +#if TARGET_OS_IPHONE +#define TR_PLATFORM_IS_IOS 1 +#if TARGET_OS_TV +#define TR_PLATFORM_IS_TVOS 1 +#endif +#elif TARGET_OS_MAC +#define TR_PLATFORM_IS_MACOS 1 +#else +#error "Unsupported Apple platform." +#endif + +#elif defined(__Fuchsia__) +#define TR_PLATFORM_IS_FUCHSIA 1 +#define TR_PLATFORM_IS_POSIX 1 + +#elif defined(__EMSCRIPTEN__) +#define TR_PLATFORM_IS_EMSCRIPTEN 1 +#define TR_PLATFORM_IS_POSIX 1 +#include + +#else +#error "Unsupported platform." +#endif + +// Define platform macros for CPU architectures: +// +// - X86 +// - I386 +// - X86_64 +// - ARM +// - ARM32 +// - ARM64 +// - LOONGARCH +// - LOONGARCH32 +// - LOONGARCH64 +// - RISCV +// - RISCV32 +// - RISCV64 +// - MIPS +// - MIPS32 +// - MIPS64 +// - S390 +// - S390X +// - PPC +// - PPC64 +#if defined(__i386__) || defined(_M_IX86) +#define TR_PLATFORM_IS_X86 1 +#define TR_PLATFORM_IS_I386 1 +#elif defined(__x86_64__) || defined(_M_X64) +#define TR_PLATFORM_IS_X86 1 +#define TR_PLATFORM_IS_X86_64 1 + +#elif defined(__arm__) || defined(_M_ARM) +#define TR_PLATFORM_IS_ARM 1 +#define TR_PLATFORM_IS_ARM32 1 +#elif defined(__aarch64__) || defined(_M_ARM64) +#define TR_PLATFORM_IS_ARM 1 +#define TR_PLATFORM_IS_ARM64 1 + +#elif defined(__loongarch__) +#define TR_PLATFORM_IS_LOONGARCH 1 +#if __loongarch_grlen == 64 +#define TR_PLATFORM_IS_LOONGARCH64 1 +#else +#define TR_PLATFORM_IS_LOONGARCH32 1 +#endif + +#elif defined(__riscv) +#define TR_PLATFORM_IS_RISCV 1 +#if __riscv_xlen == 32 +#define TR_PLATFORM_IS_RISCV32 1 +#else +#define TR_PLATFORM_IS_RISCV64 1 +#endif + +#elif defined(__mips__) +#define TR_PLATFORM_IS_MIPS 1 +#if _MIPS_SIM == _ABIO32 +#define TR_PLATFORM_IS_MIPS32 1 +#else +#define TR_PLATFORM_IS_MIPS64 1 +#endif + +#elif defined(__s390__) +#define TR_PLATFORM_IS_S390 1 +#elif defined(__s390x__) +#define TR_PLATFORM_IS_S390X 1 + +#elif defined(__PPC__) +#define TR_PLATFORM_IS_PPC 1 +#elif defined(__PPC64__) +#define TR_PLATFORM_IS_PPC64 1 + +#elif defined(__wasm32__) +#define TR_PLATFORM_IS_WASM32 1 +#elif defined(__wasm64__) +#define TR_PLATFORM_IS_WASM64 1 + +#else +#error "Unsupported platform." +#endif + +// Define platform macros for pointer width: +// +// - 64_BIT +// - 32_BIT +#if defined(TR_PLATFORM_IS_X86_64) || defined(TR_PLATFORM_IS_ARM64) || \ + defined(TR_PLATFORM_IS_RISCV64) || defined(TR_PLATFORM_IS_MIPS64) || \ + defined(TR_PLATFORM_IS_S390X) || defined(TR_PLATFORM_IS_PPC64) || \ + defined(TR_PLATFORM_IS_LOONGARCH64) || defined(TR_PLATFORM_IS_WASM64) +#define TR_PLATFORM_IS_64_BIT 1 +static_assert(sizeof(sizeof(char)) == 8, "Expect sizeof(size_t) == 8"); +#elif defined(TR_PLATFORM_IS_I386) || defined(TR_PLATFORM_IS_ARM32) || \ + defined(TR_PLATFORM_IS_RISCV32) || defined(TR_PLATFORM_IS_MIPS32) || \ + defined(TR_PLATFORM_IS_S390) || defined(TR_PLATFORM_IS_PPC32) || \ + defined(TR_PLATFORM_IS_LOONGARCH32) || defined(TR_PLATFORM_IS_WASM32) +#define TR_PLATFORM_IS_32_BIT 1 +static_assert(sizeof(sizeof(char)) == 4, "Expect sizeof(size_t) == 4"); +#else +#error "Unsupported platform" +#endif + +// This section define other platform macros to 0 to avoid undefined macro usage error. +#if !defined(TR_PLATFORM_IS_WINDOWS) +#define TR_PLATFORM_IS_WINDOWS 0 +#endif +#if !defined(TR_PLATFORM_IS_WIN32) +#define TR_PLATFORM_IS_WIN32 0 +#endif +#if !defined(TR_PLATFORM_IS_WINUWP) +#define TR_PLATFORM_IS_WINUWP 0 +#endif + +#if !defined(TR_PLATFORM_IS_POSIX) +#define TR_PLATFORM_IS_POSIX 0 +#endif + +#if !defined(TR_PLATFORM_IS_LINUX) +#define TR_PLATFORM_IS_LINUX 0 +#endif +#if !defined(TR_PLATFORM_IS_ANDROID) +#define TR_PLATFORM_IS_ANDROID 0 +#endif +#if !defined(TR_PLATFORM_IS_CHROMEOS) +#define TR_PLATFORM_IS_CHROMEOS 0 +#endif +#if !defined(TR_PLATFORM_IS_LINUX_DESKTOP) +#define TR_PLATFORM_IS_LINUX_DESKTOP 0 +#endif + +#if !defined(TR_PLATFORM_IS_APPLE) +#define TR_PLATFORM_IS_APPLE 0 +#endif +#if !defined(TR_PLATFORM_IS_IOS) +#define TR_PLATFORM_IS_IOS 0 +#endif +#if !defined(TR_PLATFORM_IS_MACOS) +#define TR_PLATFORM_IS_MACOS 0 +#endif + +#if !defined(TR_PLATFORM_IS_FUCHSIA) +#define TR_PLATFORM_IS_FUCHSIA 0 +#endif +#if !defined(TR_PLATFORM_IS_EMSCRIPTEN) +#define TR_PLATFORM_IS_EMSCRIPTEN 0 +#endif + +#if !defined(TR_PLATFORM_IS_X86) +#define TR_PLATFORM_IS_X86 0 +#endif +#if !defined(TR_PLATFORM_IS_I386) +#define TR_PLATFORM_IS_I386 0 +#endif +#if !defined(TR_PLATFORM_IS_X86_64) +#define TR_PLATFORM_IS_X86_64 0 +#endif + +#if !defined(TR_PLATFORM_IS_ARM) +#define TR_PLATFORM_IS_ARM 0 +#endif +#if !defined(TR_PLATFORM_IS_ARM32) +#define TR_PLATFORM_IS_ARM32 0 +#endif +#if !defined(TR_PLATFORM_IS_ARM64) +#define TR_PLATFORM_IS_ARM64 0 +#endif + +#if !defined(TR_PLATFORM_IS_LOONGARCH) +#define TR_PLATFORM_IS_LOONGARCH 0 +#endif +#if !defined(TR_PLATFORM_IS_LOONGARCH32) +#define TR_PLATFORM_IS_LOONGARCH32 0 +#endif +#if !defined(TR_PLATFORM_IS_LOONGARCH64) +#define TR_PLATFORM_IS_LOONGARCH64 0 +#endif + +#if !defined(TR_PLATFORM_IS_RISCV) +#define TR_PLATFORM_IS_RISCV 0 +#endif +#if !defined(TR_PLATFORM_IS_RISCV32) +#define TR_PLATFORM_IS_RISCV32 0 +#endif +#if !defined(TR_PLATFORM_IS_RISCV64) +#define TR_PLATFORM_IS_RISCV64 0 +#endif + +#if !defined(TR_PLATFORM_IS_MIPS) +#define TR_PLATFORM_IS_MIPS 0 +#endif +#if !defined(TR_PLATFORM_IS_MIPS32) +#define TR_PLATFORM_IS_MIPS32 0 +#endif +#if !defined(TR_PLATFORM_IS_MIPS64) +#define TR_PLATFORM_IS_MIPS64 0 +#endif + +#if !defined(TR_PLATFORM_IS_S390) +#define TR_PLATFORM_IS_S390 0 +#endif +#if !defined(TR_PLATFORM_IS_S390X) +#define TR_PLATFORM_IS_S390X 0 +#endif + +#if !defined(TR_PLATFORM_IS_PPC) +#define TR_PLATFORM_IS_PPC 0 +#endif +#if !defined(TR_PLATFORM_IS_PPC64) +#define TR_PLATFORM_IS_PPC64 0 +#endif + +#if !defined(TR_PLATFORM_IS_WASM32) +#define TR_PLATFORM_IS_WASM32 0 +#endif +#if !defined(TR_PLATFORM_IS_WASM64) +#define TR_PLATFORM_IS_WASM64 0 +#endif + +#if !defined(TR_PLATFORM_IS_64_BIT) +#define TR_PLATFORM_IS_64_BIT 0 +#endif +#if !defined(TR_PLATFORM_IS_32_BIT) +#define TR_PLATFORM_IS_32_BIT 0 +#endif diff --git a/src/common/utility.hpp b/src/common/utility.hpp index 9dfbbf633..9e8a963ad 100644 --- a/src/common/utility.hpp +++ b/src/common/utility.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #ifndef TR_UNLIKELY @@ -252,4 +253,20 @@ namespace transmute::common template concept derived_from = std::derived_from; #endif + + inline std::pair GetEnvironmentVar(const char *variableName) + { + char *value = getenv(variableName); + return value == nullptr ? std::make_pair(std::string(), false) + : std::make_pair(std::string(value), true); + } + + inline bool SetEnvironmentVar(const char *variableName, const char *value) + { + if (value == nullptr) + { + return unsetenv(variableName) == 0; + } + return setenv(variableName, value, 1) == 0; + } } diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp index 1eecb6990..2576ccc8e 100644 --- a/src/renderer/gles/gpu_device_impl.hpp +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -5,19 +5,18 @@ namespace gles { - class GPUQueueImpl : public commandbuffers::gpu::GPUQueue + class GPUDeviceImpl final : public commandbuffers::GPUDeviceBase { - public: - GPUQueueImpl(); - void submit(const std::vector> &) override; - }; + private: + GPUDeviceImpl(); - class GPUDeviceImpl : public commandbuffers::gpu::GPUDeviceBase - { public: - GPUDeviceImpl(); + commandbuffers::GPUHandleType type() const override + { + return commandbuffers::GPUHandleType::kDevice; + } public: - std::unique_ptr createCommandEncoder(std::optional label) override; + std::unique_ptr createCommandEncoder(std::optional label) override; }; } From 00ac3ac509ca4301646e23e82b40575358ade234 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Mon, 3 Nov 2025 23:04:02 +0800 Subject: [PATCH 05/37] update common errors --- .../command_buffers/gpu/gpu_adapter.hpp | 1 + src/common/command_buffers/gpu/gpu_base.cpp | 24 ++- src/common/command_buffers/gpu/gpu_base.hpp | 84 ++++++++++- .../gpu/gpu_bind_group_layout.cpp | 2 +- .../gpu/gpu_command_buffer.cpp | 7 +- .../gpu/gpu_command_buffer.hpp | 12 +- .../gpu/gpu_command_encoder.hpp | 17 +-- .../command_buffers/gpu/gpu_constants.hpp | 24 +++ src/common/command_buffers/gpu/gpu_device.hpp | 2 +- .../command_buffers/gpu/gpu_instance.cpp | 4 +- .../command_buffers/gpu/gpu_instance.hpp | 12 +- .../gpu/gpu_pass_encoder_base.cpp | 1 + .../gpu/gpu_pass_encoder_base.hpp | 3 +- .../gpu/gpu_renderpass_encoder.hpp | 96 ++++-------- .../command_buffers/gpu/gpu_texture.hpp | 140 +----------------- .../command_buffers/gpu/gpu_texture_view.hpp | 48 ++++-- 16 files changed, 233 insertions(+), 244 deletions(-) diff --git a/src/common/command_buffers/gpu/gpu_adapter.hpp b/src/common/command_buffers/gpu/gpu_adapter.hpp index 89cfb8a9b..426b08060 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.hpp +++ b/src/common/command_buffers/gpu/gpu_adapter.hpp @@ -11,6 +11,7 @@ namespace commandbuffers { class GPUInstanceBase; class GPUPhysicalDeviceBase; + struct GPUDeviceDescriptor; class GPUAdapterInfo { diff --git a/src/common/command_buffers/gpu/gpu_base.cpp b/src/common/command_buffers/gpu/gpu_base.cpp index c8568bf45..439cb12e5 100644 --- a/src/common/command_buffers/gpu/gpu_base.cpp +++ b/src/common/command_buffers/gpu/gpu_base.cpp @@ -6,6 +6,20 @@ using namespace std; namespace commandbuffers { + bool GPUExtent2D::operator==(const GPUExtent2D &rhs) const + { + const auto &lhs = std::tie(width, height); + return lhs == std::tie(rhs.width, rhs.height); + } + + bool GPUExtent3D::operator==(const GPUExtent3D &rhs) const + { + const auto &lhs = std::tie(width, height, depthOrArrayLayers); + return lhs == std::tie(rhs.width, + rhs.height, + rhs.depthOrArrayLayers); + } + // // ErrorMonad Implementation // @@ -76,7 +90,7 @@ namespace commandbuffers GPUInstanceBase *GPUObject::instance() const { - return device_->instance(); + return device_->getInstance(); } shared_ptr GPUObject::device() const @@ -90,7 +104,7 @@ namespace commandbuffers GPUHandle::GPUHandle(shared_ptr device, string_view label) : GPUObject(device) - , id_(Ids.get()) + , id(Ids.get()) , label_(string(label)) { } @@ -99,7 +113,7 @@ namespace commandbuffers ErrorTag tag, string_view label) : GPUObject(device, tag) - , id_(Ids.get()) + , id(Ids.get()) , label_(string(label)) { } @@ -108,14 +122,14 @@ namespace commandbuffers DelayedInitializationTag tag, string_view label) : GPUObject(device, tag) - , id_(Ids.get()) + , id(Ids.get()) , label_(string(label)) { } GPUHandle::GPUHandle(shared_ptr device, LabelNotImplementedTag tag) : GPUObject(device) - , id_(Ids.get()) + , id(Ids.get()) { } diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 692c0812a..2fc11c621 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -47,6 +47,47 @@ namespace commandbuffers using GPUBindGroupIndex = uint32_t; constexpr GPUBindGroupIndex kMaxBindGroupsTyped = GPUBindGroupIndex(gpu_constants::kMaxBindGroups); + struct GPUExtent2D + { + uint32_t width; + uint32_t height; + + // Equality operators, mostly for testing. Note that this tests + // strict pointer-pointer equality if the struct contains member pointers. + bool operator==(const GPUExtent2D &rhs) const; + }; + + struct GPUExtent3D + { + uint32_t width; + uint32_t height = 1; + uint32_t depthOrArrayLayers = 1; + + // Equality operators, mostly for testing. Note that this tests + // strict pointer-pointer equality if the struct contains member pointers. + bool operator==(const GPUExtent3D &rhs) const; + }; + + enum class GPUComponentSwizzle : uint32_t + { + kUndefined, + kZero, + kOne, + kR, + kG, + kB, + kA, + }; + + enum class GPUCompositeAlphaMode : uint32_t + { + kAuto, + kOpaque, + kPremultiplied, + kUnpremultiplied, + kInherit, + }; + enum class GPUHandleType : uint32_t { kAdapter, @@ -135,6 +176,29 @@ namespace commandbuffers kComparison, }; + enum class GPUTextureAspect : uint32_t + { + kUndefined, + kAll, + kStencilOnly, + kDepthOnly, + kPlane0Only, + kPlane1Only, + kPlane2Only, + }; + + enum class GPUTextureUsage : uint64_t + { + kNone, + kCopySrc, + kCopyDst, + kTextureBinding, + kStorageBinding, + kRenderAttachment, + kTransientAttachment, + kStorageAttachment, + }; + enum class GPUTextureSampleType : uint32_t { kBindingNotUsed, @@ -146,6 +210,14 @@ namespace commandbuffers kUint, }; + enum class GPUTextureDimension : uint32_t + { + kUndefined, + k1D, + k2D, + k3D, + }; + enum class GPUTextureViewDimension : uint32_t { kUndefined, @@ -277,6 +349,14 @@ namespace commandbuffers kExternal, }; + struct GPUTextureComponentSwizzle + { + GPUComponentSwizzle r = GPUComponentSwizzle::kUndefined; + GPUComponentSwizzle g = GPUComponentSwizzle::kUndefined; + GPUComponentSwizzle b = GPUComponentSwizzle::kUndefined; + GPUComponentSwizzle a = GPUComponentSwizzle::kUndefined; + }; + enum class GPUStorageTextureAccess : uint32_t { kBindingNotUsed, @@ -435,8 +515,10 @@ namespace commandbuffers void setLabel(std::string label); const std::string &getLabel() const; + public: + const GPUIdentifier id; + private: std::string label_ = ""; - const GPUIdentifier id_; }; } diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp b/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp index 75d74347a..8ca9755c6 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp @@ -25,7 +25,7 @@ namespace commandbuffers } bool GPUBindGroupLayoutBase::equal(const GPUBindGroupLayoutBase *other, - bool excludePipelineCompatibiltyToken = false) const + bool excludePipelineCompatibiltyToken) const { return getInternalBindGroupLayout() == other->getInternalBindGroupLayout(); } diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.cpp b/src/common/command_buffers/gpu/gpu_command_buffer.cpp index 8501dae93..991abe251 100644 --- a/src/common/command_buffers/gpu/gpu_command_buffer.cpp +++ b/src/common/command_buffers/gpu/gpu_command_buffer.cpp @@ -1,10 +1,11 @@ #include +#include using namespace std; namespace commandbuffers { - GPUCommandBufferBase::GPUCommandBufferBase(GPUCommandEncoderBase *encoder, + GPUCommandBufferBase::GPUCommandBufferBase(GPUCommandEncoder *encoder, const GPUCommandBufferDescriptor *descriptor) : GPUHandle(encoder->device(), descriptor->label) { @@ -27,12 +28,12 @@ namespace commandbuffers encoder_label_ = move(encoderLabel); } - const GPUCommandBufferResourceUsage &GPUCommandBufferBase::getResourceUsages() const + const gpu::CommandBufferResourceUsage &GPUCommandBufferBase::getResourceUsages() const { return resource_usages_; } - const vector &GPUCommandBufferBase::getIndirectDrawMetadata() + const vector &GPUCommandBufferBase::getIndirectDrawMetadata() { return indirect_draw_metadata_; } diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.hpp b/src/common/command_buffers/gpu/gpu_command_buffer.hpp index 7ed6c2d2a..c3a231dd1 100644 --- a/src/common/command_buffers/gpu/gpu_command_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_command_buffer.hpp @@ -9,13 +9,13 @@ #include #include #include -#include #include #include #include namespace commandbuffers { + class GPUCommandEncoder; struct GPUCommandBufferDescriptor { std::string_view label; @@ -27,7 +27,7 @@ namespace commandbuffers friend class GPURenderPassEncoderBase; public: - GPUCommandBufferBase(GPUCommandEncoderBase *encoder, + GPUCommandBufferBase(GPUCommandEncoder *encoder, const GPUCommandBufferDescriptor *descriptor); virtual ~GPUCommandBufferBase() = default; @@ -39,8 +39,8 @@ namespace commandbuffers const std::string &getEncoderLabel() const; void setEncoderLabel(std::string encoderLabel); - const GPUCommandBufferResourceUsage &getResourceUsages() const; - const std::vector &getIndirectDrawMetadata(); + const gpu::CommandBufferResourceUsage &getResourceUsages() const; + const std::vector &getIndirectDrawMetadata(); template auto useCommands(F func) -> auto @@ -58,8 +58,8 @@ namespace commandbuffers GPUHandle::ErrorTag tag, std::string_view label); - GPUCommandBufferResourceUsage resource_usages_; - std::vector indirect_draw_metadata_; + gpu::CommandBufferResourceUsage resource_usages_; + std::vector indirect_draw_metadata_; std::string encoder_label_; }; } diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index 9c3ba0792..775e84152 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -3,10 +3,11 @@ #include #include -#include "./gpu_base.hpp" -#include "./gpu_command_buffer.hpp" -#include "./gpu_pass_encoder_base.hpp" -#include "./gpu_renderpass_encoder.hpp" +#include +#include +#include +#include +#include namespace commandbuffers { @@ -24,8 +25,6 @@ namespace commandbuffers class GPUCommandEncoder final : public GPUHandle { public: - virtual ~GPUCommandEncoder() = default; - GPUHandleType type() const override { return GPUHandleType::kCommandEncoder; @@ -33,8 +32,8 @@ namespace commandbuffers public: // TODO(yorkie): begineComputePass - virtual GPURenderPassEncoderBase beginRenderPass(GPURenderPassDescriptor &) = 0; - virtual std::unique_ptr finish(std::optional label = std::nullopt) const = 0; + GPURenderPassEncoderBase beginRenderPass(GPURenderPassDescriptor &); + std::unique_ptr finish(std::optional label = std::nullopt) const; private: GPUCommandEncoder(std::shared_ptr device, const GPUCommandEncoderDescriptor &descriptor); @@ -44,7 +43,7 @@ namespace commandbuffers bool validateFinish() const; - GPUEncodingContext encoding_context_; + gpu::EncodingContext encoding_context_; std::unordered_set top_level_buffers_; std::unordered_set top_level_textures_; // std::unordered_set used_query_sets_; diff --git a/src/common/command_buffers/gpu/gpu_constants.hpp b/src/common/command_buffers/gpu/gpu_constants.hpp index 144fb97a2..2ca90fa03 100644 --- a/src/common/command_buffers/gpu/gpu_constants.hpp +++ b/src/common/command_buffers/gpu/gpu_constants.hpp @@ -29,6 +29,18 @@ #include +#define WGPU_ARRAY_LAYER_COUNT_UNDEFINED (UINT32_MAX) +#define WGPU_COPY_STRIDE_UNDEFINED (UINT32_MAX) +#define WGPU_DEPTH_CLEAR_VALUE_UNDEFINED (NAN) +#define WGPU_DEPTH_SLICE_UNDEFINED (UINT32_MAX) +#define WGPU_LIMIT_U32_UNDEFINED (UINT32_MAX) +#define WGPU_LIMIT_U64_UNDEFINED (UINT64_MAX) +#define WGPU_MIP_LEVEL_COUNT_UNDEFINED (UINT32_MAX) +#define WGPU_QUERY_SET_INDEX_UNDEFINED (UINT32_MAX) +#define WGPU_STRLEN (SIZE_MAX) +#define WGPU_WHOLE_MAP_SIZE (SIZE_MAX) +#define WGPU_WHOLE_SIZE (UINT64_MAX) + namespace commandbuffers::gpu_constants { static constexpr uint32_t kMaxBindGroups = 4u; @@ -43,4 +55,16 @@ namespace commandbuffers::gpu_constants static constexpr uint32_t kQueryResolveAlignment = 256u; static constexpr uint32_t kMaxInterStageShaderVariables = 16u; static constexpr uint64_t kAssumedMaxBufferSize = 0x80000000u; // Use 2 GB when the limit is unavailable + + static constexpr uint32_t kArrayLayerCountUndefined = WGPU_ARRAY_LAYER_COUNT_UNDEFINED; + static constexpr uint32_t kCopyStrideUndefined = WGPU_COPY_STRIDE_UNDEFINED; + static constexpr float kDepthClearValueUndefined = std::numeric_limits::quiet_NaN(); + static constexpr uint32_t kDepthSliceUndefined = WGPU_DEPTH_SLICE_UNDEFINED; + static constexpr uint32_t kLimitU32Undefined = WGPU_LIMIT_U32_UNDEFINED; + static constexpr uint64_t kLimitU64Undefined = WGPU_LIMIT_U64_UNDEFINED; + static constexpr uint32_t kMipLevelCountUndefined = WGPU_MIP_LEVEL_COUNT_UNDEFINED; + static constexpr uint32_t kQuerySetIndexUndefined = WGPU_QUERY_SET_INDEX_UNDEFINED; + static constexpr size_t kStrlen = WGPU_STRLEN; + static constexpr size_t kWholeMapSize = WGPU_WHOLE_MAP_SIZE; + static constexpr uint64_t kWholeSize = WGPU_WHOLE_SIZE; }; diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index d65d5df96..df439c93b 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -24,7 +24,7 @@ namespace commandbuffers GPUSupportedLimits *requiredLimits = nullptr; }; - class GPUDeviceBase : public GPUHandle + class GPUDeviceBase { public: GPUDeviceBase(GPUAdapterBase *adapter, diff --git a/src/common/command_buffers/gpu/gpu_instance.cpp b/src/common/command_buffers/gpu/gpu_instance.cpp index 8c3091ca9..d6c2dd4ff 100644 --- a/src/common/command_buffers/gpu/gpu_instance.cpp +++ b/src/common/command_buffers/gpu/gpu_instance.cpp @@ -4,7 +4,7 @@ using namespace std; namespace commandbuffers { - unique_ptr GPUInstanceBase::Create(const GPUInstanceDescriptor *descriptor) + unique_ptr GPUInstanceBase::Create(const GPUInstanceDescriptor *descriptor) { static constexpr GPUInstanceDescriptor kDefaultDesc = {}; if (descriptor == nullptr) @@ -12,7 +12,7 @@ namespace commandbuffers descriptor = &kDefaultDesc; } - auto instance = make_unique(); + auto instance = unique_ptr(new GPUInstanceBase()); instance->initialize(*descriptor); return instance; } diff --git a/src/common/command_buffers/gpu/gpu_instance.hpp b/src/common/command_buffers/gpu/gpu_instance.hpp index 7dd7ea530..3c99a8578 100644 --- a/src/common/command_buffers/gpu/gpu_instance.hpp +++ b/src/common/command_buffers/gpu/gpu_instance.hpp @@ -17,8 +17,18 @@ namespace commandbuffers class GPUInstanceBase { + private: + // Custom deleter for `unique_ptr` + struct Deleter + { + void operator()(GPUInstanceBase *ptr) + { + delete ptr; + } + }; + public: - static std::unique_ptr Create(const GPUInstanceDescriptor *descriptor = nullptr); + static std::unique_ptr Create(const GPUInstanceDescriptor *descriptor = nullptr); void addDevice(std::shared_ptr); void removeDevice(std::shared_ptr); diff --git a/src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp b/src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp index 9b55f6835..5474209bf 100644 --- a/src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp +++ b/src/common/command_buffers/gpu/gpu_pass_encoder_base.cpp @@ -1,4 +1,5 @@ #include +#include namespace commandbuffers { diff --git a/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp b/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp index bbf8b4eb7..7d3ba02bc 100644 --- a/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp +++ b/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp @@ -2,10 +2,11 @@ #include #include -#include "./gpu_command_buffer.hpp" namespace commandbuffers { + class GPUCommandBufferBase; + class GPUPassEncoderBase { public: diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp index 459d153f9..f14620c59 100644 --- a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp @@ -3,12 +3,12 @@ #include #include -#include "./gpu_base.hpp" -#include "./gpu_pass_encoder_base.hpp" -#include "./gpu_buffer.hpp" -#include "./gpu_command_buffer.hpp" -#include "./gpu_pipeline.hpp" -#include "./gpu_texture_view.hpp" +#include +#include +#include +#include +#include +#include namespace commandbuffers { @@ -61,76 +61,32 @@ namespace commandbuffers public GPUHandle { public: - GPURenderPassEncoderBase(std::string label) - : GPUPassEncoderBase() - , GPUHandle(label) + GPUHandleType type() const override final { + return GPUHandleType::kRenderPassEncoder; } - - public: bool isRenderPassEncoder() const override { return true; } - void draw(uint32_t vertex_count, - uint32_t instance_count = 1, - uint32_t first_vertex = 0, - uint32_t first_instance = 0) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(vertex_count, - instance_count, - first_vertex, - first_instance); - } - void drawIndexed(uint32_t index_count, - uint32_t instance_count = 1, - uint32_t first_index = 0, - int32_t base_vertex = 0, - uint32_t first_instance = 0) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(index_count, - instance_count, - first_index, - base_vertex, - first_instance); - } - void setViewport(float x, float y, float width, float height, float min_depth = 0.0f, float max_depth = 1.0f) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(x, y, width, height, min_depth, max_depth); - } - void setScissorRect(float x, float y, float width, float height) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(x, y, width, height); - } - void setPipeline(const GPURenderPipelineBase &pipeline) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(pipeline); - } - void setIndexBuffer(const GPUBufferBase &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(buffer, index_format, offset, size); - } - void setVertexBuffer(uint32_t slot, const GPUBufferBase &buffer, uint32_t offset = 0, uint32_t size = 0) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(slot, buffer, offset, size); - } - void setBlendConstant(float r, float g, float b, float a) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(r, g, b, a); - } - void setStencilReference(uint32_t ref) - { - if (!ended_) [[likely]] - command_buffer_->addCommand(ref); - } + void draw( + uint32_t vertex_count, + uint32_t instance_count = 1, + uint32_t first_vertex = 0, + uint32_t first_instance = 0); + void drawIndexed( + uint32_t index_count, + uint32_t instance_count = 1, + uint32_t first_index = 0, + int32_t base_vertex = 0, + uint32_t first_instance = 0); + void setViewport(float x, float y, float width, float height, float min_depth = 0.0f, float max_depth = 1.0f); + void setScissorRect(float x, float y, float width, float height); + void setPipeline(const GPURenderPipelineBase &pipeline); + void setIndexBuffer(const GPUBufferBase &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size); + void setVertexBuffer(uint32_t slot, const GPUBufferBase &buffer, uint32_t offset = 0, uint32_t size = 0); + void setBlendConstant(float r, float g, float b, float a); + void setStencilReference(uint32_t ref); }; } diff --git a/src/common/command_buffers/gpu/gpu_texture.hpp b/src/common/command_buffers/gpu/gpu_texture.hpp index fd077effc..12e7c4963 100644 --- a/src/common/command_buffers/gpu/gpu_texture.hpp +++ b/src/common/command_buffers/gpu/gpu_texture.hpp @@ -1,150 +1,22 @@ #pragma once -#include "./gpu_base.hpp" +#include namespace commandbuffers { - enum class GPUTextureFormat - { - // 8-bit formats - kR8UNORM, - kR8SNORM, - kR8UINT, - kR8SINT, - - // 16-bit formats - kR16UNORM, - kR16SNORM, - kR16UINT, - kR16SINT, - kR16FLOAT, - kRG8UNORM, - kRG8SNORM, - kRG8UINT, - kRG8SINT, - - // 32-bit formats - kR32UINT, - kR32SINT, - kR32FLOAT, - kRG16UNORM, - kRG16SNORM, - kRG16UINT, - kRG16SINT, - kRG16FLOAT, - kRGBA8UNORM, - kRGBA8UNORM_SRGB, - kRGBA8SNORM, - kRGBA8UINT, - kRGBA8SINT, - kBGRA8UNORM, - kBGRA8UNORM_SRGB, - - // Packed 32-bit formats - kRGB9E5UFLOAT, - kRGB10A2UINT, - kRGB10A2UNORM, - kRG11B10UFLOAT, - - // 64-bit formats - kRG32UINT, - kRG32SINT, - kRG32FLOAT, - kRGBA16UNORM, - kRGBA16SNORM, - kRGBA16UINT, - kRGBA16SINT, - kRGBA16FLOAT, - - // 128-bit formats - kRGBA32UINT, - kRGBA32SINT, - kRGBA32FLOAT, - - // Depth/stencil formats - kSTENCIL8, - kDEPTH16UNORM, - kDEPTH24PLUS, - kDEPTH24PLUS_STENCIL8, - kDEPTH32FLOAT, - kDEPTH32FLOAT_STENCIL8, - - // BC compressed formats - kBC1_RGBA_UNORM, - kBC1_RGBA_UNORM_SRGB, - kBC2_RGBA_UNORM, - kBC2_RGBA_UNORM_SRGB, - kBC3_RGBA_UNORM, - kBC3_RGBA_UNORM_SRGB, - kBC4_R_UNORM, - kBC4_R_SNORM, - kBC5_RG_UNORM, - kBC5_RG_SNORM, - kBC6H_RGB_UFLOAT, - kBC6H_RGB_FLOAT, - kBC7_RGBA_UNORM, - kBC7_RGBA_UNORM_SRGB, - - // ETC2 compressed formats - kETC2_RGB8UNORM, - kETC2_RGB8UNORM_SRGB, - kETC2_RGB8A1UNORM, - kETC2_RGB8A1UNORM_SRGB, - kETC2_RGBA8UNORM, - kETC2_RGBA8UNORM_SRGB, - kEAC_R11UNORM, - kEAC_R11SNORM, - kEAC_RG11UNORM, - kEAC_RG11SNORM, - - // ASTC compressed formats - kASTC_4x4_UNORM, - kASTC_4x4_UNORM_SRGB, - kASTC_5x4_UNORM, - kASTC_5x4_UNORM_SRGB, - kASTC_5x5_UNORM, - kASTC_5x5_UNORM_SRGB, - kASTC_6x5_UNORM, - kASTC_6x5_UNORM_SRGB, - kASTC_6x6_UNORM, - kASTC_6x6_UNORM_SRGB, - kASTC_8x5_UNORM, - kASTC_8x5_UNORM_SRGB, - kASTC_8x6_UNORM, - kASTC_8x6_UNORM_SRGB, - kASTC_8x8_UNORM, - kASTC_8x8_UNORM_SRGB, - kASTC_10x5_UNORM, - kASTC_10x5_UNORM_SRGB, - kASTC_10x6_UNORM, - kASTC_10x6_UNORM_SRGB, - kASTC_10x8_UNORM, - kASTC_10x8_UNORM_SRGB, - kASTC_10x10_UNORM, - kASTC_10x10_UNORM_SRGB, - kASTC_12x10_UNORM, - kASTC_12x10_UNORM_SRGB, - kASTC_12x12_UNORM, - kASTC_12x12_UNORM_SRGB - }; - - enum class GPUTextureDimension - { - kTexture1D, - kTexture2D, - kTexture3D, - }; + class GPUTextureViewBase; class GPUTextureBase : public GPUHandle { public: private: - uint32_t width_; - uint32_t height_; - uint32_t depth_or_array_layers_; + GPUExtent3D base_size_; GPUTextureDimension dimension_; GPUTextureFormat format_; uint32_t mip_level_count_; uint32_t sample_count_; + GPUTextureUsage usage_ = GPUTextureUsage::kNone; + GPUTextureUsage internal_usage_ = GPUTextureUsage::kNone; + GPUTextureViewBase *default_view_ = nullptr; }; } diff --git a/src/common/command_buffers/gpu/gpu_texture_view.hpp b/src/common/command_buffers/gpu/gpu_texture_view.hpp index a3a1a1526..6e57e4305 100644 --- a/src/common/command_buffers/gpu/gpu_texture_view.hpp +++ b/src/common/command_buffers/gpu/gpu_texture_view.hpp @@ -1,24 +1,52 @@ #pragma once #include +#include #include - -#include "./gpu_texture.hpp" +#include +#include namespace commandbuffers { + struct TextureViewDescriptor + { + std::string_view label; + GPUTextureFormat format = GPUTextureFormat::kUndefined; + GPUTextureViewDimension dimension = GPUTextureViewDimension::kUndefined; + uint32_t baseMipLevel = 0; + uint32_t mipLevelCount = gpu_constants::kMipLevelCountUndefined; + uint32_t baseArrayLayer = 0; + uint32_t arrayLayerCount = gpu_constants::kArrayLayerCountUndefined; + GPUTextureAspect aspect = GPUTextureAspect::kAll; + GPUTextureUsage usage = GPUTextureUsage::kNone; + }; + class GPUTextureViewBase : public GPUHandle { public: - const GPUTexture &textureRef() const - { - auto texture = texture_.lock(); - if (!texture) - throw std::runtime_error("GPUTextureView: Texture has been destroyed."); - return *texture; - } + GPUTextureViewBase(std::shared_ptr texture, const TextureViewDescriptor &descriptor); + + std::shared_ptr texture() const; + const GPUTextureBase &textureRef() const; + + GPUTextureViewDimension dimension() const; + uint32_t getBaseMipLevel() const; + uint32_t getLevelCount() const; + uint32_t getBaseArrayLayer() const; + uint32_t getLayerCount() const; + + GPUTextureComponentSwizzle getSwizzle() const; + bool isSwizzleIdentity() const; private: - std::weak_ptr texture_; + std::shared_ptr texture_; + GPUTextureViewDimension dimension_; + GPUTextureUsage usage_ = GPUTextureUsage::kNone; + GPUTextureUsage internal_usage_ = GPUTextureUsage::kNone; + GPUComponentSwizzle swizzle_red_ = GPUComponentSwizzle::kR; + GPUComponentSwizzle swizzle_green_ = GPUComponentSwizzle::kG; + GPUComponentSwizzle swizzle_blue_ = GPUComponentSwizzle::kB; + GPUComponentSwizzle swizzle_alpha_ = GPUComponentSwizzle::kA; + bool is_swizzle_identity_ = false; }; } From 648a38e6c377bf8c7751bd41971a34a8a3762629 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 4 Nov 2025 17:41:41 +0800 Subject: [PATCH 06/37] update --- src/common/command_buffers/gpu/gpu_base.hpp | 257 +++++++++++++++++- .../gpu/gpu_command_encoder.hpp | 2 +- .../command_buffers/gpu/gpu_commands.hpp | 8 +- .../gpu/gpu_compute_pipeline.cpp | 1 + .../gpu/gpu_compute_pipeline.hpp | 10 + .../command_buffers/gpu/gpu_pipeline.cpp | 26 ++ .../command_buffers/gpu/gpu_pipeline.hpp | 38 +-- .../gpu/gpu_render_pipeline.cpp | 15 + .../gpu/gpu_render_pipeline.hpp | 28 ++ .../gpu/gpu_renderpass_encoder.hpp | 4 +- src/renderer/gles/context_app.hpp | 1 - src/renderer/gles/gpu_command_buffer_impl.cpp | 37 +-- src/renderer/gles/gpu_command_buffer_impl.hpp | 9 +- .../gles/gpu_command_encoder_impl.cpp | 54 ---- .../gles/gpu_command_encoder_impl.hpp | 24 -- src/renderer/gles/gpu_device_impl.cpp | 27 +- src/renderer/gles/gpu_device_impl.hpp | 12 +- src/renderer/gles/gpu_pipeline_impl.cpp | 9 + src/renderer/gles/gpu_pipeline_impl.hpp | 11 +- .../gles/gpu_renderpass_encoder_impl.cpp | 24 -- .../gles/gpu_renderpass_encoder_impl.hpp | 25 -- src/renderer/render_api.hpp | 7 +- 22 files changed, 393 insertions(+), 236 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_compute_pipeline.cpp create mode 100644 src/common/command_buffers/gpu/gpu_compute_pipeline.hpp create mode 100644 src/common/command_buffers/gpu/gpu_pipeline.cpp create mode 100644 src/common/command_buffers/gpu/gpu_render_pipeline.cpp create mode 100644 src/common/command_buffers/gpu/gpu_render_pipeline.hpp delete mode 100644 src/renderer/gles/gpu_command_encoder_impl.cpp delete mode 100644 src/renderer/gles/gpu_command_encoder_impl.hpp create mode 100644 src/renderer/gles/gpu_pipeline_impl.cpp delete mode 100644 src/renderer/gles/gpu_renderpass_encoder_impl.cpp delete mode 100644 src/renderer/gles/gpu_renderpass_encoder_impl.hpp diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 2fc11c621..1f082bdb4 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -47,6 +47,12 @@ namespace commandbuffers using GPUBindGroupIndex = uint32_t; constexpr GPUBindGroupIndex kMaxBindGroupsTyped = GPUBindGroupIndex(gpu_constants::kMaxBindGroups); + struct GPUConstantEntry + { + std::string_view key; + double value; + }; + struct GPUExtent2D { uint32_t width; @@ -68,6 +74,90 @@ namespace commandbuffers bool operator==(const GPUExtent3D &rhs) const; }; + enum class GPUPrimitiveTopology : uint32_t + { + kUndefined, + kPointList, + kLineList, + kLineStrip, + kTriangleList, + kTriangleStrip, + }; + + enum class GPUIndexFormat : uint32_t + { + kUndefined, + kUint16, + kUint32, + }; + + enum class GPUFrontFace : uint32_t + { + kUndefined, + kCCW, + kCW, + }; + + enum class GPUCullMode : uint32_t + { + kUndefined, + kNone, + kFront, + kBack, + }; + + enum class GPUVertexStepMode : uint32_t + { + kUndefined, + kVertex, + kInstance, + }; + + enum class GPUVertexFormat : uint32_t + { + kUint8, + kUint8x2, + kUint8x4, + kSint8, + kSint8x2, + kSint8x4, + kUnorm8, + kUnorm8x2, + kUnorm8x4, + kSnorm8, + kSnorm8x2, + kSnorm8x4, + kUint16, + kUint16x2, + kUint16x4, + kSint16, + kSint16x2, + kSint16x4, + kUnorm16, + kUnorm16x2, + kUnorm16x4, + kSnorm16, + kSnorm16x2, + kSnorm16x4, + kFloat16, + kFloat16x2, + kFloat16x4, + kFloat32, + kFloat32x2, + kFloat32x3, + kFloat32x4, + kUint32, + kUint32x2, + kUint32x3, + kUint32x4, + kSint32, + kSint32x2, + kSint32x3, + kSint32x4, + kUnorm10_10_10_2, + kUnorm8x4BGRA, + }; + enum class GPUComponentSwizzle : uint32_t { kUndefined, @@ -88,6 +178,74 @@ namespace commandbuffers kInherit, }; + enum class GPUColorWriteMask : uint64_t + { + kNone, + kRed, + kGreen, + kBlue, + kAlpha, + kAll, + }; + + enum class GPUBlendFactor : uint32_t + { + kUndefined, + kZero, + kOne, + kSrc, + kOneMinusSrc, + kSrcAlpha, + kOneMinusSrcAlpha, + kDst, + kOneMinusDst, + kDstAlpha, + kOneMinusDstAlpha, + kSrcAlphaSaturated, + kConstant, + kOneMinusConstant, + kSrc1, + kOneMinusSrc1, + kSrc1Alpha, + kOneMinusSrc1Alpha, + }; + + enum class GPUBlendOperation : uint32_t + { + kUndefined, + kAdd, + kSubtract, + kReverseSubtract, + kMin, + kMax, + }; + + enum class GPUCompareFunction : uint32_t + { + kUndefined, + kNever, + kLess, + kEqual, + kLessEqual, + kGreater, + kNotEqual, + kGreaterEqual, + kAlways, + }; + + enum class GPUStencilOperation : uint32_t + { + kUndefined, + kKeep, + kZero, + kReplace, + kInvert, + kIncrementClamp, + kDecrementClamp, + kIncrementWrap, + kDecrementWrap, + }; + enum class GPUHandleType : uint32_t { kAdapter, @@ -229,12 +387,6 @@ namespace commandbuffers k3D, }; - enum class GPUIndexFormat - { - kUint16, - kUint32, - }; - enum class GPUTextureFormat : uint32_t { kUndefined, @@ -366,6 +518,99 @@ namespace commandbuffers kReadWrite, }; + struct GPUPrimitiveState + { + GPUPrimitiveTopology topology = GPUPrimitiveTopology::kTriangleList; + GPUIndexFormat stripIndexFormat = GPUIndexFormat::kUndefined; + GPUFrontFace frontFace = GPUFrontFace::kCCW; + GPUCullMode cullMode = GPUCullMode::kNone; + bool unclippedDepth = false; + }; + + struct GPUStencilFaceState + { + GPUCompareFunction compare = GPUCompareFunction::kUndefined; + GPUStencilOperation failOp = GPUStencilOperation::kUndefined; + GPUStencilOperation depthFailOp = GPUStencilOperation::kUndefined; + GPUStencilOperation passOp = GPUStencilOperation::kUndefined; + }; + + struct GPUDepthStencilState + { + GPUTextureFormat format = GPUTextureFormat::kUndefined; + std::optional depthWriteEnabled = std::nullopt; + GPUCompareFunction depthCompare = GPUCompareFunction::kUndefined; + GPUStencilFaceState stencilFront; + GPUStencilFaceState stencilBack; + uint32_t stencilReadMask = 0xFFFFFFFF; + uint32_t stencilWriteMask = 0xFFFFFFFF; + int32_t depthBias = 0; + float depthBiasSlopeScale = 0.f; + float depthBiasClamp = 0.f; + }; + + struct GPUMultisampleState + { + uint32_t count = 1; + uint32_t mask = 0xFFFFFFFF; + bool alphaToCoverageEnabled = false; + }; + + struct GPUBlendComponent + { + GPUBlendOperation operation = GPUBlendOperation::kUndefined; + GPUBlendFactor srcFactor = GPUBlendFactor::kUndefined; + GPUBlendFactor dstFactor = GPUBlendFactor::kUndefined; + }; + + struct GPUBlendState + { + GPUBlendComponent color = {}; + GPUBlendComponent alpha = {}; + }; + + struct GPUColorTargetState + { + GPUTextureFormat format = GPUTextureFormat::kUndefined; + GPUBlendState const *blend = nullptr; + GPUColorWriteMask writeMask = GPUColorWriteMask::kAll; + }; + + struct GPUFragmentState + { + // ShaderModuleBase *module; + std::string_view entryPoint; + size_t constantCount = 0; + GPUConstantEntry const *constants = nullptr; + size_t targetCount; + GPUColorTargetState const *targets = nullptr; + }; + + struct GPUVertexAttribute + { + GPUVertexFormat format = {}; + uint64_t offset; + uint32_t shaderLocation; + }; + + struct GPUVertexBufferLayout + { + GPUVertexStepMode stepMode = GPUVertexStepMode::kUndefined; + uint64_t arrayStride; + size_t attributeCount; + GPUVertexAttribute const *attributes = nullptr; + }; + + struct GPUVertexState + { + // ShaderModuleBase *module; + std::string_view entryPoint; + size_t constantCount = 0; + GPUConstantEntry const *constants = nullptr; + size_t bufferCount = 0; + GPUVertexBufferLayout const *buffers = nullptr; + }; + enum class GPUDynamicBindingKind : uint32_t { kUndefined, diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index 775e84152..f1bd5951f 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -32,7 +32,7 @@ namespace commandbuffers public: // TODO(yorkie): begineComputePass - GPURenderPassEncoderBase beginRenderPass(GPURenderPassDescriptor &); + GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor &); std::unique_ptr finish(std::optional label = std::nullopt) const; private: diff --git a/src/common/command_buffers/gpu/gpu_commands.hpp b/src/common/command_buffers/gpu/gpu_commands.hpp index 71eae1585..177bd6afa 100644 --- a/src/common/command_buffers/gpu/gpu_commands.hpp +++ b/src/common/command_buffers/gpu/gpu_commands.hpp @@ -3,9 +3,11 @@ #include #include -#include "./gpu_base.hpp" -#include "./gpu_buffer.hpp" -#include "./gpu_pipeline.hpp" +#include +#include +#include +#include +#include namespace commandbuffers { diff --git a/src/common/command_buffers/gpu/gpu_compute_pipeline.cpp b/src/common/command_buffers/gpu/gpu_compute_pipeline.cpp new file mode 100644 index 000000000..d845cc780 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_compute_pipeline.cpp @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/src/common/command_buffers/gpu/gpu_compute_pipeline.hpp b/src/common/command_buffers/gpu/gpu_compute_pipeline.hpp new file mode 100644 index 000000000..994092108 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_compute_pipeline.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace commandbuffers +{ + class GPUComputePipelineBase : public GPUPipelineBase + { + }; +} diff --git a/src/common/command_buffers/gpu/gpu_pipeline.cpp b/src/common/command_buffers/gpu/gpu_pipeline.cpp new file mode 100644 index 000000000..9fec159ed --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_pipeline.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +namespace commandbuffers +{ + const GPUComputePipelineBase *GPUPipelineBase::getAsComputePipeline() const + { + return nullptr; + } + + GPUComputePipelineBase *GPUPipelineBase::getAsComputePipeline() + { + return nullptr; + } + + const GPURenderPipelineBase *GPUPipelineBase::getAsRenderPipeline() const + { + return nullptr; + } + + GPURenderPipelineBase *GPUPipelineBase::getAsRenderPipeline() + { + return nullptr; + } +} diff --git a/src/common/command_buffers/gpu/gpu_pipeline.hpp b/src/common/command_buffers/gpu/gpu_pipeline.hpp index 4d1c6a58a..e29a593ea 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_pipeline.hpp @@ -4,8 +4,8 @@ #include #include -#include "./gpu_base.hpp" -#include "./gpu_bind_group.hpp" +#include +#include namespace commandbuffers { @@ -15,25 +15,31 @@ namespace commandbuffers std::vector bind_group_layouts_; }; - class GPURenderPipelineDescriptor + class GPURenderPipelineBase; + class GPUComputePipelineBase; + + class GPUPipelineBase : public GPUHandle { public: - std::optional label; - }; + virtual const GPUComputePipelineBase *getAsComputePipeline() const; + virtual GPUComputePipelineBase *getAsComputePipeline(); - class GPURenderPipelineBase : public GPUHandle - { - using GPUHandle::GPUHandle; + virtual const GPURenderPipelineBase *getAsRenderPipeline() const; + virtual GPURenderPipelineBase *getAsRenderPipeline(); - public: - GPUBindGroupLayoutBase &getBindGroupLayout(size_t index) - { - if (index < bind_group_layouts_.size()) - return bind_group_layouts_[index]; - throw std::out_of_range("Bind group layout index out of range"); - } + GPUPipelineBase *layout(); + const GPUPipelineLayoutBase *layout() const; + + protected: + GPUPipelineBase(std::shared_ptr device, + std::shared_ptr layout, + std::string_view label); + GPUPipelineBase(std::shared_ptr device, + GPUHandle::ErrorTag, + std::string_view label); private: - std::vector bind_group_layouts_; + GPUShaderStage stage_mask_ = GPUShaderStage::kNone; + std::shared_ptr layout_; }; } diff --git a/src/common/command_buffers/gpu/gpu_render_pipeline.cpp b/src/common/command_buffers/gpu/gpu_render_pipeline.cpp new file mode 100644 index 000000000..b44e80a49 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_render_pipeline.cpp @@ -0,0 +1,15 @@ +#include +#include + +using namespace std; + +namespace commandbuffers +{ + GPURenderPipelineBase::GPURenderPipelineBase(shared_ptr device, + const GPURenderPipelineDescriptor &descriptor) + : GPUPipelineBase(device, + descriptor.layout, + descriptor.label) + { + } +} \ No newline at end of file diff --git a/src/common/command_buffers/gpu/gpu_render_pipeline.hpp b/src/common/command_buffers/gpu/gpu_render_pipeline.hpp new file mode 100644 index 000000000..0bbff5864 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_render_pipeline.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + struct GPURenderPipelineDescriptor + { + std::string_view label; + std::shared_ptr layout = nullptr; + GPUVertexState vertex; + GPUPrimitiveState primitive; + GPUDepthStencilState const *depthStencil = nullptr; + GPUMultisampleState multisample; + GPUFragmentState const *fragment = nullptr; + }; + + class GPURenderPipelineBase : public GPUPipelineBase + { + public: + GPURenderPipelineBase(std::shared_ptr device, + const GPURenderPipelineDescriptor &descriptor); + }; +} diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp index f14620c59..41b7272d4 100644 --- a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp @@ -57,8 +57,8 @@ namespace commandbuffers std::optional depthStencilAttachment; }; - class GPURenderPassEncoderBase : public GPUPassEncoderBase, - public GPUHandle + class GPURenderPassEncoder : public GPUPassEncoderBase, + public GPUHandle { public: GPUHandleType type() const override final diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index 0a330467a..ba84297b5 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -9,7 +9,6 @@ #include "./context_storage.hpp" #include "./framebuffer.hpp" -#include "./gpu_command_encoder_impl.hpp" class ContextGLHost; class ContextGLApp : public ContextGLStorage diff --git a/src/renderer/gles/gpu_command_buffer_impl.cpp b/src/renderer/gles/gpu_command_buffer_impl.cpp index 63894facb..d399d34a9 100644 --- a/src/renderer/gles/gpu_command_buffer_impl.cpp +++ b/src/renderer/gles/gpu_command_buffer_impl.cpp @@ -7,45 +7,14 @@ namespace gles using namespace std; using namespace commandbuffers; - GPUCommandBufferImpl::GPUCommandBufferImpl(optional label) - : GPUCommandBufferBase(move(label)) - , framebuffer_(0) + GPUCommandBufferImpl::GPUCommandBufferImpl(GPUCommandEncoder *encoder, const GPUCommandBufferDescriptor *descriptor) + : GPUCommandBufferBase(encoder, descriptor) { } - GPUCommandBufferImpl::GPUCommandBufferImpl(optional label, const GPURenderPassEncoderImpl &renderpass_encoder) - : GPUCommandBufferBase(move(label), renderpass_encoder.commandBuffer()) - , framebuffer_(renderpass_encoder.framebuffer_) - { - assert(framebuffer_ > 0 && "Framebuffer must be bound before creating GPUCommandBufferImpl"); - } - void GPUCommandBufferImpl::execute() { - GLFramebuffer framebuffer(framebuffer_, false); - GLFramebufferScope framebuffer_scope(GL_FRAMEBUFFER, framebuffer); - - // TODO(yorkie): execute the commands in the command buffer. - for (const auto &command : commands_) - { - switch (command->type) - { - case GPUCommand::kDraw: - onDraw(*dynamic_pointer_cast(command)); - break; - case GPUCommand::kDrawIndexed: - onDraw(*dynamic_pointer_cast(command)); - break; - case GPUCommand::kSetViewport: - setViewport(*dynamic_pointer_cast(command)); - break; - case GPUCommand::kSetScissorRect: - setScissorRect(*dynamic_pointer_cast(command)); - break; - default: - break; - } - } + // TODO } void GPUCommandBufferImpl::onDraw(const commandbuffers::GPUDrawCommand &command) diff --git a/src/renderer/gles/gpu_command_buffer_impl.hpp b/src/renderer/gles/gpu_command_buffer_impl.hpp index 35e3fc496..2733ee92d 100644 --- a/src/renderer/gles/gpu_command_buffer_impl.hpp +++ b/src/renderer/gles/gpu_command_buffer_impl.hpp @@ -4,20 +4,19 @@ #include #include #include - +#include #include "./common.hpp" -#include "./gpu_renderpass_encoder_impl.hpp" namespace gles { class GPUCommandBufferImpl : public commandbuffers::GPUCommandBufferBase { public: - GPUCommandBufferImpl(std::optional label); - GPUCommandBufferImpl(std::optional label, const GPURenderPassEncoderImpl &); + GPUCommandBufferImpl(commandbuffers::GPUCommandEncoder *encoder, + const commandbuffers::GPUCommandBufferDescriptor *descriptor); public: - void execute() override; + void execute(); private: void onDraw(const commandbuffers::GPUDrawCommand &); diff --git a/src/renderer/gles/gpu_command_encoder_impl.cpp b/src/renderer/gles/gpu_command_encoder_impl.cpp deleted file mode 100644 index fac46a6e4..000000000 --- a/src/renderer/gles/gpu_command_encoder_impl.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "./common.hpp" -#include "./gpu_command_encoder_impl.hpp" -#include "./gpu_command_buffer_impl.hpp" -#include "./gpu_renderpass_encoder_impl.hpp" - -namespace gles -{ - using namespace std; - using namespace commandbuffers; - - GPURenderPassEncoder GPUCommandEncoderImpl::beginRenderPass(GPURenderPassDescriptor &) - { - assert(false && "beginRenderPass not implemented in gles::GPUCommandEncoderImpl"); - } - - std::unique_ptr GPUCommandEncoderImpl::finish(std::optional label) const - { - if (current_pass_encoder_ == nullptr) - return nullptr; - - if (current_pass_encoder_->isRenderPassEncoder()) - { - const auto &renderpass_encoder = dynamic_cast(*current_pass_encoder_); - return unique_ptr(new GPUCommandBufferImpl(label, renderpass_encoder)); - } - else - { - return nullptr; - } - } - - GPURenderPassEncoder &GPUCommandEncoderImpl::getOrStartRecordingRenderPass() - { - if (current_pass_encoder_ == nullptr || !current_pass_encoder_->isRenderPassEncoder()) - { - unique_ptr renderpass_encoder = make_unique(); - renderpass_encoder->begin(); - current_pass_encoder_ = move(renderpass_encoder); - } - - auto renderpass_encoder = dynamic_pointer_cast(current_pass_encoder_); - assert(renderpass_encoder != nullptr && "Current pass encoder must be a GPURenderPassEncoderImpl"); - return *renderpass_encoder; - } - - bool GPUCommandEncoderImpl::isRenderPassWith(GLuint target_framebuffer) const - { - if (current_pass_encoder_ == nullptr || !current_pass_encoder_->isRenderPassEncoder()) - return false; - - const auto &renderpass_encoder = dynamic_cast(*current_pass_encoder_); - return renderpass_encoder.targetFramebuffer() == target_framebuffer; - } -} diff --git a/src/renderer/gles/gpu_command_encoder_impl.hpp b/src/renderer/gles/gpu_command_encoder_impl.hpp deleted file mode 100644 index 21faf4ece..000000000 --- a/src/renderer/gles/gpu_command_encoder_impl.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include "./gpu_command_buffer_impl.hpp" - -namespace gles -{ - class GPUCommandEncoderImpl : public commandbuffers::gpu::GPUCommandEncoderBase - { - friend class GPUDeviceImpl; - using commandbuffers::gpu::GPUCommandEncoderBase::GPUCommandEncoderBase; - - public: - commandbuffers::gpu::GPURenderPassEncoderBase beginRenderPass(commandbuffers::gpu::GPURenderPassDescriptor &) override; - std::unique_ptr finish(std::optional label = std::nullopt) const override; - - public: - commandbuffers::gpu::GPURenderPassEncoderBase &getOrStartRecordingRenderPass(); - bool isRenderPassWith(GLuint target_framebuffer) const; - }; -} diff --git a/src/renderer/gles/gpu_device_impl.cpp b/src/renderer/gles/gpu_device_impl.cpp index 457dd2082..cb6db853f 100644 --- a/src/renderer/gles/gpu_device_impl.cpp +++ b/src/renderer/gles/gpu_device_impl.cpp @@ -4,31 +4,15 @@ #include "./common.hpp" #include "./gpu_device_impl.hpp" -#include "./gpu_command_encoder_impl.hpp" namespace gles { using namespace std; - using namespace commandbuffers::gpu; + using namespace commandbuffers; - GPUQueueImpl::GPUQueueImpl() - : GPUQueue() + GPUDeviceImpl::GPUDeviceImpl(GPUAdapterBase *adapter, GPUDeviceDescriptor &descriptor) + : GPUDeviceBase(adapter, descriptor) { - // Initialize the queue if needed. - // For GLES, this might not require any specific initialization. - } - - void GPUQueueImpl::submit(const vector> &command_buffers) - { - for (const auto &command_buffer : command_buffers) - command_buffer->execute(); - } - - GPUDeviceImpl::GPUDeviceImpl() - : GPUDeviceBase() - { - queue_ = make_unique(); - auto get_gl_string = [](GLenum name) -> string { const char *str = (const char *)glGetString(name); @@ -65,8 +49,9 @@ namespace gles DEBUG(LOG_TAG_RENDERER, "GPU Device Info: %s", adapter_info_.toString().c_str()); } - unique_ptr GPUDeviceImpl::createCommandEncoder(optional label) + unique_ptr GPUDeviceImpl::createCommandBuffer(GPUCommandEncoder &encoder, + const GPUCommandBufferDescriptor *descriptor) { - return unique_ptr(new GPUCommandEncoderImpl(label.value_or(""))); + return nullptr; } } diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp index 2576ccc8e..6be23948d 100644 --- a/src/renderer/gles/gpu_device_impl.hpp +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -8,15 +8,11 @@ namespace gles class GPUDeviceImpl final : public commandbuffers::GPUDeviceBase { private: - GPUDeviceImpl(); + GPUDeviceImpl(commandbuffers::GPUAdapterBase *adapter, commandbuffers::GPUDeviceDescriptor &descriptor); public: - commandbuffers::GPUHandleType type() const override - { - return commandbuffers::GPUHandleType::kDevice; - } - - public: - std::unique_ptr createCommandEncoder(std::optional label) override; + std::unique_ptr createCommandBuffer( + commandbuffers::GPUCommandEncoder &encoder, + const commandbuffers::GPUCommandBufferDescriptor *descriptor = nullptr) override; }; } diff --git a/src/renderer/gles/gpu_pipeline_impl.cpp b/src/renderer/gles/gpu_pipeline_impl.cpp new file mode 100644 index 000000000..14cae3407 --- /dev/null +++ b/src/renderer/gles/gpu_pipeline_impl.cpp @@ -0,0 +1,9 @@ +#include + +namespace gles +{ + GPURenderPipelineImpl::GPURenderPipelineImpl() + : commandbuffers::GPURenderPipelineBase() + { + } +} diff --git a/src/renderer/gles/gpu_pipeline_impl.hpp b/src/renderer/gles/gpu_pipeline_impl.hpp index 51001b5a8..53bc23ca3 100644 --- a/src/renderer/gles/gpu_pipeline_impl.hpp +++ b/src/renderer/gles/gpu_pipeline_impl.hpp @@ -6,16 +6,9 @@ namespace gles { - class GPURenderPipelineImpl : public commandbuffers::GPURenderPipeline + class GPURenderPipelineImpl : public commandbuffers::GPURenderPipelineBase { public: - GPURenderPipelineImpl(GLuint program) - : commandbuffers::GPURenderPipeline("GPURenderPipeline") - , program_(program) - { - } - - private: - GLuint program_; + GPURenderPipelineImpl(); }; } diff --git a/src/renderer/gles/gpu_renderpass_encoder_impl.cpp b/src/renderer/gles/gpu_renderpass_encoder_impl.cpp deleted file mode 100644 index 6885cc5e3..000000000 --- a/src/renderer/gles/gpu_renderpass_encoder_impl.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "./common.hpp" -#include "./gpu_command_buffer_impl.hpp" -#include "./gpu_renderpass_encoder_impl.hpp" - -namespace gles -{ - using namespace std; - using namespace commandbuffers; - - GPURenderPassEncoderImpl::GPURenderPassEncoderImpl(std::string label) - : commandbuffers::GPURenderPassEncoder(label) - , framebuffer_(0) - { - } - - void GPURenderPassEncoderImpl::begin() - { - glGetIntegerv(GL_FRAMEBUFFER_BINDING, reinterpret_cast(&framebuffer_)); - assert(framebuffer_ > 0 && "Framebuffer must be bound before beginning render pass"); - command_buffer_ = make_unique(label); - - GPURenderPassEncoder::begin(); - } -} diff --git a/src/renderer/gles/gpu_renderpass_encoder_impl.hpp b/src/renderer/gles/gpu_renderpass_encoder_impl.hpp deleted file mode 100644 index 3f04a72cd..000000000 --- a/src/renderer/gles/gpu_renderpass_encoder_impl.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include -#include "./common.hpp" - -namespace gles -{ - class GPURenderPassEncoderImpl : public commandbuffers::GPURenderPassEncoderBase - { - friend class GPUCommandBufferImpl; - - public: - GPURenderPassEncoderImpl(std::string label = "GPURenderPassEncoder"); - - void begin() override; - GLuint targetFramebuffer() const - { - return framebuffer_; - } - - private: - GLuint framebuffer_; - }; -} diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index 329f59b56..c23e9ead1 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -104,7 +104,8 @@ class TrRenderHardwareInterface friend class RHIFactory; public: - TrRenderHardwareInterface(RHIBackendType backend_type, std::unique_ptr gpu_device = nullptr) + TrRenderHardwareInterface(RHIBackendType backend_type, + std::unique_ptr gpu_device = nullptr) : backendType(backend_type) , gpuDevice(std::move(gpu_device)) { @@ -158,7 +159,7 @@ class TrRenderHardwareInterface /** * Submit a GPUCommandBuffer list to the GPU device for execution. */ - void SubmitGPUCommandBuffer(std::vector> &); + void SubmitGPUCommandBuffer(std::vector> &); std::unique_ptr CreateCommandEncoder(); /** @@ -328,7 +329,7 @@ class TrRenderHardwareInterface /** * The GPU device instance. */ - std::unique_ptr gpuDevice = nullptr; + std::unique_ptr gpuDevice = nullptr; /** * The default command buffer queue. From 75f3ff4919eace3b3fb624b2b0acef3d82332f82 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 4 Nov 2025 21:34:21 +0800 Subject: [PATCH 07/37] fix --- src/renderer/gles/gpu_pipeline_impl.cpp | 3 +-- src/renderer/gles/gpu_pipeline_impl.hpp | 4 ++-- src/renderer/render_api.cpp | 12 +++++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/renderer/gles/gpu_pipeline_impl.cpp b/src/renderer/gles/gpu_pipeline_impl.cpp index 14cae3407..046aaaf7e 100644 --- a/src/renderer/gles/gpu_pipeline_impl.cpp +++ b/src/renderer/gles/gpu_pipeline_impl.cpp @@ -2,8 +2,7 @@ namespace gles { - GPURenderPipelineImpl::GPURenderPipelineImpl() - : commandbuffers::GPURenderPipelineBase() + GPUPipelineImpl::GPUPipelineImpl() { } } diff --git a/src/renderer/gles/gpu_pipeline_impl.hpp b/src/renderer/gles/gpu_pipeline_impl.hpp index 53bc23ca3..65d7d00e6 100644 --- a/src/renderer/gles/gpu_pipeline_impl.hpp +++ b/src/renderer/gles/gpu_pipeline_impl.hpp @@ -6,9 +6,9 @@ namespace gles { - class GPURenderPipelineImpl : public commandbuffers::GPURenderPipelineBase + class GPUPipelineImpl { public: - GPURenderPipelineImpl(); + GPUPipelineImpl(); }; } diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index 25754890f..75ac5c764 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -8,18 +8,20 @@ #include "xr/frame.hpp" using namespace std; +using namespace commandbuffers; -void TrRenderHardwareInterface::SubmitGPUCommandBuffer(vector> &commandBuffers) +void TrRenderHardwareInterface::SubmitGPUCommandBuffer(vector> &commandBuffers) { - gpuDevice->queueRef().submit(commandBuffers); + // TODO(yorkie): Handle the submission result and errors. } -unique_ptr TrRenderHardwareInterface::CreateCommandEncoder() +unique_ptr TrRenderHardwareInterface::CreateCommandEncoder() { - return gpuDevice->createCommandEncoder(""); + // TODO(yorkie): Create and return a GPU command encoder. + return nullptr; } -void TrRenderHardwareInterface::AddCommandBuffer(commandbuffers::TrCommandBufferBase *commandBuffer) +void TrRenderHardwareInterface::AddCommandBuffer(TrCommandBufferBase *commandBuffer) { unique_lock lock(m_CommandBuffersMutex); m_CommandBuffers.push_back(commandBuffer); From 8997825b7dff3009daccd42da755e157f9613963 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 5 Nov 2025 21:51:22 +0800 Subject: [PATCH 08/37] fix --- .../gpu/backend_connection.cpp | 20 ++++++ .../gpu/backend_connection.hpp | 36 ++++++++++ .../command_buffers/gpu/gpu_adapter.cpp | 2 +- .../command_buffers/gpu/gpu_adapter.hpp | 8 +-- src/common/command_buffers/gpu/gpu_base.cpp | 2 +- src/common/command_buffers/gpu/gpu_base.hpp | 4 +- src/common/command_buffers/gpu/gpu_device.hpp | 2 +- .../command_buffers/gpu/gpu_instance.cpp | 16 +++-- .../command_buffers/gpu/gpu_instance.hpp | 37 +++++----- .../gpu/gpu_physical_device.hpp | 4 +- src/common/utility.hpp | 3 + src/renderer/gles/gpu_backend_impl.cpp | 23 +++++++ src/renderer/gles/gpu_backend_impl.hpp | 18 +++++ .../gles/gpu_physical_device_impl.cpp | 27 ++++++++ .../gles/gpu_physical_device_impl.hpp | 19 +++++ src/renderer/render_api.cpp | 69 +++++++++++++++++++ src/renderer/render_api.hpp | 17 ++--- src/renderer/render_api_opengles.cpp | 2 +- 18 files changed, 262 insertions(+), 47 deletions(-) create mode 100644 src/common/command_buffers/gpu/backend_connection.cpp create mode 100644 src/common/command_buffers/gpu/backend_connection.hpp create mode 100644 src/renderer/gles/gpu_backend_impl.cpp create mode 100644 src/renderer/gles/gpu_backend_impl.hpp create mode 100644 src/renderer/gles/gpu_physical_device_impl.cpp create mode 100644 src/renderer/gles/gpu_physical_device_impl.hpp diff --git a/src/common/command_buffers/gpu/backend_connection.cpp b/src/common/command_buffers/gpu/backend_connection.cpp new file mode 100644 index 000000000..a2eeb0815 --- /dev/null +++ b/src/common/command_buffers/gpu/backend_connection.cpp @@ -0,0 +1,20 @@ +#include + +namespace commandbuffers::gpu +{ + BackendConnection::BackendConnection(GPUInstance *instance, GPUBackendType type) + : instance_(instance) + , type_(type) + { + } + + GPUBackendType BackendConnection::type() const + { + return type_; + } + + GPUInstance *BackendConnection::getInstance() const + { + return instance_; + } +} diff --git a/src/common/command_buffers/gpu/backend_connection.hpp b/src/common/command_buffers/gpu/backend_connection.hpp new file mode 100644 index 000000000..170e81326 --- /dev/null +++ b/src/common/command_buffers/gpu/backend_connection.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace commandbuffers::gpu +{ + struct RequestAdapterOptions + { + GPUFeatureLevel featureLevel = GPUFeatureLevel::kCore; + GPUPowerPreference powerPreference = GPUPowerPreference::Undefined; + bool forceFallbackAdapter = false; + GPUBackendType backendType = GPUBackendType::kUndefined; + }; + + class BackendConnection : public NonMovable + { + public: + BackendConnection(GPUInstance *instance, GPUBackendType type); + virtual ~BackendConnection() = default; + + GPUBackendType type() const; + GPUInstance *getInstance() const; + + virtual std::vector> discoverPhysicalDevices(const RequestAdapterOptions &) = 0; + + private: + GPUInstance *instance_ = nullptr; + GPUBackendType type_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_adapter.cpp b/src/common/command_buffers/gpu/gpu_adapter.cpp index 831b88fea..106863e0b 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.cpp +++ b/src/common/command_buffers/gpu/gpu_adapter.cpp @@ -70,7 +70,7 @@ namespace commandbuffers rhs.maxComputeWorkgroupsPerDimension); } - GPUAdapterBase::GPUAdapterBase(shared_ptr instance, + GPUAdapterBase::GPUAdapterBase(shared_ptr instance, shared_ptr physicalDevice, GPUFeatureLevel level, GPUPowerPreference powerPreference) diff --git a/src/common/command_buffers/gpu/gpu_adapter.hpp b/src/common/command_buffers/gpu/gpu_adapter.hpp index 426b08060..c1823c279 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.hpp +++ b/src/common/command_buffers/gpu/gpu_adapter.hpp @@ -9,7 +9,7 @@ namespace commandbuffers { - class GPUInstanceBase; + class GPUInstance; class GPUPhysicalDeviceBase; struct GPUDeviceDescriptor; @@ -47,12 +47,12 @@ namespace commandbuffers class GPUAdapterBase : ErrorMonad { public: - GPUAdapterBase(std::shared_ptr instance, + GPUAdapterBase(std::shared_ptr instance, std::shared_ptr physicalDevice, GPUFeatureLevel level, GPUPowerPreference powerPreference); - GPUInstanceBase *instance() const; + GPUInstance *instance() const; const GPUAdapterInfo &info() const; bool hasFeature(GPUFeatureName) const; void requestDevice(const GPUDeviceDescriptor *descriptor, @@ -66,7 +66,7 @@ namespace commandbuffers const std::string &name() const; private: - std::shared_ptr instance_; + std::shared_ptr instance_; std::shared_ptr physical_device_; GPUFeatureLevel feature_level_; GPUPowerPreference power_preference_; diff --git a/src/common/command_buffers/gpu/gpu_base.cpp b/src/common/command_buffers/gpu/gpu_base.cpp index 439cb12e5..359f0d18a 100644 --- a/src/common/command_buffers/gpu/gpu_base.cpp +++ b/src/common/command_buffers/gpu/gpu_base.cpp @@ -88,7 +88,7 @@ namespace commandbuffers { } - GPUInstanceBase *GPUObject::instance() const + GPUInstance *GPUObject::instance() const { return device_->getInstance(); } diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 1f082bdb4..d953fd92d 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -718,8 +718,8 @@ namespace commandbuffers static constexpr uint64_t kInitialized = 0b0; }; + class GPUInstance; class GPUDeviceBase; - class GPUInstanceBase; class GPUObject : public ErrorMonad { @@ -728,7 +728,7 @@ namespace commandbuffers GPUObject(std::shared_ptr device, ErrorTag tag); GPUObject(std::shared_ptr device, DelayedInitializationTag tag); - GPUInstanceBase *instance() const; + GPUInstance *instance() const; std::shared_ptr device() const; private: diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index df439c93b..372eb6fee 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -38,7 +38,7 @@ namespace commandbuffers bool validateHandle(const GPUHandle &handle) const; - GPUInstanceBase *getInstance() const; + GPUInstance *getInstance() const; GPUAdapterBase *getAdapter() const; GPUPhysicalDeviceBase *getPhysicalDevice() const; diff --git a/src/common/command_buffers/gpu/gpu_instance.cpp b/src/common/command_buffers/gpu/gpu_instance.cpp index d6c2dd4ff..d5dbae55f 100644 --- a/src/common/command_buffers/gpu/gpu_instance.cpp +++ b/src/common/command_buffers/gpu/gpu_instance.cpp @@ -1,10 +1,11 @@ #include +#include using namespace std; namespace commandbuffers { - unique_ptr GPUInstanceBase::Create(const GPUInstanceDescriptor *descriptor) + Ref GPUInstance::Create(const GPUInstanceDescriptor *descriptor) { static constexpr GPUInstanceDescriptor kDefaultDesc = {}; if (descriptor == nullptr) @@ -12,29 +13,30 @@ namespace commandbuffers descriptor = &kDefaultDesc; } - auto instance = unique_ptr(new GPUInstanceBase()); + auto instance = Ref(new GPUInstance(), [](GPUInstance *ptr) + { delete ptr; }); instance->initialize(*descriptor); return instance; } - void GPUInstanceBase::addDevice(shared_ptr) + void GPUInstance::addDevice(shared_ptr) { } - void GPUInstanceBase::removeDevice(shared_ptr) + void GPUInstance::removeDevice(shared_ptr) { } - bool GPUInstanceBase::hasFeature(GPUFeatureName feature) const + bool GPUInstance::hasFeature(GPUFeatureName feature) const { return instance_features_.find(feature) != instance_features_.end(); } - GPUInstanceBase::GPUInstanceBase() + GPUInstance::GPUInstance() { } - void GPUInstanceBase::initialize(const GPUInstanceDescriptor &descriptor) + void GPUInstance::initialize(const GPUInstanceDescriptor &descriptor) { } } diff --git a/src/common/command_buffers/gpu/gpu_instance.hpp b/src/common/command_buffers/gpu/gpu_instance.hpp index 3c99a8578..2bd320204 100644 --- a/src/common/command_buffers/gpu/gpu_instance.hpp +++ b/src/common/command_buffers/gpu/gpu_instance.hpp @@ -3,11 +3,17 @@ #include #include #include +#include #include #include namespace commandbuffers { + namespace gpu + { + class BackendConnection; + } + struct GPUInstanceDescriptor { size_t requiredFeatureCount = 0; @@ -15,35 +21,32 @@ namespace commandbuffers GPUSupportedLimits *requiredLimits = nullptr; }; - class GPUInstanceBase + class GPUInstance final { - private: - // Custom deleter for `unique_ptr` - struct Deleter - { - void operator()(GPUInstanceBase *ptr) - { - delete ptr; - } - }; - public: - static std::unique_ptr Create(const GPUInstanceDescriptor *descriptor = nullptr); + static Ref Create(const GPUInstanceDescriptor *descriptor = nullptr); + + void registerBackend(gpu::BackendConnection *backend); - void addDevice(std::shared_ptr); - void removeDevice(std::shared_ptr); + void addDevice(Ref); + void removeDevice(Ref); bool hasFeature(GPUFeatureName feature) const; private: - explicit GPUInstanceBase(); - virtual ~GPUInstanceBase() = default; + explicit GPUInstance(); + virtual ~GPUInstance() = default; void initialize(const GPUInstanceDescriptor &descriptor); - std::shared_ptr createAdapter(); + Ref createAdapter(Ref physicalDevice, + GPUFeatureLevel featureLevel, + GPUPowerPreference powerPreference); + + gpu::BackendConnection *getBackendConnection() const; private: std::unordered_set instance_features_; std::vector> devices_list_; + Ref backend_ = nullptr; }; } diff --git a/src/common/command_buffers/gpu/gpu_physical_device.hpp b/src/common/command_buffers/gpu/gpu_physical_device.hpp index 98ccda19b..ed903ca92 100644 --- a/src/common/command_buffers/gpu/gpu_physical_device.hpp +++ b/src/common/command_buffers/gpu/gpu_physical_device.hpp @@ -37,8 +37,8 @@ namespace commandbuffers private: virtual std::unique_ptr createDeviceImpl(std::shared_ptr adapter, - GPUDeviceDescriptor &descriptor); - virtual void initializeImpl(); + GPUDeviceDescriptor &descriptor) = 0; + virtual void initializeImpl() = 0; virtual void initializeSupportedFeaturesImpl() = 0; virtual void initializeVendorArchitectureImpl(); diff --git a/src/common/utility.hpp b/src/common/utility.hpp index 7c4a55543..cc54a738e 100644 --- a/src/common/utility.hpp +++ b/src/common/utility.hpp @@ -33,6 +33,9 @@ public: \ private: \ void *operator new(size_t) = delete +template +using Ref = std::shared_ptr; + /** * Shared reference is a template class that holds the shared pointer of a type. * diff --git a/src/renderer/gles/gpu_backend_impl.cpp b/src/renderer/gles/gpu_backend_impl.cpp new file mode 100644 index 000000000..15411b42d --- /dev/null +++ b/src/renderer/gles/gpu_backend_impl.cpp @@ -0,0 +1,23 @@ +#include + +using namespace std; +using namespace commandbuffers; + +namespace gles +{ + GPUBackend::GPUBackend(GPUInstance *instance, GPUBackendType type) + : BackendConnection(instance, type) + { + } + + vector> GPUBackend::discoverPhysicalDevices(const gpu::RequestAdapterOptions &options) + { + return {}; + } + + gpu::BackendConnection *Connect(GPUInstance *instance, GPUBackendType type) + { + assert(type == GPUBackendType::kOpenGL || type == GPUBackendType::kOpenGLES); + return new GPUBackend(instance, type); + } +} diff --git a/src/renderer/gles/gpu_backend_impl.hpp b/src/renderer/gles/gpu_backend_impl.hpp new file mode 100644 index 000000000..9e28a9f28 --- /dev/null +++ b/src/renderer/gles/gpu_backend_impl.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include +#include + +namespace gles +{ + class GPUBackend final : public commandbuffers::gpu::BackendConnection + { + public: + GPUBackend(commandbuffers::GPUInstance *instance, commandbuffers::GPUBackendType type); + + std::vector> discoverPhysicalDevices( + const commandbuffers::gpu::RequestAdapterOptions &options) override; + }; +} diff --git a/src/renderer/gles/gpu_physical_device_impl.cpp b/src/renderer/gles/gpu_physical_device_impl.cpp new file mode 100644 index 000000000..9fa409981 --- /dev/null +++ b/src/renderer/gles/gpu_physical_device_impl.cpp @@ -0,0 +1,27 @@ +#include + +using namespace std; +using namespace commandbuffers; + +namespace gles +{ + bool GPUPhysicalDeviceImpl::supportsExternalImages() const + { + return false; + } + + unique_ptr GPUPhysicalDeviceImpl::createDeviceImpl(shared_ptr adapter, + GPUDeviceDescriptor &descriptor) + { + return nullptr; + } + + void GPUPhysicalDeviceImpl::initializeImpl() + { + } + + void GPUPhysicalDeviceImpl::initializeSupportedFeaturesImpl() + { + } + +} diff --git a/src/renderer/gles/gpu_physical_device_impl.hpp b/src/renderer/gles/gpu_physical_device_impl.hpp new file mode 100644 index 000000000..ecb2529ca --- /dev/null +++ b/src/renderer/gles/gpu_physical_device_impl.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace gles +{ + class GPUPhysicalDeviceImpl final : public commandbuffers::GPUPhysicalDeviceBase + { + public: + bool supportsExternalImages() const override; + + private: + std::unique_ptr createDeviceImpl(std::shared_ptr adapter, + GPUDeviceDescriptor &descriptor) override; + void initializeImpl() override; + void initializeSupportedFeaturesImpl() override; + }; +} diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index 75ac5c764..aac76a26a 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -10,6 +10,75 @@ using namespace std; using namespace commandbuffers; +#if SUPPORT_D3D11 // D3D11 backend +namespace d3d11 +{ + extern gpu::BackendConnection *Connect(GPUInstance *, GPUBackendType); +} +#endif + +#if SUPPORT_OPENGL_UNIFIED // OpenGL / OpenGL ES backend +namespace gles +{ + extern gpu::BackendConnection *Connect(GPUInstance *, GPUBackendType); +} +#endif + +#if SUPPORT_METAL // Metal backend +namespace metal +{ + extern gpu::BackendConnection *Connect(GPUInstance *, GPUBackendType); +} +#endif + +#if SUPPORT_VULKAN // Vulkan backend +namespace vulkan +{ + extern gpu::BackendConnection *Connect(GPUInstance *, GPUBackendType); +} +#endif + +TrRenderHardwareInterface::TrRenderHardwareInterface(RHIBackendType backend_type) + : backendType(backend_type) + , gpuInstance(GPUInstance::Create()) +{ + switch (backend_type) + { +#if SUPPORT_D3D11 + case RHIBackendType::D3D11: + gpuInstance->registerBackend(d3d11::Connect(gpuInstance.get(), GPUBackendType::kD3D11)); + break; +#endif + +#if SUPPORT_OPENGL_UNIFIED + case RHIBackendType::OpenGLCore: + gpuInstance->registerBackend(gles::Connect(gpuInstance.get(), GPUBackendType::kOpenGL)); + break; + + case RHIBackendType::OpenGLESv2: + case RHIBackendType::OpenGLESv3: + gpuInstance->registerBackend(gles::Connect(gpuInstance.get(), GPUBackendType::kOpenGLES)); + break; +#endif + +#if SUPPORT_METAL + case RHIBackendType::Metal: + gpuInstance->registerBackend(metal::Connect(gpuInstance.get(), GPUBackendType::kMetal)); + break; +#endif + +#if SUPPORT_VULKAN + case RHIBackendType::VULKAN: + gpuInstance->registerBackend(vulkan::Connect(gpuInstance.get(), GPUBackendType::kVulkan)); + break; +#endif + + default: + // Unsupported backend type + assert(false && "Unsupported RHI backend type."); + } +} + void TrRenderHardwareInterface::SubmitGPUCommandBuffer(vector> &commandBuffers) { // TODO(yorkie): Handle the submission result and errors. diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index c23e9ead1..cfc88ff8c 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -7,11 +7,13 @@ #include #include -#include #include +#include +#include #include #include #include +#include #include #include @@ -104,12 +106,7 @@ class TrRenderHardwareInterface friend class RHIFactory; public: - TrRenderHardwareInterface(RHIBackendType backend_type, - std::unique_ptr gpu_device = nullptr) - : backendType(backend_type) - , gpuDevice(std::move(gpu_device)) - { - } + TrRenderHardwareInterface(RHIBackendType backend_type); virtual ~TrRenderHardwareInterface() = default; /** @@ -326,10 +323,8 @@ class TrRenderHardwareInterface */ bool m_PrintsContext = false; - /** - * The GPU device instance. - */ - std::unique_ptr gpuDevice = nullptr; + Ref gpuInstance = nullptr; + Ref gpuDevice = nullptr; /** * The default command buffer queue. diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 23341bff1..9ab101282 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -60,7 +60,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface public: RHI_OpenGL(RHIBackendType backend_type) - : TrRenderHardwareInterface(backend_type, make_unique()) + : TrRenderHardwareInterface(backend_type) { memset(m_TmpMatrixL, 0, 16); memset(m_TmpMatrixR, 0, 16); From d620fdbe2cc1e78c4ec9ef2076022a5daa4ecdf4 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 5 Nov 2025 21:58:47 +0800 Subject: [PATCH 09/37] fix nits --- src/renderer/gles/gpu_physical_device_impl.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/renderer/gles/gpu_physical_device_impl.hpp b/src/renderer/gles/gpu_physical_device_impl.hpp index ecb2529ca..9c0d220cc 100644 --- a/src/renderer/gles/gpu_physical_device_impl.hpp +++ b/src/renderer/gles/gpu_physical_device_impl.hpp @@ -11,8 +11,10 @@ namespace gles bool supportsExternalImages() const override; private: - std::unique_ptr createDeviceImpl(std::shared_ptr adapter, - GPUDeviceDescriptor &descriptor) override; + std::unique_ptr createDeviceImpl( + std::shared_ptr adapter, + commandbuffers::GPUDeviceDescriptor &descriptor) override; + void initializeImpl() override; void initializeSupportedFeaturesImpl() override; }; From de581c5b2d8847baa79ef642e32d0cd664030d55 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 6 Nov 2025 17:37:14 +0800 Subject: [PATCH 10/37] build working --- cmake/TransmuteCore.cmake | 2 +- .../gpu/backend_connection.hpp | 4 +- .../command_buffers/gpu/encoding_context.cpp | 27 ++- .../command_buffers/gpu/encoding_context.hpp | 6 +- .../command_buffers/gpu/gpu_adapter.cpp | 174 +++++++++++------- .../command_buffers/gpu/gpu_adapter.hpp | 20 +- .../command_buffers/gpu/gpu_binding_info.cpp | 6 + src/common/command_buffers/gpu/gpu_device.cpp | 51 +++++ src/common/command_buffers/gpu/gpu_device.hpp | 14 +- .../command_buffers/gpu/gpu_instance.cpp | 7 + .../command_buffers/gpu/gpu_instance.hpp | 8 +- .../gpu/gpu_physical_device.cpp | 5 - .../command_buffers/gpu/gpu_pipeline.cpp | 26 +++ .../command_buffers/gpu/gpu_pipeline.hpp | 11 +- .../gpu/gpu_render_pipeline.cpp | 8 +- .../gpu/gpu_render_pipeline.hpp | 7 +- .../command_buffers/gpu/physical_device.cpp | 79 ++++++++ ...hysical_device.hpp => physical_device.hpp} | 13 +- src/renderer/gles/gpu_backend_impl.cpp | 2 +- src/renderer/gles/gpu_backend_impl.hpp | 2 +- .../gles/gpu_physical_device_impl.cpp | 5 +- .../gles/gpu_physical_device_impl.hpp | 7 +- src/renderer/metal/gpu_backend_mtl.h | 18 ++ src/renderer/metal/gpu_backend_mtl.mm | 23 +++ 24 files changed, 409 insertions(+), 116 deletions(-) delete mode 100644 src/common/command_buffers/gpu/gpu_physical_device.cpp create mode 100644 src/common/command_buffers/gpu/physical_device.cpp rename src/common/command_buffers/gpu/{gpu_physical_device.hpp => physical_device.hpp} (82%) create mode 100644 src/renderer/metal/gpu_backend_mtl.h create mode 100644 src/renderer/metal/gpu_backend_mtl.mm diff --git a/cmake/TransmuteCore.cmake b/cmake/TransmuteCore.cmake index f2013e2ac..ed97eb50e 100644 --- a/cmake/TransmuteCore.cmake +++ b/cmake/TransmuteCore.cmake @@ -11,7 +11,7 @@ if(NOT TR_ENABLE_INSPECTOR) endif() if(APPLE) - file(GLOB TR_CORE_SOURCE_MM "src/renderer/*.mm") + file(GLOB TR_CORE_SOURCE_MM "src/renderer/*.mm" "src/renderer/metal/*.mm") list(APPEND TR_CORE_SOURCE ${TR_CORE_SOURCE_MM}) endif() diff --git a/src/common/command_buffers/gpu/backend_connection.hpp b/src/common/command_buffers/gpu/backend_connection.hpp index 170e81326..05b401c91 100644 --- a/src/common/command_buffers/gpu/backend_connection.hpp +++ b/src/common/command_buffers/gpu/backend_connection.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include namespace commandbuffers::gpu { @@ -27,7 +27,7 @@ namespace commandbuffers::gpu GPUBackendType type() const; GPUInstance *getInstance() const; - virtual std::vector> discoverPhysicalDevices(const RequestAdapterOptions &) = 0; + virtual std::vector> discoverPhysicalDevices(const RequestAdapterOptions &) = 0; private: GPUInstance *instance_ = nullptr; diff --git a/src/common/command_buffers/gpu/encoding_context.cpp b/src/common/command_buffers/gpu/encoding_context.cpp index 2ee01c71b..1079e1ae2 100644 --- a/src/common/command_buffers/gpu/encoding_context.cpp +++ b/src/common/command_buffers/gpu/encoding_context.cpp @@ -1,9 +1,11 @@ #include #include +using namespace std; + namespace commandbuffers::gpu { - EncodingContext::EncodingContext(std::shared_ptr device, std::shared_ptr initialEncoder) + EncodingContext::EncodingContext(Ref device, Ref initialEncoder) : device_(device.get()) , top_level_encoder_(initialEncoder.get()) , current_encoder_(initialEncoder.get()) @@ -12,7 +14,7 @@ namespace commandbuffers::gpu assert(!initialEncoder->isError()); } - EncodingContext::EncodingContext(std::shared_ptr device, GPUHandle::ErrorTag tag) + EncodingContext::EncodingContext(Ref device, GPUHandle::ErrorTag tag) : device_(device.get()) , top_level_encoder_(nullptr) , current_encoder_(nullptr) @@ -88,6 +90,11 @@ namespace commandbuffers::gpu // mComputePassUsages.push_back(std::move(usages)); } + bool EncodingContext::finish() + { + return false; + } + void EncodingContext::ensurePassExited(const GPUHandle *passEncoder) { if (current_encoder_ != top_level_encoder_ && current_encoder_ == passEncoder) @@ -98,4 +105,20 @@ namespace commandbuffers::gpu // passEncoder)); } } + + void EncodingContext::pushDebugGroupLabel(string_view groupLabel) + { + } + + void EncodingContext::popDebugGroupLabel() + { + } + + void EncodingContext::commitCommands(CommandAllocator allocator) + { + } + + void EncodingContext::closeWithStatus(Status status) + { + } } diff --git a/src/common/command_buffers/gpu/encoding_context.hpp b/src/common/command_buffers/gpu/encoding_context.hpp index c1e6d57d2..72407ccf4 100644 --- a/src/common/command_buffers/gpu/encoding_context.hpp +++ b/src/common/command_buffers/gpu/encoding_context.hpp @@ -2,6 +2,8 @@ #include #include + +#include #include #include #include @@ -19,8 +21,8 @@ namespace commandbuffers class EncodingContext { public: - EncodingContext(std::shared_ptr device, std::shared_ptr initialEncoder); - EncodingContext(std::shared_ptr device, GPUHandle::ErrorTag tag); + EncodingContext(Ref device, Ref initialEncoder); + EncodingContext(Ref device, GPUHandle::ErrorTag tag); ~EncodingContext(); // Marks the encoding context as destroyed so that any future encodes will fail, and all diff --git a/src/common/command_buffers/gpu/gpu_adapter.cpp b/src/common/command_buffers/gpu/gpu_adapter.cpp index 106863e0b..3d7ee1143 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.cpp +++ b/src/common/command_buffers/gpu/gpu_adapter.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include using namespace std; @@ -8,70 +8,70 @@ namespace commandbuffers { bool GPUSupportedLimits::operator==(const GPUSupportedLimits &rhs) const { - const auto &lhs = std::tie(maxTextureDimension1D, - maxTextureDimension2D, - maxTextureDimension3D, - maxTextureArrayLayers, - maxBindGroups, - maxBindingsPerBindGroup, - maxDynamicUniformBuffersPerPipelineLayout, - maxDynamicStorageBuffersPerPipelineLayout, - maxSampledTexturesPerShaderStage, - maxSamplersPerShaderStage, - maxStorageBuffersPerShaderStage, - maxStorageTexturesPerShaderStage, - maxUniformBuffersPerShaderStage, - maxUniformBufferBindingSize, - maxStorageBufferBindingSize, - minUniformBufferOffsetAlignment, - minStorageBufferOffsetAlignment, - maxVertexBuffers, - maxBufferSize, - maxVertexAttributes, - maxVertexBufferArrayStride, - maxInterStageShaderVariables, - maxColorAttachments, - maxColorAttachmentBytesPerSample, - maxComputeWorkgroupStorageSize, - maxComputeInvocationsPerWorkgroup, - maxComputeWorkgroupSizeX, - maxComputeWorkgroupSizeY, - maxComputeWorkgroupSizeZ, - maxComputeWorkgroupsPerDimension); - return lhs == std::tie(rhs.maxTextureDimension1D, - rhs.maxTextureDimension2D, - rhs.maxTextureDimension3D, - rhs.maxTextureArrayLayers, - rhs.maxBindGroups, - rhs.maxBindingsPerBindGroup, - rhs.maxDynamicUniformBuffersPerPipelineLayout, - rhs.maxDynamicStorageBuffersPerPipelineLayout, - rhs.maxSampledTexturesPerShaderStage, - rhs.maxSamplersPerShaderStage, - rhs.maxStorageBuffersPerShaderStage, - rhs.maxStorageTexturesPerShaderStage, - rhs.maxUniformBuffersPerShaderStage, - rhs.maxUniformBufferBindingSize, - rhs.maxStorageBufferBindingSize, - rhs.minUniformBufferOffsetAlignment, - rhs.minStorageBufferOffsetAlignment, - rhs.maxVertexBuffers, - rhs.maxBufferSize, - rhs.maxVertexAttributes, - rhs.maxVertexBufferArrayStride, - rhs.maxInterStageShaderVariables, - rhs.maxColorAttachments, - rhs.maxColorAttachmentBytesPerSample, - rhs.maxComputeWorkgroupStorageSize, - rhs.maxComputeInvocationsPerWorkgroup, - rhs.maxComputeWorkgroupSizeX, - rhs.maxComputeWorkgroupSizeY, - rhs.maxComputeWorkgroupSizeZ, - rhs.maxComputeWorkgroupsPerDimension); + const auto &lhs = tie(maxTextureDimension1D, + maxTextureDimension2D, + maxTextureDimension3D, + maxTextureArrayLayers, + maxBindGroups, + maxBindingsPerBindGroup, + maxDynamicUniformBuffersPerPipelineLayout, + maxDynamicStorageBuffersPerPipelineLayout, + maxSampledTexturesPerShaderStage, + maxSamplersPerShaderStage, + maxStorageBuffersPerShaderStage, + maxStorageTexturesPerShaderStage, + maxUniformBuffersPerShaderStage, + maxUniformBufferBindingSize, + maxStorageBufferBindingSize, + minUniformBufferOffsetAlignment, + minStorageBufferOffsetAlignment, + maxVertexBuffers, + maxBufferSize, + maxVertexAttributes, + maxVertexBufferArrayStride, + maxInterStageShaderVariables, + maxColorAttachments, + maxColorAttachmentBytesPerSample, + maxComputeWorkgroupStorageSize, + maxComputeInvocationsPerWorkgroup, + maxComputeWorkgroupSizeX, + maxComputeWorkgroupSizeY, + maxComputeWorkgroupSizeZ, + maxComputeWorkgroupsPerDimension); + return lhs == tie(rhs.maxTextureDimension1D, + rhs.maxTextureDimension2D, + rhs.maxTextureDimension3D, + rhs.maxTextureArrayLayers, + rhs.maxBindGroups, + rhs.maxBindingsPerBindGroup, + rhs.maxDynamicUniformBuffersPerPipelineLayout, + rhs.maxDynamicStorageBuffersPerPipelineLayout, + rhs.maxSampledTexturesPerShaderStage, + rhs.maxSamplersPerShaderStage, + rhs.maxStorageBuffersPerShaderStage, + rhs.maxStorageTexturesPerShaderStage, + rhs.maxUniformBuffersPerShaderStage, + rhs.maxUniformBufferBindingSize, + rhs.maxStorageBufferBindingSize, + rhs.minUniformBufferOffsetAlignment, + rhs.minStorageBufferOffsetAlignment, + rhs.maxVertexBuffers, + rhs.maxBufferSize, + rhs.maxVertexAttributes, + rhs.maxVertexBufferArrayStride, + rhs.maxInterStageShaderVariables, + rhs.maxColorAttachments, + rhs.maxColorAttachmentBytesPerSample, + rhs.maxComputeWorkgroupStorageSize, + rhs.maxComputeInvocationsPerWorkgroup, + rhs.maxComputeWorkgroupSizeX, + rhs.maxComputeWorkgroupSizeY, + rhs.maxComputeWorkgroupSizeZ, + rhs.maxComputeWorkgroupsPerDimension); } - GPUAdapterBase::GPUAdapterBase(shared_ptr instance, - shared_ptr physicalDevice, + GPUAdapterBase::GPUAdapterBase(Ref instance, + Ref physicalDevice, GPUFeatureLevel level, GPUPowerPreference powerPreference) : ErrorMonad() @@ -81,4 +81,52 @@ namespace commandbuffers , power_preference_(powerPreference) { } + + GPUInstance *GPUAdapterBase::instance() const + { + return instance_.get(); + } + + const GPUAdapterInfo &GPUAdapterBase::info() const + { + return info_; + } + + bool GPUAdapterBase::hasFeature(GPUFeatureName feature) const + { + return false; + } + + void GPUAdapterBase::requestDevice(const GPUDeviceDescriptor *descriptor, + function)> callback) + { + auto device = createDevice(descriptor); + callback(move(device)); + } + + unique_ptr GPUAdapterBase::createDevice(const GPUDeviceDescriptor *descriptor) + { + // Implementation for creating a GPU device based on the descriptor + return nullptr; + } + + gpu::PhysicalDeviceBase *GPUAdapterBase::physicalDevice() + { + return physical_device_.get(); + } + + const gpu::PhysicalDeviceBase *GPUAdapterBase::physicalDevice() const + { + return physical_device_.get(); + } + + GPUFeatureLevel GPUAdapterBase::featureLevel() const + { + return feature_level_; + } + + const string &GPUAdapterBase::name() const + { + return physical_device_->name(); + } } diff --git a/src/common/command_buffers/gpu/gpu_adapter.hpp b/src/common/command_buffers/gpu/gpu_adapter.hpp index c1823c279..ece81ebcd 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.hpp +++ b/src/common/command_buffers/gpu/gpu_adapter.hpp @@ -5,13 +5,18 @@ #include #include #include + +#include #include namespace commandbuffers { class GPUInstance; - class GPUPhysicalDeviceBase; struct GPUDeviceDescriptor; + namespace gpu + { + class PhysicalDeviceBase; + } class GPUAdapterInfo { @@ -47,8 +52,8 @@ namespace commandbuffers class GPUAdapterBase : ErrorMonad { public: - GPUAdapterBase(std::shared_ptr instance, - std::shared_ptr physicalDevice, + GPUAdapterBase(Ref instance, + Ref physicalDevice, GPUFeatureLevel level, GPUPowerPreference powerPreference); @@ -59,15 +64,16 @@ namespace commandbuffers std::function)> callback); std::unique_ptr createDevice(const GPUDeviceDescriptor *descriptor = nullptr); - GPUPhysicalDeviceBase *physicalDevice(); - const GPUPhysicalDeviceBase *physicalDevice() const; + gpu::PhysicalDeviceBase *physicalDevice(); + const gpu::PhysicalDeviceBase *physicalDevice() const; GPUFeatureLevel featureLevel() const; const std::string &name() const; private: - std::shared_ptr instance_; - std::shared_ptr physical_device_; + Ref instance_; + Ref physical_device_; + GPUAdapterInfo info_; GPUFeatureLevel feature_level_; GPUPowerPreference power_preference_; diff --git a/src/common/command_buffers/gpu/gpu_binding_info.cpp b/src/common/command_buffers/gpu/gpu_binding_info.cpp index 5c41068de..c63edf3cf 100644 --- a/src/common/command_buffers/gpu/gpu_binding_info.cpp +++ b/src/common/command_buffers/gpu/gpu_binding_info.cpp @@ -1,5 +1,11 @@ #include +using namespace std; + namespace commandbuffers { + string GPUBindingInfo::toString() const + { + return "GPUBindingInfo {}"; + } } diff --git a/src/common/command_buffers/gpu/gpu_device.cpp b/src/common/command_buffers/gpu/gpu_device.cpp index 2c49b14c7..01a8a56b2 100644 --- a/src/common/command_buffers/gpu/gpu_device.cpp +++ b/src/common/command_buffers/gpu/gpu_device.cpp @@ -2,6 +2,52 @@ namespace commandbuffers { + GPUDeviceBase::GPUDeviceBase(GPUAdapterBase *adapter, + GPUDeviceDescriptor &descriptor) + : adapter_(adapter) + { + } + + const GPUAdapterInfo &GPUDeviceBase::adapterInfo() const + { + return adapter_->info(); + } + + const GPUSupportedFeatures &GPUDeviceBase::features() const + { + return features_; + } + + const GPUSupportedLimits &GPUDeviceBase::limits() const + { + return limits_; + } + + bool GPUDeviceBase::validateHandle(const GPUHandle &handle) const + { + return false; + } + + GPUInstance *GPUDeviceBase::getInstance() const + { + return adapter_->instance(); + } + + GPUAdapterBase *GPUDeviceBase::getAdapter() const + { + return adapter_.get(); + } + + gpu::PhysicalDeviceBase *GPUDeviceBase::getPhysicalDevice() const + { + return adapter_->physicalDevice(); + } + + Ref GPUDeviceBase::getOrCreateBindGroupLayout() + { + return nullptr; + } + bool GPUDeviceBase::isValidationEnabled() const { // return !IsToggleEnabled(Toggle::SkipValidation); @@ -25,4 +71,9 @@ namespace commandbuffers // return mIsImmediateErrorHandlingEnabled; return false; } + + bool GPUDeviceBase::mayRequireDuplicationOfIndirectParameters() const + { + return false; + } } diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index 372eb6fee..d1fecdf7e 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -13,9 +14,13 @@ #include #include - namespace commandbuffers { + namespace gpu + { + class PhysicalDeviceBase; + } + struct GPUDeviceDescriptor { std::string_view label; @@ -40,13 +45,13 @@ namespace commandbuffers GPUInstance *getInstance() const; GPUAdapterBase *getAdapter() const; - GPUPhysicalDeviceBase *getPhysicalDevice() const; + gpu::PhysicalDeviceBase *getPhysicalDevice() const; virtual std::unique_ptr createCommandBuffer( GPUCommandEncoder &encoder, const GPUCommandBufferDescriptor *descriptor = nullptr) = 0; - std::shared_ptr GetOrCreateBindGroupLayout(); + Ref getOrCreateBindGroupLayout(); bool isValidationEnabled() const; bool isRobustnessEnabled() const; @@ -59,5 +64,8 @@ namespace commandbuffers GPUAdapterInfo adapter_info_; GPUSupportedFeatures features_; GPUSupportedLimits limits_; + + private: + Ref adapter_; }; } diff --git a/src/common/command_buffers/gpu/gpu_instance.cpp b/src/common/command_buffers/gpu/gpu_instance.cpp index d5dbae55f..34d73c735 100644 --- a/src/common/command_buffers/gpu/gpu_instance.cpp +++ b/src/common/command_buffers/gpu/gpu_instance.cpp @@ -1,5 +1,6 @@ #include #include +#include using namespace std; @@ -19,6 +20,12 @@ namespace commandbuffers return instance; } + void GPUInstance::registerBackend(gpu::BackendConnection *backend) + { + assert(backend != nullptr && "Backend connection cannot be null."); + backend_ = std::unique_ptr(backend); + } + void GPUInstance::addDevice(shared_ptr) { } diff --git a/src/common/command_buffers/gpu/gpu_instance.hpp b/src/common/command_buffers/gpu/gpu_instance.hpp index 2bd320204..3d477e76c 100644 --- a/src/common/command_buffers/gpu/gpu_instance.hpp +++ b/src/common/command_buffers/gpu/gpu_instance.hpp @@ -12,6 +12,7 @@ namespace commandbuffers namespace gpu { class BackendConnection; + class PhysicalDeviceBase; } struct GPUInstanceDescriptor @@ -27,7 +28,6 @@ namespace commandbuffers static Ref Create(const GPUInstanceDescriptor *descriptor = nullptr); void registerBackend(gpu::BackendConnection *backend); - void addDevice(Ref); void removeDevice(Ref); @@ -38,7 +38,7 @@ namespace commandbuffers virtual ~GPUInstance() = default; void initialize(const GPUInstanceDescriptor &descriptor); - Ref createAdapter(Ref physicalDevice, + Ref createAdapter(Ref physicalDevice, GPUFeatureLevel featureLevel, GPUPowerPreference powerPreference); @@ -46,7 +46,7 @@ namespace commandbuffers private: std::unordered_set instance_features_; - std::vector> devices_list_; - Ref backend_ = nullptr; + std::vector> devices_list_; + std::unique_ptr backend_; }; } diff --git a/src/common/command_buffers/gpu/gpu_physical_device.cpp b/src/common/command_buffers/gpu/gpu_physical_device.cpp deleted file mode 100644 index f393294b8..000000000 --- a/src/common/command_buffers/gpu/gpu_physical_device.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include - -namespace commandbuffers -{ -} diff --git a/src/common/command_buffers/gpu/gpu_pipeline.cpp b/src/common/command_buffers/gpu/gpu_pipeline.cpp index 9fec159ed..5f40f5534 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline.cpp +++ b/src/common/command_buffers/gpu/gpu_pipeline.cpp @@ -2,8 +2,24 @@ #include #include +using namespace std; + namespace commandbuffers { + GPUPipelineBase::GPUPipelineBase(Ref device, + Ref layout, + string_view label) + : GPUHandle(device, label) + { + } + + GPUPipelineBase::GPUPipelineBase(shared_ptr device, + GPUHandle::ErrorTag, + string_view label) + : GPUHandle(device, ErrorTag{}, label) + { + } + const GPUComputePipelineBase *GPUPipelineBase::getAsComputePipeline() const { return nullptr; @@ -23,4 +39,14 @@ namespace commandbuffers { return nullptr; } + + GPUPipelineLayoutBase *GPUPipelineBase::layout() + { + return layout_.get(); + } + + const GPUPipelineLayoutBase *GPUPipelineBase::layout() const + { + return layout_.get(); + } } diff --git a/src/common/command_buffers/gpu/gpu_pipeline.hpp b/src/common/command_buffers/gpu/gpu_pipeline.hpp index e29a593ea..56393f851 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_pipeline.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -27,19 +28,19 @@ namespace commandbuffers virtual const GPURenderPipelineBase *getAsRenderPipeline() const; virtual GPURenderPipelineBase *getAsRenderPipeline(); - GPUPipelineBase *layout(); + GPUPipelineLayoutBase *layout(); const GPUPipelineLayoutBase *layout() const; protected: - GPUPipelineBase(std::shared_ptr device, - std::shared_ptr layout, + GPUPipelineBase(Ref device, + Ref layout, std::string_view label); - GPUPipelineBase(std::shared_ptr device, + GPUPipelineBase(Ref device, GPUHandle::ErrorTag, std::string_view label); private: GPUShaderStage stage_mask_ = GPUShaderStage::kNone; - std::shared_ptr layout_; + Ref layout_; }; } diff --git a/src/common/command_buffers/gpu/gpu_render_pipeline.cpp b/src/common/command_buffers/gpu/gpu_render_pipeline.cpp index b44e80a49..4a2edce24 100644 --- a/src/common/command_buffers/gpu/gpu_render_pipeline.cpp +++ b/src/common/command_buffers/gpu/gpu_render_pipeline.cpp @@ -5,11 +5,9 @@ using namespace std; namespace commandbuffers { - GPURenderPipelineBase::GPURenderPipelineBase(shared_ptr device, + GPURenderPipelineBase::GPURenderPipelineBase(Ref device, const GPURenderPipelineDescriptor &descriptor) - : GPUPipelineBase(device, - descriptor.layout, - descriptor.label) + : GPUPipelineBase(device, descriptor.layout, descriptor.label) { } -} \ No newline at end of file +} diff --git a/src/common/command_buffers/gpu/gpu_render_pipeline.hpp b/src/common/command_buffers/gpu/gpu_render_pipeline.hpp index 0bbff5864..448c1bf2e 100644 --- a/src/common/command_buffers/gpu/gpu_render_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_render_pipeline.hpp @@ -2,6 +2,8 @@ #include #include + +#include #include #include @@ -11,7 +13,7 @@ namespace commandbuffers struct GPURenderPipelineDescriptor { std::string_view label; - std::shared_ptr layout = nullptr; + Ref layout = nullptr; GPUVertexState vertex; GPUPrimitiveState primitive; GPUDepthStencilState const *depthStencil = nullptr; @@ -22,7 +24,6 @@ namespace commandbuffers class GPURenderPipelineBase : public GPUPipelineBase { public: - GPURenderPipelineBase(std::shared_ptr device, - const GPURenderPipelineDescriptor &descriptor); + GPURenderPipelineBase(Ref device, const GPURenderPipelineDescriptor &descriptor); }; } diff --git a/src/common/command_buffers/gpu/physical_device.cpp b/src/common/command_buffers/gpu/physical_device.cpp new file mode 100644 index 000000000..71b364ab0 --- /dev/null +++ b/src/common/command_buffers/gpu/physical_device.cpp @@ -0,0 +1,79 @@ +#include + +using namespace std; + +namespace commandbuffers::gpu +{ + void PhysicalDeviceBase::initialize() + { + } + + Ref PhysicalDeviceBase::createDevice(Ref adapter, + GPUDeviceDescriptor &descriptor) + { + return nullptr; + } + + uint32_t PhysicalDeviceBase::vendorId() const + { + return vendor_id_; + } + + uint32_t PhysicalDeviceBase::deviceId() const + { + return device_id_; + } + + const string &PhysicalDeviceBase::vendorName() const + { + return vendor_name_; + } + + const string &PhysicalDeviceBase::architectureName() const + { + return arch_name_; + } + + const string &PhysicalDeviceBase::name() const + { + return name_; + } + + const gpu_info::DriverVersion &PhysicalDeviceBase::driverVersion() const + { + return driver_version_; + } + + const string &PhysicalDeviceBase::driverDescription() const + { + return driver_description_; + } + + GPUAdapterType PhysicalDeviceBase::adapterType() const + { + return adapter_type_; + } + + GPUBackendType PhysicalDeviceBase::backendType() const + { + return backend_type_; + } + + uint32_t PhysicalDeviceBase::subgroupMinSize() const + { + return subgroup_min_size_; + } + + uint32_t PhysicalDeviceBase::subgroupMaxSize() const + { + return subgroup_max_size_; + } + + void PhysicalDeviceBase::enableFeature(GPUFeatureName feature) + { + } + + void PhysicalDeviceBase::initializeVendorArchitectureImpl() + { + } +} diff --git a/src/common/command_buffers/gpu/gpu_physical_device.hpp b/src/common/command_buffers/gpu/physical_device.hpp similarity index 82% rename from src/common/command_buffers/gpu/gpu_physical_device.hpp rename to src/common/command_buffers/gpu/physical_device.hpp index ed903ca92..8b3a2b361 100644 --- a/src/common/command_buffers/gpu/gpu_physical_device.hpp +++ b/src/common/command_buffers/gpu/physical_device.hpp @@ -2,21 +2,22 @@ #include #include + +#include #include #include #include #include -namespace commandbuffers +namespace commandbuffers::gpu { - class GPUPhysicalDeviceBase + class PhysicalDeviceBase { public: - explicit GPUPhysicalDeviceBase() = default; + explicit PhysicalDeviceBase() = default; void initialize(); - std::shared_ptr createDevice(std::shared_ptr adapter, - GPUDeviceDescriptor &descriptor); + Ref createDevice(Ref adapter, GPUDeviceDescriptor &descriptor); uint32_t vendorId() const; uint32_t deviceId() const; @@ -36,7 +37,7 @@ namespace commandbuffers void enableFeature(GPUFeatureName feature); private: - virtual std::unique_ptr createDeviceImpl(std::shared_ptr adapter, + virtual std::unique_ptr createDeviceImpl(Ref adapter, GPUDeviceDescriptor &descriptor) = 0; virtual void initializeImpl() = 0; virtual void initializeSupportedFeaturesImpl() = 0; diff --git a/src/renderer/gles/gpu_backend_impl.cpp b/src/renderer/gles/gpu_backend_impl.cpp index 15411b42d..e0a880300 100644 --- a/src/renderer/gles/gpu_backend_impl.cpp +++ b/src/renderer/gles/gpu_backend_impl.cpp @@ -10,7 +10,7 @@ namespace gles { } - vector> GPUBackend::discoverPhysicalDevices(const gpu::RequestAdapterOptions &options) + vector> GPUBackend::discoverPhysicalDevices(const gpu::RequestAdapterOptions &options) { return {}; } diff --git a/src/renderer/gles/gpu_backend_impl.hpp b/src/renderer/gles/gpu_backend_impl.hpp index 9e28a9f28..5b3844427 100644 --- a/src/renderer/gles/gpu_backend_impl.hpp +++ b/src/renderer/gles/gpu_backend_impl.hpp @@ -12,7 +12,7 @@ namespace gles public: GPUBackend(commandbuffers::GPUInstance *instance, commandbuffers::GPUBackendType type); - std::vector> discoverPhysicalDevices( + std::vector> discoverPhysicalDevices( const commandbuffers::gpu::RequestAdapterOptions &options) override; }; } diff --git a/src/renderer/gles/gpu_physical_device_impl.cpp b/src/renderer/gles/gpu_physical_device_impl.cpp index 9fa409981..bd49051da 100644 --- a/src/renderer/gles/gpu_physical_device_impl.cpp +++ b/src/renderer/gles/gpu_physical_device_impl.cpp @@ -10,8 +10,8 @@ namespace gles return false; } - unique_ptr GPUPhysicalDeviceImpl::createDeviceImpl(shared_ptr adapter, - GPUDeviceDescriptor &descriptor) + std::unique_ptr GPUPhysicalDeviceImpl::createDeviceImpl(Ref adapter, + GPUDeviceDescriptor &descriptor) { return nullptr; } @@ -23,5 +23,4 @@ namespace gles void GPUPhysicalDeviceImpl::initializeSupportedFeaturesImpl() { } - } diff --git a/src/renderer/gles/gpu_physical_device_impl.hpp b/src/renderer/gles/gpu_physical_device_impl.hpp index 9c0d220cc..099b59d63 100644 --- a/src/renderer/gles/gpu_physical_device_impl.hpp +++ b/src/renderer/gles/gpu_physical_device_impl.hpp @@ -1,18 +1,19 @@ #pragma once -#include +#include +#include #include namespace gles { - class GPUPhysicalDeviceImpl final : public commandbuffers::GPUPhysicalDeviceBase + class GPUPhysicalDeviceImpl final : public commandbuffers::gpu::PhysicalDeviceBase { public: bool supportsExternalImages() const override; private: std::unique_ptr createDeviceImpl( - std::shared_ptr adapter, + Ref adapter, commandbuffers::GPUDeviceDescriptor &descriptor) override; void initializeImpl() override; diff --git a/src/renderer/metal/gpu_backend_mtl.h b/src/renderer/metal/gpu_backend_mtl.h new file mode 100644 index 000000000..acd5b61c5 --- /dev/null +++ b/src/renderer/metal/gpu_backend_mtl.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include +#include + +namespace metal +{ + class GPUBackend final : public commandbuffers::gpu::BackendConnection + { + public: + GPUBackend(commandbuffers::GPUInstance *instance, commandbuffers::GPUBackendType type); + + std::vector> discoverPhysicalDevices( + const commandbuffers::gpu::RequestAdapterOptions &options) override; + }; +} diff --git a/src/renderer/metal/gpu_backend_mtl.mm b/src/renderer/metal/gpu_backend_mtl.mm new file mode 100644 index 000000000..3897de1a9 --- /dev/null +++ b/src/renderer/metal/gpu_backend_mtl.mm @@ -0,0 +1,23 @@ +#include + +using namespace std; +using namespace commandbuffers; + +namespace metal +{ + GPUBackend::GPUBackend(GPUInstance *instance, GPUBackendType type) + : BackendConnection(instance, type) + { + } + + vector> GPUBackend::discoverPhysicalDevices(const gpu::RequestAdapterOptions &options) + { + return {}; + } + + gpu::BackendConnection *Connect(GPUInstance *instance, GPUBackendType type) + { + assert(type == GPUBackendType::kMetal); + return new GPUBackend(instance, type); + } +} From d18d2061605a9084298b2387271a170e0fc90678 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 6 Nov 2025 17:53:54 +0800 Subject: [PATCH 11/37] update --- src/common/command_buffers/gpu/gpu_bind_group.hpp | 7 ++++--- src/common/command_buffers/gpu/gpu_bind_group_layout.cpp | 6 +++--- src/common/command_buffers/gpu/gpu_bind_group_layout.hpp | 9 +++++---- .../gpu/gpu_bind_group_layout_internal.cpp | 2 +- .../gpu/gpu_bind_group_layout_internal.hpp | 5 +++-- src/common/command_buffers/gpu/gpu_buffer.hpp | 8 ++++---- src/common/command_buffers/gpu/gpu_command_buffer.cpp | 4 +--- src/common/command_buffers/gpu/gpu_command_buffer.hpp | 5 ++--- src/common/command_buffers/gpu/gpu_command_encoder.hpp | 5 +++-- src/common/command_buffers/gpu/gpu_compute_pipeline.cpp | 6 +++++- src/common/command_buffers/gpu/gpu_instance.cpp | 4 ++-- src/common/command_buffers/gpu/gpu_pipeline.hpp | 8 ++------ src/common/command_buffers/gpu/gpu_texture_view.hpp | 8 +++++--- src/common/command_buffers/gpu/pass_resource_usage.hpp | 5 +++-- .../command_buffers/gpu/pass_resource_usage_tracker.cpp | 4 ++++ 15 files changed, 47 insertions(+), 39 deletions(-) diff --git a/src/common/command_buffers/gpu/gpu_bind_group.hpp b/src/common/command_buffers/gpu/gpu_bind_group.hpp index 8be2b63a0..46d98d499 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group.hpp +++ b/src/common/command_buffers/gpu/gpu_bind_group.hpp @@ -4,8 +4,9 @@ #include #include -#include "./gpu_base.hpp" -#include "./gpu_bind_group_layout.hpp" +#include +#include +#include namespace commandbuffers { @@ -15,6 +16,6 @@ namespace commandbuffers virtual ~GPUBindGroupBase() = default; private: - std::shared_ptr *layout_ = nullptr; + Ref *layout_ = nullptr; }; } diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp b/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp index 8ca9755c6..456800ab3 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout.cpp @@ -4,15 +4,15 @@ using namespace std; namespace commandbuffers { - GPUBindGroupLayoutBase::GPUBindGroupLayoutBase(shared_ptr device, + GPUBindGroupLayoutBase::GPUBindGroupLayoutBase(Ref device, string_view label, - shared_ptr internal) + Ref internal) : GPUHandle(device, label) , internal_layout_(internal) { } - GPUBindGroupLayoutBase::GPUBindGroupLayoutBase(shared_ptr device, + GPUBindGroupLayoutBase::GPUBindGroupLayoutBase(Ref device, GPUHandle::ErrorTag tag, string_view label) : GPUHandle(device, tag, label) diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp b/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp index 6ebc23de3..9ead60a1b 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -11,9 +12,9 @@ namespace commandbuffers class GPUBindGroupLayoutBase : public GPUHandle { public: - GPUBindGroupLayoutBase(std::shared_ptr device, + GPUBindGroupLayoutBase(Ref device, std::string_view label, - std::shared_ptr internal); + Ref internal); virtual ~GPUBindGroupLayoutBase() = default; GPUHandleType type() const override @@ -28,11 +29,11 @@ namespace commandbuffers bool isEmpty() const; private: - GPUBindGroupLayoutBase(std::shared_ptr device, + GPUBindGroupLayoutBase(Ref device, GPUHandle::ErrorTag tag, std::string_view label); private: - std::shared_ptr internal_layout_; + Ref internal_layout_; }; } diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp index 2c4236aa1..597c635b2 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.cpp @@ -4,7 +4,7 @@ using namespace std; namespace commandbuffers { - GPUBindGroupLayoutInternalBase::GPUBindGroupLayoutInternalBase(shared_ptr device, + GPUBindGroupLayoutInternalBase::GPUBindGroupLayoutInternalBase(Ref device, const GPUBindGroupLayoutDescriptor &descriptor) : GPUHandle(device, descriptor.label) { diff --git a/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp index bdf7eb70d..a3915fda8 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp +++ b/src/common/command_buffers/gpu/gpu_bind_group_layout_internal.hpp @@ -2,6 +2,8 @@ #include #include #include + +#include #include #include #include @@ -10,7 +12,6 @@ namespace commandbuffers { class GPUDeviceBase; - // In the BindGroupLayout, entries are sorted by type for more efficient lookup and iteration. // This enum is the order that's used and can also be used to index various ranges of entries. // The enum is public so that helper function can use it during creation of the BindGroupLayout, @@ -41,7 +42,7 @@ namespace commandbuffers using BindingMap = std::map; public: - GPUBindGroupLayoutInternalBase(std::shared_ptr device, + GPUBindGroupLayoutInternalBase(Ref device, const GPUBindGroupLayoutDescriptor &descriptor); virtual ~GPUBindGroupLayoutInternalBase(); diff --git a/src/common/command_buffers/gpu/gpu_buffer.hpp b/src/common/command_buffers/gpu/gpu_buffer.hpp index b67a6e068..10e572e9d 100644 --- a/src/common/command_buffers/gpu/gpu_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_buffer.hpp @@ -2,6 +2,7 @@ #include #include +#include #include namespace commandbuffers @@ -69,9 +70,8 @@ namespace commandbuffers void unmap(); protected: - GPUBufferBase(std::shared_ptr device, - const GPUBufferDescriptor &descriptor); - GPUBufferBase(std::shared_ptr device, + GPUBufferBase(Ref device, const GPUBufferDescriptor &descriptor); + GPUBufferBase(Ref device, const GPUBufferDescriptor *descriptor, GPUHandle::ErrorTag tag); @@ -93,7 +93,7 @@ namespace commandbuffers std::atomic map_state_ = BufferState::kUnmapped; // A recursive buffer used to implement mappedAtCreation for buffers with non-mappable usage. - std::shared_ptr staging_buffer_ = nullptr; + Ref staging_buffer_ = nullptr; // Mapping specific states. GPUMapMode mMapMode = GPUMapMode::kNone; diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.cpp b/src/common/command_buffers/gpu/gpu_command_buffer.cpp index 991abe251..de4402059 100644 --- a/src/common/command_buffers/gpu/gpu_command_buffer.cpp +++ b/src/common/command_buffers/gpu/gpu_command_buffer.cpp @@ -11,9 +11,7 @@ namespace commandbuffers { } - GPUCommandBufferBase::GPUCommandBufferBase(shared_ptr device, - GPUHandle::ErrorTag tag, - string_view label) + GPUCommandBufferBase::GPUCommandBufferBase(Ref device, GPUHandle::ErrorTag tag, string_view label) : GPUHandle(device, tag, label) { } diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.hpp b/src/common/command_buffers/gpu/gpu_command_buffer.hpp index c3a231dd1..96bbf97ec 100644 --- a/src/common/command_buffers/gpu/gpu_command_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_command_buffer.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -54,9 +55,7 @@ namespace commandbuffers gpu::CommandIterator commands_; private: - GPUCommandBufferBase(std::shared_ptr device, - GPUHandle::ErrorTag tag, - std::string_view label); + GPUCommandBufferBase(Ref device, GPUHandle::ErrorTag tag, std::string_view label); gpu::CommandBufferResourceUsage resource_usages_; std::vector indirect_draw_metadata_; diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index f1bd5951f..140b30a79 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -36,8 +37,8 @@ namespace commandbuffers std::unique_ptr finish(std::optional label = std::nullopt) const; private: - GPUCommandEncoder(std::shared_ptr device, const GPUCommandEncoderDescriptor &descriptor); - GPUCommandEncoder(std::shared_ptr device, + GPUCommandEncoder(Ref device, const GPUCommandEncoderDescriptor &descriptor); + GPUCommandEncoder(Ref device, GPUHandle::ErrorTag tag, std::string_view label); diff --git a/src/common/command_buffers/gpu/gpu_compute_pipeline.cpp b/src/common/command_buffers/gpu/gpu_compute_pipeline.cpp index d845cc780..01e4b4686 100644 --- a/src/common/command_buffers/gpu/gpu_compute_pipeline.cpp +++ b/src/common/command_buffers/gpu/gpu_compute_pipeline.cpp @@ -1 +1,5 @@ -#include \ No newline at end of file +#include + +namespace commandbuffers +{ +} diff --git a/src/common/command_buffers/gpu/gpu_instance.cpp b/src/common/command_buffers/gpu/gpu_instance.cpp index 34d73c735..1b8f580e8 100644 --- a/src/common/command_buffers/gpu/gpu_instance.cpp +++ b/src/common/command_buffers/gpu/gpu_instance.cpp @@ -26,11 +26,11 @@ namespace commandbuffers backend_ = std::unique_ptr(backend); } - void GPUInstance::addDevice(shared_ptr) + void GPUInstance::addDevice(Ref) { } - void GPUInstance::removeDevice(shared_ptr) + void GPUInstance::removeDevice(Ref) { } diff --git a/src/common/command_buffers/gpu/gpu_pipeline.hpp b/src/common/command_buffers/gpu/gpu_pipeline.hpp index 56393f851..965c280c5 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_pipeline.hpp @@ -32,12 +32,8 @@ namespace commandbuffers const GPUPipelineLayoutBase *layout() const; protected: - GPUPipelineBase(Ref device, - Ref layout, - std::string_view label); - GPUPipelineBase(Ref device, - GPUHandle::ErrorTag, - std::string_view label); + GPUPipelineBase(Ref device, Ref layout, std::string_view label); + GPUPipelineBase(Ref device, GPUHandle::ErrorTag, std::string_view label); private: GPUShaderStage stage_mask_ = GPUShaderStage::kNone; diff --git a/src/common/command_buffers/gpu/gpu_texture_view.hpp b/src/common/command_buffers/gpu/gpu_texture_view.hpp index 6e57e4305..b314f4589 100644 --- a/src/common/command_buffers/gpu/gpu_texture_view.hpp +++ b/src/common/command_buffers/gpu/gpu_texture_view.hpp @@ -3,6 +3,8 @@ #include #include #include + +#include #include #include @@ -24,9 +26,9 @@ namespace commandbuffers class GPUTextureViewBase : public GPUHandle { public: - GPUTextureViewBase(std::shared_ptr texture, const TextureViewDescriptor &descriptor); + GPUTextureViewBase(Ref texture, const TextureViewDescriptor &descriptor); - std::shared_ptr texture() const; + Ref texture() const; const GPUTextureBase &textureRef() const; GPUTextureViewDimension dimension() const; @@ -39,7 +41,7 @@ namespace commandbuffers bool isSwizzleIdentity() const; private: - std::shared_ptr texture_; + Ref texture_; GPUTextureViewDimension dimension_; GPUTextureUsage usage_ = GPUTextureUsage::kNone; GPUTextureUsage internal_usage_ = GPUTextureUsage::kNone; diff --git a/src/common/command_buffers/gpu/pass_resource_usage.hpp b/src/common/command_buffers/gpu/pass_resource_usage.hpp index 12a44ffdf..4a8ffd7d6 100644 --- a/src/common/command_buffers/gpu/pass_resource_usage.hpp +++ b/src/common/command_buffers/gpu/pass_resource_usage.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ namespace commandbuffers::gpu ComputePassUsages computePasses; // Resources used in commands that aren't in a pass. - std::unordered_set> topLevelBuffers; - std::unordered_set> topLevelTextures; + std::unordered_set> topLevelBuffers; + std::unordered_set> topLevelTextures; }; } diff --git a/src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp b/src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp index d75765df9..e6a389e0f 100644 --- a/src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp +++ b/src/common/command_buffers/gpu/pass_resource_usage_tracker.cpp @@ -1 +1,5 @@ #include + +namespace commandbuffers::gpu +{ +} From 39c7742ec155398886188b95dbea6e9994248d44 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 7 Nov 2025 16:46:30 +0800 Subject: [PATCH 12/37] update --- .../gpu/backend_connection.hpp | 8 -- .../command_buffers/gpu/gpu_adapter.cpp | 62 ++++++++++++-- .../command_buffers/gpu/gpu_adapter.hpp | 17 +++- src/common/command_buffers/gpu/gpu_base.hpp | 83 ++++++++++++++----- .../command_buffers/gpu/gpu_instance.cpp | 59 ++++++++++++- .../command_buffers/gpu/gpu_instance.hpp | 13 ++- .../command_buffers/gpu/physical_device.cpp | 13 ++- .../command_buffers/gpu/physical_device.hpp | 10 ++- src/common/utility.hpp | 7 ++ src/renderer/gles/gpu_backend_impl.cpp | 18 +++- src/renderer/gles/gpu_backend_impl.hpp | 2 +- src/renderer/gles/gpu_display_egl.cpp | 23 +++++ src/renderer/gles/gpu_display_egl.hpp | 18 ++++ .../gles/gpu_physical_device_impl.cpp | 30 ++++++- .../gles/gpu_physical_device_impl.hpp | 22 ++++- src/renderer/metal/gpu_backend_mtl.h | 2 +- src/renderer/metal/gpu_backend_mtl.mm | 2 +- src/renderer/render_api.cpp | 14 +++- src/renderer/render_api.hpp | 5 +- 19 files changed, 347 insertions(+), 61 deletions(-) create mode 100644 src/renderer/gles/gpu_display_egl.cpp create mode 100644 src/renderer/gles/gpu_display_egl.hpp diff --git a/src/common/command_buffers/gpu/backend_connection.hpp b/src/common/command_buffers/gpu/backend_connection.hpp index 05b401c91..46f1130b5 100644 --- a/src/common/command_buffers/gpu/backend_connection.hpp +++ b/src/common/command_buffers/gpu/backend_connection.hpp @@ -10,14 +10,6 @@ namespace commandbuffers::gpu { - struct RequestAdapterOptions - { - GPUFeatureLevel featureLevel = GPUFeatureLevel::kCore; - GPUPowerPreference powerPreference = GPUPowerPreference::Undefined; - bool forceFallbackAdapter = false; - GPUBackendType backendType = GPUBackendType::kUndefined; - }; - class BackendConnection : public NonMovable { public: diff --git a/src/common/command_buffers/gpu/gpu_adapter.cpp b/src/common/command_buffers/gpu/gpu_adapter.cpp index 3d7ee1143..3d2a2eb97 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.cpp +++ b/src/common/command_buffers/gpu/gpu_adapter.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -98,16 +99,15 @@ namespace commandbuffers } void GPUAdapterBase::requestDevice(const GPUDeviceDescriptor *descriptor, - function)> callback) + function callback) { auto device = createDevice(descriptor); - callback(move(device)); + callback(*device); } - unique_ptr GPUAdapterBase::createDevice(const GPUDeviceDescriptor *descriptor) + Ref GPUAdapterBase::createDevice(const GPUDeviceDescriptor *descriptor) { - // Implementation for creating a GPU device based on the descriptor - return nullptr; + return physical_device_->createDevice(shared_from_this(), *descriptor); } gpu::PhysicalDeviceBase *GPUAdapterBase::physicalDevice() @@ -129,4 +129,56 @@ namespace commandbuffers { return physical_device_->name(); } + + vector> SortAdapters(vector> adapters, + const RequestAdapterOptions &options) + { + const bool highPerformance = options.powerPreference == GPUPowerPreference::kHighPerformance; + const auto ComputeAdapterTypeRank = [&](const Ref &a) + { + switch (a->physicalDevice()->adapterType()) + { + case GPUAdapterType::kDiscreteGPU: + return highPerformance ? 0 : 1; + case GPUAdapterType::kIntegratedGPU: + return highPerformance ? 1 : 0; + case GPUAdapterType::kCPU: + return 2; + case GPUAdapterType::kUnknown: + return 3; + } + assert(false && "Unhandled GPUAdapterType"); + }; + const auto ComputeBackendTypeRank = [](const Ref &a) + { + switch (a->physicalDevice()->backendType()) + { + // Sort backends generally in order of Core -> Compat -> Testing, + // while preferring OS-specific backends like Metal/D3D. + case GPUBackendType::kMetal: + case GPUBackendType::kD3D12: + return 0; + case GPUBackendType::kVulkan: + return 1; + case GPUBackendType::kD3D11: + return 2; + case GPUBackendType::kOpenGLES: + return 3; + case GPUBackendType::kOpenGL: + return 4; + case GPUBackendType::kWebGPU: + return 5; + case GPUBackendType::kNull: + return 6; + case GPUBackendType::kUndefined: + break; + } + assert(false && "Unhandled GPUBackendType"); + }; + + sort(adapters.begin(), adapters.end(), [&](const Ref &a, const Ref &b) -> bool + { return tuple(ComputeAdapterTypeRank(a), ComputeBackendTypeRank(a)) < + tuple(ComputeAdapterTypeRank(b), ComputeBackendTypeRank(b)); }); + return adapters; + } } diff --git a/src/common/command_buffers/gpu/gpu_adapter.hpp b/src/common/command_buffers/gpu/gpu_adapter.hpp index ece81ebcd..50412f540 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.hpp +++ b/src/common/command_buffers/gpu/gpu_adapter.hpp @@ -18,6 +18,14 @@ namespace commandbuffers class PhysicalDeviceBase; } + struct RequestAdapterOptions + { + GPUFeatureLevel featureLevel = GPUFeatureLevel::kCore; + GPUPowerPreference powerPreference = GPUPowerPreference::kUndefined; + bool forceFallbackAdapter = false; + GPUBackendType backendType = GPUBackendType::kUndefined; + }; + class GPUAdapterInfo { public: @@ -49,7 +57,7 @@ namespace commandbuffers } }; - class GPUAdapterBase : ErrorMonad + class GPUAdapterBase : ErrorMonad, public std::enable_shared_from_this { public: GPUAdapterBase(Ref instance, @@ -61,8 +69,8 @@ namespace commandbuffers const GPUAdapterInfo &info() const; bool hasFeature(GPUFeatureName) const; void requestDevice(const GPUDeviceDescriptor *descriptor, - std::function)> callback); - std::unique_ptr createDevice(const GPUDeviceDescriptor *descriptor = nullptr); + std::function callback); + Ref createDevice(const GPUDeviceDescriptor *descriptor = nullptr); gpu::PhysicalDeviceBase *physicalDevice(); const gpu::PhysicalDeviceBase *physicalDevice() const; @@ -83,4 +91,7 @@ namespace commandbuffers // create a device. bool adapter_is_consumed = false; }; + + std::vector> SortAdapters(std::vector> adapters, + const RequestAdapterOptions &options); } diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index d953fd92d..68aaac556 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -280,26 +280,67 @@ namespace commandbuffers kBindGroupLayoutInternal, }; - enum class GPUBackendType : uint32_t - { - kUndefined, - kNull, - kWebGPU, - kD3D11, - kD3D12, - kMetal, - kVulkan, - kOpenGL, - kOpenGLES, - }; +#define GPU_BACKEND_TYPES(XX) \ + XX(kUndefined, "undefined") \ + XX(kNull, "null") \ + XX(kWebGPU, "webgpu") \ + XX(kD3D11, "d3d11") \ + XX(kD3D12, "d3d12") \ + XX(kMetal, "metal") \ + XX(kVulkan, "vulkan") \ + XX(kOpenGL, "opengl") \ + XX(kOpenGLES, "opengles") + +#define GPU_ADAPTER_TYPES(XX) \ + XX(kDiscreteGPU, "discrete-gpu") \ + XX(kIntegratedGPU, "integrated-gpu") \ + XX(kCPU, "cpu") \ + XX(kUnknown, "unknown") + +#define DECL_GPU_ENUM_ITEM(NAME, _) NAME, +#define ADD_GPU_ENUM(ENUM_TYPE, BASE_TYPE, MAP) \ + enum class ENUM_TYPE : BASE_TYPE \ + { \ + MAP(DECL_GPU_ENUM_ITEM) \ + }; + + ADD_GPU_ENUM(GPUBackendType, uint32_t, GPU_BACKEND_TYPES) + ADD_GPU_ENUM(GPUAdapterType, uint32_t, GPU_ADAPTER_TYPES) + +#undef DECL_GPU_ENUM_ITEM +#undef ADD_GPU_ENUM + + inline std::string to_string(GPUBackendType type) + { +#define XX(NAME, STR) \ + case GPUBackendType::NAME: \ + return STR; + + switch (type) + { + GPU_BACKEND_TYPES(XX) + default: + assert(false && "Unknown GPUBackendType"); + return "unknown"; + } +#undef XX + } - enum class GPUAdapterType : uint32_t + inline std::string to_string(GPUAdapterType type) { - kDiscreteGPU, - kIntegratedGPU, - kCPU, - kUnknown, - }; +#define XX(NAME, STR) \ + case GPUAdapterType::NAME: \ + return STR; + + switch (type) + { + GPU_ADAPTER_TYPES(XX) + default: + assert(false && "Unknown GPUAdapterType"); + return "unknown"; + } +#undef XX + } enum class GPUShaderStage : uint64_t { @@ -632,9 +673,9 @@ namespace commandbuffers enum class GPUPowerPreference : uint32_t { - Undefined = 0x00000000, - LowPower = 0x00000001, - HighPerformance = 0x00000002, + kUndefined = 0x00000000, + kLowPower = 0x00000001, + kHighPerformance = 0x00000002, }; class GPUSupportedFeatures : public std::unordered_set diff --git a/src/common/command_buffers/gpu/gpu_instance.cpp b/src/common/command_buffers/gpu/gpu_instance.cpp index 1b8f580e8..b5127a8a4 100644 --- a/src/common/command_buffers/gpu/gpu_instance.cpp +++ b/src/common/command_buffers/gpu/gpu_instance.cpp @@ -6,6 +6,7 @@ using namespace std; namespace commandbuffers { + // static Ref GPUInstance::Create(const GPUInstanceDescriptor *descriptor) { static constexpr GPUInstanceDescriptor kDefaultDesc = {}; @@ -20,10 +21,41 @@ namespace commandbuffers return instance; } + GPUInstance::GPUInstance() + { + } + + Ref GPUInstance::requestAdapter(const RequestAdapterOptions &options) + { + auto adapters = enumerateAdapters(&options); + if (adapters.empty()) + { + return nullptr; + } + return adapters[0]; + } + + vector> GPUInstance::enumerateAdapters(const RequestAdapterOptions *options) + { + static constexpr RequestAdapterOptions kDefaultOptions = {}; + if (options == nullptr) + { + options = &kDefaultOptions; + } + + vector> adapters; + for (const auto &physicalDevice : enumeratePhysicalDevices(*options)) + { + assert(physicalDevice->supportsFeatureLevel(options->featureLevel, this)); + adapters.push_back(createAdapter(physicalDevice, options->featureLevel, options->powerPreference)); + } + return SortAdapters(std::move(adapters), *options); + } + void GPUInstance::registerBackend(gpu::BackendConnection *backend) { assert(backend != nullptr && "Backend connection cannot be null."); - backend_ = std::unique_ptr(backend); + backend_ = unique_ptr(backend); } void GPUInstance::addDevice(Ref) @@ -39,11 +71,32 @@ namespace commandbuffers return instance_features_.find(feature) != instance_features_.end(); } - GPUInstance::GPUInstance() + void GPUInstance::initialize(const GPUInstanceDescriptor &descriptor) { } - void GPUInstance::initialize(const GPUInstanceDescriptor &descriptor) + Ref GPUInstance::createAdapter(Ref physicalDevice, + GPUFeatureLevel featureLevel, + GPUPowerPreference powerPreference) + { + return AcquireRef(new GPUAdapterBase(shared_from_this(), + physicalDevice, + featureLevel, + powerPreference)); + } + + gpu::BackendConnection *GPUInstance::getBackendConnection() const { + return backend_.get(); + } + + vector> GPUInstance::enumeratePhysicalDevices(const RequestAdapterOptions &options) + { + vector> discoveredPhysicalDevices; + if (backend_) + { + discoveredPhysicalDevices = backend_->discoverPhysicalDevices(options); + } + return discoveredPhysicalDevices; } } diff --git a/src/common/command_buffers/gpu/gpu_instance.hpp b/src/common/command_buffers/gpu/gpu_instance.hpp index 3d477e76c..21fa7ede0 100644 --- a/src/common/command_buffers/gpu/gpu_instance.hpp +++ b/src/common/command_buffers/gpu/gpu_instance.hpp @@ -22,11 +22,19 @@ namespace commandbuffers GPUSupportedLimits *requiredLimits = nullptr; }; - class GPUInstance final + class GPUInstance final : std::enable_shared_from_this { public: static Ref Create(const GPUInstanceDescriptor *descriptor = nullptr); + // Discovers and returns a single adapter based on the `options`. + Ref requestAdapter(const RequestAdapterOptions &options); + + // Discovers and returns a vector of adapters. + // All systems adapters that can be found are returned if no options are passed. + // Otherwise, returns adapters based on the `options`. + std::vector> enumerateAdapters(const RequestAdapterOptions *options = nullptr); + void registerBackend(gpu::BackendConnection *backend); void addDevice(Ref); void removeDevice(Ref); @@ -44,6 +52,9 @@ namespace commandbuffers gpu::BackendConnection *getBackendConnection() const; + // Enumerate physical devices according to options and return them. + std::vector> enumeratePhysicalDevices(const RequestAdapterOptions &options); + private: std::unordered_set instance_features_; std::vector> devices_list_; diff --git a/src/common/command_buffers/gpu/physical_device.cpp b/src/common/command_buffers/gpu/physical_device.cpp index 71b364ab0..585d62729 100644 --- a/src/common/command_buffers/gpu/physical_device.cpp +++ b/src/common/command_buffers/gpu/physical_device.cpp @@ -4,14 +4,21 @@ using namespace std; namespace commandbuffers::gpu { + PhysicalDeviceBase::PhysicalDeviceBase(GPUBackendType type) + : backend_type_(type) + { + } + void PhysicalDeviceBase::initialize() { + initializeImpl(); + initializeVendorArchitectureImpl(); } Ref PhysicalDeviceBase::createDevice(Ref adapter, - GPUDeviceDescriptor &descriptor) + const GPUDeviceDescriptor &descriptor) { - return nullptr; + return createDeviceImpl(adapter, descriptor); } uint32_t PhysicalDeviceBase::vendorId() const @@ -75,5 +82,7 @@ namespace commandbuffers::gpu void PhysicalDeviceBase::initializeVendorArchitectureImpl() { + vendor_name_ = gpu_info::GetVendorName(vendor_id_); + arch_name_ = gpu_info::GetArchitectureName(vendor_id_, device_id_); } } diff --git a/src/common/command_buffers/gpu/physical_device.hpp b/src/common/command_buffers/gpu/physical_device.hpp index 8b3a2b361..27355cc6f 100644 --- a/src/common/command_buffers/gpu/physical_device.hpp +++ b/src/common/command_buffers/gpu/physical_device.hpp @@ -8,16 +8,17 @@ #include #include #include +#include namespace commandbuffers::gpu { class PhysicalDeviceBase { public: - explicit PhysicalDeviceBase() = default; + explicit PhysicalDeviceBase(GPUBackendType); void initialize(); - Ref createDevice(Ref adapter, GPUDeviceDescriptor &descriptor); + Ref createDevice(Ref adapter, const GPUDeviceDescriptor &descriptor); uint32_t vendorId() const; uint32_t deviceId() const; @@ -32,13 +33,14 @@ namespace commandbuffers::gpu uint32_t subgroupMaxSize() const; virtual bool supportsExternalImages() const = 0; + virtual bool supportsFeatureLevel(GPUFeatureLevel featureLevel, GPUInstance *instance) const = 0; protected: void enableFeature(GPUFeatureName feature); private: - virtual std::unique_ptr createDeviceImpl(Ref adapter, - GPUDeviceDescriptor &descriptor) = 0; + virtual Ref createDeviceImpl(Ref adapter, + const GPUDeviceDescriptor &descriptor) = 0; virtual void initializeImpl() = 0; virtual void initializeSupportedFeaturesImpl() = 0; virtual void initializeVendorArchitectureImpl(); diff --git a/src/common/utility.hpp b/src/common/utility.hpp index cc54a738e..3b5292a44 100644 --- a/src/common/utility.hpp +++ b/src/common/utility.hpp @@ -36,6 +36,13 @@ private: \ template using Ref = std::shared_ptr; +template +inline Ref AcquireRef(T *ptr) +{ + return std::shared_ptr(ptr, [](T *p) + { delete p; }); +} + /** * Shared reference is a template class that holds the shared pointer of a type. * diff --git a/src/renderer/gles/gpu_backend_impl.cpp b/src/renderer/gles/gpu_backend_impl.cpp index e0a880300..77e7fcf94 100644 --- a/src/renderer/gles/gpu_backend_impl.cpp +++ b/src/renderer/gles/gpu_backend_impl.cpp @@ -1,4 +1,7 @@ +#include #include +#include +#include using namespace std; using namespace commandbuffers; @@ -10,9 +13,20 @@ namespace gles { } - vector> GPUBackend::discoverPhysicalDevices(const gpu::RequestAdapterOptions &options) + vector> GPUBackend::discoverPhysicalDevices(const RequestAdapterOptions &options) { - return {}; + if (options.forceFallbackAdapter) + return {}; + if (options.featureLevel != GPUFeatureLevel::kCompatibility) + return {}; + + vector> devices; + { + Ref display = DisplayEGL::CreateFromCurrent(); + Ref newDevice = GPUPhysicalDeviceImpl::Create(type(), display, true); + devices.push_back(newDevice); + } + return devices; } gpu::BackendConnection *Connect(GPUInstance *instance, GPUBackendType type) diff --git a/src/renderer/gles/gpu_backend_impl.hpp b/src/renderer/gles/gpu_backend_impl.hpp index 5b3844427..2ecb1a67e 100644 --- a/src/renderer/gles/gpu_backend_impl.hpp +++ b/src/renderer/gles/gpu_backend_impl.hpp @@ -13,6 +13,6 @@ namespace gles GPUBackend(commandbuffers::GPUInstance *instance, commandbuffers::GPUBackendType type); std::vector> discoverPhysicalDevices( - const commandbuffers::gpu::RequestAdapterOptions &options) override; + const commandbuffers::RequestAdapterOptions &options) override; }; } diff --git a/src/renderer/gles/gpu_display_egl.cpp b/src/renderer/gles/gpu_display_egl.cpp new file mode 100644 index 000000000..b5fbf68ea --- /dev/null +++ b/src/renderer/gles/gpu_display_egl.cpp @@ -0,0 +1,23 @@ +#include + +using namespace std; +using namespace commandbuffers; + +namespace gles +{ + // static + Ref DisplayEGL::CreateFromCurrent() + { + Ref display = AcquireRef(new DisplayEGL(GPUBackendType::kOpenGLES)); + display->initializeFromCurrent(); + return display; + } + + DisplayEGL::DisplayEGL(GPUBackendType type) + { + } + + void DisplayEGL::initializeFromCurrent() + { + } +} diff --git a/src/renderer/gles/gpu_display_egl.hpp b/src/renderer/gles/gpu_display_egl.hpp new file mode 100644 index 000000000..72cb4bf7c --- /dev/null +++ b/src/renderer/gles/gpu_display_egl.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +namespace gles +{ + class DisplayEGL + { + public: + static Ref CreateFromCurrent(); + + explicit DisplayEGL(commandbuffers::GPUBackendType); + + private: + void initializeFromCurrent(); + }; +} diff --git a/src/renderer/gles/gpu_physical_device_impl.cpp b/src/renderer/gles/gpu_physical_device_impl.cpp index bd49051da..4a732d08b 100644 --- a/src/renderer/gles/gpu_physical_device_impl.cpp +++ b/src/renderer/gles/gpu_physical_device_impl.cpp @@ -5,15 +5,33 @@ using namespace commandbuffers; namespace gles { + // static + Ref GPUPhysicalDeviceImpl::Create(GPUBackendType backendType, + Ref display, + bool forceES31AndMinExtensions) + { + return nullptr; + } + + GPUPhysicalDeviceImpl::GPUPhysicalDeviceImpl(GPUBackendType backendType, Ref display) + : PhysicalDeviceBase(backendType) + { + } + + DisplayEGL *GPUPhysicalDeviceImpl::display() const + { + return display_.get(); + } + bool GPUPhysicalDeviceImpl::supportsExternalImages() const { return false; } - std::unique_ptr GPUPhysicalDeviceImpl::createDeviceImpl(Ref adapter, - GPUDeviceDescriptor &descriptor) + bool GPUPhysicalDeviceImpl::supportsFeatureLevel(GPUFeatureLevel featureLevel, + GPUInstance *instance) const { - return nullptr; + return false; } void GPUPhysicalDeviceImpl::initializeImpl() @@ -23,4 +41,10 @@ namespace gles void GPUPhysicalDeviceImpl::initializeSupportedFeaturesImpl() { } + + Ref GPUPhysicalDeviceImpl::createDeviceImpl(Ref adapter, + const GPUDeviceDescriptor &descriptor) + { + return nullptr; + } } diff --git a/src/renderer/gles/gpu_physical_device_impl.hpp b/src/renderer/gles/gpu_physical_device_impl.hpp index 099b59d63..5d2f986e3 100644 --- a/src/renderer/gles/gpu_physical_device_impl.hpp +++ b/src/renderer/gles/gpu_physical_device_impl.hpp @@ -3,20 +3,36 @@ #include #include #include +#include +#include namespace gles { class GPUPhysicalDeviceImpl final : public commandbuffers::gpu::PhysicalDeviceBase { public: + static Ref Create(commandbuffers::GPUBackendType backendType, + Ref display, + bool forceES31AndMinExtensions); + + DisplayEGL *display() const; + bool supportsExternalImages() const override; + bool supportsFeatureLevel(commandbuffers::GPUFeatureLevel featureLevel, + commandbuffers::GPUInstance *instance) const override; private: - std::unique_ptr createDeviceImpl( - Ref adapter, - commandbuffers::GPUDeviceDescriptor &descriptor) override; + GPUPhysicalDeviceImpl(commandbuffers::GPUBackendType backendType, + Ref display); void initializeImpl() override; void initializeSupportedFeaturesImpl() override; + + Ref createDeviceImpl( + Ref adapter, + const commandbuffers::GPUDeviceDescriptor &descriptor) override; + + private: + Ref display_; }; } diff --git a/src/renderer/metal/gpu_backend_mtl.h b/src/renderer/metal/gpu_backend_mtl.h index acd5b61c5..6e35dc0ac 100644 --- a/src/renderer/metal/gpu_backend_mtl.h +++ b/src/renderer/metal/gpu_backend_mtl.h @@ -13,6 +13,6 @@ namespace metal GPUBackend(commandbuffers::GPUInstance *instance, commandbuffers::GPUBackendType type); std::vector> discoverPhysicalDevices( - const commandbuffers::gpu::RequestAdapterOptions &options) override; + const commandbuffers::RequestAdapterOptions &options) override; }; } diff --git a/src/renderer/metal/gpu_backend_mtl.mm b/src/renderer/metal/gpu_backend_mtl.mm index 3897de1a9..1a4aeb674 100644 --- a/src/renderer/metal/gpu_backend_mtl.mm +++ b/src/renderer/metal/gpu_backend_mtl.mm @@ -10,7 +10,7 @@ { } - vector> GPUBackend::discoverPhysicalDevices(const gpu::RequestAdapterOptions &options) + vector> GPUBackend::discoverPhysicalDevices(const RequestAdapterOptions &options) { return {}; } diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index aac76a26a..d5f59d8c3 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -42,34 +42,43 @@ TrRenderHardwareInterface::TrRenderHardwareInterface(RHIBackendType backend_type : backendType(backend_type) , gpuInstance(GPUInstance::Create()) { + RequestAdapterOptions requestOptions; + requestOptions.featureLevel = GPUFeatureLevel::kCompatibility; + requestOptions.powerPreference = GPUPowerPreference::kHighPerformance; + switch (backend_type) { #if SUPPORT_D3D11 case RHIBackendType::D3D11: gpuInstance->registerBackend(d3d11::Connect(gpuInstance.get(), GPUBackendType::kD3D11)); + requestOptions.backendType = GPUBackendType::kD3D11; break; #endif #if SUPPORT_OPENGL_UNIFIED case RHIBackendType::OpenGLCore: gpuInstance->registerBackend(gles::Connect(gpuInstance.get(), GPUBackendType::kOpenGL)); + requestOptions.backendType = GPUBackendType::kOpenGL; break; case RHIBackendType::OpenGLESv2: case RHIBackendType::OpenGLESv3: gpuInstance->registerBackend(gles::Connect(gpuInstance.get(), GPUBackendType::kOpenGLES)); + requestOptions.backendType = GPUBackendType::kOpenGLES; break; #endif #if SUPPORT_METAL case RHIBackendType::Metal: gpuInstance->registerBackend(metal::Connect(gpuInstance.get(), GPUBackendType::kMetal)); + requestOptions.backendType = GPUBackendType::kMetal; break; #endif #if SUPPORT_VULKAN case RHIBackendType::VULKAN: gpuInstance->registerBackend(vulkan::Connect(gpuInstance.get(), GPUBackendType::kVulkan)); + requestOptions.backendType = GPUBackendType::kVulkan; break; #endif @@ -77,9 +86,12 @@ TrRenderHardwareInterface::TrRenderHardwareInterface(RHIBackendType backend_type // Unsupported backend type assert(false && "Unsupported RHI backend type."); } + + gpuAdapter = gpuInstance->requestAdapter(requestOptions); + gpuDevice = gpuAdapter->createDevice(); } -void TrRenderHardwareInterface::SubmitGPUCommandBuffer(vector> &commandBuffers) +void TrRenderHardwareInterface::SubmitGPUCommandBuffer(vector> &commandBuffers) { // TODO(yorkie): Handle the submission result and errors. } diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index cfc88ff8c..9cfa82e74 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -156,7 +156,7 @@ class TrRenderHardwareInterface /** * Submit a GPUCommandBuffer list to the GPU device for execution. */ - void SubmitGPUCommandBuffer(std::vector> &); + void SubmitGPUCommandBuffer(std::vector> &); std::unique_ptr CreateCommandEncoder(); /** @@ -269,7 +269,7 @@ class TrRenderHardwareInterface /** * @returns the `renderer::TrRenderer` shared pointer to use. */ - inline std::shared_ptr GetRenderer() + inline Ref GetRenderer() { return renderer.lock(); } @@ -324,6 +324,7 @@ class TrRenderHardwareInterface bool m_PrintsContext = false; Ref gpuInstance = nullptr; + Ref gpuAdapter = nullptr; Ref gpuDevice = nullptr; /** From ea89d9bbd9f52cba9e17ac4481eae76ba4219ad3 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 7 Nov 2025 20:41:30 +0800 Subject: [PATCH 13/37] update --- src/common/command_buffers/gpu/gpu_device.cpp | 3 +- src/common/command_buffers/gpu/gpu_device.hpp | 3 +- .../command_buffers/gpu/gpu_instance.cpp | 3 +- .../command_buffers/gpu/gpu_instance.hpp | 5 +- src/common/utility.hpp | 13 ++- src/renderer/gles/gpu_device_impl.cpp | 19 +++- src/renderer/gles/gpu_device_impl.hpp | 10 +- .../gles/gpu_physical_device_impl.cpp | 105 +++++++++++++++++- 8 files changed, 144 insertions(+), 17 deletions(-) diff --git a/src/common/command_buffers/gpu/gpu_device.cpp b/src/common/command_buffers/gpu/gpu_device.cpp index 01a8a56b2..742086215 100644 --- a/src/common/command_buffers/gpu/gpu_device.cpp +++ b/src/common/command_buffers/gpu/gpu_device.cpp @@ -2,8 +2,7 @@ namespace commandbuffers { - GPUDeviceBase::GPUDeviceBase(GPUAdapterBase *adapter, - GPUDeviceDescriptor &descriptor) + GPUDeviceBase::GPUDeviceBase(Ref adapter, const GPUDeviceDescriptor &descriptor) : adapter_(adapter) { } diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index d1fecdf7e..f99cb38f6 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -32,8 +32,7 @@ namespace commandbuffers class GPUDeviceBase { public: - GPUDeviceBase(GPUAdapterBase *adapter, - GPUDeviceDescriptor &descriptor); + GPUDeviceBase(Ref adapter, const GPUDeviceDescriptor &descriptor); virtual ~GPUDeviceBase() = default; public: diff --git a/src/common/command_buffers/gpu/gpu_instance.cpp b/src/common/command_buffers/gpu/gpu_instance.cpp index b5127a8a4..4c94e32f2 100644 --- a/src/common/command_buffers/gpu/gpu_instance.cpp +++ b/src/common/command_buffers/gpu/gpu_instance.cpp @@ -15,8 +15,7 @@ namespace commandbuffers descriptor = &kDefaultDesc; } - auto instance = Ref(new GPUInstance(), [](GPUInstance *ptr) - { delete ptr; }); + auto instance = AcquireRef(new GPUInstance()); instance->initialize(*descriptor); return instance; } diff --git a/src/common/command_buffers/gpu/gpu_instance.hpp b/src/common/command_buffers/gpu/gpu_instance.hpp index 21fa7ede0..f68f18867 100644 --- a/src/common/command_buffers/gpu/gpu_instance.hpp +++ b/src/common/command_buffers/gpu/gpu_instance.hpp @@ -22,7 +22,7 @@ namespace commandbuffers GPUSupportedLimits *requiredLimits = nullptr; }; - class GPUInstance final : std::enable_shared_from_this + class GPUInstance final : public std::enable_shared_from_this { public: static Ref Create(const GPUInstanceDescriptor *descriptor = nullptr); @@ -41,6 +41,9 @@ namespace commandbuffers bool hasFeature(GPUFeatureName feature) const; + // Allow AcquireRef to access the private constructor. + friend Ref (::AcquireRef)(GPUInstance *ptr); + private: explicit GPUInstance(); virtual ~GPUInstance() = default; diff --git a/src/common/utility.hpp b/src/common/utility.hpp index 3b5292a44..fab9e355d 100644 --- a/src/common/utility.hpp +++ b/src/common/utility.hpp @@ -39,8 +39,17 @@ using Ref = std::shared_ptr; template inline Ref AcquireRef(T *ptr) { - return std::shared_ptr(ptr, [](T *p) - { delete p; }); + auto ref = std::shared_ptr(ptr, [](T *p) + { delete p; }); + + // If T derives from std::enable_shared_from_this, set the weak_from_this pointer. + if constexpr (std::derived_from>) + { + ref->weak_from_this() = ref; + } + + // Return the shared pointer. + return ref; } /** diff --git a/src/renderer/gles/gpu_device_impl.cpp b/src/renderer/gles/gpu_device_impl.cpp index cb6db853f..86f536321 100644 --- a/src/renderer/gles/gpu_device_impl.cpp +++ b/src/renderer/gles/gpu_device_impl.cpp @@ -2,15 +2,23 @@ #include #include -#include "./common.hpp" -#include "./gpu_device_impl.hpp" +#include +#include namespace gles { using namespace std; using namespace commandbuffers; - GPUDeviceImpl::GPUDeviceImpl(GPUAdapterBase *adapter, GPUDeviceDescriptor &descriptor) + // static + Ref GPUDeviceImpl::Create(Ref adapter, const GPUDeviceDescriptor &descriptor) + { + Ref device = AcquireRef(new GPUDeviceImpl(adapter, descriptor)); + device->initialize(descriptor); + return device; + } + + GPUDeviceImpl::GPUDeviceImpl(Ref adapter, const GPUDeviceDescriptor &descriptor) : GPUDeviceBase(adapter, descriptor) { auto get_gl_string = [](GLenum name) -> string @@ -49,6 +57,11 @@ namespace gles DEBUG(LOG_TAG_RENDERER, "GPU Device Info: %s", adapter_info_.toString().c_str()); } + bool GPUDeviceImpl::initialize(const GPUDeviceDescriptor &descriptor) + { + return true; + } + unique_ptr GPUDeviceImpl::createCommandBuffer(GPUCommandEncoder &encoder, const GPUCommandBufferDescriptor *descriptor) { diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp index 6be23948d..5479028b0 100644 --- a/src/renderer/gles/gpu_device_impl.hpp +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -1,14 +1,22 @@ #pragma once #include +#include #include namespace gles { class GPUDeviceImpl final : public commandbuffers::GPUDeviceBase { + public: + static Ref Create(Ref adapter, + const commandbuffers::GPUDeviceDescriptor &descriptor); + private: - GPUDeviceImpl(commandbuffers::GPUAdapterBase *adapter, commandbuffers::GPUDeviceDescriptor &descriptor); + GPUDeviceImpl(Ref adapter, + const commandbuffers::GPUDeviceDescriptor &descriptor); + + bool initialize(const commandbuffers::GPUDeviceDescriptor &descriptor); public: std::unique_ptr createCommandBuffer( diff --git a/src/renderer/gles/gpu_physical_device_impl.cpp b/src/renderer/gles/gpu_physical_device_impl.cpp index 4a732d08b..51651f222 100644 --- a/src/renderer/gles/gpu_physical_device_impl.cpp +++ b/src/renderer/gles/gpu_physical_device_impl.cpp @@ -1,16 +1,99 @@ +// Copyright 2022 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include #include +#include using namespace std; using namespace commandbuffers; namespace gles { + struct Vendor + { + const char *vendorName; + uint32_t vendorId; + }; + + const Vendor kVendors[] = {{"ATI", gpu_info::kVendorID_AMD}, + {"ARM", gpu_info::kVendorID_ARM}, + {"Imagination", gpu_info::kVendorID_ImgTec}, + {"Intel", gpu_info::kVendorID_Intel}, + {"NVIDIA", gpu_info::kVendorID_Nvidia}, + {"Qualcomm", gpu_info::kVendorID_QualcommPCI}}; + + uint32_t GetVendorIdFromVendors(const char *vendor) + { + uint32_t vendorId = 0; + for (const auto &it : kVendors) + { + // Matching vendor name with vendor string + if (strstr(vendor, it.vendorName) != nullptr) + { + vendorId = it.vendorId; + break; + } + } + return vendorId; + } + + uint32_t GetDeviceIdFromRender(string_view render) + { + uint32_t deviceId = 0; + size_t pos = render.find("(0x"); + if (pos == string_view::npos) + { + pos = render.find("(0X"); + } + if (pos == string_view::npos) + { + return deviceId; + } + render.remove_prefix(pos + 3); + + // The first character after the prefix must be hexadecimal, otherwise an invalid argument + // exception is thrown. + if (!render.empty() && isxdigit(static_cast(*render.data()))) + { + deviceId = static_cast(stoul(render.data(), nullptr, 16)); + } + + return deviceId; + } + // static Ref GPUPhysicalDeviceImpl::Create(GPUBackendType backendType, Ref display, bool forceES31AndMinExtensions) { - return nullptr; + Ref physicalDevice = AcquireRef(new GPUPhysicalDeviceImpl(backendType, display)); + physicalDevice->initialize(); + return physicalDevice; } GPUPhysicalDeviceImpl::GPUPhysicalDeviceImpl(GPUBackendType backendType, Ref display) @@ -25,17 +108,29 @@ namespace gles bool GPUPhysicalDeviceImpl::supportsExternalImages() const { - return false; + return backendType() == GPUBackendType::kOpenGLES; } bool GPUPhysicalDeviceImpl::supportsFeatureLevel(GPUFeatureLevel featureLevel, GPUInstance *instance) const { - return false; + return featureLevel == GPUFeatureLevel::kCompatibility; } void GPUPhysicalDeviceImpl::initializeImpl() { + name_ = reinterpret_cast(glGetString(GL_RENDERER)); + + const char *vendor = reinterpret_cast(glGetString(GL_VENDOR)); + vendor_id_ = GetVendorIdFromVendors(vendor); + + driver_description_ = string("OpenGL Version ") + + reinterpret_cast(glGetString(GL_VERSION)); + + if (name_.find("SwiftShader") != std::string::npos) + { + adapter_type_ = GPUAdapterType::kCPU; + } } void GPUPhysicalDeviceImpl::initializeSupportedFeaturesImpl() @@ -45,6 +140,8 @@ namespace gles Ref GPUPhysicalDeviceImpl::createDeviceImpl(Ref adapter, const GPUDeviceDescriptor &descriptor) { - return nullptr; + // TODO(yorkie): handle opengl context? + Ref device = GPUDeviceImpl::Create(adapter, descriptor); + return device; } } From be49a2f76452068a5505ddc03f479f3e38fa50f4 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 7 Nov 2025 22:12:04 +0800 Subject: [PATCH 14/37] continue adding impls --- src/common/command_buffers/gpu/gpu_base.hpp | 8 +++ .../command_buffers/gpu/gpu_bind_group.cpp | 20 +++++++ .../command_buffers/gpu/gpu_bind_group.hpp | 11 ++++ .../gpu/gpu_bind_group_base.hpp | 29 +++++++++ .../gpu/gpu_compute_pipeline.hpp | 8 +++ src/common/command_buffers/gpu/gpu_device.cpp | 59 ++++++++++++++++++- src/common/command_buffers/gpu/gpu_device.hpp | 30 +++++++++- .../command_buffers/gpu/gpu_pipeline.hpp | 7 +-- .../gpu/gpu_pipeline_layout.hpp | 18 ++++++ .../command_buffers/gpu/gpu_sampler.cpp | 5 ++ .../command_buffers/gpu/gpu_sampler.hpp | 10 ++++ src/renderer/gles/gpu_device_impl.cpp | 12 ++++ src/renderer/gles/gpu_device_impl.hpp | 6 ++ 13 files changed, 215 insertions(+), 8 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_bind_group.cpp create mode 100644 src/common/command_buffers/gpu/gpu_bind_group_base.hpp create mode 100644 src/common/command_buffers/gpu/gpu_pipeline_layout.hpp create mode 100644 src/common/command_buffers/gpu/gpu_sampler.cpp create mode 100644 src/common/command_buffers/gpu/gpu_sampler.hpp diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 68aaac556..00e7e826f 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -719,6 +719,14 @@ namespace commandbuffers bool operator==(const GPUSupportedLimits &rhs) const; }; + struct GPUComputeState + { + // ShaderModuleBase *module; + std::string_view entryPoint; + size_t constantCount = 0; + GPUConstantEntry const *constants = nullptr; + }; + class ErrorMonad { public: diff --git a/src/common/command_buffers/gpu/gpu_bind_group.cpp b/src/common/command_buffers/gpu/gpu_bind_group.cpp new file mode 100644 index 000000000..1c3e59e39 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group.cpp @@ -0,0 +1,20 @@ +#include + +using namespace std; + +namespace commandbuffers +{ + GPUBindGroupBase::GPUBindGroupBase(Ref device, + const GPUBindGroupDescriptor &descriptor, + void *bindingDataStart) + : GPUHandle(device, descriptor.label) + { + } + + GPUBindGroupBase::GPUBindGroupBase(Ref device, + GPUHandle::ErrorTag tag, + string_view label) + : GPUHandle(device, tag, label) + { + } +} diff --git a/src/common/command_buffers/gpu/gpu_bind_group.hpp b/src/common/command_buffers/gpu/gpu_bind_group.hpp index 46d98d499..5a6ea6775 100644 --- a/src/common/command_buffers/gpu/gpu_bind_group.hpp +++ b/src/common/command_buffers/gpu/gpu_bind_group.hpp @@ -6,16 +6,27 @@ #include #include +#include #include +#include namespace commandbuffers { + class GPUDeviceBase; + class GPUBindGroupBase : public GPUHandle { public: virtual ~GPUBindGroupBase() = default; + protected: + GPUBindGroupBase(Ref device, + const GPUBindGroupDescriptor &descriptor, + void *bindingDataStart); + private: + GPUBindGroupBase(Ref device, GPUHandle::ErrorTag tag, std::string_view label); + Ref *layout_ = nullptr; }; } diff --git a/src/common/command_buffers/gpu/gpu_bind_group_base.hpp b/src/common/command_buffers/gpu/gpu_bind_group_base.hpp new file mode 100644 index 000000000..e7dd82d9a --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group_base.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + struct GPUBindGroupEntry + { + uint32_t binding; + GPUBufferBase *buffer = nullptr; + uint64_t offset = 0; + uint64_t size = gpu_constants::kWholeSize; + GPUSamplerBase *sampler = nullptr; + GPUTextureViewBase *textureView = nullptr; + }; + + struct GPUBindGroupDescriptor + { + std::string_view label; + GPUBindGroupLayoutBase *layout; + size_t entryCount = 0; + GPUBindGroupEntry const *entries = nullptr; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_compute_pipeline.hpp b/src/common/command_buffers/gpu/gpu_compute_pipeline.hpp index 994092108..b082b9b33 100644 --- a/src/common/command_buffers/gpu/gpu_compute_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_compute_pipeline.hpp @@ -1,9 +1,17 @@ #pragma once +#include #include namespace commandbuffers { + struct GPUComputePipelineDescriptor + { + std::string_view label; + GPUPipelineLayoutBase *layout = nullptr; + GPUComputeState compute; + }; + class GPUComputePipelineBase : public GPUPipelineBase { }; diff --git a/src/common/command_buffers/gpu/gpu_device.cpp b/src/common/command_buffers/gpu/gpu_device.cpp index 742086215..278b22588 100644 --- a/src/common/command_buffers/gpu/gpu_device.cpp +++ b/src/common/command_buffers/gpu/gpu_device.cpp @@ -42,7 +42,49 @@ namespace commandbuffers return adapter_->physicalDevice(); } - Ref GPUDeviceBase::getOrCreateBindGroupLayout() + Ref GPUDeviceBase::getOrCreateBindGroupLayout( + const GPUBindGroupLayoutDescriptor &descriptor) + { + return nullptr; + } + + GPUBindGroupLayoutBase *GPUDeviceBase::getEmptyBindGroupLayout() + { + assert(empty_bind_group_layout_ != nullptr); + return empty_bind_group_layout_.get(); + } + + GPUPipelineLayoutBase *GPUDeviceBase::getEmptyPipelineLayout() + { + assert(empty_pipeline_layout_ != nullptr); + return empty_pipeline_layout_.get(); + } + + // Object creation methods that be used in a reentrant manner. + Ref GPUDeviceBase::createBindGroup( + const GPUBindGroupDescriptor *descriptor, + GPUUsageValidationMode mode) + { + return createBindGroupImpl(*descriptor); + } + + Ref GPUDeviceBase::createBindGroupLayout(const GPUBindGroupLayoutDescriptor *descriptor, + bool allowInternalBinding) + { + return nullptr; + } + + Ref GPUDeviceBase::createBuffer(const GPUBufferDescriptor *rawDescriptor) + { + return nullptr; + } + + Ref GPUDeviceBase::createCommandEncoder(const GPUCommandEncoderDescriptor *descriptor) + { + return nullptr; + } + + Ref GPUDeviceBase::createComputePipeline(const GPUComputePipelineDescriptor *descriptor) { return nullptr; } @@ -75,4 +117,19 @@ namespace commandbuffers { return false; } + + Ref GPUDeviceBase::createEmptyBindGroupLayout() + { + GPUBindGroupLayoutDescriptor desc = {}; + desc.entryCount = 0; + desc.entries = nullptr; + + return getOrCreateBindGroupLayout(desc); + } + + Ref GPUDeviceBase::createEmptyPipelineLayout() + { + // TODO(yorkie): implement this. + return nullptr; + } } diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index f99cb38f6..501db0031 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -13,6 +13,10 @@ #include #include #include +#include +#include +#include +#include namespace commandbuffers { @@ -50,7 +54,20 @@ namespace commandbuffers GPUCommandEncoder &encoder, const GPUCommandBufferDescriptor *descriptor = nullptr) = 0; - Ref getOrCreateBindGroupLayout(); + Ref getOrCreateBindGroupLayout( + const GPUBindGroupLayoutDescriptor &descriptor); + + GPUBindGroupLayoutBase *getEmptyBindGroupLayout(); + GPUPipelineLayoutBase *getEmptyPipelineLayout(); + + // Object creation methods that be used in a reentrant manner. + Ref createBindGroup(const GPUBindGroupDescriptor *descriptor, + GPUUsageValidationMode mode = GPUUsageValidationMode::kDefault); + Ref createBindGroupLayout(const GPUBindGroupLayoutDescriptor *descriptor, + bool allowInternalBinding = false); + Ref createBuffer(const GPUBufferDescriptor *rawDescriptor); + Ref createCommandEncoder(const GPUCommandEncoderDescriptor *descriptor = nullptr); + Ref createComputePipeline(const GPUComputePipelineDescriptor *descriptor); bool isValidationEnabled() const; bool isRobustnessEnabled() const; @@ -65,6 +82,17 @@ namespace commandbuffers GPUSupportedLimits limits_; private: + virtual Ref createBindGroupImpl( + const GPUBindGroupDescriptor &descriptor) = 0; + virtual Ref createBindGroupLayoutImpl( + const GPUBindGroupLayoutDescriptor &descriptor) = 0; + + Ref createEmptyBindGroupLayout(); + Ref createEmptyPipelineLayout(); + Ref adapter_; + + Ref empty_bind_group_layout_; + Ref empty_pipeline_layout_; }; } diff --git a/src/common/command_buffers/gpu/gpu_pipeline.hpp b/src/common/command_buffers/gpu/gpu_pipeline.hpp index 965c280c5..70264a6b8 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_pipeline.hpp @@ -7,15 +7,10 @@ #include #include #include +#include namespace commandbuffers { - class GPUPipelineLayoutBase : public GPUHandle - { - private: - std::vector bind_group_layouts_; - }; - class GPURenderPipelineBase; class GPUComputePipelineBase; diff --git a/src/common/command_buffers/gpu/gpu_pipeline_layout.hpp b/src/common/command_buffers/gpu/gpu_pipeline_layout.hpp new file mode 100644 index 000000000..5a986f666 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_pipeline_layout.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include + +namespace commandbuffers +{ + class GPUPipelineLayoutBase : public GPUHandle + { + private: + std::vector bind_group_layouts_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_sampler.cpp b/src/common/command_buffers/gpu/gpu_sampler.cpp new file mode 100644 index 000000000..b940dd017 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_sampler.cpp @@ -0,0 +1,5 @@ +#include + +namespace commandbuffers +{ +} diff --git a/src/common/command_buffers/gpu/gpu_sampler.hpp b/src/common/command_buffers/gpu/gpu_sampler.hpp new file mode 100644 index 000000000..e986ce88a --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_sampler.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace commandbuffers +{ + class GPUSamplerBase : public GPUHandle + { + }; +} diff --git a/src/renderer/gles/gpu_device_impl.cpp b/src/renderer/gles/gpu_device_impl.cpp index 86f536321..9606d4b0f 100644 --- a/src/renderer/gles/gpu_device_impl.cpp +++ b/src/renderer/gles/gpu_device_impl.cpp @@ -67,4 +67,16 @@ namespace gles { return nullptr; } + + Ref GPUDeviceImpl::createBindGroupImpl( + const GPUBindGroupDescriptor &descriptor) + { + return nullptr; + } + + Ref GPUDeviceImpl::createBindGroupLayoutImpl( + const GPUBindGroupLayoutDescriptor &descriptor) + { + return nullptr; + } } diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp index 5479028b0..08c03e91b 100644 --- a/src/renderer/gles/gpu_device_impl.hpp +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -22,5 +22,11 @@ namespace gles std::unique_ptr createCommandBuffer( commandbuffers::GPUCommandEncoder &encoder, const commandbuffers::GPUCommandBufferDescriptor *descriptor = nullptr) override; + + private: + Ref createBindGroupImpl( + const commandbuffers::GPUBindGroupDescriptor &descriptor) override; + Ref createBindGroupLayoutImpl( + const commandbuffers::GPUBindGroupLayoutDescriptor &descriptor) override; }; } From e2a3d57b8e3d6eda6ccfb919ec2586072b55368b Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 12 Nov 2025 16:19:18 +0800 Subject: [PATCH 15/37] fixup --- src/common/command_buffers/gpu/gpu_device.cpp | 19 ++++++ src/common/command_buffers/gpu/gpu_device.hpp | 23 ++++++-- .../gpu/gpu_pipeline_layout.hpp | 4 ++ .../command_buffers/gpu/gpu_shader_module.cpp | 13 ++++ .../command_buffers/gpu/gpu_shader_module.hpp | 31 ++++++++++ .../command_buffers/gpu/gpu_texture.hpp | 4 ++ .../command_buffers/gpu/gpu_texture_view.hpp | 4 +- src/common/wgsl/enums.h | 59 +++++++++++++++++++ src/renderer/gles/gpu_device_impl.cpp | 49 +++++++++++++++ src/renderer/gles/gpu_device_impl.hpp | 22 ++++++- src/renderer/render_api.cpp | 1 + 11 files changed, 221 insertions(+), 8 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_shader_module.cpp create mode 100644 src/common/command_buffers/gpu/gpu_shader_module.hpp create mode 100644 src/common/wgsl/enums.h diff --git a/src/common/command_buffers/gpu/gpu_device.cpp b/src/common/command_buffers/gpu/gpu_device.cpp index 278b22588..906646deb 100644 --- a/src/common/command_buffers/gpu/gpu_device.cpp +++ b/src/common/command_buffers/gpu/gpu_device.cpp @@ -89,6 +89,12 @@ namespace commandbuffers return nullptr; } + Ref GPUDeviceBase::createShaderModule(const GPUShaderModuleDescriptor *descriptor, + const std::vector &internalExtensions) + { + return nullptr; + } + bool GPUDeviceBase::isValidationEnabled() const { // return !IsToggleEnabled(Toggle::SkipValidation); @@ -118,6 +124,19 @@ namespace commandbuffers return false; } + void GPUDeviceBase::setLabelImpl() + { + } + + bool GPUDeviceBase::reduceMemoryUsageImpl() + { + return false; + } + + void GPUDeviceBase::performIdleTasksImpl() + { + } + Ref GPUDeviceBase::createEmptyBindGroupLayout() { GPUBindGroupLayoutDescriptor desc = {}; diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index 501db0031..eff90504c 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,8 @@ namespace commandbuffers Ref createBuffer(const GPUBufferDescriptor *rawDescriptor); Ref createCommandEncoder(const GPUCommandEncoderDescriptor *descriptor = nullptr); Ref createComputePipeline(const GPUComputePipelineDescriptor *descriptor); + Ref createShaderModule(const GPUShaderModuleDescriptor *descriptor = nullptr, + const std::vector &internalExtensions = {}); bool isValidationEnabled() const; bool isRobustnessEnabled() const; @@ -82,10 +85,22 @@ namespace commandbuffers GPUSupportedLimits limits_; private: - virtual Ref createBindGroupImpl( - const GPUBindGroupDescriptor &descriptor) = 0; - virtual Ref createBindGroupLayoutImpl( - const GPUBindGroupLayoutDescriptor &descriptor) = 0; + virtual Ref createBindGroupImpl(const GPUBindGroupDescriptor &) = 0; + virtual Ref createBindGroupLayoutImpl(const GPUBindGroupLayoutDescriptor &) = 0; + virtual Ref createBufferImpl(const GPUBufferDescriptor &) = 0; + virtual Ref createPipelineLayoutImpl(const GPUPipelineLayoutDescriptor &) = 0; + virtual Ref createShaderModuleImpl(const GPUShaderModuleDescriptor &, + const std::vector &) = 0; + virtual Ref createTextureImpl(const GPUTextureDescriptor &) = 0; + virtual Ref createTextureViewImpl(Ref texture, + const GPUTextureViewDescriptor &) = 0; + virtual Ref createUninitializedComputePipelineImpl(const GPUComputePipelineDescriptor &) = 0; + virtual Ref createUninitializedRenderPipelineImpl(const GPURenderPipelineDescriptor &) = 0; + + virtual bool tickImpl() = 0; + virtual void setLabelImpl(); + virtual bool reduceMemoryUsageImpl(); + virtual void performIdleTasksImpl(); Ref createEmptyBindGroupLayout(); Ref createEmptyPipelineLayout(); diff --git a/src/common/command_buffers/gpu/gpu_pipeline_layout.hpp b/src/common/command_buffers/gpu/gpu_pipeline_layout.hpp index 5a986f666..571f9adf7 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline_layout.hpp +++ b/src/common/command_buffers/gpu/gpu_pipeline_layout.hpp @@ -10,6 +10,10 @@ namespace commandbuffers { + struct GPUPipelineLayoutDescriptor + { + }; + class GPUPipelineLayoutBase : public GPUHandle { private: diff --git a/src/common/command_buffers/gpu/gpu_shader_module.cpp b/src/common/command_buffers/gpu/gpu_shader_module.cpp new file mode 100644 index 000000000..037167e9d --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_shader_module.cpp @@ -0,0 +1,13 @@ +#include + +using namespace std; + +namespace commandbuffers +{ + GPUShaderModuleBase::GPUShaderModuleBase(Ref device, + const GPUShaderModuleDescriptor &descriptor, + vector internalExtensions) + : GPUHandle(device, descriptor.label) + { + } +} diff --git a/src/common/command_buffers/gpu/gpu_shader_module.hpp b/src/common/command_buffers/gpu/gpu_shader_module.hpp new file mode 100644 index 000000000..6762438c5 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_shader_module.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + + struct GPUShaderModuleDescriptor + { + std::string_view label; + std::string_view code; + std::vector hints; + }; + + class GPUShaderModuleBase : public GPUHandle + { + public: + GPUShaderModuleBase(Ref device, + const GPUShaderModuleDescriptor &descriptor, + std::vector internalExtensions); + + GPUHandleType type() const override + { + return GPUHandleType::kShaderModule; + } + }; +} diff --git a/src/common/command_buffers/gpu/gpu_texture.hpp b/src/common/command_buffers/gpu/gpu_texture.hpp index 12e7c4963..2fb9289f6 100644 --- a/src/common/command_buffers/gpu/gpu_texture.hpp +++ b/src/common/command_buffers/gpu/gpu_texture.hpp @@ -6,6 +6,10 @@ namespace commandbuffers { class GPUTextureViewBase; + struct GPUTextureDescriptor + { + }; + class GPUTextureBase : public GPUHandle { public: diff --git a/src/common/command_buffers/gpu/gpu_texture_view.hpp b/src/common/command_buffers/gpu/gpu_texture_view.hpp index b314f4589..97c8c8855 100644 --- a/src/common/command_buffers/gpu/gpu_texture_view.hpp +++ b/src/common/command_buffers/gpu/gpu_texture_view.hpp @@ -10,7 +10,7 @@ namespace commandbuffers { - struct TextureViewDescriptor + struct GPUTextureViewDescriptor { std::string_view label; GPUTextureFormat format = GPUTextureFormat::kUndefined; @@ -26,7 +26,7 @@ namespace commandbuffers class GPUTextureViewBase : public GPUHandle { public: - GPUTextureViewBase(Ref texture, const TextureViewDescriptor &descriptor); + GPUTextureViewBase(Ref texture, const GPUTextureViewDescriptor &); Ref texture() const; const GPUTextureBase &textureRef() const; diff --git a/src/common/wgsl/enums.h b/src/common/wgsl/enums.h new file mode 100644 index 000000000..36185006e --- /dev/null +++ b/src/common/wgsl/enums.h @@ -0,0 +1,59 @@ +// Copyright 2025 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +#include + +namespace wgsl +{ + enum class CoreDiagnosticRule : uint8_t + { + kUndefined, + kDerivativeUniformity, + kSubgroupUniformity, + }; + + enum class Extension : uint8_t + { + kUndefined, + kChromiumDisableUniformityAnalysis, + kChromiumExperimentalBarycentricCoord, + kChromiumExperimentalDynamicBinding, + kChromiumExperimentalFramebufferFetch, + kChromiumExperimentalImmediate, + kChromiumExperimentalPixelLocal, + kChromiumExperimentalSubgroupMatrix, + kChromiumInternalGraphite, + kChromiumInternalInputAttachments, + kClipDistances, + kDualSourceBlending, + kF16, + kPrimitiveIndex, + kSubgroups, + }; +} diff --git a/src/renderer/gles/gpu_device_impl.cpp b/src/renderer/gles/gpu_device_impl.cpp index 9606d4b0f..7b8ceb800 100644 --- a/src/renderer/gles/gpu_device_impl.cpp +++ b/src/renderer/gles/gpu_device_impl.cpp @@ -79,4 +79,53 @@ namespace gles { return nullptr; } + + Ref GPUDeviceImpl::createBufferImpl( + const GPUBufferDescriptor &descriptor) + { + return nullptr; + } + + Ref GPUDeviceImpl::createPipelineLayoutImpl( + const GPUPipelineLayoutDescriptor &descriptor) + { + return nullptr; + } + + Ref GPUDeviceImpl::createShaderModuleImpl( + const GPUShaderModuleDescriptor &descriptor, + const std::vector &internalExtensions) + { + return nullptr; + } + + Ref GPUDeviceImpl::createTextureImpl( + const GPUTextureDescriptor &descriptor) + { + return nullptr; + } + + Ref GPUDeviceImpl::createTextureViewImpl( + Ref texture, + const GPUTextureViewDescriptor &descriptor) + { + return nullptr; + } + + Ref GPUDeviceImpl::createUninitializedComputePipelineImpl( + const GPUComputePipelineDescriptor &descriptor) + { + return nullptr; + } + + Ref GPUDeviceImpl::createUninitializedRenderPipelineImpl( + const GPURenderPipelineDescriptor &descriptor) + { + return nullptr; + } + + bool GPUDeviceImpl::tickImpl() + { + return true; + } } diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp index 08c03e91b..5df5a22eb 100644 --- a/src/renderer/gles/gpu_device_impl.hpp +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -25,8 +25,26 @@ namespace gles private: Ref createBindGroupImpl( - const commandbuffers::GPUBindGroupDescriptor &descriptor) override; + const commandbuffers::GPUBindGroupDescriptor &) override; Ref createBindGroupLayoutImpl( - const commandbuffers::GPUBindGroupLayoutDescriptor &descriptor) override; + const commandbuffers::GPUBindGroupLayoutDescriptor &) override; + Ref createBufferImpl( + const commandbuffers::GPUBufferDescriptor &) override; + Ref createPipelineLayoutImpl( + const commandbuffers::GPUPipelineLayoutDescriptor &) override; + Ref createShaderModuleImpl( + const commandbuffers::GPUShaderModuleDescriptor &, + const std::vector &) override; + Ref createTextureImpl( + const commandbuffers::GPUTextureDescriptor &) override; + Ref createTextureViewImpl( + Ref texture, + const commandbuffers::GPUTextureViewDescriptor &) override; + Ref createUninitializedComputePipelineImpl( + const commandbuffers::GPUComputePipelineDescriptor &) override; + Ref createUninitializedRenderPipelineImpl( + const commandbuffers::GPURenderPipelineDescriptor &) override; + + bool tickImpl() override; }; } diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index d5f59d8c3..04da9a378 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -89,6 +89,7 @@ TrRenderHardwareInterface::TrRenderHardwareInterface(RHIBackendType backend_type gpuAdapter = gpuInstance->requestAdapter(requestOptions); gpuDevice = gpuAdapter->createDevice(); + assert(gpuDevice != nullptr && "Failed to create GPU device"); } void TrRenderHardwareInterface::SubmitGPUCommandBuffer(vector> &commandBuffers) From fa81598d2b6c4fce1def4afb0d909d41257d0544 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 12 Nov 2025 20:07:23 +0800 Subject: [PATCH 16/37] fix --- src/common/command_buffers/gpu/gpu_instance.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/command_buffers/gpu/gpu_instance.hpp b/src/common/command_buffers/gpu/gpu_instance.hpp index f68f18867..9ba3590fe 100644 --- a/src/common/command_buffers/gpu/gpu_instance.hpp +++ b/src/common/command_buffers/gpu/gpu_instance.hpp @@ -42,7 +42,7 @@ namespace commandbuffers bool hasFeature(GPUFeatureName feature) const; // Allow AcquireRef to access the private constructor. - friend Ref (::AcquireRef)(GPUInstance *ptr); + friend Ref(::AcquireRef)(GPUInstance *ptr); private: explicit GPUInstance(); From 752d9b51d32f4a03aa6d81d8bfcc2d5a785c9afc Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 14 Nov 2025 15:54:52 +0800 Subject: [PATCH 17/37] update --- .vscode/settings.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 89d56cba4..f820c1d25 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -105,5 +105,10 @@ "cmake.buildDirectory": "${workspaceFolder}/build/targets/darwin", "C_Cpp.default.cppStandard": "c++17", "C_Cpp.default.cStandard": "c17", - "C_Cpp.errorSquiggles": "enabledIfIncludesResolve" + "C_Cpp.errorSquiggles": "enabledIfIncludesResolve", + "clangd.arguments": [ + "--compile-commands-dir=${workspaceFolder}/build/targets/darwin", + "--background-index", + "--query-driver=/usr/bin/clang*;${env:ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/darwin-x86_64/bin/*" + ] } \ No newline at end of file From 863ea6a67598d60cb436b1c1f4f952d9cbf1f463 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 14 Nov 2025 19:39:24 +0800 Subject: [PATCH 18/37] fix --- .../command_buffers/gpu/encoding_context.cpp | 6 +- .../command_buffers/gpu/encoding_context.hpp | 32 +- src/common/command_buffers/gpu/error.cpp | 0 src/common/command_buffers/gpu/error.hpp | 80 +++ src/common/command_buffers/gpu/error_data.cpp | 1 + src/common/command_buffers/gpu/error_data.hpp | 9 +- .../gpu/gpu_command_encoder.cpp | 94 +++ .../gpu/gpu_command_encoder.hpp | 15 + src/common/result.cpp | 47 ++ src/common/result.hpp | 608 ++++++++++++++++++ 10 files changed, 880 insertions(+), 12 deletions(-) create mode 100644 src/common/command_buffers/gpu/error.cpp create mode 100644 src/common/command_buffers/gpu/error.hpp create mode 100644 src/common/command_buffers/gpu/gpu_command_encoder.cpp create mode 100644 src/common/result.cpp create mode 100644 src/common/result.hpp diff --git a/src/common/command_buffers/gpu/encoding_context.cpp b/src/common/command_buffers/gpu/encoding_context.cpp index 1079e1ae2..3570ad679 100644 --- a/src/common/command_buffers/gpu/encoding_context.cpp +++ b/src/common/command_buffers/gpu/encoding_context.cpp @@ -5,10 +5,10 @@ using namespace std; namespace commandbuffers::gpu { - EncodingContext::EncodingContext(Ref device, Ref initialEncoder) + EncodingContext::EncodingContext(Ref device, const GPUHandle *initialEncoder) : device_(device.get()) - , top_level_encoder_(initialEncoder.get()) - , current_encoder_(initialEncoder.get()) + , top_level_encoder_(initialEncoder) + , current_encoder_(initialEncoder) , status_(Status::kOpen) { assert(!initialEncoder->isError()); diff --git a/src/common/command_buffers/gpu/encoding_context.hpp b/src/common/command_buffers/gpu/encoding_context.hpp index 72407ccf4..aa32780f1 100644 --- a/src/common/command_buffers/gpu/encoding_context.hpp +++ b/src/common/command_buffers/gpu/encoding_context.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,7 @@ namespace commandbuffers class EncodingContext { public: - EncodingContext(Ref device, Ref initialEncoder); + EncodingContext(Ref device, const GPUHandle *initialEncoder); EncodingContext(Ref device, GPUHandle::ErrorTag tag); ~EncodingContext(); @@ -30,6 +31,35 @@ namespace commandbuffers void destroy(); CommandIterator acquireCommands(); + void handleError(std::unique_ptr error); + + inline bool consumedError(MaybeError maybeError) + { + if (maybeError.IsError()) [[unlikely]] + { + handleError(maybeError.AcquireError()); + return true; + } + return false; + } + + inline MaybeError validateCanEncodeOn(const GPUHandle *encoder) + { + // TODO: validate encoder is valid. + return {}; + } + + template + inline bool tryEncode(const GPUHandle *encoder, EncodeFunction &&encodeFunction) + { + if (consumedError(validateCanEncodeOn(encoder))) + { + return false; + } + assert(!were_commands_acquired_); + return !consumedError(encodeFunction(&pending_commands_)); + } + // Must be called prior to encoding a BeginRenderPassCmd. Note that it's OK to call this // and then not actually call EnterPass+ExitRenderPass, for example if some other pass setup // failed validation before the BeginRenderPassCmd could be encoded. diff --git a/src/common/command_buffers/gpu/error.cpp b/src/common/command_buffers/gpu/error.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/common/command_buffers/gpu/error.hpp b/src/common/command_buffers/gpu/error.hpp new file mode 100644 index 000000000..a9c3457d4 --- /dev/null +++ b/src/common/command_buffers/gpu/error.hpp @@ -0,0 +1,80 @@ +// Copyright 2018 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include + +#include +#include + +namespace commandbuffers::gpu +{ + enum class InternalErrorType : uint32_t + { + kNone = 0, + kValidation = 1, + kDeviceLost = 2, + kInternal = 4, + kOutOfMemory = 8 + }; + + // MaybeError and ResultOrError are meant to be used as return value for function that are not + // expected to, but might fail. The handling of error is potentially much slower than successes. + using MaybeError = jsar::Result; + + template + using ResultOrError = jsar::Result; + + namespace detail + { + template + struct UnwrapResultOrError + { + using type = T; + }; + + template + struct UnwrapResultOrError> + { + using type = T; + }; + + template + struct IsResultOrError + { + static constexpr bool value = false; + }; + + template + struct IsResultOrError> + { + static constexpr bool value = true; + }; + + } +} diff --git a/src/common/command_buffers/gpu/error_data.cpp b/src/common/command_buffers/gpu/error_data.cpp index f8596d1c5..191ef39fe 100644 --- a/src/common/command_buffers/gpu/error_data.cpp +++ b/src/common/command_buffers/gpu/error_data.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include using namespace std; diff --git a/src/common/command_buffers/gpu/error_data.hpp b/src/common/command_buffers/gpu/error_data.hpp index 431ff12cf..5cb9ddfd9 100644 --- a/src/common/command_buffers/gpu/error_data.hpp +++ b/src/common/command_buffers/gpu/error_data.hpp @@ -7,14 +7,7 @@ namespace commandbuffers::gpu { - enum class InternalErrorType : uint32_t - { - kNone = 0, - kValidation = 1, - kDeviceLost = 2, - kInternal = 4, - kOutOfMemory = 8 - }; + enum class InternalErrorType : uint32_t; class [[nodiscard]] ErrorData { diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.cpp b/src/common/command_buffers/gpu/gpu_command_encoder.cpp new file mode 100644 index 000000000..d8311b3d7 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_command_encoder.cpp @@ -0,0 +1,94 @@ +#include +#include + +using namespace std; + +namespace commandbuffers +{ + Ref GPUCommandEncoder::Create(Ref device, + const GPUCommandEncoderDescriptor &descriptor) + { + return AcquireRef(new GPUCommandEncoder(device, descriptor)); + } + + Ref GPUCommandEncoder::MakeError(Ref device, string_view label) + { + return AcquireRef(new GPUCommandEncoder(device, GPUHandle::kError, label)); + } + + GPUCommandEncoder::GPUCommandEncoder(Ref device, const GPUCommandEncoderDescriptor &descriptor) + : GPUHandle(device, descriptor.label) + , encoding_context_(device, this) + , usage_validation_mode_(GPUUsageValidationMode::kDefault) + { + } + + GPUCommandEncoder::GPUCommandEncoder(Ref device, + GPUHandle::ErrorTag tag, + string_view label) + : GPUHandle(device, tag, label) + , encoding_context_(device, this) + , usage_validation_mode_(GPUUsageValidationMode::kDefault) + { + } + + GPURenderPassEncoder GPUCommandEncoder::beginRenderPass(GPURenderPassDescriptor &) + { + throw runtime_error("beginRenderPass is not implemented"); + } + + void GPUCommandEncoder::clearBuffer() + { + throw runtime_error("clearBuffer is not implemented"); + } + + void GPUCommandEncoder::copyBufferToBuffer() + { + throw runtime_error("copyBufferToBuffer is not implemented"); + } + + void GPUCommandEncoder::copyBufferToTexture() + { + throw runtime_error("copyBufferToTexture is not implemented"); + } + + void GPUCommandEncoder::copyTextureToBuffer() + { + throw runtime_error("copyTextureToBuffer is not implemented"); + } + + void GPUCommandEncoder::copyTextureToTexture() + { + throw runtime_error("copyTextureToTexture is not implemented"); + } + + unique_ptr GPUCommandEncoder::finish(optional label) const + { + return nullptr; + } + + void GPUCommandEncoder::insertDebugMarker(std::string_view marker) + { + throw runtime_error("insertDebugMarker is not implemented"); + } + + void GPUCommandEncoder::pushDebugGroup(std::string_view group) + { + throw runtime_error("pushDebugGroup is not implemented"); + } + + void GPUCommandEncoder::popDebugGroup() + { + throw runtime_error("popDebugGroup is not implemented"); + } + + void GPUCommandEncoder::resolveQuerySet() + { + throw runtime_error("resolveQuerySet is not implemented"); + } + + void GPUCommandEncoder::writeTimestamp() + { + throw runtime_error("writeTimestamp is not implemented"); + } +} diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index 140b30a79..a07b5fef8 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -26,6 +26,9 @@ namespace commandbuffers class GPUCommandEncoder final : public GPUHandle { public: + static Ref Create(Ref device, const GPUCommandEncoderDescriptor &descriptor); + static Ref MakeError(Ref device, std::string_view label); + GPUHandleType type() const override { return GPUHandleType::kCommandEncoder; @@ -34,8 +37,20 @@ namespace commandbuffers public: // TODO(yorkie): begineComputePass GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor &); + void clearBuffer(); + void copyBufferToBuffer(); + void copyBufferToTexture(); + void copyTextureToBuffer(); + void copyTextureToTexture(); std::unique_ptr finish(std::optional label = std::nullopt) const; + void insertDebugMarker(std::string_view marker); + void pushDebugGroup(std::string_view group); + void popDebugGroup(); + + void resolveQuerySet(); + void writeTimestamp(); + private: GPUCommandEncoder(Ref device, const GPUCommandEncoderDescriptor &descriptor); GPUCommandEncoder(Ref device, diff --git a/src/common/result.cpp b/src/common/result.cpp new file mode 100644 index 000000000..68266b773 --- /dev/null +++ b/src/common/result.cpp @@ -0,0 +1,47 @@ +// Copyright 2019 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +namespace jsar +{ + // Implementation details of the tagged pointer Results + namespace detail + { + intptr_t MakePayload(const void *pointer, PayloadType type) + { + intptr_t payload = reinterpret_cast(pointer); + assert((payload & 3) == 0); + return payload | type; + } + + PayloadType GetPayloadType(intptr_t payload) + { + return static_cast(payload & 3); + } + } +} diff --git a/src/common/result.hpp b/src/common/result.hpp new file mode 100644 index 000000000..4d1a91cac --- /dev/null +++ b/src/common/result.hpp @@ -0,0 +1,608 @@ +// Copyright 2018 The Dawn & Tint Authors +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include +#include +#include +#include +#include + +namespace jsar +{ + // Result is the following sum type (Haskell notation): + // + // data Result T E = Success T | Error E | Empty + // + // It is meant to be used as the return type of functions that might fail. The reason for the Empty + // case is that a Result should never be discarded, only destructured (its error or success moved + // out) or moved into a different Result. The Empty case tags Results that have been moved out and + // Result's destructor should assert on it being Empty. + // + // Since C++ doesn't have efficient sum types for the special cases we care about, we provide + // template specializations for them. + + template + class Result; + + // The interface of Result should look like the following. + // public: + // Result(T&& success); + // Result(std::unique_ptr error); + // + // Result(Result&& other); + // Result& operator=(Result&& other); + // + // ~Result(); + // + // bool IsError() const; + // bool IsSuccess() const; + // + // T&& AcquireSuccess(); + // std::unique_ptr AcquireError(); + + // Specialization of Result for returning errors only via pointers. It is basically a pointer + // where nullptr is both Success and Empty. + template + class [[nodiscard]] Result + { + public: + Result(); + Result(std::unique_ptr error); + + Result(Result &&other); + Result &operator=(Result &&other); + + ~Result(); + + bool IsError() const; + bool IsSuccess() const; + + void AcquireSuccess(); + std::unique_ptr AcquireError(); + + private: + std::unique_ptr mError; + }; + + // Uses SFINAE to try to get alignof(T) but fallback to Default if T isn't defined. + template + constexpr size_t alignof_if_defined_else_default = Default; + + template + constexpr size_t alignof_if_defined_else_default = alignof(T); + + // Specialization of Result when both the error an success are pointers. It is implemented as a + // tagged pointer. The tag for Success is 0 so that returning the value is fastest. + + namespace detail + { + // Utility functions to manipulate the tagged pointer. Some of them don't need to be templated + // but we really want them inlined so we keep them in the headers + enum PayloadType + { + Success = 0, + Error = 1, + Empty = 2, + }; + + intptr_t MakePayload(const void *pointer, PayloadType type); + PayloadType GetPayloadType(intptr_t payload); + + template + static T *GetSuccessFromPayload(intptr_t payload); + template + static E *GetErrorFromPayload(intptr_t payload); + + constexpr static intptr_t kEmptyPayload = Empty; + } // namespace detail + + template + class [[nodiscard]] Result + { + public: + static_assert(alignof_if_defined_else_default >= 4, + "Result reserves two bits for tagging pointers"); + static_assert(alignof_if_defined_else_default >= 4, + "Result reserves two bits for tagging pointers"); + + Result(T *success); + Result(std::unique_ptr error); + + // Support returning a Result from a Result + template + requires std::same_as || std::derived_from + Result(Result &&other); + template + requires std::same_as || std::derived_from + Result &operator=(Result &&other); + + ~Result(); + + bool IsError() const; + bool IsSuccess() const; + + T *AcquireSuccess(); + std::unique_ptr AcquireError(); + + private: + template + friend class Result; + + intptr_t mPayload = detail::kEmptyPayload; + }; + + template + class [[nodiscard]] Result + { + public: + static_assert(alignof_if_defined_else_default >= 4, + "Result reserves two bits for tagging pointers"); + static_assert(alignof_if_defined_else_default >= 4, + "Result reserves two bits for tagging pointers"); + + Result(const T *success); + Result(std::unique_ptr error); + + Result(Result &&other); + Result &operator=(Result &&other); + + ~Result(); + + bool IsError() const; + bool IsSuccess() const; + + const T *AcquireSuccess(); + std::unique_ptr AcquireError(); + + private: + intptr_t mPayload = detail::kEmptyPayload; + }; + + template + class Ref; + + template + class [[nodiscard]] Result, E> + { + public: + static_assert(alignof_if_defined_else_default >= 4, + "Result, E> reserves two bits for tagging pointers"); + static_assert(alignof_if_defined_else_default >= 4, + "Result, E> reserves two bits for tagging pointers"); + + template + requires std::convertible_to + Result(Ref &&success); + template + requires std::convertible_to + Result(const Ref &success); + Result(std::unique_ptr error); + constexpr Result(std::nullptr_t); + + template + requires std::convertible_to + Result(Result, E> &&other); + template + requires std::convertible_to + Result, E> &operator=(Result, E> &&other); + + ~Result(); + + bool IsError() const; + bool IsSuccess() const; + + Ref AcquireSuccess(); + std::unique_ptr AcquireError(); + + private: + template + friend class Result; + + intptr_t mPayload = detail::kEmptyPayload; + }; + + // Catchall definition of Result implemented as a tagged struct. It could be improved to use + // a tagged union instead if it turns out to be a hotspot. T and E must be movable and default + // constructible. + template + class [[nodiscard]] Result + { + public: + Result(T success); + Result(std::unique_ptr error); + + Result(Result &&other); + Result &operator=(Result &&other); + + ~Result(); + + bool IsError() const; + bool IsSuccess() const; + + T AcquireSuccess(); + std::unique_ptr AcquireError(); + + private: + std::variant> mPayload; + }; + + // Implementation of Result + template + Result::Result() + { + } + + template + Result::Result(std::unique_ptr error) + : mError(std::move(error)) + { + } + + template + Result::Result(Result &&other) + : mError(std::move(other.mError)) + { + } + + template + Result &Result::operator=(Result &&other) + { + assert(mError == nullptr); + mError = std::move(other.mError); + return *this; + } + + template + Result::~Result() + { + assert(mError == nullptr); + } + + template + bool Result::IsError() const + { + return mError != nullptr; + } + + template + bool Result::IsSuccess() const + { + return mError == nullptr; + } + + template + void Result::AcquireSuccess() + { + } + + template + std::unique_ptr Result::AcquireError() + { + return std::move(mError); + } + + // Implementation details of the tagged pointer Results + namespace detail + { + + template + T *GetSuccessFromPayload(intptr_t payload) + { + assert(GetPayloadType(payload) == Success); + return reinterpret_cast(payload); + } + + template + E *GetErrorFromPayload(intptr_t payload) + { + assert(GetPayloadType(payload) == Error); + return reinterpret_cast(payload ^ 1); + } + + } // namespace detail + + // Implementation of Result + template + Result::Result(T *success) + : mPayload(detail::MakePayload(success, detail::Success)) + { + } + + template + Result::Result(std::unique_ptr error) + : mPayload(detail::MakePayload(error.release(), detail::Error)) + { + } + + template + template + requires std::same_as || std::derived_from + Result::Result(Result &&other) + : mPayload(other.mPayload) + { + other.mPayload = detail::kEmptyPayload; + } + + template + template + requires std::same_as || std::derived_from + Result &Result::operator=(Result &&other) + { + assert(mPayload == detail::kEmptyPayload); + mPayload = other.mPayload; + other.mPayload = detail::kEmptyPayload; + return *this; + } + + template + Result::~Result() + { + assert(mPayload == detail::kEmptyPayload); + } + + template + bool Result::IsError() const + { + return detail::GetPayloadType(mPayload) == detail::Error; + } + + template + bool Result::IsSuccess() const + { + return detail::GetPayloadType(mPayload) == detail::Success; + } + + template + T *Result::AcquireSuccess() + { + T *success = detail::GetSuccessFromPayload(mPayload); + mPayload = detail::kEmptyPayload; + return success; + } + + template + std::unique_ptr Result::AcquireError() + { + std::unique_ptr error(detail::GetErrorFromPayload(mPayload)); + mPayload = detail::kEmptyPayload; + return std::move(error); + } + + // Implementation of Result + template + Result::Result(const T *success) + : mPayload(detail::MakePayload(success, detail::Success)) + { + } + + template + Result::Result(std::unique_ptr error) + : mPayload(detail::MakePayload(error.release(), detail::Error)) + { + } + + template + Result::Result(Result &&other) + : mPayload(other.mPayload) + { + other.mPayload = detail::kEmptyPayload; + } + + template + Result &Result::operator=(Result &&other) + { + assert(mPayload == detail::kEmptyPayload); + mPayload = other.mPayload; + other.mPayload = detail::kEmptyPayload; + return *this; + } + + template + Result::~Result() + { + assert(mPayload == detail::kEmptyPayload); + } + + template + bool Result::IsError() const + { + return detail::GetPayloadType(mPayload) == detail::Error; + } + + template + bool Result::IsSuccess() const + { + return detail::GetPayloadType(mPayload) == detail::Success; + } + + template + const T *Result::AcquireSuccess() + { + T *success = detail::GetSuccessFromPayload(mPayload); + mPayload = detail::kEmptyPayload; + return success; + } + + template + std::unique_ptr Result::AcquireError() + { + std::unique_ptr error(detail::GetErrorFromPayload(mPayload)); + mPayload = detail::kEmptyPayload; + return std::move(error); + } + + // Implementation of Result, E> + template + constexpr Result, E>::Result(std::nullptr_t) + : Result(Ref(nullptr)) + { + } + + template + template + requires std::convertible_to + Result, E>::Result(Ref &&success) + : mPayload(detail::MakePayload(success.Detach(), detail::Success)) + { + } + + template + template + requires std::convertible_to + Result, E>::Result(const Ref &success) + : Result(Ref(success)) + { + } + + template + Result, E>::Result(std::unique_ptr error) + : mPayload(detail::MakePayload(error.release(), detail::Error)) + { + } + + template + template + requires std::convertible_to + Result, E>::Result(Result, E> &&other) + : mPayload(other.mPayload) + { + other.mPayload = detail::kEmptyPayload; + } + + template + template + requires std::convertible_to + Result, E> &Result, E>::operator=(Result, E> &&other) + { + assert(mPayload == detail::kEmptyPayload); + mPayload = other.mPayload; + other.mPayload = detail::kEmptyPayload; + return *this; + } + + template + Result, E>::~Result() + { + assert(mPayload == detail::kEmptyPayload); + } + + template + bool Result, E>::IsError() const + { + return detail::GetPayloadType(mPayload) == detail::Error; + } + + template + bool Result, E>::IsSuccess() const + { + return detail::GetPayloadType(mPayload) == detail::Success; + } + + template + Ref Result, E>::AcquireSuccess() + { + assert(IsSuccess()); + Ref success = AcquireRef(detail::GetSuccessFromPayload(mPayload)); + mPayload = detail::kEmptyPayload; + return success; + } + + template + std::unique_ptr Result, E>::AcquireError() + { + assert(IsError()); + std::unique_ptr error(detail::GetErrorFromPayload(mPayload)); + mPayload = detail::kEmptyPayload; + return std::move(error); + } + + // Implementation of Result + template + Result::Result(T success) + : mPayload(std::move(success)) + { + } + + template + Result::Result(std::unique_ptr error) + : mPayload(std::move(error)) + { + } + + template + Result::~Result() + { + // Happens if you ignore a result. + assert(std::holds_alternative(mPayload)); + } + + template + Result::Result(Result &&other) + { + *this = std::move(other); + } + + template + Result &Result::operator=(Result &&other) + { + assert(std::holds_alternative(mPayload)); + std::swap(mPayload, other.mPayload); + return *this; + } + + template + bool Result::IsError() const + { + return std::holds_alternative>(mPayload); + } + + template + bool Result::IsSuccess() const + { + return std::holds_alternative(mPayload); + } + + template + T Result::AcquireSuccess() + { + assert(IsSuccess()); + auto payload = std::move(mPayload); + mPayload = {}; + return std::move(std::get(payload)); + } + + template + std::unique_ptr Result::AcquireError() + { + assert(IsError()); + auto payload = std::move(mPayload); + mPayload = {}; + return std::move(std::get>(payload)); + } +} From 54d145184af61a8ff7987aef934fd4b45b281d87 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Mon, 17 Nov 2025 21:51:52 +0800 Subject: [PATCH 19/37] fix --- src/common/command_buffers/gpu/encoding_context.hpp | 12 ++++++++++++ .../command_buffers/gpu/gpu_command_encoder.cpp | 10 +++++++++- src/common/command_buffers/gpu/gpu_commands.hpp | 6 ++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/common/command_buffers/gpu/encoding_context.hpp b/src/common/command_buffers/gpu/encoding_context.hpp index aa32780f1..e9c74345f 100644 --- a/src/common/command_buffers/gpu/encoding_context.hpp +++ b/src/common/command_buffers/gpu/encoding_context.hpp @@ -45,6 +45,18 @@ namespace commandbuffers inline MaybeError validateCanEncodeOn(const GPUHandle *encoder) { + if (encoder != current_encoder_) [[unlikely]] + { + switch (status_) + { + case Status::kErrorAtCreation: + case Status::kErrorInRecording: + case Status::kDestroyed: + case Status::kFinished: + case Status::kOpen: + break; + } + } // TODO: validate encoder is valid. return {}; } diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.cpp b/src/common/command_buffers/gpu/gpu_command_encoder.cpp index d8311b3d7..ac5bd8f8f 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.cpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include using namespace std; @@ -69,7 +71,13 @@ namespace commandbuffers void GPUCommandEncoder::insertDebugMarker(std::string_view marker) { - throw runtime_error("insertDebugMarker is not implemented"); + encoding_context_.tryEncode( + this, + [&](gpu::CommandAllocator *allocator) -> gpu::MaybeError + { + GPUInsertDebugMarkerCommand *cmd = allocator->allocate(GPUCommand::kInsertDebugMarker); + return {}; + }); } void GPUCommandEncoder::pushDebugGroup(std::string_view group) diff --git a/src/common/command_buffers/gpu/gpu_commands.hpp b/src/common/command_buffers/gpu/gpu_commands.hpp index 177bd6afa..9ffa33fea 100644 --- a/src/common/command_buffers/gpu/gpu_commands.hpp +++ b/src/common/command_buffers/gpu/gpu_commands.hpp @@ -63,6 +63,12 @@ namespace commandbuffers virtual ~GPUCommand() = default; }; + class GPUInsertDebugMarkerCommand : public GPUCommand + { + public: + uint32_t length; + }; + class GPUDrawCommand : public GPUCommand { public: From 359703b031e2491476c5fcb4f8b681de3d713853 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 20 Nov 2025 16:04:26 +0800 Subject: [PATCH 20/37] fix --- .../command_buffers/gpu/encoding_context.cpp | 5 + src/common/command_buffers/gpu/error.hpp | 2 + .../gpu/gpu_command_encoder.cpp | 72 ++++++++- .../gpu/gpu_command_encoder.hpp | 3 +- .../command_buffers/gpu/gpu_commands.hpp | 151 ++++-------------- .../gpu/gpu_renderpass_encoder.cpp | 58 +++++++ .../gpu/gpu_renderpass_encoder.hpp | 34 +++- 7 files changed, 201 insertions(+), 124 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_renderpass_encoder.cpp diff --git a/src/common/command_buffers/gpu/encoding_context.cpp b/src/common/command_buffers/gpu/encoding_context.cpp index 3570ad679..7cf412b7b 100644 --- a/src/common/command_buffers/gpu/encoding_context.cpp +++ b/src/common/command_buffers/gpu/encoding_context.cpp @@ -56,6 +56,11 @@ namespace commandbuffers::gpu return commands; } + void EncodingContext::handleError(unique_ptr error) + { + // TODO + } + void EncodingContext::willBeginRenderPass() { assert(current_encoder_ == top_level_encoder_); diff --git a/src/common/command_buffers/gpu/error.hpp b/src/common/command_buffers/gpu/error.hpp index a9c3457d4..30ea0b70b 100644 --- a/src/common/command_buffers/gpu/error.hpp +++ b/src/common/command_buffers/gpu/error.hpp @@ -25,6 +25,8 @@ // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#pragma once + #include #include #include diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.cpp b/src/common/command_buffers/gpu/gpu_command_encoder.cpp index ac5bd8f8f..2d949caf3 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.cpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.cpp @@ -2,11 +2,44 @@ #include #include #include +#include using namespace std; namespace commandbuffers { + class RenderPassValidationState final : NonMovable + { + public: + RenderPassValidationState() = default; + ~RenderPassValidationState() = default; + + + uint32_t getRenderWidth() const + { + return render_width_; + } + uint32_t getRenderHeight() const + { + return render_height_; + } + uint32_t getSampleCount() const + { + return sample_count_; + } + uint32_t getImplicitSampleCount() const + { + return implicit_sample_count_; + } + + private: + uint32_t render_width_ = 0; + uint32_t render_height_ = 0; + uint32_t sample_count_ = 0; + // The implicit multisample count used by MSAA render to single sampled. + uint32_t implicit_sample_count_ = 0; + }; + Ref GPUCommandEncoder::Create(Ref device, const GPUCommandEncoderDescriptor &descriptor) { @@ -34,9 +67,44 @@ namespace commandbuffers { } - GPURenderPassEncoder GPUCommandEncoder::beginRenderPass(GPURenderPassDescriptor &) + Ref GPUCommandEncoder::beginRenderPass(GPURenderPassDescriptor &descriptor) { - throw runtime_error("beginRenderPass is not implemented"); + Ref device_ = device(); + bool depthReadOnly = false; + bool stencilReadOnly = false; + + RenderPassValidationState validationState; + + auto MakeError = [&]() + { + return GPURenderPassEncoder::MakeError(this, + &encoding_context_, + descriptor.label.value_or("")); + }; + + bool success = encoding_context_.tryEncode( + this, + [&](gpu::CommandAllocator *allocator) -> gpu::MaybeError + { + GPUBeginRenderPassCommand *cmd = allocator->allocate(GPUCommand::kBeginRenderPass); + return {}; + }); + + if (success) + { + Ref passEncoder = GPURenderPassEncoder::Create(descriptor, + this, + &encoding_context_, + validationState.getRenderWidth(), + validationState.getRenderHeight(), + depthReadOnly, + stencilReadOnly); + + encoding_context_.enterPass(passEncoder.get()); + return passEncoder; + } + + return MakeError(); } void GPUCommandEncoder::clearBuffer() diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index a07b5fef8..32242cde2 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -36,7 +37,7 @@ namespace commandbuffers public: // TODO(yorkie): begineComputePass - GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor &); + Ref beginRenderPass(GPURenderPassDescriptor &); void clearBuffer(); void copyBufferToBuffer(); void copyBufferToTexture(); diff --git a/src/common/command_buffers/gpu/gpu_commands.hpp b/src/common/command_buffers/gpu/gpu_commands.hpp index 9ffa33fea..20ebbd7a9 100644 --- a/src/common/command_buffers/gpu/gpu_commands.hpp +++ b/src/common/command_buffers/gpu/gpu_commands.hpp @@ -11,9 +11,8 @@ namespace commandbuffers { - class GPUCommand + struct GPUCommand { - public: enum CommandType { kBeginComputePass, @@ -55,191 +54,105 @@ namespace commandbuffers kWriteTimestamp, }; const CommandType type; - - GPUCommand(CommandType type) - : type(type) - { - } - virtual ~GPUCommand() = default; }; - class GPUInsertDebugMarkerCommand : public GPUCommand + struct GPUInsertDebugMarkerCommand { - public: uint32_t length; }; - class GPUDrawCommand : public GPUCommand + + struct GPUBeginRenderPassCommand + { + // Ref attachmentState; + // PerColorAttachment colorAttachments; + // RenderPassDepthStencilAttachmentInfo depthStencilAttachment; + + // std::array storageAttachments; + + // Cache the width and height of all attachments for convenience + uint32_t width; + uint32_t height; + // Used for partial resolve + // ResolveRect resolveRect; + + // Ref occlusionQuerySet; + // TimestampWrites timestampWrites; + std::string label; + }; + + struct GPUDrawCommand { - public: const uint32_t vertexCount; const uint32_t instanceCount; const uint32_t firstVertex; const uint32_t firstInstance; - - GPUDrawCommand(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) - : GPUCommand(kDraw) - , vertexCount(vertex_count) - , instanceCount(instance_count) - , firstVertex(first_vertex) - , firstInstance(first_instance) - { - } }; - class GPUDrawIndexedCommand : public GPUCommand + struct GPUDrawIndexedCommand { - public: const uint32_t indexCount; const uint32_t instanceCount; const uint32_t firstIndex; const int32_t baseVertex; const uint32_t firstInstance; - - GPUDrawIndexedCommand(uint32_t index_count, - uint32_t instance_count, - uint32_t first_index, - int32_t base_vertex, - uint32_t first_instance) - : GPUCommand(kDrawIndexed) - , indexCount(index_count) - , instanceCount(instance_count) - , firstIndex(first_index) - , baseVertex(base_vertex) - , firstInstance(first_instance) - { - } }; - class GPUSetViewportCommand : public GPUCommand + struct GPUSetViewportCommand { - public: const float x; const float y; const float width; const float height; const float minDepth; const float maxDepth; - - GPUSetViewportCommand(float x, float y, float width, float height, float min_depth, float max_depth) - : GPUCommand(kSetViewport) - , x(x) - , y(y) - , width(width) - , height(height) - , minDepth(min_depth) - , maxDepth(max_depth) - { - } }; - class GPUSetScissorCommand : public GPUCommand + struct GPUSetScissorCommand { - public: const float x; const float y; const float width; const float height; - - GPUSetScissorCommand(float x, float y, float width, float height) - : GPUCommand(kSetScissorRect) - , x(x) - , y(y) - , width(width) - , height(height) - { - } }; - class GPUSetRenderPipelineCommand : public GPUCommand + struct GPUSetRenderPipelineCommand { - public: const GPUIdentifier pipelineId; - - GPUSetRenderPipelineCommand(const GPURenderPipelineBase &pipeline) - : GPUCommand(kSetRenderPipeline) - , pipelineId(pipeline.id) - { - } }; - class GPUSetIndexBufferCommand : public GPUCommand + struct GPUSetIndexBufferCommand { - public: const GPUIdentifier bufferId; const GPUIndexFormat indexFormat; const uint32_t offset; const uint32_t size; - - GPUSetIndexBufferCommand(const GPUBufferBase &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) - : GPUCommand(kSetIndexBuffer) - , bufferId(buffer.id) - , indexFormat(index_format) - , offset(offset) - , size(size) - { - } }; - class GPUSetVertexBufferCommand : public GPUCommand + struct GPUSetVertexBufferCommand { - public: const uint32_t slot; const GPUIdentifier bufferId; const uint32_t offset; const uint32_t size; - - GPUSetVertexBufferCommand(const uint32_t slot, const GPUBufferBase &buffer, uint64_t offset, uint32_t size) - : GPUCommand(kSetVertexBuffer) - , slot(slot) - , bufferId(buffer.id) - , offset(offset) - , size(size) - { - } }; - class GPUSetBindGroupCommand : public GPUCommand + struct GPUSetBindGroupCommand { - public: const GPUIdentifier bindGroupId; const uint32_t index; - - GPUSetBindGroupCommand(const GPUBindGroupBase &bindGroup, uint32_t index) - : GPUCommand(kSetBindGroup) - , bindGroupId(bindGroup.id) - , index(index) - { - } }; - class GPUSetBlendConstantCommand : public GPUCommand + struct GPUSetBlendConstantCommand { - public: const float r; const float g; const float b; const float a; - - GPUSetBlendConstantCommand(float r, float g, float b, float a) - : GPUCommand(kSetBlendConstant) - , r(r) - , g(g) - , b(b) - , a(a) - { - } }; - class GPUSetStencilReferenceCommand : public GPUCommand + struct GPUSetStencilReferenceCommand { - public: const uint32_t reference; - - GPUSetStencilReferenceCommand(uint32_t reference) - : GPUCommand(kSetStencilReference) - , reference(reference) - { - } }; } diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.cpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.cpp new file mode 100644 index 000000000..a98593b64 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.cpp @@ -0,0 +1,58 @@ +#include + +namespace commandbuffers +{ + // static + Ref GPURenderPassEncoder::Create(const GPURenderPassDescriptor &descriptor, + GPUCommandEncoder *encoder, + gpu::EncodingContext *context, + uint32_t renderTargetWidth, + uint32_t renderTargetHeight, + bool depthReadOnly, + bool stencilReadOnly) + { + return AcquireRef(new GPURenderPassEncoder( + nullptr, + descriptor, + encoder, + context, + renderTargetWidth, + renderTargetHeight, + depthReadOnly, + stencilReadOnly)); + } + // static + Ref GPURenderPassEncoder::MakeError(GPUCommandEncoder *encoder, + gpu::EncodingContext *context, + std::string_view label) + { + return AcquireRef( + new GPURenderPassEncoder( + nullptr, + encoder, + context, + GPUHandle::kError, + label)); + } + + GPURenderPassEncoder::GPURenderPassEncoder(Ref device, + const GPURenderPassDescriptor &descriptor, + GPUCommandEncoder *commandEncoder, + gpu::EncodingContext *encodingContext, + uint32_t renderTargetWidth, + uint32_t renderTargetHeight, + bool depthReadOnly, + bool stencilReadOnly) + : GPUHandle(device, descriptor.label.value_or("GPURenderPassEncoder")) + { + } + + GPURenderPassEncoder::GPURenderPassEncoder(Ref device, + GPUCommandEncoder *commandEncoder, + gpu::EncodingContext *encodingContext, + ErrorTag errorTag, + std::string_view label) + : GPUHandle(device, errorTag, label) + { + } +} diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp index 41b7272d4..7c4ce24dd 100644 --- a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -9,9 +10,12 @@ #include #include #include +#include namespace commandbuffers { + class GPUCommandEncoder; + class GPURenderPassDescriptor { public: @@ -57,10 +61,21 @@ namespace commandbuffers std::optional depthStencilAttachment; }; - class GPURenderPassEncoder : public GPUPassEncoderBase, - public GPUHandle + class GPURenderPassEncoder final : public GPUPassEncoderBase, + public GPUHandle { public: + static Ref Create(const GPURenderPassDescriptor &descriptor, + GPUCommandEncoder *encoder, + gpu::EncodingContext *context, + uint32_t renderTargetWidth, + uint32_t renderTargetHeight, + bool depthReadOnly, + bool stencilReadOnly); + static Ref MakeError(GPUCommandEncoder *encoder, + gpu::EncodingContext *context, + std::string_view label); + GPUHandleType type() const override final { return GPUHandleType::kRenderPassEncoder; @@ -88,5 +103,20 @@ namespace commandbuffers void setVertexBuffer(uint32_t slot, const GPUBufferBase &buffer, uint32_t offset = 0, uint32_t size = 0); void setBlendConstant(float r, float g, float b, float a); void setStencilReference(uint32_t ref); + + protected: + GPURenderPassEncoder(Ref device, + const GPURenderPassDescriptor &descriptor, + GPUCommandEncoder *commandEncoder, + gpu::EncodingContext *encodingContext, + uint32_t renderTargetWidth, + uint32_t renderTargetHeight, + bool depthReadOnly, + bool stencilReadOnly); + GPURenderPassEncoder(Ref device, + GPUCommandEncoder *commandEncoder, + gpu::EncodingContext *encodingContext, + ErrorTag errorTag, + std::string_view label); }; } From 1aeac41ab6dac424b4f64ea011f1b4cdf8e3481b Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Mon, 24 Nov 2025 17:13:45 +0800 Subject: [PATCH 21/37] add gpu queue --- .../command_buffers/gpu/execution_queue.cpp | 9 ++ .../command_buffers/gpu/execution_queue.hpp | 50 ++++++++++ src/common/command_buffers/gpu/gpu_buffer.cpp | 10 ++ src/common/command_buffers/gpu/gpu_buffer.hpp | 3 + src/common/command_buffers/gpu/gpu_device.cpp | 29 ++++++ src/common/command_buffers/gpu/gpu_device.hpp | 32 ++++++ src/common/command_buffers/gpu/gpu_queue.cpp | 97 +++++++++++++++++++ src/common/command_buffers/gpu/gpu_queue.hpp | 51 ++++++++++ src/renderer/gles/gpu_queue_impl.cpp | 44 +++++++++ src/renderer/gles/gpu_queue_impl.hpp | 37 +++++++ 10 files changed, 362 insertions(+) create mode 100644 src/common/command_buffers/gpu/execution_queue.cpp create mode 100644 src/common/command_buffers/gpu/execution_queue.hpp create mode 100644 src/common/command_buffers/gpu/gpu_queue.cpp create mode 100644 src/common/command_buffers/gpu/gpu_queue.hpp create mode 100644 src/renderer/gles/gpu_queue_impl.cpp create mode 100644 src/renderer/gles/gpu_queue_impl.hpp diff --git a/src/common/command_buffers/gpu/execution_queue.cpp b/src/common/command_buffers/gpu/execution_queue.cpp new file mode 100644 index 000000000..a8aee76ff --- /dev/null +++ b/src/common/command_buffers/gpu/execution_queue.cpp @@ -0,0 +1,9 @@ +#include + +namespace commandbuffers::gpu +{ + bool ExecutionQueueBase::hasScheduledCommands() const + { + return false; + } +} diff --git a/src/common/command_buffers/gpu/execution_queue.hpp b/src/common/command_buffers/gpu/execution_queue.hpp new file mode 100644 index 000000000..d1d93fc10 --- /dev/null +++ b/src/common/command_buffers/gpu/execution_queue.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace commandbuffers::gpu +{ + class ExecutionQueueBase : public GPUHandle + { + public: + using Task = std::function; + + // Whether the execution queue has scheduled commands to be submitted or executing. + bool hasScheduledCommands() const; + + // In the 'Normal' mode, currently recorded commands in the backend submitted in the next Tick. + // However in the 'Passive' mode, the submission will be postponed as late as possible, for + // example, until the client has explictly issued a submission. + enum class SubmitMode + { + Normal, + Passive + }; + + // Tracks whether we are in a submit to avoid submit reentrancy. Reentrancy could otherwise + // happen when allocating resources or staging memory during submission (for workarounds, or + // emulation) and the heuristics ask for an early submit to happen (which would cause a + // submit-in-submit and many issues). + bool inSubmit = false; + + protected: + using GPUHandle::GPUHandle; + + private: + // Backend specific wait for idle function. + virtual MaybeError waitForIdleForDestructionImpl() = 0; + + // Indicates whether the backend has pending commands to be submitted as soon as possible. + virtual bool hasPendingCommands() const = 0; + + std::mutex mMutex; + std::condition_variable mCv; + bool mCallingCallbacks = false; + bool mWaitingForIdle = false; + bool mAssumeCompleted = false; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_buffer.cpp b/src/common/command_buffers/gpu/gpu_buffer.cpp index 1bee3b64a..dbc9fbf96 100644 --- a/src/common/command_buffers/gpu/gpu_buffer.cpp +++ b/src/common/command_buffers/gpu/gpu_buffer.cpp @@ -2,4 +2,14 @@ namespace commandbuffers { + gpu::MaybeError GPUBufferBase::uploadData(uint64_t bufferOffset, const void *data, size_t size) + { + if (size == 0) + { + return {}; + } + + // TODO: implement uploadData + return {}; + } } diff --git a/src/common/command_buffers/gpu/gpu_buffer.hpp b/src/common/command_buffers/gpu/gpu_buffer.hpp index 10e572e9d..2b067d1db 100644 --- a/src/common/command_buffers/gpu/gpu_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_buffer.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace commandbuffers @@ -69,6 +70,8 @@ namespace commandbuffers BufferState mapState() const; void unmap(); + virtual gpu::MaybeError uploadData(uint64_t bufferOffset, const void *data, size_t size); + protected: GPUBufferBase(Ref device, const GPUBufferDescriptor &descriptor); GPUBufferBase(Ref device, diff --git a/src/common/command_buffers/gpu/gpu_device.cpp b/src/common/command_buffers/gpu/gpu_device.cpp index 906646deb..af0f99475 100644 --- a/src/common/command_buffers/gpu/gpu_device.cpp +++ b/src/common/command_buffers/gpu/gpu_device.cpp @@ -95,6 +95,24 @@ namespace commandbuffers return nullptr; } + GPUDeviceBase::State GPUDeviceBase::getState() const + { + return state_; + } + + bool GPUDeviceBase::isLost() const + { + assert(state_ != State::BeingCreated); + return state_ != State::Alive; + } + + gpu::MaybeError GPUDeviceBase::validateIsAlive() const + { + // TODO(yorkie): implement this. + assert(state_ == State::Alive); + return {}; + } + bool GPUDeviceBase::isValidationEnabled() const { // return !IsToggleEnabled(Toggle::SkipValidation); @@ -119,6 +137,17 @@ namespace commandbuffers return false; } + gpu::MaybeError GPUDeviceBase::tick() + { + if (isLost() || !queue_->hasScheduledCommands()) + { + return {}; + } + + tickImpl(); + return {}; + } + bool GPUDeviceBase::mayRequireDuplicationOfIndirectParameters() const { return false; diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index eff90504c..5bdbde704 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -2,14 +2,17 @@ #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -72,11 +75,38 @@ namespace commandbuffers Ref createShaderModule(const GPUShaderModuleDescriptor *descriptor = nullptr, const std::vector &internalExtensions = {}); + // The device state which is a combination of creation state and loss state. + // + // - BeingCreated: the device didn't finish creation yet and the frontend cannot be used + // (both for the application calling WebGPU, or re-entrant calls). No work exists on + // the GPU timeline. + // - Alive: the device is usable and might have work happening on the GPU timeline. + // - BeingDisconnected: the device is no longer usable because we are waiting for all + // work on the GPU timeline to finish. (this is to make validation prevent the + // application from adding more work during the transition from Available to + // Disconnected) + // - Disconnected: there is no longer work happening on the GPU timeline and the CPU data + // structures can be safely destroyed without additional synchronization. + // - Destroyed: the device is disconnected and resources have been reclaimed. + enum class State + { + BeingCreated, + Alive, + BeingDisconnected, + Disconnected, + Destroyed, + }; + State getState() const; + bool isLost() const; + + gpu::MaybeError validateIsAlive() const; bool isValidationEnabled() const; bool isRobustnessEnabled() const; bool isCompatibilityMode() const; bool isImmediateErrorHandlingEnabled() const; + gpu::MaybeError tick(); + virtual bool mayRequireDuplicationOfIndirectParameters() const; protected: @@ -105,7 +135,9 @@ namespace commandbuffers Ref createEmptyBindGroupLayout(); Ref createEmptyPipelineLayout(); + std::atomic state_ = State::BeingCreated; Ref adapter_; + Ref queue_; Ref empty_bind_group_layout_; Ref empty_pipeline_layout_; diff --git a/src/common/command_buffers/gpu/gpu_queue.cpp b/src/common/command_buffers/gpu/gpu_queue.cpp new file mode 100644 index 000000000..6d5aba28b --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_queue.cpp @@ -0,0 +1,97 @@ +#include +#include + +namespace commandbuffers +{ + class GPUErrorQueue : public GPUQueueBase + { + public: + explicit GPUErrorQueue(Ref device, std::string_view label) + : GPUQueueBase(device, GPUHandle::kError, label) + { + } + + private: + gpu::MaybeError submitImpl(uint32_t commandCount, GPUCommandBufferBase *const *commands) override + { + assert(false); + } + bool hasPendingCommands() const override + { + assert(false); + } + gpu::MaybeError waitForIdleForDestructionImpl() override + { + return {}; + } + }; + + GPUQueueBase::GPUQueueBase(Ref device, const GPUQueueDescriptor &descriptor) + : gpu::ExecutionQueueBase(device, descriptor.label) + { + } + + GPUQueueBase::GPUQueueBase(Ref device, GPUHandle::ErrorTag, std::string_view label) + : gpu::ExecutionQueueBase(device, label) + { + } + + // static + Ref GPUQueueBase::MakeError(Ref device, std::string_view label) + { + return AcquireRef(new GPUErrorQueue(device, label)); + } + + void GPUQueueBase::submit(uint32_t commandCount, GPUCommandBufferBase *const *commands) + { + } + + void GPUQueueBase::writeBuffer(GPUBufferBase *buffer, + uint64_t bufferOffset, + const void *data, + size_t size) + { + } + + gpu::MaybeError GPUQueueBase::writeBufferImpl(GPUBufferBase *buffer, + uint64_t bufferOffset, + const void *data, + size_t size) + { + return buffer->uploadData(bufferOffset, data, size); + } + + gpu::MaybeError GPUQueueBase::validateSubmit(uint32_t commandCount, GPUCommandBufferBase *const *commands) const + { + return {}; + } + + gpu::MaybeError GPUQueueBase::validateOnSubmittedWorkDone() const + { + return {}; + } + + gpu::MaybeError GPUQueueBase::submitInternal(uint32_t commandCount, GPUCommandBufferBase *const *commands) + { + assert(device()->validateIsAlive().IsSuccess()); + + if (device()->isValidationEnabled()) + { + assert(validateSubmit(commandCount, commands).IsSuccess()); + } + assert(!isError()); + + inSubmit = true; + { + if (submitImpl(commandCount, commands).IsError()) + { + assert(false && "submitImpl failed"); + } + } + inSubmit = false; + + // Call tick() to flush pending work. + assert(device()->tick().IsSuccess()); + return {}; + } +} diff --git a/src/common/command_buffers/gpu/gpu_queue.hpp b/src/common/command_buffers/gpu/gpu_queue.hpp new file mode 100644 index 000000000..ea6542284 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_queue.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + struct GPUQueueDescriptor + { + std::string_view label; + }; + + class GPUQueueBase : public gpu::ExecutionQueueBase + { + public: + static Ref MakeError(Ref device, std::string_view label); + + GPUHandleType type() const override + { + return GPUHandleType::kQueue; + } + + void submit(uint32_t commandCount, GPUCommandBufferBase *const *commands); + void writeBuffer(GPUBufferBase *buffer, + uint64_t bufferOffset, + const void *data, + size_t size); + + protected: + GPUQueueBase(Ref device, const GPUQueueDescriptor &descriptor); + GPUQueueBase(Ref device, GPUHandle::ErrorTag, std::string_view label); + + virtual gpu::MaybeError submitImpl(uint32_t commandCount, GPUCommandBufferBase *const *commands) = 0; + virtual gpu::MaybeError writeBufferImpl(GPUBufferBase *buffer, + uint64_t bufferOffset, + const void *data, + size_t size); + + private: + gpu::MaybeError validateSubmit(uint32_t commandCount, GPUCommandBufferBase *const *commands) const; + gpu::MaybeError validateOnSubmittedWorkDone() const; + + gpu::MaybeError submitInternal(uint32_t commandCount, GPUCommandBufferBase *const *commands); + }; +} diff --git a/src/renderer/gles/gpu_queue_impl.cpp b/src/renderer/gles/gpu_queue_impl.cpp new file mode 100644 index 000000000..e8280ecdc --- /dev/null +++ b/src/renderer/gles/gpu_queue_impl.cpp @@ -0,0 +1,44 @@ +#include + +namespace gles +{ + using namespace std; + using namespace commandbuffers; + + GPUQueueImpl::GPUQueueImpl(Ref device, + const GPUQueueDescriptor &descriptor) + : GPUQueueBase(device, descriptor) + { + } + + // static + gpu::ResultOrError> GPUQueueImpl::Create(Ref device, + const GPUQueueDescriptor &descriptor) + { + return AcquireRef(new GPUQueueImpl(device, descriptor)); + } + + gpu::MaybeError GPUQueueImpl::submitImpl(uint32_t commandCount, + GPUCommandBufferBase *const *commands) + { + return {}; + } + + gpu::MaybeError GPUQueueImpl::writeBufferImpl(GPUBufferBase *buffer, + uint64_t bufferOffset, + const void *data, + size_t size) + { + return {}; + } + + bool GPUQueueImpl::hasPendingCommands() const + { + return has_pending_commands_; + } + + gpu::MaybeError GPUQueueImpl::waitForIdleForDestructionImpl() + { + return {}; + } +} diff --git a/src/renderer/gles/gpu_queue_impl.hpp b/src/renderer/gles/gpu_queue_impl.hpp new file mode 100644 index 000000000..5edd50568 --- /dev/null +++ b/src/renderer/gles/gpu_queue_impl.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace gles +{ + class GPUQueueImpl : public commandbuffers::GPUQueueBase + { + public: + static commandbuffers::gpu::ResultOrError> Create( + Ref device, + const commandbuffers::GPUQueueDescriptor &descriptor); + + private: + GPUQueueImpl(Ref device, + const commandbuffers::GPUQueueDescriptor &descriptor); + + commandbuffers::gpu::MaybeError submitImpl( + uint32_t commandCount, + commandbuffers::GPUCommandBufferBase *const *commands) override; + commandbuffers::gpu::MaybeError writeBufferImpl( + commandbuffers::GPUBufferBase *buffer, + uint64_t bufferOffset, + const void *data, + size_t size) override; + + bool hasPendingCommands() const override; + commandbuffers::gpu::MaybeError waitForIdleForDestructionImpl() override; + + uint32_t egl_sync_type_; + bool has_pending_commands_ = false; + }; +} From 780a6e4a5030bc4cdc9f6a7d41273168b433902e Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Mon, 24 Nov 2025 21:21:16 +0800 Subject: [PATCH 22/37] add render bundle --- .../command_buffers/gpu/attachment_set.hpp | 13 ++ src/common/command_buffers/gpu/gpu_base.cpp | 16 +-- src/common/command_buffers/gpu/gpu_base.hpp | 19 +-- .../command_buffers/gpu/gpu_render_bundle.cpp | 78 ++++++++++++ .../command_buffers/gpu/gpu_render_bundle.hpp | 60 +++++++++ .../gpu/gpu_render_bundle_encoder.cpp | 46 +++++++ .../gpu/gpu_render_bundle_encoder.hpp | 47 +++++++ .../gpu/programmable_encoder.cpp | 52 ++++++++ .../gpu/programmable_encoder.hpp | 45 +++++++ .../gpu/render_encoder_base.cpp | 119 ++++++++++++++++++ .../gpu/render_encoder_base.hpp | 92 ++++++++++++++ src/renderer/content_renderer.hpp | 6 +- 12 files changed, 573 insertions(+), 20 deletions(-) create mode 100644 src/common/command_buffers/gpu/attachment_set.hpp create mode 100644 src/common/command_buffers/gpu/gpu_render_bundle.cpp create mode 100644 src/common/command_buffers/gpu/gpu_render_bundle.hpp create mode 100644 src/common/command_buffers/gpu/gpu_render_bundle_encoder.cpp create mode 100644 src/common/command_buffers/gpu/gpu_render_bundle_encoder.hpp create mode 100644 src/common/command_buffers/gpu/programmable_encoder.cpp create mode 100644 src/common/command_buffers/gpu/programmable_encoder.hpp create mode 100644 src/common/command_buffers/gpu/render_encoder_base.cpp create mode 100644 src/common/command_buffers/gpu/render_encoder_base.hpp diff --git a/src/common/command_buffers/gpu/attachment_set.hpp b/src/common/command_buffers/gpu/attachment_set.hpp new file mode 100644 index 000000000..973a2b2b9 --- /dev/null +++ b/src/common/command_buffers/gpu/attachment_set.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace commandbuffers +{ + class GPUDeviceBase; + + namespace gpu + { + class AttachmentState + { + }; + } +} diff --git a/src/common/command_buffers/gpu/gpu_base.cpp b/src/common/command_buffers/gpu/gpu_base.cpp index 359f0d18a..b0213911b 100644 --- a/src/common/command_buffers/gpu/gpu_base.cpp +++ b/src/common/command_buffers/gpu/gpu_base.cpp @@ -70,19 +70,19 @@ namespace commandbuffers // GPUObject Implementation // - GPUObject::GPUObject(shared_ptr device) + GPUObject::GPUObject(Ref device) : ErrorMonad() , device_(device) { } - GPUObject::GPUObject(shared_ptr device, ErrorTag) + GPUObject::GPUObject(Ref device, ErrorTag) : ErrorMonad(kError) , device_(device) { } - GPUObject::GPUObject(shared_ptr device, DelayedInitializationTag) + GPUObject::GPUObject(Ref device, DelayedInitializationTag) : ErrorMonad(kDelayedInitialization) , device_(device) { @@ -93,7 +93,7 @@ namespace commandbuffers return device_->getInstance(); } - shared_ptr GPUObject::device() const + Ref GPUObject::device() const { return device_; } @@ -102,14 +102,14 @@ namespace commandbuffers // GPUHandle Implementation // - GPUHandle::GPUHandle(shared_ptr device, string_view label) + GPUHandle::GPUHandle(Ref device, string_view label) : GPUObject(device) , id(Ids.get()) , label_(string(label)) { } - GPUHandle::GPUHandle(shared_ptr device, + GPUHandle::GPUHandle(Ref device, ErrorTag tag, string_view label) : GPUObject(device, tag) @@ -118,7 +118,7 @@ namespace commandbuffers { } - GPUHandle::GPUHandle(shared_ptr device, + GPUHandle::GPUHandle(Ref device, DelayedInitializationTag tag, string_view label) : GPUObject(device, tag) @@ -127,7 +127,7 @@ namespace commandbuffers { } - GPUHandle::GPUHandle(shared_ptr device, LabelNotImplementedTag tag) + GPUHandle::GPUHandle(Ref device, LabelNotImplementedTag tag) : GPUObject(device) , id(Ids.get()) { diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 00e7e826f..9f8351fc0 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -34,6 +34,7 @@ #include #include +#include #include namespace commandbuffers @@ -773,15 +774,15 @@ namespace commandbuffers class GPUObject : public ErrorMonad { public: - explicit GPUObject(std::shared_ptr device); - GPUObject(std::shared_ptr device, ErrorTag tag); - GPUObject(std::shared_ptr device, DelayedInitializationTag tag); + explicit GPUObject(Ref device); + GPUObject(Ref device, ErrorTag tag); + GPUObject(Ref device, DelayedInitializationTag tag); GPUInstance *instance() const; - std::shared_ptr device() const; + Ref device() const; private: - std::shared_ptr device_; + Ref device_; }; typedef uint32_t GPUIdentifier; @@ -800,10 +801,10 @@ namespace commandbuffers }; static constexpr UntrackedByDeviceTag kUntrackedByDevice = {}; - GPUHandle(std::shared_ptr device, std::string_view label); - GPUHandle(std::shared_ptr device, ErrorTag tag, std::string_view label = {}); - GPUHandle(std::shared_ptr device, DelayedInitializationTag tag, std::string_view label = {}); - GPUHandle(std::shared_ptr device, LabelNotImplementedTag tag); + GPUHandle(Ref device, std::string_view label); + GPUHandle(Ref device, ErrorTag tag, std::string_view label = {}); + GPUHandle(Ref device, DelayedInitializationTag tag, std::string_view label = {}); + GPUHandle(Ref device, LabelNotImplementedTag tag); virtual GPUHandleType type() const = 0; void setLabel(std::string label); diff --git a/src/common/command_buffers/gpu/gpu_render_bundle.cpp b/src/common/command_buffers/gpu/gpu_render_bundle.cpp new file mode 100644 index 000000000..e0f2d4747 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_render_bundle.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include + +using namespace std; + +namespace commandbuffers +{ + GPURenderBundle::GPURenderBundle(GPURenderBundleEncoder *encoder, + const GPURenderBundleDescriptor *descriptor, + Ref attachment_state, + bool depth_readonly, + bool stencil_readonly, + gpu::RenderPassResourceUsage resource_usage, + gpu::IndirectDrawMetadata indirect_draw_metadata) + : GPUHandle(encoder->device(), kLabelNotImplemented) + , commands_(encoder->acquireCommands()) + , attachment_state_(std::move(attachment_state)) + , indirect_draw_metadata_(std::move(indirect_draw_metadata)) + , depth_readonly_(depth_readonly) + , stencil_readonly_(stencil_readonly) + , resource_usage_(std::move(resource_usage)) + , encoder_label_(encoder->getLabel()) + { + } + + GPURenderBundle::GPURenderBundle(Ref device, ErrorTag error_tag, string_view label) + : GPUHandle(device, error_tag, label) + { + } + + const string &GPURenderBundle::getEncoderLabel() const + { + return encoder_label_; + } + + void GPURenderBundle::setEncoderLabel(string encoder_label) + { + encoder_label_ = encoder_label; + } + + gpu::CommandIterator *GPURenderBundle::getCommands() + { + return &commands_; + } + + const gpu::AttachmentState *GPURenderBundle::getAttachmentState() const + { + return attachment_state_.get(); + } + + bool GPURenderBundle::isDepthReadOnly() const + { + return depth_readonly_; + } + + bool GPURenderBundle::isStencilReadOnly() const + { + return stencil_readonly_; + } + + uint64_t GPURenderBundle::getDrawCount() const + { + return draw_count_; + } + + const gpu::RenderPassResourceUsage &GPURenderBundle::getResourceUsage() const + { + return resource_usage_; + } + + const gpu::IndirectDrawMetadata &GPURenderBundle::getIndirectDrawMetadata() + { + return indirect_draw_metadata_; + } +} diff --git a/src/common/command_buffers/gpu/gpu_render_bundle.hpp b/src/common/command_buffers/gpu/gpu_render_bundle.hpp new file mode 100644 index 000000000..9d30ca561 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_render_bundle.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + class GPURenderBundleEncoder; + struct GPURenderBundleDescriptor + { + std::string_view label; + }; + + class GPURenderBundle final : public GPUHandle + { + public: + GPURenderBundle(GPURenderBundleEncoder *encoder, + const GPURenderBundleDescriptor *descriptor, + Ref attachment_state, + bool depth_readonly, + bool stencil_readonly, + gpu::RenderPassResourceUsage resource_usage, + gpu::IndirectDrawMetadata indirect_draw_metadata); + + GPUHandleType type() const override + { + return GPUHandleType::kRenderBundle; + } + + const std::string &getEncoderLabel() const; + void setEncoderLabel(std::string); + + gpu::CommandIterator *getCommands(); + + const gpu::AttachmentState *getAttachmentState() const; + bool isDepthReadOnly() const; + bool isStencilReadOnly() const; + uint64_t getDrawCount() const; + const gpu::RenderPassResourceUsage &getResourceUsage() const; + const gpu::IndirectDrawMetadata &getIndirectDrawMetadata(); + + private: + GPURenderBundle(Ref device, ErrorTag error_tag, std::string_view label); + + gpu::CommandIterator commands_; + gpu::IndirectDrawMetadata indirect_draw_metadata_; + Ref attachment_state_; + bool depth_readonly_; + bool stencil_readonly_; + uint64_t draw_count_; + gpu::RenderPassResourceUsage resource_usage_; + std::string encoder_label_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_render_bundle_encoder.cpp b/src/common/command_buffers/gpu/gpu_render_bundle_encoder.cpp new file mode 100644 index 000000000..cacd52ecb --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_render_bundle_encoder.cpp @@ -0,0 +1,46 @@ +#include +#include +#include + +namespace commandbuffers +{ + GPURenderBundleEncoder::GPURenderBundleEncoder(Ref device, + const GPURenderBundleEncoderDescriptor *descriptor) + : RenderEncoderBase(device, + descriptor->label, + &bundle_encoding_context_, + nullptr, + descriptor->depthReadOnly, + descriptor->stencilReadOnly) + , bundle_encoding_context_(device, this) + { + } + + GPURenderBundleEncoder::GPURenderBundleEncoder(Ref device, + ErrorTag error_tag, + std::string_view label) + : RenderEncoderBase(device, &bundle_encoding_context_, error_tag, label) + , bundle_encoding_context_(device, error_tag) + { + } + + Ref GPURenderBundleEncoder::finish(const GPURenderBundleEncoderDescriptor *descriptor) + { + assert(false && "GPURenderBundleEncoder::finish is not implemented"); + } + + gpu::CommandIterator GPURenderBundleEncoder::acquireCommands() + { + return bundle_encoding_context_.acquireCommands(); + } + + gpu::ResultOrError> GPURenderBundleEncoder::finishInternal(const GPURenderBundleEncoderDescriptor *descriptor) + { + assert(false && "GPURenderBundleEncoder::finishInternal is not implemented"); + } + + gpu::MaybeError GPURenderBundleEncoder::validateFinish(const gpu::RenderPassResourceUsage &usages) const + { + return {}; + } +} diff --git a/src/common/command_buffers/gpu/gpu_render_bundle_encoder.hpp b/src/common/command_buffers/gpu/gpu_render_bundle_encoder.hpp new file mode 100644 index 000000000..8f5089a05 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_render_bundle_encoder.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + class GPURenderBundle; + + struct GPURenderBundleEncoderDescriptor + { + std::string_view label; + size_t colorFormatCount; + GPUTextureFormat const *colorFormats = nullptr; + GPUTextureFormat depthStencilFormat = GPUTextureFormat::kUndefined; + uint32_t sampleCount = 1; + bool depthReadOnly = false; + bool stencilReadOnly = false; + }; + + class GPURenderBundleEncoder final : public gpu::RenderEncoderBase + { + public: + GPUHandleType type() const override + { + return GPUHandleType::kRenderBundleEncoder; + } + + Ref finish(const GPURenderBundleEncoderDescriptor *descriptor); + gpu::CommandIterator acquireCommands(); + + private: + GPURenderBundleEncoder(Ref device, const GPURenderBundleEncoderDescriptor *descriptor); + GPURenderBundleEncoder(Ref device, ErrorTag error_tag, std::string_view label); + + gpu::ResultOrError> finishInternal(const GPURenderBundleEncoderDescriptor *descriptor); + gpu::MaybeError validateFinish(const gpu::RenderPassResourceUsage &usages) const; + + gpu::EncodingContext bundle_encoding_context_; + }; +} diff --git a/src/common/command_buffers/gpu/programmable_encoder.cpp b/src/common/command_buffers/gpu/programmable_encoder.cpp new file mode 100644 index 000000000..da28b56bd --- /dev/null +++ b/src/common/command_buffers/gpu/programmable_encoder.cpp @@ -0,0 +1,52 @@ +#include +#include + +namespace commandbuffers::gpu +{ + using namespace std; + + ProgrammableEncoder::ProgrammableEncoder(Ref device, + string_view label, + EncodingContext *encoding_context) + : GPUHandle(device, label) + , encoding_context_(encoding_context) + , validation_enabled_(device->isValidationEnabled()) + { + } + + ProgrammableEncoder::ProgrammableEncoder(Ref device, + EncodingContext *encodingContext, + ErrorTag errorTag, + string_view label) + : GPUHandle(device, errorTag, label) + , encoding_context_(encodingContext) + , validation_enabled_(device->isValidationEnabled()) + { + } + + void ProgrammableEncoder::insertDebugMarker(string_view group_label) + { + } + + void ProgrammableEncoder::popDebugMarker() + { + } + + void ProgrammableEncoder::pushDebugMarker(string_view group_label) + { + } + + void ProgrammableEncoder::setImmediateData(uint32_t offset, const void *data, size_t size) + { + } + + bool ProgrammableEncoder::isValidationEnabled() const + { + return validation_enabled_; + } + + MaybeError ProgrammableEncoder::validateProgrammableEncoderEnd() const + { + return {}; + } +} \ No newline at end of file diff --git a/src/common/command_buffers/gpu/programmable_encoder.hpp b/src/common/command_buffers/gpu/programmable_encoder.hpp new file mode 100644 index 000000000..4f9677447 --- /dev/null +++ b/src/common/command_buffers/gpu/programmable_encoder.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace commandbuffers +{ + class GPUDeviceBase; + + namespace gpu + { + class ProgrammableEncoder : public GPUHandle + { + public: + ProgrammableEncoder(Ref device, + std::string_view label, + EncodingContext *encoding_context); + + void insertDebugMarker(std::string_view group_label); + void popDebugMarker(); + void pushDebugMarker(std::string_view group_label); + void setImmediateData(uint32_t offset, const void *data, size_t size); + + protected: + bool isValidationEnabled() const; + MaybeError validateProgrammableEncoderEnd() const; + + // Construct an "error" programmable pass encoder. + ProgrammableEncoder(Ref device, + EncodingContext *encodingContext, + ErrorTag errorTag, + std::string_view label); + + EncodingContext *encoding_context_ = nullptr; + uint64_t debug_group_stack_size_ = 0; + bool ended_ = false; + + private: + const bool validation_enabled_; + }; + } +} diff --git a/src/common/command_buffers/gpu/render_encoder_base.cpp b/src/common/command_buffers/gpu/render_encoder_base.cpp new file mode 100644 index 000000000..9f5b13069 --- /dev/null +++ b/src/common/command_buffers/gpu/render_encoder_base.cpp @@ -0,0 +1,119 @@ +#include +#include +#include "command_buffers/gpu/indirect_draw_metadata.hpp" + +namespace commandbuffers::gpu +{ + using namespace std; + + RenderEncoderBase::RenderEncoderBase(Ref device, + string_view label, + EncodingContext *encoding_context, + Ref attachment_state, + bool depth_readonly, + bool stencil_readonly) + : ProgrammableEncoder(device, label, encoding_context) + , attachment_state_(std::move(attachment_state)) + , disable_base_vertex_(true) + , disable_base_instance_(true) + { + } + + RenderEncoderBase::RenderEncoderBase(Ref device, + EncodingContext *encoding_context, + ErrorTag error_tag, + std::string_view label) + : ProgrammableEncoder(device, encoding_context, error_tag, label) + , disable_base_vertex_(true) + , disable_base_instance_(true) + { + } + + void RenderEncoderBase::draw(uint32_t vertex_count, + uint32_t instance_count, + uint32_t first_vertex, + uint32_t first_instance) + { + } + + void RenderEncoderBase::drawIndexed(uint32_t vertex_count, + uint32_t instance_count, + uint32_t first_index, + int32_t base_vertex, + uint32_t first_instance) + { + } + + void RenderEncoderBase::drawIndirect(GPUBufferBase *indirect_buffer, uint64_t indirect_fffset) + { + } + + void RenderEncoderBase::drawIndexedIndirect(GPUBufferBase *indirect_buffer, uint64_t indirect_fffset) + { + } + + void RenderEncoderBase::multiDrawIndirect( + GPUBufferBase *indirect_buffer, + uint64_t indirect_fffset, + uint32_t max_draw_count, + GPUBufferBase *draw_count_buffer, + uint64_t draw_count_buffer_offset) + { + } + + void RenderEncoderBase::multiDrawIndexedIndirect( + GPUBufferBase *indirect_buffer, + uint64_t indirect_fffset, + uint32_t max_draw_count, + GPUBufferBase *draw_count_buffer, + uint64_t draw_count_buffer_offset) + { + } + + void RenderEncoderBase::setPipeline(GPURenderPipelineBase *pipeline) + { + } + + void RenderEncoderBase::setVertexBuffer(uint32_t slot, GPUBufferBase *buffer, uint64_t offset, uint64_t size) + { + } + + void RenderEncoderBase::setIndexBuffer(GPUBufferBase *buffer, + GPUIndexFormat format, + uint64_t offset, + uint64_t size) + { + } + + void RenderEncoderBase::setBindGroup(uint32_t group_index, + GPUBindGroupBase *group, + uint32_t dynamic_offset_count, + const uint32_t *dynamic_offsets) + { + } + + const AttachmentState *RenderEncoderBase::getAttachmentState() const + { + return attachment_state_.get(); + } + + bool RenderEncoderBase::isDepthReadOnly() const + { + return depth_read_only_; + } + + bool RenderEncoderBase::isStencilReadOnly() const + { + return stencil_read_only_; + } + + uint64_t RenderEncoderBase::getDrawCount() const + { + return draw_count_; + } + + Ref RenderEncoderBase::acquireAttachmentState() + { + return std::move(attachment_state_); + } +} \ No newline at end of file diff --git a/src/common/command_buffers/gpu/render_encoder_base.hpp b/src/common/command_buffers/gpu/render_encoder_base.hpp new file mode 100644 index 000000000..b11bf3c3e --- /dev/null +++ b/src/common/command_buffers/gpu/render_encoder_base.hpp @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "command_buffers/gpu/indirect_draw_metadata.hpp" + +namespace commandbuffers +{ + class GPUDeviceBase; + + namespace gpu + { + class RenderEncoderBase : public ProgrammableEncoder + { + public: + RenderEncoderBase(Ref device, + std::string_view label, + EncodingContext *encoding_context, + Ref attachment_state, + bool depth_readonly, + bool stencil_readonly); + + void draw(uint32_t vertex_count, + uint32_t instance_count = 1, + uint32_t first_vertex = 0, + uint32_t first_instance = 0); + void drawIndexed(uint32_t vertex_count, + uint32_t instance_count, + uint32_t first_index, + int32_t base_vertex, + uint32_t first_instance); + + void drawIndirect(GPUBufferBase *indirect_buffer, uint64_t indirect_fffset); + void drawIndexedIndirect(GPUBufferBase *indirect_buffer, uint64_t indirect_fffset); + + void multiDrawIndirect( + GPUBufferBase *indirect_buffer, + uint64_t indirect_fffset, + uint32_t max_draw_count, + GPUBufferBase *draw_count_buffer = nullptr, + uint64_t draw_count_buffer_offset = 0); + void multiDrawIndexedIndirect( + GPUBufferBase *indirect_buffer, + uint64_t indirect_fffset, + uint32_t max_draw_count, + GPUBufferBase *draw_count_buffer = nullptr, + uint64_t draw_count_buffer_offset = 0); + + void setPipeline(GPURenderPipelineBase *pipeline); + void setVertexBuffer(uint32_t slot, GPUBufferBase *buffer, uint64_t offset, uint64_t size); + void setIndexBuffer(GPUBufferBase *buffer, + GPUIndexFormat format, + uint64_t offset, + uint64_t size); + + void setBindGroup(uint32_t group_index, + GPUBindGroupBase *group, + uint32_t dynamic_offset_count = 0, + const uint32_t *dynamic_offsets = nullptr); + + const AttachmentState *getAttachmentState() const; + bool isDepthReadOnly() const; + bool isStencilReadOnly() const; + uint64_t getDrawCount() const; + Ref acquireAttachmentState(); + + protected: + // Construct an "error" render encoder base. + RenderEncoderBase(Ref device, + EncodingContext *encoding_context, + ErrorTag error_tag, + std::string_view label); + + IndirectDrawMetadata indirect_draw_metadata_; + uint64_t draw_count_ = 0; + + private: + Ref attachment_state_; + const bool disable_base_vertex_; + const bool disable_base_instance_; + bool depth_read_only_ = false; + bool stencil_read_only_ = false; + }; + } +} diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index 4ee88e213..cb3c68b62 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -12,11 +12,11 @@ #include #include #include + #include #include - -#include "./gles/context_storage.hpp" -#include "./render_api.hpp" +#include +#include using namespace std; using namespace commandbuffers; From 659819ddc7531d959848b6b31d1015ee2ba77651 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 26 Nov 2025 20:05:29 +0800 Subject: [PATCH 23/37] renderer: add context webgl --- .../command_buffers/webgl_constants.hpp | 26 + src/renderer/content_renderer.hpp | 15 +- src/renderer/context_webgl.cpp | 123 +++++ src/renderer/context_webgl.hpp | 496 ++++++++++++++++++ src/renderer/render_pass.cpp | 58 ++ src/renderer/render_pass.hpp | 77 +++ src/renderer/render_resource.cpp | 34 ++ src/renderer/render_resource.hpp | 31 ++ 8 files changed, 857 insertions(+), 3 deletions(-) create mode 100644 src/renderer/context_webgl.cpp create mode 100644 src/renderer/context_webgl.hpp create mode 100644 src/renderer/render_pass.cpp create mode 100644 src/renderer/render_pass.hpp create mode 100644 src/renderer/render_resource.cpp create mode 100644 src/renderer/render_resource.hpp diff --git a/src/common/command_buffers/webgl_constants.hpp b/src/common/command_buffers/webgl_constants.hpp index a2b30d1b5..0b5ca746b 100644 --- a/src/common/command_buffers/webgl_constants.hpp +++ b/src/common/command_buffers/webgl_constants.hpp @@ -9,6 +9,32 @@ * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#standard_webgl_1_constants */ +// Types + +typedef uint32_t WebGLbitfield; +typedef uint8_t WebGLboolean; +typedef int8_t WebGLbyte; +typedef float WebGLclampf; +typedef uint32_t WebGLenum; +typedef float WebGLfloat; +typedef int32_t WebGLint; +typedef int16_t WebGLshort; +typedef int32_t WebGLsizei; +typedef uint8_t WebGLubyte; +typedef uint32_t WebGLuint; +typedef uint16_t WebGLushort; +typedef void WebGLvoid; + +typedef char WebGLchar; +typedef double WebGLdouble; +typedef double WebGLclampd; +typedef uint16_t WebGLhalf; +typedef int64_t WebGLint64; +typedef struct __WebGLsync *WebGLsync; +typedef uint64_t WebGLuint64; +typedef intptr_t WebGLintptr; +typedef intptr_t WebGLsizeiptr; + // Standard WebGL 1 constants // Clearing buffers diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index cb3c68b62..ab2aa1a7e 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,8 @@ #include #include #include +#include +#include #include using namespace std; @@ -64,7 +67,7 @@ namespace renderer * @param constellation The constellation that the content belongs to. * @return The created content renderer. */ - static inline std::shared_ptr Make(std::shared_ptr content, + static inline Ref Make(Ref content, uint8_t contextId, TrConstellation *constellation) { @@ -74,7 +77,7 @@ namespace renderer } public: - TrContentRenderer(std::shared_ptr content, uint8_t contextId, TrConstellation *constellation); + TrContentRenderer(Ref content, uint8_t contextId, TrConstellation *constellation); ~TrContentRenderer(); public: // public lifecycle @@ -85,7 +88,7 @@ namespace renderer bool sendCommandBufferResponse(TrCommandBufferResponse &res); // Returns the current using GL context. ContextGLApp *getContextGL() const; - inline shared_ptr getContent() const + inline Ref getContent() const { return content.lock(); } @@ -206,6 +209,12 @@ namespace renderer std::chrono::milliseconds frameDuration = std::chrono::milliseconds(0); std::chrono::milliseconds maxFrameDuration = std::chrono::milliseconds(0); + private: + Ref render_resource_; + Ref opaque_renderpass_; + Ref transparent_renderpass_; + Ref offscreen_renderpass_; + private: // frame rate control uint32_t targetFrameRate; }; diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp new file mode 100644 index 000000000..da75c687e --- /dev/null +++ b/src/renderer/context_webgl.cpp @@ -0,0 +1,123 @@ +#include +#include "command_buffers/details/texture.hpp" +#include "command_buffers/shared.hpp" + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + TrContextWebGL::TrContextWebGL() + { + } + + TrContextWebGL::~TrContextWebGL() + { + } + + void TrContextWebGL::receiveIncomingCall(const TrCommandBufferRequest &req) + { + switch (req.type) + { + case COMMAND_BUFFER_ACTIVE_TEXTURE_REQ: + { + const auto &typed_req = To(req); + glActiveTexture(typed_req.activeUnit); + break; + } + case COMMAND_BUFFER_BIND_TEXTURE_REQ: + { + const auto &typed_req = To(req); + glBindTexture(typed_req.target, typed_req.texture); + break; + } + case COMMAND_BUFFER_COPY_TEXTURE_IMAGE_2D_REQ: + { + const auto &typed_req = To(req); + glCopyTexImage2D( + typed_req.target, + typed_req.internalFormat, + typed_req.level, + typed_req.x, + typed_req.y, + typed_req.width, + typed_req.height, + typed_req.border); + break; + } + case COMMAND_BUFFER_COPY_TEXTURE_SUB_IMAGE_2D_REQ: + { + const auto &typed_req = To(req); + glCopyTexSubImage2D( + typed_req.target, + typed_req.level, + typed_req.xoffset, + typed_req.yoffset, + typed_req.x, + typed_req.y, + typed_req.width, + typed_req.height); + break; + } + case COMMAND_BUFFER_DELETE_TEXTURE_REQ: + { + const auto &typed_req = To(req); + glDeleteTextures(1, (const WebGLuint *)&typed_req.texture); + break; + } + case COMMAND_BUFFER_CREATE_TEXTURE_REQ: + { + const auto &typed_req = To(req); + WebGLint texture; + glGenTextures(1, (WebGLuint *)&texture); + break; + } + default: + break; + } + } + + void TrContextWebGL::glActiveTexture(WebGLenum texture) + { + active_texture_ = texture; + } + + void TrContextWebGL::glBindTexture(WebGLenum target, WebGLuint texture) + { + texture_bindings_[TextureTarget(target)] = {target, texture}; + } + + void TrContextWebGL::glCopyTexImage2D(WebGLenum target, + WebGLenum internalformat, + WebGLint level, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height, + WebGLint border) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCopyTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glDeleteTextures(WebGLsizei n, const WebGLuint *textures) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glGenTextures(WebGLsizei n, WebGLuint *textures) + { + // TODO(yorkie): implement + } +} diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp new file mode 100644 index 000000000..118cf885d --- /dev/null +++ b/src/renderer/context_webgl.hpp @@ -0,0 +1,496 @@ +#pragma once + +#include +#include +#include + +namespace renderer +{ + class TrContextWebGL + { + public: + TrContextWebGL(); + ~TrContextWebGL(); + + class TextureTarget + { + public: + enum + { + k2D = WEBGL_TEXTURE_2D, + k3D = WEBGL2_TEXTURE_3D, + k2DArray = WEBGL2_TEXTURE_2D_ARRAY, + }; + + TextureTarget(WebGLenum target) + : target_(target) + { + assert(target_ == k2D || target_ == k3D || target_ == k2DArray); + } + + inline WebGLenum value() const + { + return target_; + } + + inline bool operator==(const TextureTarget &rhs) const + { + return target_ == rhs.target_; + } + + struct HashKey + { + size_t operator()(const TextureTarget &t) const noexcept + { + return std::hash{}(t.value()); + } + }; + + private: + WebGLenum target_; + }; + + struct TextureBinding + { + WebGLenum target; + WebGLuint texture; + }; + + void receiveIncomingCall(const commandbuffers::TrCommandBufferRequest &); + + private: + template + static const T &To(const commandbuffers::TrCommandBufferRequest &req) + { + return dynamic_cast(req); + } + + // Textures + void glActiveTexture(WebGLenum texture); + void glBindTexture(WebGLenum target, WebGLuint texture); + void glCompressedTexImage2D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei border, + WebGLsizei imageSize, + const WebGLvoid *data); + void glCompressedTexImage3D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLsizei border, + WebGLsizei imageSize, + const WebGLvoid *data); + void glCompressedTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLsizei width, + WebGLsizei height, + WebGLenum format, + WebGLsizei imageSize, + const WebGLvoid *data); + void glCompressedTexSubImage3D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint zoffset, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLenum format, + WebGLsizei imageSize, + const WebGLvoid *data); + void glCopyTexImage2D(WebGLenum target, + WebGLenum internalformat, + WebGLint level, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height, + WebGLint border); + void glCopyTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height); + void glDeleteTextures(WebGLsizei n, const WebGLuint *textures); + void glGenTextures(WebGLsizei n, WebGLuint *textures); + void glGetTexParameter(WebGLenum target, WebGLenum pname, WebGLint *params); + void glIsTexture(WebGLuint texture); + void glTexImage2D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei border, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data); + void glTexImage3D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLsizei border, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data); + void glTexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param); + void glTexParameteri(WebGLenum target, WebGLenum pname, WebGLint param); + void glTexParameterfv(WebGLenum target, WebGLenum pname, const WebGLfloat *params); + void glTexParameteriv(WebGLenum target, WebGLenum pname, const WebGLint *params); + void glTexStorage2D(WebGLenum target, + WebGLint levels, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height); + void glTexStorage3D(WebGLenum target, + WebGLint levels, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth); + void glTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLsizei width, + WebGLsizei height, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data); + void glTexSubImage3D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint zoffset, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data); + + // Rendering + void glClear(WebGLbitfield mask); + void glClearBufferiv(WebGLenum buffer, WebGLint drawbuffer, const WebGLint *value); + void glClearBufferuiv(WebGLenum buffer, WebGLint drawbuffer, const WebGLuint *value); + void glClearBufferfv(WebGLenum buffer, WebGLint drawbuffer, const WebGLfloat *value); + void glClearBufferfi(WebGLenum buffer, WebGLint drawbuffer, WebGLfloat depth, WebGLint stencil); + void glClearColor(WebGLfloat red, WebGLfloat green, WebGLfloat blue, WebGLfloat alpha); + void glClearDepthf(WebGLfloat depth); + void glClearStencil(WebGLint s); + void glFinish(); + void glFlush(); + void glReadBuffer(WebGLenum buffer); + void glReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height, WebGLenum format, WebGLenum type, WebGLvoid *pixels); + + // Frame Buffers + void glBindFramebuffer(WebGLenum target, WebGLuint framebuffer); + void glBindRenderbuffer(WebGLenum target, WebGLuint renderbuffer); + void glBlitFramebuffer(WebGLint srcX0, + WebGLint srcY0, + WebGLint srcX1, + WebGLint srcY1, + WebGLint dstX0, + WebGLint dstY0, + WebGLint dstX1, + WebGLint dstY1, + WebGLbitfield mask, + WebGLenum filter); + void glCheckFramebufferStatus(WebGLenum target); + void glDeleteFramebuffers(WebGLsizei n, const WebGLuint *framebuffers); + void glDeleteRenderbuffers(WebGLsizei n, const WebGLuint *renderbuffers); + void glDrawBuffers(WebGLsizei n, const WebGLenum *buffers); + void glFramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum renderbuffertarget, WebGLuint renderbuffer); + void glFramebufferTexture2D(WebGLenum target, WebGLenum attachment, WebGLenum textarget, WebGLuint texture, WebGLint level); + void glFramebufferTextureLayer(WebGLenum target, WebGLenum attachment, WebGLuint texture, WebGLint level, WebGLint layer); + void glGenFramebuffers(WebGLsizei n, WebGLuint *framebuffers); + void glGenRenderbuffers(WebGLsizei n, WebGLuint *renderbuffers); + void glGenerateMipmap(WebGLenum target); + void glGetFramebufferAttachmentParameteriv(WebGLenum target, WebGLenum attachment, WebGLenum pname, WebGLint *params); + void glGetRenderbufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params); + void glInvalidateFramebuffer(WebGLenum target, WebGLsizei n, const WebGLenum *attachments); + void glInvalidateSubFramebuffer(WebGLenum target, + WebGLsizei n, + const WebGLenum *attachments, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height); + void glIsFramebuffer(WebGLuint framebuffer); + void glIsRenderbuffer(WebGLuint renderbuffer); + void glRenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height); + void glRenderbufferStorageMultisample(WebGLenum target, + WebGLsizei samples, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height); + + // Shaders + void glAttachShader(WebGLuint program, WebGLuint shader); + void glBindAttribLocation(WebGLuint program, WebGLuint index, const WebGLchar *name); + void glCompileShader(WebGLuint shader); + void glCreateProgram(); + void glCreateShader(WebGLenum type); + void glDeleteProgram(WebGLuint program); + void glDeleteShader(WebGLuint shader); + void glDetachShader(WebGLuint program, WebGLuint shader); + void glGetActiveAttrib(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLint *size, + WebGLenum *type, + WebGLchar *name); + void glGetActiveUniform(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLint *size, + WebGLenum *type, + WebGLchar *name); + void glGetActiveUniformBlockName(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLchar *name); + void glGetActiveUniformBlockiv(WebGLuint program, + WebGLuint index, + WebGLenum pname, + WebGLint *params); + void glGetActiveUniformsiv(WebGLuint program, + WebGLsizei count, + const WebGLuint *uniforms, + WebGLenum pname, + WebGLint *params); + void glGetAttachedShaders(WebGLuint program, WebGLsizei maxCount, WebGLsizei *count, WebGLuint *shaders); + void glGetAttribLocation(WebGLuint program, const WebGLchar *name); + void glGetFragDataLocation(WebGLuint program, const WebGLchar *name); + void glGetProgramBinary(WebGLuint program, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLenum binaryFormat, + WebGLsizei *binaryLength, + WebGLbyte *binary); + void glGetProgramInfoLog(WebGLuint program, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog); + void glGetProgramiv(WebGLuint program, WebGLenum pname, WebGLint *params); + void glGetShaderInfoLog(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog); + void glGetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype, WebGLint *range, WebGLint *precision); + void glGetShaderSource(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *source); + void glGetShaderiv(WebGLuint shader, WebGLenum pname, WebGLint *params); + void glGetUniformfv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLfloat *params); + void glGetUniformiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLint *params); + void glGetUniformuiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLuint *params); + void glGetUniformBlockIndex(WebGLuint program, const WebGLchar *name); + void glGetUniformIndices(WebGLuint program, WebGLsizei count, const WebGLchar **names, WebGLuint *indices); + void glGetUniformLocation(WebGLuint program, const WebGLchar *name); + void glIsProgram(WebGLuint program); + void glIsShader(WebGLuint shader); + void glLinkProgram(WebGLuint program); + void glProgramBinary(WebGLuint program, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength); + void glProgramParameteri(WebGLuint program, WebGLenum pname, WebGLint param); + void glReleaseShaderCompiler(); + void glShaderBinary(WebGLuint shader, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength); + void glShaderSource(WebGLuint shader, WebGLsizei count, const WebGLchar **string, const WebGLint *length); + void glUniform1f(WebGLuint location, WebGLfloat v0); + void glUniform2f(WebGLuint location, WebGLfloat v0, WebGLfloat v1); + void glUniform3f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2); + void glUniform4f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3); + void glUniform1i(WebGLuint location, WebGLint v0); + void glUniform2i(WebGLuint location, WebGLint v0, WebGLint v1); + void glUniform3i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2); + void glUniform4i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3); + void glUniform1ui(WebGLuint location, WebGLuint v0); + void glUniform2ui(WebGLuint location, WebGLuint v0, WebGLuint v1); + void glUniform3ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2); + void glUniform4ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2, WebGLuint v3); + void glUniform1fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value); + void glUniform2fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value); + void glUniform3fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value); + void glUniform4fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value); + void glUniform1iv(WebGLuint location, WebGLsizei count, const WebGLint *value); + void glUniform2iv(WebGLuint location, WebGLsizei count, const WebGLint *value); + void glUniform3iv(WebGLuint location, WebGLsizei count, const WebGLint *value); + void glUniform4iv(WebGLuint location, WebGLsizei count, const WebGLint *value); + void glUniform1uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value); + void glUniform2uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value); + void glUniform3uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value); + void glUniform4uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value); + void glUniformMatrix2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix2x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix3x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix2x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix4x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix3x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformMatrix4x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value); + void glUniformBlockBinding(WebGLuint program, WebGLuint uniformBlockIndex, WebGLuint bindingPoint); + void glUseProgram(WebGLuint program); + void glValidateProgram(WebGLuint program); + + // Buffer Objects + void glBindBuffer(WebGLenum target, WebGLuint buffer); + void glBindBufferBase(WebGLenum target, WebGLuint bindingPoint, WebGLuint buffer); + void glBindBufferRange(WebGLenum target, WebGLuint bindingPoint, WebGLuint buffer, WebGLintptr offset, WebGLsizeiptr size); + void glBufferData(WebGLenum target, WebGLsizeiptr size, const WebGLvoid *data, WebGLenum usage); + void glBufferSubData(WebGLenum target, WebGLintptr offset, WebGLsizeiptr size, const WebGLvoid *data); + void glCopyBufferSubData(WebGLenum readTarget, + WebGLenum writeTarget, + WebGLintptr readOffset, + WebGLintptr writeOffset, + WebGLsizeiptr size); + void glDeleteBuffers(WebGLsizei count, const WebGLuint *buffers); + void glDisableVertexAttribArray(WebGLuint index); + void glDrawArrays(WebGLenum mode, WebGLint first, WebGLsizei count); + void glDrawArraysInstanced(WebGLenum mode, WebGLint first, WebGLsizei count, WebGLsizei instanceCount); + void glDrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, const WebGLvoid *indices); + void glDrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type, const WebGLvoid *indices, WebGLsizei instanceCount); + void glDrawRangeElements(WebGLenum mode, WebGLuint start, WebGLuint end, WebGLsizei count, WebGLenum type, const WebGLvoid *indices); + void glEnableVertexAttribArray(WebGLuint index); + void glFlushMappedBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr size); + void glGenBuffers(WebGLsizei n, WebGLuint *buffers); + void glGetBufferParameter(WebGLenum target, WebGLenum pname, WebGLint *params); + void glGetBufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params); + void glGetBufferPointerv(WebGLenum target, WebGLenum pname, WebGLvoid **params); + void glGetVertexAttrib(WebGLuint index, WebGLenum pname, WebGLint *params); + void glGetVertexAttribPointerv(WebGLuint index, WebGLenum pname, WebGLvoid **pointer); + void glIsBuffer(WebGLuint buffer); + void glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access); + void glUnmapBuffer(WebGLenum target); + void glVertexAttrib(WebGLuint index, WebGLfloat x); + void glVertexAttrib1f(WebGLuint index, WebGLfloat x); + void glVertexAttrib2f(WebGLuint index, WebGLfloat x, WebGLfloat y); + void glVertexAttrib3f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z); + void glVertexAttrib4f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z, WebGLfloat w); + void glVertexAttrib1fv(WebGLuint index, const WebGLfloat *v); + void glVertexAttrib2fv(WebGLuint index, const WebGLfloat *v); + void glVertexAttrib3fv(WebGLuint index, const WebGLfloat *v); + void glVertexAttrib4fv(WebGLuint index, const WebGLfloat *v); + void glVertexAttribDivisor(WebGLuint index, WebGLuint divisor); + void glVertexAttribPointer(WebGLuint index, + WebGLint size, + WebGLenum type, + WebGLboolean normalized, + WebGLsizei stride, + WebGLintptr offset); + void glVertexAttribIPointer(WebGLuint index, + WebGLint size, + WebGLenum type, + WebGLsizei stride, + WebGLintptr offset); + + // State Management + void glBlendColor(WebGLfloat red, WebGLfloat green, WebGLfloat blue, WebGLfloat alpha); + void glBlendEquation(WebGLenum mode); + void glBlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha); + void glBlendFunc(WebGLenum sfactor, WebGLenum dfactor); + void glBlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB, WebGLenum srcAlpha, WebGLenum dstAlpha); + void glColorMask(WebGLboolean red, WebGLboolean green, WebGLboolean blue, WebGLboolean alpha); + void glCullFace(WebGLenum mode); + void glDepthFunc(WebGLenum func); + void glDepthMask(WebGLboolean flag); + void glDepthRangef(WebGLfloat near, WebGLfloat far); + void glDisable(WebGLenum cap); + void glEnable(WebGLenum cap); + void glFrontFace(WebGLenum mode); + void glGet(WebGLenum pname, WebGLint *params); + void glGetError(); + void glHint(WebGLenum target, WebGLenum mode); + void glIsEnabled(WebGLenum cap); + void glLineWidth(WebGLfloat width); + void glPixelStorei(WebGLenum pname, WebGLint param); + void glPolygonOffset(WebGLfloat factor, WebGLfloat units); + void glSampleCoverage(WebGLfloat value, WebGLboolean invert); + void glScissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height); + void glStencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask); + void glStencilFuncSeparate(WebGLenum face, WebGLenum func, WebGLint ref, WebGLuint mask); + void glStencilMask(WebGLuint mask); + void glStencilMaskSeparate(WebGLenum face, WebGLuint mask); + void glStencilOp(WebGLenum fail, WebGLenum zfail, WebGLenum zpass); + void glStencilOpSeparate(WebGLenum face, WebGLenum fail, WebGLenum zfail, WebGLenum zpass); + void glViewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height); + + // Transform Feedback + void glBeginTransformFeedback(WebGLenum primitiveMode); + void glBindTransformFeedback(WebGLenum target, WebGLuint transformFeedback); + void glDeleteTransformFeedbacks(WebGLsizei n, const WebGLuint *transformFeedbacks); + void glEndTransformFeedback(); + void glGenTransformFeedbacks(WebGLsizei n, WebGLuint *transformFeedbacks); + void glGetTransformFeedbackVarying(WebGLuint program, + WebGLuint index, + WebGLsizei bufSize, + WebGLsizei *length, + WebGLsizei *size, + WebGLenum *type, + WebGLchar *name); + void glIsTransformFeedback(WebGLuint transformFeedback); + void glPauseTransformFeedback(); + void glResumeTransformFeedback(); + void glTransformFeedbackVaryings(WebGLuint program, + WebGLsizei count, + const WebGLchar **varyings, + WebGLenum bufferMode); + + // Utility + void glGetInternalformativ(WebGLenum target, WebGLenum internalformat, WebGLsizei propCount, WebGLenum *props, WebGLint *params); + void glGetString(WebGLenum pname, WebGLchar *params); + void glGetStringi(WebGLenum pname, WebGLuint index); + + // Queries + void glBeginQuery(WebGLenum target, WebGLuint id); + void glDeleteQueries(WebGLsizei n, const WebGLuint *ids); + void glEndQuery(WebGLenum target); + void glGenQueries(WebGLsizei n, WebGLuint *ids); + void glGetQueryObjectuiv(WebGLuint id, WebGLenum pname, WebGLuint *params); + void glGetQueryiv(WebGLenum target, WebGLenum pname, WebGLint *params); + void glIsQuery(WebGLuint id); + + // Syncing + void glClientWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout); + void glDeleteSync(WebGLsync sync); + WebGLsync glFenceSync(WebGLenum condition, WebGLbitfield flags); + void glGetSynciv(WebGLsync sync, WebGLenum pname, WebGLsizei bufSize, WebGLsizei *length, WebGLint *values); + WebGLboolean glIsSync(WebGLsync sync); + void glWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout); + + // Vertex Array Objects + void glBindVertexArray(WebGLuint array); + void glDeleteVertexArrays(WebGLsizei n, const WebGLuint *arrays); + void glGenVertexArrays(WebGLsizei n, WebGLuint *arrays); + void glIsVertexArray(WebGLuint array); + + // Samplers + void glBindSampler(WebGLuint unit, WebGLuint sampler); + void glDeleteSamplers(WebGLsizei n, const WebGLuint *samplers); + void glGenSamplers(WebGLsizei n, WebGLuint *samplers); + void glGetSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint *params); + void glIsSampler(WebGLuint sampler); + void glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param); + + WebGLenum active_texture_; + std::unordered_map texture_bindings_; + }; +} + +namespace std +{ + template <> + struct hash + { + size_t operator()(const renderer::TrContextWebGL::TextureTarget &t) const noexcept + { + return std::hash{}(t.value()); + } + }; +} diff --git a/src/renderer/render_pass.cpp b/src/renderer/render_pass.cpp new file mode 100644 index 000000000..060061ca2 --- /dev/null +++ b/src/renderer/render_pass.cpp @@ -0,0 +1,58 @@ +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + TrRenderPass::TrRenderPass(RenderPassType type, const string &name) + : type_(type) + , name_(name) + , active_(false) + , command_encoder_(nullptr) + , renderpass_encoder_(nullptr) + { + } + + TrRenderPass::~TrRenderPass() + { + } + + RenderPassType TrRenderPass::type() const + { + return type_; + } + + const string &TrRenderPass::name() const + { + return name_; + } + + bool TrRenderPass::isActive() const + { + return active_; + } + + void TrRenderPass::receiveIncomingRequest(const TrCommandBufferRequest &request) + { + } + + void TrRenderPass::begin() + { + active_ = true; + { + renderpass_encoder_ = command_encoder_->beginRenderPass(renderpass_descriptor_); + } + } + + void TrRenderPass::end() + { + active_ = false; + renderpass_encoder_->end(); + } + + unique_ptr TrRenderPass::finish(optional label) + { + return command_encoder_->finish(label); + } +} diff --git a/src/renderer/render_pass.hpp b/src/renderer/render_pass.hpp new file mode 100644 index 000000000..bcda299c0 --- /dev/null +++ b/src/renderer/render_pass.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace renderer +{ + enum class RenderPassType + { + /** + * Opaque render pass for rendering opaque objects. + * This is the default pass for objects without transparency. + */ + kOpaque, + /** + * Transparent render pass for rendering transparent objects. + * Objects with blending enabled should be routed here. + */ + kTransparent, + /** + * Offscreen render pass for rendering to off-screen targets. + * Used when the framebuffer is different from the main render target. + */ + kOffscreen, + }; + + inline const char *RenderPassTypeToString(RenderPassType type) + { + switch (type) + { + case RenderPassType::kOpaque: + return "Opaque"; + case RenderPassType::kTransparent: + return "Transparent"; + case RenderPassType::kOffscreen: + return "Offscreen"; + default: + return "Unknown"; + } + } + + /** + * The `TrRenderPass` class represents a render pass that manages a collection of command buffers. + * It wraps the `GPURenderPassEncoder` and provides an interface for adding and executing command buffers + * based on the pass type (opaque, transparent, or offscreen). + */ + class TrRenderPass final + { + public: + TrRenderPass(RenderPassType type, const std::string &name); + ~TrRenderPass(); + + RenderPassType type() const; + const std::string &name() const; + bool isActive() const; + + void receiveIncomingRequest(const commandbuffers::TrCommandBufferRequest &request); + void begin(); + void end(); + std::unique_ptr finish(std::optional label = std::nullopt); + + private: + RenderPassType type_; + std::string name_; + bool active_; + Ref command_encoder_; + Ref renderpass_encoder_; + commandbuffers::GPURenderPassDescriptor renderpass_descriptor_; + }; +} diff --git a/src/renderer/render_resource.cpp b/src/renderer/render_resource.cpp new file mode 100644 index 000000000..19647fa42 --- /dev/null +++ b/src/renderer/render_resource.cpp @@ -0,0 +1,34 @@ +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + TrRenderResource::TrRenderResource(Ref device) + : device_(device) + , pipelines_() + , buffers_() + , textures_() + { + } + + void TrRenderResource::receiveIncomingRequest(const TrCommandBufferRequest &request) + { + } + + Ref TrRenderResource::getPipeline(int id) + { + return pipelines_.at(id); + } + + Ref TrRenderResource::getBuffer(int id) + { + return buffers_.at(id); + } + + Ref TrRenderResource::getTexture(int id) + { + return textures_.at(id); + } +} diff --git a/src/renderer/render_resource.hpp b/src/renderer/render_resource.hpp new file mode 100644 index 000000000..5a74583e8 --- /dev/null +++ b/src/renderer/render_resource.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace renderer +{ + class TrRenderResource final + { + public: + TrRenderResource(Ref device); + + void receiveIncomingRequest(const commandbuffers::TrCommandBufferRequest &request); + Ref getPipeline(int id); + Ref getBuffer(int id); + Ref getTexture(int id); + + private: + Ref device_; + std::unordered_map> pipelines_; + std::unordered_map> buffers_; + std::unordered_map> textures_; + }; +} From 3c2bfd5b79a4431ced9a6c239e25f603db181ec2 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 26 Nov 2025 20:28:26 +0800 Subject: [PATCH 24/37] update --- src/renderer/context_webgl.cpp | 39 ++++++++++++++++++++++++++++++++++ src/renderer/context_webgl.hpp | 9 +++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index da75c687e..448574407 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -1,6 +1,7 @@ #include #include "command_buffers/details/texture.hpp" #include "command_buffers/shared.hpp" +#include "command_buffers/webgl_constants.hpp" namespace renderer { @@ -120,4 +121,42 @@ namespace renderer { // TODO(yorkie): implement } + + void TrContextWebGL::glGetTexParameter(WebGLenum target, WebGLenum pname, WebGLint *params) + { + // TODO(yorkie): implement + } + + WebGLboolean TrContextWebGL::glIsTexture(WebGLuint texture) + { + // TODO(yorkie): implement + return true; + } + + void TrContextWebGL::glTexImage2D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei border, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexImage3D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLsizei border, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } } diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index 118cf885d..e0136290c 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -59,6 +59,13 @@ namespace renderer void receiveIncomingCall(const commandbuffers::TrCommandBufferRequest &); private: + /** + * @brief Convert the request to the given type. + * + * @tparam T The type to convert. + * @param req The request to convert. + * @return const T& The converted request. + */ template static const T &To(const commandbuffers::TrCommandBufferRequest &req) { @@ -124,7 +131,7 @@ namespace renderer void glDeleteTextures(WebGLsizei n, const WebGLuint *textures); void glGenTextures(WebGLsizei n, WebGLuint *textures); void glGetTexParameter(WebGLenum target, WebGLenum pname, WebGLint *params); - void glIsTexture(WebGLuint texture); + WebGLboolean glIsTexture(WebGLuint texture); void glTexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, From f72567f4e9f67f0e443db116ac38261b93353367 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Wed, 26 Nov 2025 23:06:40 +0800 Subject: [PATCH 25/37] fix --- src/renderer/context_webgl.cpp | 1286 ++++++++++++++++++++++++++++++++ src/renderer/context_webgl.hpp | 69 +- 2 files changed, 1353 insertions(+), 2 deletions(-) diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index 448574407..e3706684a 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -159,4 +159,1290 @@ namespace renderer { // TODO(yorkie): implement } + + // --- Additional texture APIs --- + void TrContextWebGL::glCompressedTexImage2D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei border, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCompressedTexImage3D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLsizei border, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCompressedTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLsizei width, + WebGLsizei height, + WebGLenum format, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCompressedTexSubImage3D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint zoffset, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLenum format, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameterfv(WebGLenum target, WebGLenum pname, const WebGLfloat *params) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameteriv(WebGLenum target, WebGLenum pname, const WebGLint *params) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexStorage2D(WebGLenum target, + WebGLint levels, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexStorage3D(WebGLenum target, + WebGLint levels, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLsizei width, + WebGLsizei height, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexSubImage3D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint zoffset, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + // --- Rendering --- + void TrContextWebGL::glClear(WebGLbitfield mask) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferiv(WebGLenum buffer, WebGLint drawbuffer, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferuiv(WebGLenum buffer, WebGLint drawbuffer, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferfv(WebGLenum buffer, WebGLint drawbuffer, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferfi(WebGLenum buffer, WebGLint drawbuffer, WebGLfloat depth, WebGLint stencil) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearColor(WebGLfloat red, WebGLfloat green, WebGLfloat blue, WebGLfloat alpha) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearDepthf(WebGLfloat depth) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearStencil(WebGLint s) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFinish() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFlush() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glReadBuffer(WebGLenum buffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height, WebGLenum format, WebGLenum type, WebGLvoid *pixels) + { + /* TODO(yorkie): implement */ + } + + // --- Framebuffers --- + void TrContextWebGL::glBindFramebuffer(WebGLenum target, WebGLuint framebuffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBindRenderbuffer(WebGLenum target, WebGLuint renderbuffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBlitFramebuffer(WebGLint srcX0, + WebGLint srcY0, + WebGLint srcX1, + WebGLint srcY1, + WebGLint dstX0, + WebGLint dstY0, + WebGLint dstX1, + WebGLint dstY1, + WebGLbitfield mask, + WebGLenum filter) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glCheckFramebufferStatus(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteFramebuffers(WebGLsizei n, const WebGLuint *framebuffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteRenderbuffers(WebGLsizei n, const WebGLuint *renderbuffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawBuffers(WebGLsizei n, const WebGLenum *buffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum renderbuffertarget, WebGLuint renderbuffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFramebufferTexture2D(WebGLenum target, WebGLenum attachment, WebGLenum textarget, WebGLuint texture, WebGLint level) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFramebufferTextureLayer(WebGLenum target, WebGLenum attachment, WebGLuint texture, WebGLint level, WebGLint layer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenFramebuffers(WebGLsizei n, WebGLuint *framebuffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenRenderbuffers(WebGLsizei n, WebGLuint *renderbuffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenerateMipmap(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetFramebufferAttachmentParameteriv(WebGLenum target, WebGLenum attachment, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetRenderbufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glInvalidateFramebuffer(WebGLenum target, WebGLsizei n, const WebGLenum *attachments) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glInvalidateSubFramebuffer(WebGLenum target, + WebGLsizei n, + const WebGLenum *attachments, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsFramebuffer(WebGLuint framebuffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsRenderbuffer(WebGLuint renderbuffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glRenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glRenderbufferStorageMultisample(WebGLenum target, + WebGLsizei samples, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height) + { + /* TODO(yorkie): implement */ + } + + // --- Shaders --- + void TrContextWebGL::glAttachShader(WebGLuint program, WebGLuint shader) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBindAttribLocation(WebGLuint program, WebGLuint index, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glCompileShader(WebGLuint shader) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glCreateProgram() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glCreateShader(WebGLenum type) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteShader(WebGLuint shader) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDetachShader(WebGLuint program, WebGLuint shader) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveAttrib(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLint *size, + WebGLenum *type, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniform(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLint *size, + WebGLenum *type, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniformBlockName(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniformBlockiv(WebGLuint program, + WebGLuint index, + WebGLenum pname, + WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniformsiv(WebGLuint program, + WebGLsizei count, + const WebGLuint *uniforms, + WebGLenum pname, + WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetAttachedShaders(WebGLuint program, WebGLsizei maxCount, WebGLsizei *count, WebGLuint *shaders) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetAttribLocation(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetFragDataLocation(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetProgramBinary(WebGLuint program, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLenum binaryFormat, + WebGLsizei *binaryLength, + WebGLbyte *binary) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetProgramInfoLog(WebGLuint program, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetProgramiv(WebGLuint program, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderInfoLog(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype, WebGLint *range, WebGLint *precision) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderSource(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *source) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderiv(WebGLuint shader, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformfv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLfloat *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformuiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLuint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformBlockIndex(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformIndices(WebGLuint program, WebGLsizei count, const WebGLchar **names, WebGLuint *indices) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformLocation(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsShader(WebGLuint shader) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glLinkProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glProgramBinary(WebGLuint program, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glProgramParameteri(WebGLuint program, WebGLenum pname, WebGLint param) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glReleaseShaderCompiler() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glShaderBinary(WebGLuint shader, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glShaderSource(WebGLuint shader, WebGLsizei count, const WebGLchar **string, const WebGLint *length) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1f(WebGLuint location, WebGLfloat v0) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2f(WebGLuint location, WebGLfloat v0, WebGLfloat v1) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1i(WebGLuint location, WebGLint v0) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2i(WebGLuint location, WebGLint v0, WebGLint v1) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1ui(WebGLuint location, WebGLuint v0) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2ui(WebGLuint location, WebGLuint v0, WebGLuint v1) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2, WebGLuint v3) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix2x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix3x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix2x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix4x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix3x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix4x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformBlockBinding(WebGLuint program, WebGLuint uniformBlockIndex, WebGLuint bindingPoint) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUseProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glValidateProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + // --- Buffer Objects --- + void TrContextWebGL::glBindBuffer(WebGLenum target, WebGLuint buffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBindBufferBase(WebGLenum target, + WebGLuint bindingPoint, + WebGLuint buffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBindBufferRange(WebGLenum target, + WebGLuint bindingPoint, + WebGLuint buffer, + WebGLintptr offset, + WebGLsizeiptr size) + { + /* TODO(yorkie): implement */ + } + void TrContextWebGL::glBufferData(WebGLenum target, + WebGLsizeiptr size, + const WebGLvoid *data, + WebGLenum usage) + { + /* TODO(yorkie): implement */ + } + void TrContextWebGL::glBufferSubData(WebGLenum target, + WebGLintptr offset, + WebGLsizeiptr size, + const WebGLvoid *data) + { + /* TODO(yorkie): implement */ + } + void TrContextWebGL::glCopyBufferSubData(WebGLenum readTarget, + WebGLenum writeTarget, + WebGLintptr readOffset, + WebGLintptr writeOffset, + WebGLsizeiptr size) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteBuffers(WebGLsizei count, const WebGLuint *buffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDisableVertexAttribArray(WebGLuint index) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawArrays(WebGLenum mode, WebGLint first, WebGLsizei count) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawArraysInstanced(WebGLenum mode, + WebGLint first, + WebGLsizei count, + WebGLsizei instanceCount) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawElements(WebGLenum mode, + WebGLsizei count, + WebGLenum type, + const WebGLvoid *indices) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type, const WebGLvoid *indices, WebGLsizei instanceCount) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawRangeElements(WebGLenum mode, WebGLuint start, WebGLuint end, WebGLsizei count, WebGLenum type, const WebGLvoid *indices) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glEnableVertexAttribArray(WebGLuint index) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFlushMappedBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr size) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenBuffers(WebGLsizei n, WebGLuint *buffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetBufferParameter(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetBufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetBufferPointerv(WebGLenum target, WebGLenum pname, WebGLvoid **params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetVertexAttrib(WebGLuint index, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetVertexAttribPointerv(WebGLuint index, WebGLenum pname, WebGLvoid **pointer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsBuffer(WebGLuint buffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUnmapBuffer(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib(WebGLuint index, WebGLfloat x) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib1f(WebGLuint index, WebGLfloat x) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib2f(WebGLuint index, WebGLfloat x, WebGLfloat y) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib3f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib4f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z, WebGLfloat w) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib1fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib2fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib3fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib4fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttribDivisor(WebGLuint index, WebGLuint divisor) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttribPointer(WebGLuint index, + WebGLint size, + WebGLenum type, + WebGLboolean normalized, + WebGLsizei stride, + WebGLintptr offset) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttribIPointer(WebGLuint index, + WebGLint size, + WebGLenum type, + WebGLsizei stride, + WebGLintptr offset) + { + /* TODO(yorkie): implement */ + } + + // --- State Management --- + void TrContextWebGL::glBlendColor(WebGLfloat red, + WebGLfloat green, + WebGLfloat blue, + WebGLfloat alpha) + { + blend_color_[0] = red; + blend_color_[1] = green; + blend_color_[2] = blue; + blend_color_[3] = alpha; + } + + void TrContextWebGL::glBlendEquation(WebGLenum mode) + { + blend_equation_rgb_ = mode; + blend_equation_alpha_ = mode; + } + + void TrContextWebGL::glBlendEquationSeparate(WebGLenum mode_rgb, WebGLenum mode_alpha) + { + blend_equation_rgb_ = mode_rgb; + blend_equation_alpha_ = mode_alpha; + } + + void TrContextWebGL::glBlendFunc(WebGLenum sfactor, WebGLenum dfactor) + { + blend_sfactor_rgb_ = sfactor; + blend_dfactor_rgb_ = dfactor; + blend_sfactor_alpha_ = sfactor; + blend_dfactor_alpha_ = dfactor; + } + + void TrContextWebGL::glBlendFuncSeparate(WebGLenum src_rgb, + WebGLenum dst_rgb, + WebGLenum src_alpha, + WebGLenum dst_alpha) + { + blend_sfactor_rgb_ = src_rgb; + blend_dfactor_rgb_ = dst_rgb; + blend_sfactor_alpha_ = src_alpha; + blend_dfactor_alpha_ = dst_alpha; + } + + void TrContextWebGL::glColorMask(WebGLboolean red, + WebGLboolean green, + WebGLboolean blue, + WebGLboolean alpha) + { + color_mask_[0] = red; + color_mask_[1] = green; + color_mask_[2] = blue; + color_mask_[3] = alpha; + } + + void TrContextWebGL::glCullFace(WebGLenum mode) + { + cull_face_ = mode; + } + + void TrContextWebGL::glDepthFunc(WebGLenum func) + { + depth_func_ = func; + } + + void TrContextWebGL::glDepthMask(WebGLboolean flag) + { + depth_mask_ = flag; + } + + void TrContextWebGL::glDepthRangef(WebGLfloat near, WebGLfloat far) + { + depth_range_[0] = near; + depth_range_[1] = far; + } + + void TrContextWebGL::glDisable(WebGLenum cap) + { + caps_.disable(cap); + } + + void TrContextWebGL::glEnable(WebGLenum cap) + { + caps_.enable(cap); + } + + void TrContextWebGL::glFrontFace(WebGLenum mode) + { + front_face_ = mode; + } + + void TrContextWebGL::glGet(WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + WebGLenum TrContextWebGL::glGetError() + { + WebGLenum error = last_error_; + last_error_ = WEBGL_NO_ERROR; + return error; + } + + void TrContextWebGL::glHint(WebGLenum target, WebGLenum mode) + { /* TODO(yorkie): implement */ + } + + WebGLboolean TrContextWebGL::glIsEnabled(WebGLenum cap) + { + return caps_.isEnabled(cap); + } + + void TrContextWebGL::glLineWidth(WebGLfloat width) + { + line_width_ = width; + } + + void TrContextWebGL::glPixelStorei(WebGLenum pname, WebGLint param) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glPolygonOffset(WebGLfloat factor, WebGLfloat units) + { + polygon_offset_factor_ = factor; + polygon_offset_units_ = units; + } + + void TrContextWebGL::glSampleCoverage(WebGLfloat value, WebGLboolean invert) + { + sample_coverage_value_ = value; + sample_coverage_invert_ = invert; + } + + void TrContextWebGL::glScissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) + { + scissor_box_[0] = x; + scissor_box_[1] = y; + scissor_box_[2] = width; + scissor_box_[3] = height; + } + + void TrContextWebGL::glStencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask) + { + stencil_func_ = func; + stencil_ref_ = ref; + stencil_mask_ = mask; + } + + void TrContextWebGL::glStencilFuncSeparate(WebGLenum face, + WebGLenum func, + WebGLint ref, + WebGLuint mask) + { + stencil_func_ = func; + stencil_ref_ = ref; + stencil_mask_ = mask; + } + + void TrContextWebGL::glStencilMask(WebGLuint mask) + { + stencil_mask_ = mask; + } + + void TrContextWebGL::glStencilMaskSeparate(WebGLenum face, WebGLuint mask) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glStencilOp(WebGLenum fail, WebGLenum zfail, WebGLenum zpass) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glStencilOpSeparate(WebGLenum face, WebGLenum fail, WebGLenum zfail, WebGLenum zpass) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glViewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) + { + viewport_[0] = x; + viewport_[1] = y; + viewport_[2] = width; + viewport_[3] = height; + } + + // --- Transform Feedback --- + void TrContextWebGL::glBeginTransformFeedback(WebGLenum primitiveMode) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBindTransformFeedback(WebGLenum target, WebGLuint transformFeedback) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteTransformFeedbacks(WebGLsizei n, const WebGLuint *transformFeedbacks) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glEndTransformFeedback() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenTransformFeedbacks(WebGLsizei n, WebGLuint *transformFeedbacks) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetTransformFeedbackVarying(WebGLuint program, + WebGLuint index, + WebGLsizei bufSize, + WebGLsizei *length, + WebGLsizei *size, + WebGLenum *type, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsTransformFeedback(WebGLuint transformFeedback) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glPauseTransformFeedback() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glResumeTransformFeedback() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glTransformFeedbackVaryings(WebGLuint program, + WebGLsizei count, + const WebGLchar **varyings, + WebGLenum bufferMode) + { + /* TODO(yorkie): implement */ + } + + // --- Utility --- + void TrContextWebGL::glGetInternalformativ(WebGLenum target, WebGLenum internalformat, WebGLsizei propCount, WebGLenum *props, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetString(WebGLenum pname, WebGLchar *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetStringi(WebGLenum pname, WebGLuint index) + { + /* TODO(yorkie): implement */ + } + + // --- Queries --- + void TrContextWebGL::glBeginQuery(WebGLenum target, WebGLuint id) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteQueries(WebGLsizei n, const WebGLuint *ids) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glEndQuery(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenQueries(WebGLsizei n, WebGLuint *ids) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetQueryObjectuiv(WebGLuint id, WebGLenum pname, WebGLuint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetQueryiv(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsQuery(WebGLuint id) + { + /* TODO(yorkie): implement */ + } + + // --- Syncing --- + void TrContextWebGL::glClientWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteSync(WebGLsync sync) + { + /* TODO(yorkie): implement */ + } + + WebGLsync TrContextWebGL::glFenceSync(WebGLenum condition, WebGLbitfield flags) + { + /* TODO(yorkie): implement */ + return nullptr; + } + + void TrContextWebGL::glGetSynciv(WebGLsync sync, WebGLenum pname, WebGLsizei bufSize, WebGLsizei *length, WebGLint *values) + { + /* TODO(yorkie): implement */ + } + + WebGLboolean TrContextWebGL::glIsSync(WebGLsync sync) + { + /* TODO(yorkie): implement */ + return false; + } + + void TrContextWebGL::glWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout) + { + /* TODO(yorkie): implement */ + } + + // --- Vertex Array Objects --- + void TrContextWebGL::glBindVertexArray(WebGLuint array) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteVertexArrays(WebGLsizei n, const WebGLuint *arrays) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenVertexArrays(WebGLsizei n, WebGLuint *arrays) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsVertexArray(WebGLuint array) + { + /* TODO(yorkie): implement */ + } + + // --- Samplers --- + void TrContextWebGL::glBindSampler(WebGLuint unit, WebGLuint sampler) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteSamplers(WebGLsizei n, const WebGLuint *samplers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenSamplers(WebGLsizei n, WebGLuint *samplers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsSampler(WebGLuint sampler) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param) + { + /* TODO(yorkie): implement */ + } } diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index e0136290c..60bd3dc98 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -56,6 +56,42 @@ namespace renderer WebGLuint texture; }; + struct FramebufferBinding + { + WebGLenum target; + WebGLuint framebuffer; + }; + + struct RenderbufferBinding + { + WebGLenum target; + WebGLuint renderbuffer; + }; + + struct Capabilities + { + using Map = std::unordered_map; + + inline void enable(WebGLenum cap) + { + caps_[cap] = true; + } + + inline void disable(WebGLenum cap) + { + caps_[cap] = false; + } + + inline WebGLboolean isEnabled(WebGLenum cap) const + { + auto it = caps_.find(cap); + return it != caps_.end() ? it->second : false; + } + + private: + Map caps_; + }; + void receiveIncomingCall(const commandbuffers::TrCommandBufferRequest &); private: @@ -412,9 +448,9 @@ namespace renderer void glEnable(WebGLenum cap); void glFrontFace(WebGLenum mode); void glGet(WebGLenum pname, WebGLint *params); - void glGetError(); + WebGLenum glGetError(); void glHint(WebGLenum target, WebGLenum mode); - void glIsEnabled(WebGLenum cap); + WebGLboolean glIsEnabled(WebGLenum cap); void glLineWidth(WebGLfloat width); void glPixelStorei(WebGLenum pname, WebGLint param); void glPolygonOffset(WebGLfloat factor, WebGLfloat units); @@ -485,8 +521,37 @@ namespace renderer void glIsSampler(WebGLuint sampler); void glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param); + WebGLenum last_error_ = WEBGL_NO_ERROR; + Capabilities caps_; WebGLenum active_texture_; std::unordered_map texture_bindings_; + + WebGLfloat blend_color_[4]; + WebGLenum blend_equation_rgb_; + WebGLenum blend_equation_alpha_; + WebGLenum blend_sfactor_rgb_; + WebGLenum blend_dfactor_rgb_; + WebGLenum blend_sfactor_alpha_; + WebGLenum blend_dfactor_alpha_; + WebGLboolean color_mask_[4]; + + WebGLenum cull_face_; + WebGLenum front_face_; + WebGLenum depth_func_; + WebGLboolean depth_mask_; + WebGLfloat depth_range_[2]; + + WebGLenum stencil_func_; + WebGLint stencil_ref_; + WebGLuint stencil_mask_; + + WebGLfloat line_width_; + WebGLfloat polygon_offset_factor_; + WebGLfloat polygon_offset_units_; + WebGLfloat sample_coverage_value_; + WebGLboolean sample_coverage_invert_; + WebGLint scissor_box_[4]; + WebGLint viewport_[4]; }; } From 5c60bd4d8a125750bbe6cb98812703d1e68cc3cf Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Wed, 26 Nov 2025 23:53:06 +0800 Subject: [PATCH 26/37] fix --- src/renderer/content_renderer.hpp | 2 ++ src/renderer/context_webgl.cpp | 6 +++--- src/renderer/render_pass.hpp | 3 ++- src/renderer/render_resource.cpp | 4 ---- src/renderer/render_resource.hpp | 1 - 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index ab2aa1a7e..944ab8dc1 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include using namespace std; @@ -210,6 +211,7 @@ namespace renderer std::chrono::milliseconds maxFrameDuration = std::chrono::milliseconds(0); private: + Ref context_; Ref render_resource_; Ref opaque_renderpass_; Ref transparent_renderpass_; diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index e3706684a..07daccaa1 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -1,7 +1,7 @@ #include -#include "command_buffers/details/texture.hpp" -#include "command_buffers/shared.hpp" -#include "command_buffers/webgl_constants.hpp" +#include +#include +#include namespace renderer { diff --git a/src/renderer/render_pass.hpp b/src/renderer/render_pass.hpp index bcda299c0..5ac2b1056 100644 --- a/src/renderer/render_pass.hpp +++ b/src/renderer/render_pass.hpp @@ -64,7 +64,8 @@ namespace renderer void receiveIncomingRequest(const commandbuffers::TrCommandBufferRequest &request); void begin(); void end(); - std::unique_ptr finish(std::optional label = std::nullopt); + std::unique_ptr finish( + std::optional label = std::nullopt); private: RenderPassType type_; diff --git a/src/renderer/render_resource.cpp b/src/renderer/render_resource.cpp index 19647fa42..af1c211f8 100644 --- a/src/renderer/render_resource.cpp +++ b/src/renderer/render_resource.cpp @@ -13,10 +13,6 @@ namespace renderer { } - void TrRenderResource::receiveIncomingRequest(const TrCommandBufferRequest &request) - { - } - Ref TrRenderResource::getPipeline(int id) { return pipelines_.at(id); diff --git a/src/renderer/render_resource.hpp b/src/renderer/render_resource.hpp index 5a74583e8..3b5ff5e34 100644 --- a/src/renderer/render_resource.hpp +++ b/src/renderer/render_resource.hpp @@ -17,7 +17,6 @@ namespace renderer public: TrRenderResource(Ref device); - void receiveIncomingRequest(const commandbuffers::TrCommandBufferRequest &request); Ref getPipeline(int id); Ref getBuffer(int id); Ref getTexture(int id); From 54e66bc30ff0a78a2135bb7236242e718f3ce452 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Thu, 27 Nov 2025 01:27:12 +0800 Subject: [PATCH 27/37] start working context webgl --- src/common/command_buffers/gpu/gpu_device.hpp | 1 - src/renderer/content_renderer.hpp | 13 ++++ src/renderer/context_webgl.cpp | 42 +++++++++-- src/renderer/context_webgl.hpp | 72 ++++++++++++++----- src/renderer/render_resource.cpp | 18 +++++ src/renderer/render_resource.hpp | 7 +- 6 files changed, 129 insertions(+), 24 deletions(-) diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index 5bdbde704..f1ea70504 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index 944ab8dc1..39d65ab63 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -97,6 +97,19 @@ namespace renderer TrRenderer &getRendererRef() const; public: + Ref renderResource() const + { + return render_resource_; + } + Ref opaqueRenderPass() const + { + return opaque_renderpass_; + } + Ref transparentRenderPass() const + { + return transparent_renderpass_; + } + /** * Dispatch a command buffer request. * diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index 07daccaa1..c00998597 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -2,13 +2,15 @@ #include #include #include +#include namespace renderer { using namespace std; using namespace commandbuffers; - TrContextWebGL::TrContextWebGL() + TrContextWebGL::TrContextWebGL(Ref content_renderer) + : content_renderer_(content_renderer) { } @@ -862,7 +864,20 @@ namespace renderer // --- Buffer Objects --- void TrContextWebGL::glBindBuffer(WebGLenum target, WebGLuint buffer) { - /* TODO(yorkie): implement */ + if (!glIsBuffer(buffer)) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + for (auto &binding : buffer_bindings_) + { + if (binding.buffer == buffer) + { + binding.target = target; + break; + } + } } void TrContextWebGL::glBindBufferBase(WebGLenum target, @@ -956,7 +971,17 @@ namespace renderer void TrContextWebGL::glGenBuffers(WebGLsizei n, WebGLuint *buffers) { - /* TODO(yorkie): implement */ + static WebGLuint next_buffer_id = 0; + + for (int i = 0; i < n; i++) + { + const BufferBinding binding = { + .target = nullopt, + .buffer = next_buffer_id++, + }; + buffer_bindings_.push_back(binding); + buffers[i] = binding.buffer; + } } void TrContextWebGL::glGetBufferParameter(WebGLenum target, WebGLenum pname, WebGLint *params) @@ -984,9 +1009,16 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glIsBuffer(WebGLuint buffer) + WebGLboolean TrContextWebGL::glIsBuffer(WebGLuint buffer) { - /* TODO(yorkie): implement */ + for (const auto &binding : buffer_bindings_) + { + if (binding.buffer == buffer) + { + return true; + } + } + return false; } void TrContextWebGL::glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access) diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index 60bd3dc98..1d56ada5c 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -6,26 +6,20 @@ namespace renderer { + class TrContentRenderer; + class TrContextWebGL { public: - TrContextWebGL(); + TrContextWebGL(Ref content_renderer); ~TrContextWebGL(); - class TextureTarget + class ObjectTarget { public: - enum - { - k2D = WEBGL_TEXTURE_2D, - k3D = WEBGL2_TEXTURE_3D, - k2DArray = WEBGL2_TEXTURE_2D_ARRAY, - }; - - TextureTarget(WebGLenum target) + ObjectTarget(WebGLenum target) : target_(target) { - assert(target_ == k2D || target_ == k3D || target_ == k2DArray); } inline WebGLenum value() const @@ -33,23 +27,59 @@ namespace renderer return target_; } - inline bool operator==(const TextureTarget &rhs) const + inline bool operator==(const ObjectTarget &rhs) const { return target_ == rhs.target_; } struct HashKey { - size_t operator()(const TextureTarget &t) const noexcept + size_t operator()(const ObjectTarget &t) const noexcept { return std::hash{}(t.value()); } }; - private: + protected: WebGLenum target_; }; + class TextureTarget : public ObjectTarget + { + public: + enum + { + k2D = WEBGL_TEXTURE_2D, + k3D = WEBGL2_TEXTURE_3D, + k2DArray = WEBGL2_TEXTURE_2D_ARRAY, + }; + + TextureTarget(WebGLenum target) + : ObjectTarget(target) + { + assert(target_ == k2D || + target_ == k3D || + target_ == k2DArray); + } + }; + + class BufferTarget : public ObjectTarget + { + public: + enum + { + kArrayBuffer = WEBGL_ARRAY_BUFFER, + kElementArrayBuffer = WEBGL_ELEMENT_ARRAY_BUFFER, + }; + + BufferTarget(WebGLenum target) + : ObjectTarget(target) + { + assert(target_ == kArrayBuffer || + target_ == kElementArrayBuffer); + } + }; + struct TextureBinding { WebGLenum target; @@ -92,6 +122,13 @@ namespace renderer Map caps_; }; + + struct BufferBinding + { + std::optional target; + WebGLuint buffer; + }; + void receiveIncomingCall(const commandbuffers::TrCommandBufferRequest &); private: @@ -408,7 +445,7 @@ namespace renderer void glGetBufferPointerv(WebGLenum target, WebGLenum pname, WebGLvoid **params); void glGetVertexAttrib(WebGLuint index, WebGLenum pname, WebGLint *params); void glGetVertexAttribPointerv(WebGLuint index, WebGLenum pname, WebGLvoid **pointer); - void glIsBuffer(WebGLuint buffer); + WebGLboolean glIsBuffer(WebGLuint buffer); void glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access); void glUnmapBuffer(WebGLenum target); void glVertexAttrib(WebGLuint index, WebGLfloat x); @@ -521,10 +558,13 @@ namespace renderer void glIsSampler(WebGLuint sampler); void glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param); + Ref content_renderer_; + std::unordered_map texture_bindings_; + std::vector buffer_bindings_; + WebGLenum last_error_ = WEBGL_NO_ERROR; Capabilities caps_; WebGLenum active_texture_; - std::unordered_map texture_bindings_; WebGLfloat blend_color_[4]; WebGLenum blend_equation_rgb_; diff --git a/src/renderer/render_resource.cpp b/src/renderer/render_resource.cpp index af1c211f8..b17f65428 100644 --- a/src/renderer/render_resource.cpp +++ b/src/renderer/render_resource.cpp @@ -13,6 +13,24 @@ namespace renderer { } + Ref TrRenderResource::createPipeline() + { + return nullptr; + } + + Ref TrRenderResource::createBuffer( + const GPUBufferDescriptor *descriptor) + { + auto buffer = device_->createBuffer(descriptor); + buffers_.emplace(buffer->id, buffer); + return buffer; + } + + Ref TrRenderResource::createTexture() + { + return nullptr; + } + Ref TrRenderResource::getPipeline(int id) { return pipelines_.at(id); diff --git a/src/renderer/render_resource.hpp b/src/renderer/render_resource.hpp index 3b5ff5e34..d7415e9b5 100644 --- a/src/renderer/render_resource.hpp +++ b/src/renderer/render_resource.hpp @@ -1,8 +1,6 @@ #pragma once -#include #include - #include #include #include @@ -17,6 +15,11 @@ namespace renderer public: TrRenderResource(Ref device); + Ref createPipeline(); + Ref createBuffer( + const commandbuffers::GPUBufferDescriptor *descriptor); + Ref createTexture(); + Ref getPipeline(int id); Ref getBuffer(int id); Ref getTexture(int id); From 090387657a8966571c908f1f9b2909082bd85905 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Thu, 27 Nov 2025 01:44:00 +0800 Subject: [PATCH 28/37] fixup --- src/renderer/context_webgl.cpp | 88 ++++++++++++++++++++++++++++++---- src/renderer/context_webgl.hpp | 57 +++++++++++++++++----- 2 files changed, 126 insertions(+), 19 deletions(-) diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index c00998597..0b65fa845 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -347,12 +347,52 @@ namespace renderer // --- Framebuffers --- void TrContextWebGL::glBindFramebuffer(WebGLenum target, WebGLuint framebuffer) { - /* TODO(yorkie): implement */ + if (!glIsFramebuffer(framebuffer)) [[unlikely]] + { + last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; + return; + } + + if (target != WEBGL_FRAMEBUFFER && + target != WEBGL2_DRAW_FRAMEBUFFER && + target != WEBGL2_READ_FRAMEBUFFER) [[unlikely]] + { + last_error_ = WEBGL_INVALID_ENUM; + return; + } + + for (auto &binding : framebuffer_bindings_) + { + if (binding.framebuffer == framebuffer) + { + binding.target = target; + break; + } + } } void TrContextWebGL::glBindRenderbuffer(WebGLenum target, WebGLuint renderbuffer) { - /* TODO(yorkie): implement */ + if (!glIsRenderbuffer(renderbuffer)) [[unlikely]] + { + last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; + return; + } + + if (target != WEBGL_RENDERBUFFER) [[unlikely]] + { + last_error_ = WEBGL_INVALID_ENUM; + return; + } + + for (auto &binding : renderbuffer_bindings_) + { + if (binding.renderbuffer == renderbuffer) + { + binding.target = target; + break; + } + } } void TrContextWebGL::glBlitFramebuffer(WebGLint srcX0, @@ -406,12 +446,30 @@ namespace renderer void TrContextWebGL::glGenFramebuffers(WebGLsizei n, WebGLuint *framebuffers) { - /* TODO(yorkie): implement */ + static WebGLuint next_framebuffer_id_ = 1; + for (WebGLsizei i = 0; i < n; i++) + { + const FramebufferBinding binding = { + .target = nullopt, + .framebuffer = next_framebuffer_id_++, + }; + framebuffer_bindings_.push_back(binding); + framebuffers[i] = binding.framebuffer; + } } void TrContextWebGL::glGenRenderbuffers(WebGLsizei n, WebGLuint *renderbuffers) { - /* TODO(yorkie): implement */ + static WebGLuint next_renderbuffer_id_ = 1; + for (WebGLsizei i = 0; i < n; i++) + { + const RenderbufferBinding binding = { + .target = nullopt, + .renderbuffer = next_renderbuffer_id_++, + }; + renderbuffer_bindings_.push_back(binding); + renderbuffers[i] = binding.renderbuffer; + } } void TrContextWebGL::glGenerateMipmap(WebGLenum target) @@ -445,14 +503,28 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glIsFramebuffer(WebGLuint framebuffer) + WebGLboolean TrContextWebGL::glIsFramebuffer(WebGLuint framebuffer) { - /* TODO(yorkie): implement */ + for (const auto &binding : framebuffer_bindings_) + { + if (binding.framebuffer == framebuffer) + { + return true; + } + } + return false; } - void TrContextWebGL::glIsRenderbuffer(WebGLuint renderbuffer) + WebGLboolean TrContextWebGL::glIsRenderbuffer(WebGLuint renderbuffer) { - /* TODO(yorkie): implement */ + for (const auto &binding : renderbuffer_bindings_) + { + if (binding.renderbuffer == renderbuffer) + { + return true; + } + } + return false; } void TrContextWebGL::glRenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height) diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index 1d56ada5c..f88cfb7d9 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -80,21 +80,61 @@ namespace renderer } }; + class FramebufferTarget : public ObjectTarget + { + public: + enum + { + kFramebuffer = WEBGL_FRAMEBUFFER, + kReadFramebuffer = WEBGL2_READ_FRAMEBUFFER, + kDrawFramebuffer = WEBGL2_DRAW_FRAMEBUFFER, + }; + + FramebufferTarget(WebGLenum target) + : ObjectTarget(target) + { + assert(target_ == kFramebuffer || + target_ == kReadFramebuffer || + target_ == kDrawFramebuffer); + } + }; + + class RenderbufferTarget : public ObjectTarget + { + public: + enum + { + kRenderbuffer = WEBGL_RENDERBUFFER, + }; + + RenderbufferTarget(WebGLenum target) + : ObjectTarget(target) + { + assert(target_ == kRenderbuffer); + } + }; + struct TextureBinding { WebGLenum target; WebGLuint texture; }; + struct BufferBinding + { + std::optional target; + WebGLuint buffer; + }; + struct FramebufferBinding { - WebGLenum target; + std::optional target; WebGLuint framebuffer; }; struct RenderbufferBinding { - WebGLenum target; + std::optional target; WebGLuint renderbuffer; }; @@ -122,13 +162,6 @@ namespace renderer Map caps_; }; - - struct BufferBinding - { - std::optional target; - WebGLuint buffer; - }; - void receiveIncomingCall(const commandbuffers::TrCommandBufferRequest &); private: @@ -307,8 +340,8 @@ namespace renderer WebGLint y, WebGLsizei width, WebGLsizei height); - void glIsFramebuffer(WebGLuint framebuffer); - void glIsRenderbuffer(WebGLuint renderbuffer); + WebGLboolean glIsFramebuffer(WebGLuint framebuffer); + WebGLboolean glIsRenderbuffer(WebGLuint renderbuffer); void glRenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height); void glRenderbufferStorageMultisample(WebGLenum target, WebGLsizei samples, @@ -561,6 +594,8 @@ namespace renderer Ref content_renderer_; std::unordered_map texture_bindings_; std::vector buffer_bindings_; + std::vector framebuffer_bindings_; + std::vector renderbuffer_bindings_; WebGLenum last_error_ = WEBGL_NO_ERROR; Capabilities caps_; From a3efd6d129a68ffa1618bfddd06473788ed01cb6 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Thu, 27 Nov 2025 01:49:22 +0800 Subject: [PATCH 29/37] fixup --- src/renderer/context_webgl.cpp | 23 +++++++++++++++++------ src/renderer/context_webgl.hpp | 28 ++++++++++++++++------------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index 0b65fa845..bf3275255 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -299,29 +299,40 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glClearBufferfv(WebGLenum buffer, WebGLint drawbuffer, const WebGLfloat *value) + void TrContextWebGL::glClearBufferfv(WebGLenum buffer, + WebGLint drawbuffer, + const WebGLfloat *value) { /* TODO(yorkie): implement */ } - void TrContextWebGL::glClearBufferfi(WebGLenum buffer, WebGLint drawbuffer, WebGLfloat depth, WebGLint stencil) + void TrContextWebGL::glClearBufferfi(WebGLenum buffer, + WebGLint drawbuffer, + WebGLfloat depth, + WebGLint stencil) { /* TODO(yorkie): implement */ } - void TrContextWebGL::glClearColor(WebGLfloat red, WebGLfloat green, WebGLfloat blue, WebGLfloat alpha) + void TrContextWebGL::glClearColor(WebGLfloat red, + WebGLfloat green, + WebGLfloat blue, + WebGLfloat alpha) { - /* TODO(yorkie): implement */ + clear_color_[0] = red; + clear_color_[1] = green; + clear_color_[2] = blue; + clear_color_[3] = alpha; } void TrContextWebGL::glClearDepthf(WebGLfloat depth) { - /* TODO(yorkie): implement */ + clear_depth_ = depth; } void TrContextWebGL::glClearStencil(WebGLint s) { - /* TODO(yorkie): implement */ + clear_stencil_ = s; } void TrContextWebGL::glFinish() diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index f88cfb7d9..c60134208 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -14,10 +14,10 @@ namespace renderer TrContextWebGL(Ref content_renderer); ~TrContextWebGL(); - class ObjectTarget + class ObjectTargetBase { public: - ObjectTarget(WebGLenum target) + ObjectTargetBase(WebGLenum target) : target_(target) { } @@ -27,14 +27,14 @@ namespace renderer return target_; } - inline bool operator==(const ObjectTarget &rhs) const + inline bool operator==(const ObjectTargetBase &rhs) const { return target_ == rhs.target_; } struct HashKey { - size_t operator()(const ObjectTarget &t) const noexcept + size_t operator()(const ObjectTargetBase &t) const noexcept { return std::hash{}(t.value()); } @@ -44,7 +44,7 @@ namespace renderer WebGLenum target_; }; - class TextureTarget : public ObjectTarget + class TextureTarget final : public ObjectTargetBase { public: enum @@ -55,7 +55,7 @@ namespace renderer }; TextureTarget(WebGLenum target) - : ObjectTarget(target) + : ObjectTargetBase(target) { assert(target_ == k2D || target_ == k3D || @@ -63,7 +63,7 @@ namespace renderer } }; - class BufferTarget : public ObjectTarget + class BufferTarget final : public ObjectTargetBase { public: enum @@ -73,14 +73,14 @@ namespace renderer }; BufferTarget(WebGLenum target) - : ObjectTarget(target) + : ObjectTargetBase(target) { assert(target_ == kArrayBuffer || target_ == kElementArrayBuffer); } }; - class FramebufferTarget : public ObjectTarget + class FramebufferTarget final : public ObjectTargetBase { public: enum @@ -91,7 +91,7 @@ namespace renderer }; FramebufferTarget(WebGLenum target) - : ObjectTarget(target) + : ObjectTargetBase(target) { assert(target_ == kFramebuffer || target_ == kReadFramebuffer || @@ -99,7 +99,7 @@ namespace renderer } }; - class RenderbufferTarget : public ObjectTarget + class RenderbufferTarget final : public ObjectTargetBase { public: enum @@ -108,7 +108,7 @@ namespace renderer }; RenderbufferTarget(WebGLenum target) - : ObjectTarget(target) + : ObjectTargetBase(target) { assert(target_ == kRenderbuffer); } @@ -601,6 +601,10 @@ namespace renderer Capabilities caps_; WebGLenum active_texture_; + WebGLfloat clear_color_[4]; + WebGLfloat clear_depth_; + WebGLint clear_stencil_; + WebGLfloat blend_color_[4]; WebGLenum blend_equation_rgb_; WebGLenum blend_equation_alpha_; From cca7498676345284cf62a44468fa01a3ba130598 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Thu, 27 Nov 2025 01:52:50 +0800 Subject: [PATCH 30/37] fix --- src/client/script_bindings/webgl/active_info.cpp | 2 +- src/client/script_bindings/webgl/active_info.hpp | 2 +- src/client/script_bindings/webgl/framebuffer.cpp | 2 +- src/client/script_bindings/webgl/framebuffer.hpp | 2 +- src/client/script_bindings/webgl/object.cpp | 2 +- src/client/script_bindings/webgl/object.hpp | 2 +- src/client/script_bindings/webgl/program.cpp | 2 +- src/client/script_bindings/webgl/program.hpp | 2 +- src/client/script_bindings/webgl/renderbuffer.cpp | 2 +- src/client/script_bindings/webgl/renderbuffer.hpp | 2 +- src/client/script_bindings/webgl/texture.cpp | 2 +- src/client/script_bindings/webgl/texture.hpp | 2 +- src/client/script_bindings/webgl/uniform_location.cpp | 2 +- src/client/script_bindings/webgl/uniform_location.hpp | 2 +- src/client/script_bindings/webgl/vertex_array.cpp | 2 +- src/client/script_bindings/webgl/vertex_array.hpp | 2 +- src/renderer/content_renderer.hpp | 4 ++-- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/client/script_bindings/webgl/active_info.cpp b/src/client/script_bindings/webgl/active_info.cpp index c0f9d3e81..803ffe763 100644 --- a/src/client/script_bindings/webgl/active_info.cpp +++ b/src/client/script_bindings/webgl/active_info.cpp @@ -60,5 +60,5 @@ namespace endor } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/active_info.hpp b/src/client/script_bindings/webgl/active_info.hpp index b125c893c..c2d6c9080 100644 --- a/src/client/script_bindings/webgl/active_info.hpp +++ b/src/client/script_bindings/webgl/active_info.hpp @@ -38,5 +38,5 @@ namespace endor }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/client/script_bindings/webgl/framebuffer.cpp b/src/client/script_bindings/webgl/framebuffer.cpp index dbe790869..d38e0687c 100644 --- a/src/client/script_bindings/webgl/framebuffer.cpp +++ b/src/client/script_bindings/webgl/framebuffer.cpp @@ -31,5 +31,5 @@ namespace endor { } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/client/script_bindings/webgl/framebuffer.hpp b/src/client/script_bindings/webgl/framebuffer.hpp index c54189e65..fd3ab4ec2 100644 --- a/src/client/script_bindings/webgl/framebuffer.hpp +++ b/src/client/script_bindings/webgl/framebuffer.hpp @@ -37,5 +37,5 @@ namespace endor }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/object.cpp b/src/client/script_bindings/webgl/object.cpp index b03f846b5..78779213d 100644 --- a/src/client/script_bindings/webgl/object.cpp +++ b/src/client/script_bindings/webgl/object.cpp @@ -28,5 +28,5 @@ namespace endor // WebGLObject is a base class, typically not instantiated directly } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/object.hpp b/src/client/script_bindings/webgl/object.hpp index cd48b93ae..f69bb78c8 100644 --- a/src/client/script_bindings/webgl/object.hpp +++ b/src/client/script_bindings/webgl/object.hpp @@ -45,5 +45,5 @@ namespace endor }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/client/script_bindings/webgl/program.cpp b/src/client/script_bindings/webgl/program.cpp index e4a68a6f8..8c21d7e26 100644 --- a/src/client/script_bindings/webgl/program.cpp +++ b/src/client/script_bindings/webgl/program.cpp @@ -20,5 +20,5 @@ namespace endor } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/client/script_bindings/webgl/program.hpp b/src/client/script_bindings/webgl/program.hpp index ede29c134..0971e7271 100644 --- a/src/client/script_bindings/webgl/program.hpp +++ b/src/client/script_bindings/webgl/program.hpp @@ -32,5 +32,5 @@ namespace endor WebGLProgram(v8::Isolate *isolate, const v8::FunctionCallbackInfo &args); }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/renderbuffer.cpp b/src/client/script_bindings/webgl/renderbuffer.cpp index 7f512b63d..d858602e8 100644 --- a/src/client/script_bindings/webgl/renderbuffer.cpp +++ b/src/client/script_bindings/webgl/renderbuffer.cpp @@ -19,5 +19,5 @@ namespace endor // WebGLRenderbuffer objects are created by WebGL context, not by user code } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/renderbuffer.hpp b/src/client/script_bindings/webgl/renderbuffer.hpp index a9651c800..581ff1b2e 100644 --- a/src/client/script_bindings/webgl/renderbuffer.hpp +++ b/src/client/script_bindings/webgl/renderbuffer.hpp @@ -33,5 +33,5 @@ namespace endor }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/client/script_bindings/webgl/texture.cpp b/src/client/script_bindings/webgl/texture.cpp index 3b51f5dfa..3d034839c 100644 --- a/src/client/script_bindings/webgl/texture.cpp +++ b/src/client/script_bindings/webgl/texture.cpp @@ -27,5 +27,5 @@ namespace endor { } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/texture.hpp b/src/client/script_bindings/webgl/texture.hpp index b40acad08..9272d305c 100644 --- a/src/client/script_bindings/webgl/texture.hpp +++ b/src/client/script_bindings/webgl/texture.hpp @@ -45,5 +45,5 @@ namespace endor }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/client/script_bindings/webgl/uniform_location.cpp b/src/client/script_bindings/webgl/uniform_location.cpp index 597a73e97..ce71bd5d6 100644 --- a/src/client/script_bindings/webgl/uniform_location.cpp +++ b/src/client/script_bindings/webgl/uniform_location.cpp @@ -47,5 +47,5 @@ namespace endor } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/uniform_location.hpp b/src/client/script_bindings/webgl/uniform_location.hpp index a5e7de1f2..a1f98b66d 100644 --- a/src/client/script_bindings/webgl/uniform_location.hpp +++ b/src/client/script_bindings/webgl/uniform_location.hpp @@ -44,5 +44,5 @@ namespace endor }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/client/script_bindings/webgl/vertex_array.cpp b/src/client/script_bindings/webgl/vertex_array.cpp index 3e6ed5f0a..48e8e644b 100644 --- a/src/client/script_bindings/webgl/vertex_array.cpp +++ b/src/client/script_bindings/webgl/vertex_array.cpp @@ -20,5 +20,5 @@ namespace endor { } } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor diff --git a/src/client/script_bindings/webgl/vertex_array.hpp b/src/client/script_bindings/webgl/vertex_array.hpp index 7ba162aa3..a4a03cc1d 100644 --- a/src/client/script_bindings/webgl/vertex_array.hpp +++ b/src/client/script_bindings/webgl/vertex_array.hpp @@ -33,5 +33,5 @@ namespace endor }; } // namespace webgl - } // namespace script_bindings + } // namespace script_bindings } // namespace endor \ No newline at end of file diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index 39d65ab63..e27546101 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -69,8 +69,8 @@ namespace renderer * @return The created content renderer. */ static inline Ref Make(Ref content, - uint8_t contextId, - TrConstellation *constellation) + uint8_t contextId, + TrConstellation *constellation) { assert(content != nullptr); assert(contextId >= commandbuffers::MinimumContextId); From 89f96f70d851bb4dfb2abcccdaa9075b3f0d1b97 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Thu, 27 Nov 2025 02:10:07 +0800 Subject: [PATCH 31/37] fix --- src/renderer/render_resource.cpp | 16 +++++++++++++++- src/renderer/render_resource.hpp | 8 +++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/renderer/render_resource.cpp b/src/renderer/render_resource.cpp index b17f65428..1a09e0778 100644 --- a/src/renderer/render_resource.cpp +++ b/src/renderer/render_resource.cpp @@ -13,6 +13,14 @@ namespace renderer { } + Ref TrRenderResource::createShaderModule( + const GPUShaderModuleDescriptor *descriptor) + { + auto shader_module = device_->createShaderModule(descriptor); + shader_modules_.emplace(shader_module->id, shader_module); + return shader_module; + } + Ref TrRenderResource::createPipeline() { return nullptr; @@ -26,11 +34,17 @@ namespace renderer return buffer; } - Ref TrRenderResource::createTexture() + Ref TrRenderResource::createTexture( + const GPUTextureDescriptor *descriptor) { return nullptr; } + Ref TrRenderResource::getShaderModule(int id) + { + return shader_modules_.at(id); + } + Ref TrRenderResource::getPipeline(int id) { return pipelines_.at(id); diff --git a/src/renderer/render_resource.hpp b/src/renderer/render_resource.hpp index d7415e9b5..f41f8809d 100644 --- a/src/renderer/render_resource.hpp +++ b/src/renderer/render_resource.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -15,17 +16,22 @@ namespace renderer public: TrRenderResource(Ref device); + Ref createShaderModule( + const commandbuffers::GPUShaderModuleDescriptor *descriptor); Ref createPipeline(); Ref createBuffer( const commandbuffers::GPUBufferDescriptor *descriptor); - Ref createTexture(); + Ref createTexture( + const commandbuffers::GPUTextureDescriptor *descriptor); + Ref getShaderModule(int id); Ref getPipeline(int id); Ref getBuffer(int id); Ref getTexture(int id); private: Ref device_; + std::unordered_map> shader_modules_; std::unordered_map> pipelines_; std::unordered_map> buffers_; std::unordered_map> textures_; From 967f312a59ad0af2d77d4ae70d24e6c805f24fdb Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 27 Nov 2025 18:18:50 +0800 Subject: [PATCH 32/37] fixup --- .../gpu/compilation_messages.hpp | 23 + src/common/command_buffers/gpu/gpu_base.hpp | 7 + src/common/command_buffers/gpu/gpu_device.cpp | 12 +- src/common/command_buffers/gpu/gpu_device.hpp | 20 +- .../command_buffers/gpu/gpu_shader_module.cpp | 42 +- .../command_buffers/gpu/gpu_shader_module.hpp | 35 +- src/renderer/content_renderer.cpp | 16 + src/renderer/content_renderer.hpp | 12 +- src/renderer/context_webgl.cpp | 1111 ++++++++++++++++- src/renderer/context_webgl.hpp | 97 +- 10 files changed, 1305 insertions(+), 70 deletions(-) create mode 100644 src/common/command_buffers/gpu/compilation_messages.hpp diff --git a/src/common/command_buffers/gpu/compilation_messages.hpp b/src/common/command_buffers/gpu/compilation_messages.hpp new file mode 100644 index 000000000..c1029cb25 --- /dev/null +++ b/src/common/command_buffers/gpu/compilation_messages.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include +#include + +namespace commandbuffers::gpu +{ + struct CompilationMessageContent + { + std::string message; + GPUCompilationMessageType type; + uint64_t line; + uint64_t column; + }; + + struct ParsedCompilationMessages + { + std::vector messages; + std::vector formattedTintMessages; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 9f8351fc0..1ee91e666 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -343,6 +343,13 @@ namespace commandbuffers #undef XX } + enum class GPUCompilationMessageType : uint32_t + { + kError = 1, + kWarning = 2, + kInfo = 3, + }; + enum class GPUShaderStage : uint64_t { kNone = 0x0000000000000000, diff --git a/src/common/command_buffers/gpu/gpu_device.cpp b/src/common/command_buffers/gpu/gpu_device.cpp index af0f99475..6682e32b9 100644 --- a/src/common/command_buffers/gpu/gpu_device.cpp +++ b/src/common/command_buffers/gpu/gpu_device.cpp @@ -74,7 +74,7 @@ namespace commandbuffers return nullptr; } - Ref GPUDeviceBase::createBuffer(const GPUBufferDescriptor *rawDescriptor) + Ref GPUDeviceBase::createBuffer(const GPUBufferDescriptor *descriptor) { return nullptr; } @@ -95,6 +95,16 @@ namespace commandbuffers return nullptr; } + Ref GPUDeviceBase::createTexture(const GPUTextureDescriptor *descriptor) + { + return nullptr; + } + + Ref GPUDeviceBase::createTextureView(const GPUTextureViewDescriptor *descriptor) + { + return nullptr; + } + GPUDeviceBase::State GPUDeviceBase::getState() const { return state_; diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index f1ea70504..b9ba98918 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -64,15 +66,17 @@ namespace commandbuffers GPUPipelineLayoutBase *getEmptyPipelineLayout(); // Object creation methods that be used in a reentrant manner. - Ref createBindGroup(const GPUBindGroupDescriptor *descriptor, + Ref createBindGroup(const GPUBindGroupDescriptor *, GPUUsageValidationMode mode = GPUUsageValidationMode::kDefault); - Ref createBindGroupLayout(const GPUBindGroupLayoutDescriptor *descriptor, - bool allowInternalBinding = false); - Ref createBuffer(const GPUBufferDescriptor *rawDescriptor); - Ref createCommandEncoder(const GPUCommandEncoderDescriptor *descriptor = nullptr); - Ref createComputePipeline(const GPUComputePipelineDescriptor *descriptor); - Ref createShaderModule(const GPUShaderModuleDescriptor *descriptor = nullptr, - const std::vector &internalExtensions = {}); + Ref createBindGroupLayout(const GPUBindGroupLayoutDescriptor *, + bool allow_internal_binding = false); + Ref createBuffer(const GPUBufferDescriptor *); + Ref createCommandEncoder(const GPUCommandEncoderDescriptor *); + Ref createComputePipeline(const GPUComputePipelineDescriptor *); + Ref createShaderModule(const GPUShaderModuleDescriptor *, + const std::vector &internal_extensions = {}); + Ref createTexture(const GPUTextureDescriptor *); + Ref createTextureView(const GPUTextureViewDescriptor *); // The device state which is a combination of creation state and loss state. // diff --git a/src/common/command_buffers/gpu/gpu_shader_module.cpp b/src/common/command_buffers/gpu/gpu_shader_module.cpp index 037167e9d..cbc719af3 100644 --- a/src/common/command_buffers/gpu/gpu_shader_module.cpp +++ b/src/common/command_buffers/gpu/gpu_shader_module.cpp @@ -1,4 +1,5 @@ #include +#include "utility.hpp" using namespace std; @@ -6,8 +7,47 @@ namespace commandbuffers { GPUShaderModuleBase::GPUShaderModuleBase(Ref device, const GPUShaderModuleDescriptor &descriptor, - vector internalExtensions) + vector internal_extensions) : GPUHandle(device, descriptor.label) + , type_(Type::kGLSL) + , original_spirv_() + , wgsl_code_(descriptor.code) + , internal_extensions_(move(internal_extensions)) { } + + GPUShaderModuleBase::GPUShaderModuleBase(Ref device, + GPUHandle::ErrorTag tag, + string_view label, + gpu::ParsedCompilationMessages &&compilation_messages) + : GPUHandle(device, tag, label) + , type_(Type::kUndefined) + { + } + + // static + Ref GPUShaderModuleBase::MakeError(Ref device, + string_view label, + gpu::ParsedCompilationMessages &&compilation_messages) + { + return AcquireRef(new GPUShaderModuleBase( + device, + GPUHandle::kError, + label, + move(compilation_messages))); + } + + void GPUShaderModuleBase::initialize() + { + } + + std::unique_ptr GPUShaderModuleBase::getInitializationError() + { + return nullptr; + } + + bool GPUShaderModuleBase::hasEntryPoint(std::string_view entry_point) const + { + return false; + } } diff --git a/src/common/command_buffers/gpu/gpu_shader_module.hpp b/src/common/command_buffers/gpu/gpu_shader_module.hpp index 6762438c5..2210f44b2 100644 --- a/src/common/command_buffers/gpu/gpu_shader_module.hpp +++ b/src/common/command_buffers/gpu/gpu_shader_module.hpp @@ -1,8 +1,13 @@ #pragma once #include +#include +#include + #include +#include #include +#include #include namespace commandbuffers @@ -19,13 +24,41 @@ namespace commandbuffers class GPUShaderModuleBase : public GPUHandle { public: + static Ref MakeError(Ref device, + std::string_view label, + gpu::ParsedCompilationMessages &&compilation_messages); + GPUShaderModuleBase(Ref device, const GPUShaderModuleDescriptor &descriptor, - std::vector internalExtensions); + std::vector internal_extensions); GPUHandleType type() const override { return GPUHandleType::kShaderModule; } + + void initialize(); + std::unique_ptr getInitializationError(); + + bool hasEntryPoint(std::string_view entry_point) const; + + private: + GPUShaderModuleBase(Ref device, + GPUHandle::ErrorTag tag, + std::string_view label, + gpu::ParsedCompilationMessages &&compilation_messages); + + enum class Type : uint8_t + { + kUndefined, + kGLSL, + kSpirv, + kWGSL, + }; + Type type_; + std::vector original_spirv_; + std::string wgsl_code_; + + const std::vector internal_extensions_; }; } diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index bade263c3..991fcc2b0 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -6,6 +6,9 @@ #include "./content_renderer.hpp" #include "./render_api.hpp" +#include "command_buffers/base.hpp" +#include "renderer/gles/context_app.hpp" +#include "utility.hpp" namespace renderer { @@ -47,6 +50,7 @@ namespace renderer , targetFrameRate(constellation->renderer->clientDefaultFrameRate) , glContext(nullptr) , glContextForBackup(nullptr) + , context_webgl_(nullptr) { assert(xrDevice != nullptr); stereoFrameForBackup = make_unique(true, 0xf); @@ -78,6 +82,12 @@ namespace renderer } } + void TrContentRenderer::initialize() + { + Ref self = shared_from_this(); + context_webgl_ = AcquireRef(new TrContextWebGL(self)); + } + void TrContentRenderer::onCommandBuffersExecuting() { lastFrameHasOutOfMemoryError = false; @@ -166,6 +176,12 @@ namespace renderer // such as `defaultCommandBufferRequests` or `stereoFramesList`, otherwise it will be deleted in this function. void TrContentRenderer::onCommandBufferRequestReceived(TrCommandBufferBase *req) { + // Send the command buffer to ContextWebGL if it is the WebGL-specific command buffer. + if (!commandbuffers::CommandTypes::IsXRFrameControl(req->type)) + { + context_webgl_->receiveIncomingCall(dynamic_cast(*req)); + } + if (!req->renderingInfo.isValid() && !commandbuffers::CommandTypes::IsXRFrameControl(req->type)) { unique_lock lock(commandBufferRequestsMutex); diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index e27546101..b6460308e 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -74,13 +74,21 @@ namespace renderer { assert(content != nullptr); assert(contextId >= commandbuffers::MinimumContextId); - return std::make_shared(content, contextId, constellation); + + auto renderer = std::make_shared(content, contextId, constellation); + renderer->initialize(); + return renderer; } public: TrContentRenderer(Ref content, uint8_t contextId, TrConstellation *constellation); ~TrContentRenderer(); + /** + * Initialize the content renderer, create the ContextWebGL, and initialize the render passes. + */ + void initialize(); + public: // public lifecycle void onCommandBuffersExecuting(); void onCommandBuffersExecuted(); @@ -224,7 +232,7 @@ namespace renderer std::chrono::milliseconds maxFrameDuration = std::chrono::milliseconds(0); private: - Ref context_; + Ref context_webgl_; Ref render_resource_; Ref opaque_renderpass_; Ref transparent_renderpass_; diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index bf3275255..dcaa10d55 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -1,3 +1,6 @@ +#include +#include + #include #include #include @@ -9,6 +12,16 @@ namespace renderer using namespace std; using namespace commandbuffers; + string TrContextWebGL::ShaderModule::toString() const + { + string type_str = "Unknown"; + if (type == WEBGL_VERTEX_SHADER) + type_str = "Vertex"; + else if (type == WEBGL_FRAGMENT_SHADER) + type_str = "Fragment"; + return "ShaderModule(" + type_str + " id=" + to_string(id) + ")"; + } + TrContextWebGL::TrContextWebGL(Ref content_renderer) : content_renderer_(content_renderer) { @@ -22,6 +35,7 @@ namespace renderer { switch (req.type) { + // Textures case COMMAND_BUFFER_ACTIVE_TEXTURE_REQ: { const auto &typed_req = To(req); @@ -70,11 +84,879 @@ namespace renderer } case COMMAND_BUFFER_CREATE_TEXTURE_REQ: { - const auto &typed_req = To(req); - WebGLint texture; - glGenTextures(1, (WebGLuint *)&texture); + glCreateTypedObject(textures_, req); + break; + } + case COMMAND_BUFFER_TEXTURE_IMAGE_2D_REQ: + { + const auto &typed_req = To(req); + glTexImage2D( + typed_req.target, + typed_req.level, + typed_req.internalformat, + typed_req.width, + typed_req.height, + typed_req.border, + typed_req.format, + typed_req.type, + typed_req.pixels); + break; + } + case COMMAND_BUFFER_TEXTURE_IMAGE_3D_REQ: + { + const auto &typed_req = To(req); + glTexImage3D( + typed_req.target, + typed_req.level, + typed_req.internalformat, + typed_req.width, + typed_req.height, + typed_req.depth, + typed_req.border, + typed_req.format, + typed_req.type, + typed_req.pixels); + break; + } + case COMMAND_BUFFER_TEXTURE_PARAMETERI_REQ: + { + const auto &typed_req = To(req); + glTexParameteri(typed_req.target, typed_req.pname, typed_req.param); + break; + } + case COMMAND_BUFFER_TEXTURE_PARAMETERF_REQ: + { + const auto &typed_req = To(req); + glTexParameterf(typed_req.target, typed_req.pname, typed_req.param); + break; + } + case COMMAND_BUFFER_TEXTURE_STORAGE_2D_REQ: + { + const auto &typed_req = To(req); + glTexStorage2D( + typed_req.target, + typed_req.levels, + typed_req.internalformat, + typed_req.width, + typed_req.height); + break; + } + case COMMAND_BUFFER_TEXTURE_STORAGE_3D_REQ: + { + const auto &typed_req = To(req); + glTexStorage3D( + typed_req.target, + typed_req.levels, + typed_req.internalformat, + typed_req.width, + typed_req.height, + typed_req.depth); + break; + } + case COMMAND_BUFFER_TEXTURE_SUB_IMAGE_2D_REQ: + { + const auto &typed_req = To(req); + glTexSubImage2D( + typed_req.target, + typed_req.level, + typed_req.xoffset, + typed_req.yoffset, + typed_req.width, + typed_req.height, + typed_req.format, + typed_req.type, + typed_req.pixels); + break; + } + case COMMAND_BUFFER_TEXTURE_SUB_IMAGE_3D_REQ: + { + const auto &typed_req = To(req); + glTexSubImage3D( + typed_req.target, + typed_req.level, + typed_req.xoffset, + typed_req.yoffset, + typed_req.zoffset, + typed_req.width, + typed_req.height, + typed_req.depth, + typed_req.format, + typed_req.type, + typed_req.pixels); + break; + } + + // Rendering + case COMMAND_BUFFER_CLEAR_REQ: + { + const auto &typed_req = To(req); + glClear(typed_req.mask); + break; + } + case COMMAND_BUFFER_CLEAR_BUFFERIV_REQ: + { + const auto &typed_req = To(req); + glClearBufferiv(typed_req.buffer, + typed_req.drawbuffer, + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_CLEAR_BUFFERUIV_REQ: + { + const auto &typed_req = To(req); + glClearBufferuiv(typed_req.buffer, + typed_req.drawbuffer, + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_CLEAR_BUFFERFI_REQ: + { + const auto &typed_req = To(req); + glClearBufferfi(typed_req.buffer, + typed_req.drawbuffer, + typed_req.depth, + typed_req.stencil); + break; + } + case COMMAND_BUFFER_CLEAR_BUFFERFV_REQ: + { + const auto &typed_req = To(req); + glClearBufferfv(typed_req.buffer, + typed_req.drawbuffer, + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_CLEAR_COLOR_REQ: + { + const auto &typed_req = To(req); + glClearColor(typed_req.r, typed_req.g, typed_req.b, typed_req.a); + break; + } + case COMMAND_BUFFER_CLEAR_DEPTH_REQ: + { + const auto &typed_req = To(req); + glClearDepth(typed_req.depth); + break; + } + case COMMAND_BUFFER_CLEAR_STENCIL_REQ: + { + const auto &typed_req = To(req); + glClearStencil(typed_req.stencil); + break; + } + + // Frame Buffers + case COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ: + { + const auto &typed_req = To(req); + glBindFramebuffer(typed_req.target, typed_req.framebuffer); + break; + } + case COMMAND_BUFFER_BIND_RENDERBUFFER_REQ: + { + const auto &typed_req = To(req); + glBindRenderbuffer(typed_req.target, typed_req.renderbuffer); + break; + } + case COMMAND_BUFFER_BLIT_FRAMEBUFFER_REQ: + { + const auto &typed_req = To(req); + glBlitFramebuffer( + typed_req.srcX0, + typed_req.srcY0, + typed_req.srcX1, + typed_req.srcY1, + typed_req.dstX0, + typed_req.dstY0, + typed_req.dstX1, + typed_req.dstY1, + typed_req.mask, + typed_req.filter); + break; + } + case COMMAND_BUFFER_CHECK_FRAMEBUFFER_STATUS_REQ: + { + const auto &typed_req = To(req); + glCheckFramebufferStatus(typed_req.target); + break; + } + case COMMAND_BUFFER_DELETE_FRAMEBUFFER_REQ: + { + const auto &typed_req = To(req); + glDeleteFramebuffers(1, &typed_req.framebuffer); + break; + } + case COMMAND_BUFFER_DELETE_RENDERBUFFER_REQ: + { + const auto &typed_req = To(req); + glDeleteRenderbuffers(1, &typed_req.renderbuffer); + break; + } + case COMMAND_BUFFER_DRAW_BUFFERS_REQ: + { + const auto &typed_req = To(req); + glDrawBuffers(typed_req.n, typed_req.bufs); + break; + } + case COMMAND_BUFFER_FRAMEBUFFER_RENDERBUFFER_REQ: + { + const auto &typed_req = To(req); + glFramebufferRenderbuffer(typed_req.target, + typed_req.attachment, + typed_req.renderbufferTarget, + typed_req.renderbuffer); + break; + } + case COMMAND_BUFFER_FRAMEBUFFER_TEXTURE2D_REQ: + { + const auto &typed_req = To(req); + glFramebufferTexture2D(typed_req.target, + typed_req.attachment, + typed_req.textarget, + typed_req.texture, + typed_req.level); + break; + } + case COMMAND_BUFFER_FRAMEBUFFER_TEXTURE_LAYER_REQ: + { + const auto &typed_req = To(req); + glFramebufferTextureLayer(typed_req.target, + typed_req.attachment, + typed_req.texture, + typed_req.level, + typed_req.layer); + break; + } + case COMMAND_BUFFER_CREATE_FRAMEBUFFER_REQ: + { + glCreateTypedObject(framebuffers_, req); + break; + } + case COMMAND_BUFFER_CREATE_RENDERBUFFER_REQ: + { + glCreateTypedObject(renderbuffers_, req); + break; + } + case COMMAND_BUFFER_GENERATE_MIPMAP_REQ: + { + const auto &typed_req = To(req); + glGenerateMipmap(typed_req.target); + break; + } + case COMMAND_BUFFER_RENDERBUFFER_STORAGE_REQ: + { + const auto &typed_req = To(req); + glRenderbufferStorage(typed_req.target, + typed_req.internalformat, + typed_req.width, + typed_req.height); + break; + } + case COMMAND_BUFFER_RENDERBUFFER_STORAGE_MULTISAMPLE_REQ: + { + const auto &typed_req = To(req); + glRenderbufferStorageMultisample(typed_req.target, + typed_req.samples, + typed_req.internalformat, + typed_req.width, + typed_req.height); + break; + } + + // Shaders + case COMMAND_BUFFER_BIND_ATTRIB_LOCATION_REQ: + { + const auto &typed_req = To(req); + glBindAttribLocation(typed_req.program, + typed_req.attribIndex, + typed_req.attribName.c_str()); + break; + } + case COMMAND_BUFFER_COMPILE_SHADER_REQ: + { + const auto &typed_req = To(req); + glCompileShader(typed_req.shader); + break; + } + case COMMAND_BUFFER_CREATE_PROGRAM_REQ: + { + const auto &typed_req = To(req); + auto index = glCreateProgram(); + programs_[index].id = req.id; // Modify the id to the request id. + break; + } + case COMMAND_BUFFER_CREATE_SHADER_REQ: + { + const auto &typed_req = To(req); + auto index = glCreateShader(typed_req.shaderType); + shader_modules_[index].id = req.id; // Modify the id to the request id. + break; + } + case COMMAND_BUFFER_DELETE_PROGRAM_REQ: + { + const auto &typed_req = To(req); + glDeleteProgram(typed_req.clientId); + break; + } + case COMMAND_BUFFER_DELETE_SHADER_REQ: + { + const auto &typed_req = To(req); + glDeleteShader(typed_req.shader); + break; + } + case COMMAND_BUFFER_ATTACH_SHADER_REQ: + { + const auto &typed_req = To(req); + glAttachShader(typed_req.program, typed_req.shader); + break; + } + case COMMAND_BUFFER_DETACH_SHADER_REQ: + { + const auto &typed_req = To(req); + glDetachShader(typed_req.program, typed_req.shader); + break; + } + case COMMAND_BUFFER_LINK_PROGRAM_REQ: + { + const auto &typed_req = To(req); + glLinkProgram(typed_req.clientId); + break; + } + case COMMAND_BUFFER_SHADER_SOURCE_REQ: + { + const auto &typed_req = To(req); + glShaderSource(typed_req.shader, + 1, + (const WebGLchar **)&typed_req.sourceStr, + reinterpret_cast(&typed_req.sourceSize)); + break; + } + case COMMAND_BUFFER_UNIFORM1F_REQ: + { + const auto &typed_req = To(req); + glUniform1f(typed_req.location, typed_req.v0); + break; + } + case COMMAND_BUFFER_UNIFORM2F_REQ: + { + const auto &typed_req = To(req); + glUniform2f(typed_req.location, typed_req.v0, typed_req.v1); + break; + } + case COMMAND_BUFFER_UNIFORM3F_REQ: + { + const auto &typed_req = To(req); + glUniform3f(typed_req.location, typed_req.v0, typed_req.v1, typed_req.v2); + break; + } + case COMMAND_BUFFER_UNIFORM4F_REQ: + { + const auto &typed_req = To(req); + glUniform4f(typed_req.location, typed_req.v0, typed_req.v1, typed_req.v2, typed_req.v3); + break; + } + case COMMAND_BUFFER_UNIFORM1I_REQ: + { + const auto &typed_req = To(req); + glUniform1i(typed_req.location, typed_req.v0); + break; + } + case COMMAND_BUFFER_UNIFORM2I_REQ: + { + const auto &typed_req = To(req); + glUniform2i(typed_req.location, typed_req.v0, typed_req.v1); + break; + } + case COMMAND_BUFFER_UNIFORM3I_REQ: + { + const auto &typed_req = To(req); + glUniform3i(typed_req.location, typed_req.v0, typed_req.v1, typed_req.v2); + break; + } + case COMMAND_BUFFER_UNIFORM4I_REQ: + { + const auto &typed_req = To(req); + glUniform4i(typed_req.location, typed_req.v0, typed_req.v1, typed_req.v2, typed_req.v3); + break; + } + case COMMAND_BUFFER_UNIFORM1FV_REQ: + { + const auto &typed_req = To(req); + glUniform1fv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM2FV_REQ: + { + const auto &typed_req = To(req); + glUniform2fv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM3FV_REQ: + { + const auto &typed_req = To(req); + glUniform3fv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM4FV_REQ: + { + const auto &typed_req = To(req); + glUniform4fv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM1IV_REQ: + { + const auto &typed_req = To(req); + glUniform1iv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM2IV_REQ: + { + const auto &typed_req = To(req); + glUniform2iv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM3IV_REQ: + { + const auto &typed_req = To(req); + glUniform3iv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM4IV_REQ: + { + const auto &typed_req = To(req); + glUniform4iv(typed_req.location, + typed_req.values.size(), + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM_MATRIX2FV_REQ: + { + const auto &typed_req = To(req); + glUniformMatrix2fv(typed_req.location, + typed_req.values.size(), + typed_req.transpose, + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM_MATRIX3FV_REQ: + { + const auto &typed_req = To(req); + glUniformMatrix3fv(typed_req.location, + typed_req.values.size(), + typed_req.transpose, + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM_MATRIX4FV_REQ: + { + const auto &typed_req = To(req); + glUniformMatrix4fv(typed_req.location, + typed_req.values.size(), + typed_req.transpose, + typed_req.values.data()); + break; + } + case COMMAND_BUFFER_UNIFORM_BLOCK_BINDING_REQ: + { + const auto &typed_req = To(req); + glUniformBlockBinding(typed_req.program, + typed_req.uniformBlockIndex, + typed_req.uniformBlockBinding); + break; + } + case COMMAND_BUFFER_USE_PROGRAM_REQ: + { + const auto &typed_req = To(req); + glUseProgram(typed_req.clientId); + break; + } + case COMMAND_BUFFER_VALIDATE_PROGRAM_REQ: + { + const auto &typed_req = To(req); + glValidateProgram(typed_req.clientId); + break; + } + + // Buffer Objects + case COMMAND_BUFFER_BIND_BUFFER_REQ: + { + const auto &typed_req = To(req); + glBindBuffer(typed_req.target, typed_req.buffer); + break; + } + case COMMAND_BUFFER_BIND_BUFFER_BASE_REQ: + { + const auto &typed_req = To(req); + glBindBufferBase(typed_req.target, + typed_req.index, + typed_req.buffer); + break; + } + case COMMAND_BUFFER_BIND_BUFFER_RANGE_REQ: + { + const auto &typed_req = To(req); + glBindBufferRange(typed_req.target, + typed_req.index, + typed_req.buffer, + typed_req.offset, + typed_req.size); + break; + } + case COMMAND_BUFFER_BUFFER_DATA_REQ: + { + const auto &typed_req = To(req); + glBufferData(typed_req.target, + typed_req.size, + typed_req.data, + typed_req.usage); break; } + case COMMAND_BUFFER_BUFFER_SUB_DATA_REQ: + { + const auto &typed_req = To(req); + glBufferSubData(typed_req.target, + typed_req.offset, + typed_req.size, + typed_req.data); + break; + } + case COMMAND_BUFFER_DELETE_BUFFER_REQ: + { + const auto &typed_req = To(req); + glDeleteBuffers(1, &typed_req.buffer); + break; + } + case COMMAND_BUFFER_DISABLE_VERTEX_ATTRIB_ARRAY_REQ: + { + const auto &typed_req = To(req); + glDisableVertexAttribArray(typed_req.location); + break; + } + case COMMAND_BUFFER_DRAW_ARRAYS_REQ: + { + const auto &typed_req = To(req); + glDrawArrays(typed_req.mode, + typed_req.first, + typed_req.count); + break; + } + case COMMAND_BUFFER_DRAW_ARRAYS_INSTANCED_REQ: + { + const auto &typed_req = To(req); + glDrawArraysInstanced(typed_req.mode, + typed_req.first, + typed_req.count, + typed_req.instanceCount); + break; + } + case COMMAND_BUFFER_DRAW_ELEMENTS_REQ: + { + const auto &typed_req = To(req); + glDrawElements(typed_req.mode, + typed_req.count, + typed_req.indicesType, + nullptr); + break; + } + case COMMAND_BUFFER_DRAW_ELEMENTS_INSTANCED_REQ: + { + const auto &typed_req = To(req); + glDrawElementsInstanced(typed_req.mode, + typed_req.count, + typed_req.indicesType, + nullptr, + typed_req.instanceCount); + break; + } + case COMMAND_BUFFER_DRAW_RANGE_ELEMENTS_REQ: + { + const auto &typed_req = To(req); + glDrawRangeElements(typed_req.mode, + typed_req.start, + typed_req.end, + typed_req.count, + typed_req.indicesType, + nullptr); + break; + } + case COMMAND_BUFFER_ENABLE_VERTEX_ATTRIB_ARRAY_REQ: + { + const auto &typed_req = To(req); + glEnableVertexAttribArray(typed_req.location); + break; + } + case COMMAND_BUFFER_CREATE_BUFFER_REQ: + { + glCreateTypedObject(buffers_, req); + break; + } + case COMMAND_BUFFER_VERTEX_ATTRIB_1F_REQ: + { + const auto &typed_req = To(req); + glVertexAttrib1f(typed_req.location, + typed_req.v0); + break; + } + case COMMAND_BUFFER_VERTEX_ATTRIB_2F_REQ: + { + const auto &typed_req = To(req); + glVertexAttrib2f(typed_req.location, + typed_req.v0, + typed_req.v1); + break; + } + case COMMAND_BUFFER_VERTEX_ATTRIB_3F_REQ: + { + const auto &typed_req = To(req); + glVertexAttrib3f(typed_req.location, + typed_req.v0, + typed_req.v1, + typed_req.v2); + break; + } + case COMMAND_BUFFER_VERTEX_ATTRIB_4F_REQ: + { + const auto &typed_req = To(req); + glVertexAttrib4f(typed_req.location, + typed_req.v0, + typed_req.v1, + typed_req.v2, + typed_req.v3); + break; + } + case COMMAND_BUFFER_VERTEX_ATTRIB_DIVISOR_REQ: + { + const auto &typed_req = To(req); + glVertexAttribDivisor(typed_req.location, + typed_req.divisor); + break; + } + case COMMAND_BUFFER_VERTEX_ATTRIB_POINTER_REQ: + { + const auto &typed_req = To(req); + glVertexAttribPointer(typed_req.location, + typed_req.size, + typed_req.type, + typed_req.normalized, + typed_req.stride, + typed_req.offset); + break; + } + case COMMAND_BUFFER_VERTEX_ATTRIB_IPOINTER_REQ: + { + const auto &typed_req = To(req); + glVertexAttribIPointer(typed_req.location, + typed_req.size, + typed_req.type, + typed_req.stride, + typed_req.offset); + break; + } + + // State Management + case COMMAND_BUFFER_BLEND_COLOR_REQ: + { + const auto &typed_req = To(req); + glBlendColor(typed_req.red, + typed_req.green, + typed_req.blue, + typed_req.alpha); + break; + } + case COMMAND_BUFFER_BLEND_EQUATION_REQ: + { + const auto &typed_req = To(req); + glBlendEquation(typed_req.mode); + break; + } + case COMMAND_BUFFER_BLEND_EQUATION_SEPARATE_REQ: + { + const auto &typed_req = To(req); + glBlendEquationSeparate(typed_req.modeRGB, + typed_req.modeAlpha); + break; + } + case COMMAND_BUFFER_BLEND_FUNC_REQ: + { + const auto &typed_req = To(req); + glBlendFunc(typed_req.sfactor, + typed_req.dfactor); + break; + } + case COMMAND_BUFFER_BLEND_FUNC_SEPARATE_REQ: + { + const auto &typed_req = To(req); + glBlendFuncSeparate(typed_req.srcRGB, + typed_req.dstRGB, + typed_req.srcAlpha, + typed_req.dstAlpha); + break; + } + case COMMAND_BUFFER_COLOR_MASK_REQ: + { + const auto &typed_req = To(req); + glColorMask(typed_req.red, + typed_req.green, + typed_req.blue, + typed_req.alpha); + break; + } + case COMMAND_BUFFER_CULL_FACE_REQ: + { + const auto &typed_req = To(req); + glCullFace(typed_req.mode); + break; + } + case COMMAND_BUFFER_DEPTH_FUNC_REQ: + { + const auto &typed_req = To(req); + glDepthFunc(typed_req.func); + break; + } + case COMMAND_BUFFER_DEPTH_MASK_REQ: + { + const auto &typed_req = To(req); + glDepthMask(typed_req.flag); + break; + } + case COMMAND_BUFFER_DEPTH_RANGE_REQ: + { + const auto &typed_req = To(req); + glDepthRange(typed_req.n, typed_req.f); + break; + } + case COMMAND_BUFFER_DISABLE_REQ: + { + const auto &typed_req = To(req); + glDisable(typed_req.cap); + break; + } + case COMMAND_BUFFER_ENABLE_REQ: + { + const auto &typed_req = To(req); + glEnable(typed_req.cap); + break; + } + case COMMAND_BUFFER_FRONT_FACE_REQ: + { + const auto &typed_req = To(req); + glFrontFace(typed_req.mode); + break; + } + case COMMAND_BUFFER_HINT_REQ: + { + const auto &typed_req = To(req); + glHint(typed_req.target, typed_req.mode); + break; + } + case COMMAND_BUFFER_LINE_WIDTH_REQ: + { + const auto &typed_req = To(req); + glLineWidth(typed_req.width); + break; + } + case COMMAND_BUFFER_PIXEL_STOREI_REQ: + { + const auto &typed_req = To(req); + glPixelStorei(typed_req.pname, typed_req.param); + break; + } + case COMMAND_BUFFER_POLYGON_OFFSET_REQ: + { + const auto &typed_req = To(req); + glPolygonOffset(typed_req.factor, typed_req.units); + break; + } + case COMMAND_BUFFER_SET_SCISSOR_REQ: + { + const auto &typed_req = To(req); + glScissor(typed_req.x, typed_req.y, typed_req.width, typed_req.height); + break; + } + case COMMAND_BUFFER_STENCIL_FUNC_REQ: + { + const auto &typed_req = To(req); + glStencilFunc(typed_req.func, typed_req.ref, typed_req.mask); + break; + } + case COMMAND_BUFFER_STENCIL_FUNC_SEPARATE_REQ: + { + const auto &typed_req = To(req); + glStencilFuncSeparate(typed_req.face, + typed_req.func, + typed_req.ref, + typed_req.mask); + break; + } + case COMMAND_BUFFER_STENCIL_MASK_REQ: + { + const auto &typed_req = To(req); + glStencilMask(typed_req.mask); + break; + } + case COMMAND_BUFFER_STENCIL_MASK_SEPARATE_REQ: + { + const auto &typed_req = To(req); + glStencilMaskSeparate(typed_req.face, typed_req.mask); + break; + } + case COMMAND_BUFFER_STENCIL_OP_REQ: + { + const auto &typed_req = To(req); + glStencilOp(typed_req.fail, typed_req.zfail, typed_req.zpass); + break; + } + case COMMAND_BUFFER_STENCIL_OP_SEPARATE_REQ: + { + const auto &typed_req = To(req); + glStencilOpSeparate(typed_req.face, + typed_req.fail, + typed_req.zfail, + typed_req.zpass); + break; + } + case COMMAND_BUFFER_SET_VIEWPORT_REQ: + { + const auto &typed_req = To(req); + glViewport(typed_req.x, typed_req.y, typed_req.width, typed_req.height); + break; + } + + // Vertex Array Objects + case COMMAND_BUFFER_BIND_VERTEX_ARRAY_REQ: + { + const auto &typed_req = To(req); + glBindVertexArray(typed_req.vertexArray); + break; + } + case COMMAND_BUFFER_DELETE_VERTEX_ARRAY_REQ: + { + const auto &typed_req = To(req); + glDeleteVertexArrays(1, &typed_req.vertexArray); + break; + } + case COMMAND_BUFFER_CREATE_VERTEX_ARRAY_REQ: + { + const auto &typed_req = To(req); + WebGLuint vao; + glGenVertexArrays(1, &vao); + break; + } + default: break; } @@ -121,7 +1003,7 @@ namespace renderer void TrContextWebGL::glGenTextures(WebGLsizei n, WebGLuint *textures) { - // TODO(yorkie): implement + glGenObjects(textures_, n, textures); } void TrContextWebGL::glGetTexParameter(WebGLenum target, WebGLenum pname, WebGLint *params) @@ -457,30 +1339,12 @@ namespace renderer void TrContextWebGL::glGenFramebuffers(WebGLsizei n, WebGLuint *framebuffers) { - static WebGLuint next_framebuffer_id_ = 1; - for (WebGLsizei i = 0; i < n; i++) - { - const FramebufferBinding binding = { - .target = nullopt, - .framebuffer = next_framebuffer_id_++, - }; - framebuffer_bindings_.push_back(binding); - framebuffers[i] = binding.framebuffer; - } + glGenObjects(framebuffers_, n, framebuffers); } void TrContextWebGL::glGenRenderbuffers(WebGLsizei n, WebGLuint *renderbuffers) { - static WebGLuint next_renderbuffer_id_ = 1; - for (WebGLsizei i = 0; i < n; i++) - { - const RenderbufferBinding binding = { - .target = nullopt, - .renderbuffer = next_renderbuffer_id_++, - }; - renderbuffer_bindings_.push_back(binding); - renderbuffers[i] = binding.renderbuffer; - } + glGenObjects(renderbuffers_, n, renderbuffers); } void TrContextWebGL::glGenerateMipmap(WebGLenum target) @@ -553,11 +1417,6 @@ namespace renderer } // --- Shaders --- - void TrContextWebGL::glAttachShader(WebGLuint program, WebGLuint shader) - { - /* TODO(yorkie): implement */ - } - void TrContextWebGL::glBindAttribLocation(WebGLuint program, WebGLuint index, const WebGLchar *name) { /* TODO(yorkie): implement */ @@ -568,29 +1427,121 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glCreateProgram() + WebGLuint TrContextWebGL::glCreateProgram() { - /* TODO(yorkie): implement */ + WebGLuint id = programs_.size(); + const Program program = { + .id = id, // Use the index as the default id. + .vertex_shader = nullopt, + .fragment_shader = nullopt, + }; + programs_.push_back(program); + return program.id; } - void TrContextWebGL::glCreateShader(WebGLenum type) + WebGLuint TrContextWebGL::glCreateShader(WebGLenum type) { - /* TODO(yorkie): implement */ + WebGLuint id = shader_modules_.size(); + const ShaderModule shader_module = { + .id = id, // Use the index as the default id. + .type = type, + }; + shader_modules_.push_back(shader_module); + return shader_module.id; } void TrContextWebGL::glDeleteProgram(WebGLuint program) { - /* TODO(yorkie): implement */ + for (auto it = programs_.begin(); it != programs_.end(); it++) + { + if (it->id == program) + { + programs_.erase(it); + return; + } + } } void TrContextWebGL::glDeleteShader(WebGLuint shader) { - /* TODO(yorkie): implement */ + for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) + { + if (it->id == shader) + { + shader_modules_.erase(it); + return; + } + } + } + + void TrContextWebGL::glAttachShader(WebGLuint program, WebGLuint shader) + { + ShaderModule *shader_module = nullptr; + for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) + { + if (it->id == shader) + { + shader_module = &*it; + break; + } + } + + if (shader_module == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + for (auto it = programs_.begin(); it != programs_.end(); it++) + { + if (it->id == program) + { + if (shader_module->type == WEBGL_VERTEX_SHADER) + it->vertex_shader = make_optional(*shader_module); + else if (shader_module->type == WEBGL_FRAGMENT_SHADER) + it->fragment_shader = make_optional(*shader_module); + else [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + } + return; + } + } } void TrContextWebGL::glDetachShader(WebGLuint program, WebGLuint shader) { - /* TODO(yorkie): implement */ + ShaderModule *shader_module = nullptr; + for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) + { + if (it->id == shader) + { + shader_module = &*it; + break; + } + } + + if (shader_module == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + for (auto it = programs_.begin(); it != programs_.end(); it++) + { + if (it->id == program) + { + if (shader_module->type == WEBGL_VERTEX_SHADER) + it->vertex_shader = nullopt; + else if (shader_module->type == WEBGL_FRAGMENT_SHADER) + it->fragment_shader = nullopt; + else [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + } + return; + } + } } void TrContextWebGL::glGetActiveAttrib(WebGLuint program, @@ -1054,17 +2005,7 @@ namespace renderer void TrContextWebGL::glGenBuffers(WebGLsizei n, WebGLuint *buffers) { - static WebGLuint next_buffer_id = 0; - - for (int i = 0; i < n; i++) - { - const BufferBinding binding = { - .target = nullopt, - .buffer = next_buffer_id++, - }; - buffer_bindings_.push_back(binding); - buffers[i] = binding.buffer; - } + glGenObjects(buffers_, n, buffers); } void TrContextWebGL::glGetBufferParameter(WebGLenum target, WebGLenum pname, WebGLint *params) @@ -1113,11 +2054,6 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glVertexAttrib(WebGLuint index, WebGLfloat x) - { - /* TODO(yorkie): implement */ - } - void TrContextWebGL::glVertexAttrib1f(WebGLuint index, WebGLfloat x) { /* TODO(yorkie): implement */ @@ -1560,4 +2496,75 @@ namespace renderer { /* TODO(yorkie): implement */ } + + void TrContextWebGL::glGenObjects(std::vector &source_list, + WebGLsizei n, + WebGLuint *generated_list) + { + if (n <= 0 || generated_list == nullptr) + return; + + size_t old_size = source_list.size(); + WebGLuint initial_value = 0x0; + source_list.resize(old_size + static_cast(n)); + std::fill(source_list.begin() + old_size, + source_list.end(), + initial_value); + + for (size_t i = 0; i < n; i++) + { + generated_list[i] = source_list[old_size + i]; + } + } + + void TrContextWebGL::debugPrintPrograms(int depth) + { + debugPrintObjects("Programs", + programs_, + depth, + [](const Program &program) + { return std::to_string(program.id); }); + } + + void TrContextWebGL::debugPrintShaderModules(int depth) + { + auto print_shader = [](const ShaderModule &module) + { + return module.toString(); + }; + debugPrintObjects("Shader Modules", shader_modules_, depth, print_shader); + } + + void TrContextWebGL::debugPrintBuffers(int depth) + { + debugPrintObjects("Buffers", buffers_, depth); + } + + void TrContextWebGL::debugPrintTextures(int depth) + { + debugPrintObjects("Textures", textures_, depth); + } + + void TrContextWebGL::debugPrintFramebuffers(int depth) + { + debugPrintObjects("Framebuffers", framebuffers_, depth); + } + + void TrContextWebGL::debugPrintRenderbuffers(int depth) + { + debugPrintObjects("Renderbuffers", renderbuffers_, depth); + } + + void TrContextWebGL::debugPrint() + { + cerr << "[WebGL] Objects Summary:" << endl; + { + debugPrintPrograms(2); + debugPrintShaderModules(2); + debugPrintBuffers(2); + debugPrintTextures(2); + debugPrintFramebuffers(2); + debugPrintRenderbuffers(2); + } + } } diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index c60134208..2ca2da7f8 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include #include @@ -350,13 +352,13 @@ namespace renderer WebGLsizei height); // Shaders - void glAttachShader(WebGLuint program, WebGLuint shader); void glBindAttribLocation(WebGLuint program, WebGLuint index, const WebGLchar *name); void glCompileShader(WebGLuint shader); - void glCreateProgram(); - void glCreateShader(WebGLenum type); + WebGLuint glCreateProgram(); + WebGLuint glCreateShader(WebGLenum type); void glDeleteProgram(WebGLuint program); void glDeleteShader(WebGLuint shader); + void glAttachShader(WebGLuint program, WebGLuint shader); void glDetachShader(WebGLuint program, WebGLuint shader); void glGetActiveAttrib(WebGLuint program, WebGLuint index, @@ -481,7 +483,6 @@ namespace renderer WebGLboolean glIsBuffer(WebGLuint buffer); void glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access); void glUnmapBuffer(WebGLenum target); - void glVertexAttrib(WebGLuint index, WebGLfloat x); void glVertexAttrib1f(WebGLuint index, WebGLfloat x); void glVertexAttrib2f(WebGLuint index, WebGLfloat x, WebGLfloat y); void glVertexAttrib3f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z); @@ -591,11 +592,97 @@ namespace renderer void glIsSampler(WebGLuint sampler); void glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param); + // Internal Utilities + void glGenObjects(std::vector &source_list, + WebGLsizei n, + WebGLuint *generated_list); + + /** + * A convenience function to create a WebGL object such as buffer, texture, framebuffer, renderbuffer in this context implementation. + * + * @tparam ReqType + * @param source_list A list of WebGL objects to store the created object. + * @param req A request to create a WebGL object. + */ + template + void glCreateTypedObject(std::vector &source_list, const commandbuffers::TrCommandBufferRequest &req) + { + const auto &typed_req = To(req); + size_t size_before = source_list.size(); + { + WebGLint obj; + glGenObjects(source_list, 1, (WebGLuint *)&obj); + assert(obj == 0 && "object must be the initial object"); + } + source_list[size_before] = req.id; + debugPrint(); + } + + // Debug Utilities + template + void debugPrintObjects( + const string &label, + const vector &list, + int depth = 0, + std::function print_func = [](const ObjectType &obj) + { return std::to_string(obj); }) + { + const std::string prefix = std::string(depth, ' '); + + if (depth > 0) // Not printing [WebGL] prefix for nested. + cerr << prefix; + else + cerr << "[WebGL] "; + cerr << label << ": {"; + + if (list.empty()) + { + cerr << " (empty) "; + } + else + { + cerr << endl; + int n = 0; + for (const auto &obj : list) + cerr << prefix << " ." << n++ << " = " << print_func(obj) << endl; + } + cerr << prefix << "}" << endl; + } + + void debugPrintPrograms(int depth = 0); + void debugPrintShaderModules(int depth = 0); + void debugPrintBuffers(int depth = 0); + void debugPrintTextures(int depth = 0); + void debugPrintFramebuffers(int depth = 0); + void debugPrintRenderbuffers(int depth = 0); + void debugPrint(); + Ref content_renderer_; - std::unordered_map texture_bindings_; + + std::vector buffers_; + std::vector textures_; + std::vector framebuffers_; + std::vector renderbuffers_; + std::vector buffer_bindings_; std::vector framebuffer_bindings_; std::vector renderbuffer_bindings_; + std::unordered_map texture_bindings_; + struct ShaderModule + { + WebGLuint id; + WebGLenum type; + + std::string toString() const; + }; + std::vector shader_modules_; + struct Program + { + WebGLuint id; + std::optional vertex_shader; + std::optional fragment_shader; + }; + std::vector programs_; WebGLenum last_error_ = WEBGL_NO_ERROR; Capabilities caps_; From 4484cf4a7852ad3b65a81945f5371608edc032a6 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Sat, 29 Nov 2025 00:24:17 +0800 Subject: [PATCH 33/37] fix --- src/renderer/context_webgl.cpp | 1537 +---------------- src/renderer/context_webgl.hpp | 5 +- src/renderer/context_webgl_buffers.cpp | 245 +++ src/renderer/context_webgl_framebuffers.cpp | 188 ++ src/renderer/context_webgl_queries.cpp | 45 + src/renderer/context_webgl_rendering.cpp | 92 + src/renderer/context_webgl_samplers.cpp | 40 + src/renderer/context_webgl_shaders.cpp | 488 ++++++ src/renderer/context_webgl_states.cpp | 193 +++ src/renderer/context_webgl_syncing.cpp | 42 + src/renderer/context_webgl_texture.cpp | 213 +++ .../context_webgl_transform_feedback.cpp | 69 + src/renderer/context_webgl_utility.cpp | 25 + src/renderer/context_webgl_vao.cpp | 30 + 14 files changed, 1674 insertions(+), 1538 deletions(-) create mode 100644 src/renderer/context_webgl_buffers.cpp create mode 100644 src/renderer/context_webgl_framebuffers.cpp create mode 100644 src/renderer/context_webgl_queries.cpp create mode 100644 src/renderer/context_webgl_rendering.cpp create mode 100644 src/renderer/context_webgl_samplers.cpp create mode 100644 src/renderer/context_webgl_shaders.cpp create mode 100644 src/renderer/context_webgl_states.cpp create mode 100644 src/renderer/context_webgl_syncing.cpp create mode 100644 src/renderer/context_webgl_texture.cpp create mode 100644 src/renderer/context_webgl_transform_feedback.cpp create mode 100644 src/renderer/context_webgl_utility.cpp create mode 100644 src/renderer/context_webgl_vao.cpp diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index dcaa10d55..9411876d5 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -962,1541 +962,6 @@ namespace renderer } } - void TrContextWebGL::glActiveTexture(WebGLenum texture) - { - active_texture_ = texture; - } - - void TrContextWebGL::glBindTexture(WebGLenum target, WebGLuint texture) - { - texture_bindings_[TextureTarget(target)] = {target, texture}; - } - - void TrContextWebGL::glCopyTexImage2D(WebGLenum target, - WebGLenum internalformat, - WebGLint level, - WebGLint x, - WebGLint y, - WebGLsizei width, - WebGLsizei height, - WebGLint border) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glCopyTexSubImage2D(WebGLenum target, - WebGLint level, - WebGLint xoffset, - WebGLint yoffset, - WebGLint x, - WebGLint y, - WebGLsizei width, - WebGLsizei height) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glDeleteTextures(WebGLsizei n, const WebGLuint *textures) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glGenTextures(WebGLsizei n, WebGLuint *textures) - { - glGenObjects(textures_, n, textures); - } - - void TrContextWebGL::glGetTexParameter(WebGLenum target, WebGLenum pname, WebGLint *params) - { - // TODO(yorkie): implement - } - - WebGLboolean TrContextWebGL::glIsTexture(WebGLuint texture) - { - // TODO(yorkie): implement - return true; - } - - void TrContextWebGL::glTexImage2D(WebGLenum target, - WebGLint level, - WebGLenum internalformat, - WebGLsizei width, - WebGLsizei height, - WebGLsizei border, - WebGLenum format, - WebGLenum type, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexImage3D(WebGLenum target, - WebGLint level, - WebGLenum internalformat, - WebGLsizei width, - WebGLsizei height, - WebGLsizei depth, - WebGLsizei border, - WebGLenum format, - WebGLenum type, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - // --- Additional texture APIs --- - void TrContextWebGL::glCompressedTexImage2D(WebGLenum target, - WebGLint level, - WebGLenum internalformat, - WebGLsizei width, - WebGLsizei height, - WebGLsizei border, - WebGLsizei imageSize, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glCompressedTexImage3D(WebGLenum target, - WebGLint level, - WebGLenum internalformat, - WebGLsizei width, - WebGLsizei height, - WebGLsizei depth, - WebGLsizei border, - WebGLsizei imageSize, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glCompressedTexSubImage2D(WebGLenum target, - WebGLint level, - WebGLint xoffset, - WebGLint yoffset, - WebGLsizei width, - WebGLsizei height, - WebGLenum format, - WebGLsizei imageSize, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glCompressedTexSubImage3D(WebGLenum target, - WebGLint level, - WebGLint xoffset, - WebGLint yoffset, - WebGLint zoffset, - WebGLsizei width, - WebGLsizei height, - WebGLsizei depth, - WebGLenum format, - WebGLsizei imageSize, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexParameterfv(WebGLenum target, WebGLenum pname, const WebGLfloat *params) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexParameteriv(WebGLenum target, WebGLenum pname, const WebGLint *params) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexStorage2D(WebGLenum target, - WebGLint levels, - WebGLenum internalformat, - WebGLsizei width, - WebGLsizei height) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexStorage3D(WebGLenum target, - WebGLint levels, - WebGLenum internalformat, - WebGLsizei width, - WebGLsizei height, - WebGLsizei depth) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexSubImage2D(WebGLenum target, - WebGLint level, - WebGLint xoffset, - WebGLint yoffset, - WebGLsizei width, - WebGLsizei height, - WebGLenum format, - WebGLenum type, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - void TrContextWebGL::glTexSubImage3D(WebGLenum target, - WebGLint level, - WebGLint xoffset, - WebGLint yoffset, - WebGLint zoffset, - WebGLsizei width, - WebGLsizei height, - WebGLsizei depth, - WebGLenum format, - WebGLenum type, - const WebGLvoid *data) - { - // TODO(yorkie): implement - } - - // --- Rendering --- - void TrContextWebGL::glClear(WebGLbitfield mask) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glClearBufferiv(WebGLenum buffer, WebGLint drawbuffer, const WebGLint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glClearBufferuiv(WebGLenum buffer, WebGLint drawbuffer, const WebGLuint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glClearBufferfv(WebGLenum buffer, - WebGLint drawbuffer, - const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glClearBufferfi(WebGLenum buffer, - WebGLint drawbuffer, - WebGLfloat depth, - WebGLint stencil) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glClearColor(WebGLfloat red, - WebGLfloat green, - WebGLfloat blue, - WebGLfloat alpha) - { - clear_color_[0] = red; - clear_color_[1] = green; - clear_color_[2] = blue; - clear_color_[3] = alpha; - } - - void TrContextWebGL::glClearDepthf(WebGLfloat depth) - { - clear_depth_ = depth; - } - - void TrContextWebGL::glClearStencil(WebGLint s) - { - clear_stencil_ = s; - } - - void TrContextWebGL::glFinish() - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glFlush() - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glReadBuffer(WebGLenum buffer) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glReadPixels(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height, WebGLenum format, WebGLenum type, WebGLvoid *pixels) - { - /* TODO(yorkie): implement */ - } - - // --- Framebuffers --- - void TrContextWebGL::glBindFramebuffer(WebGLenum target, WebGLuint framebuffer) - { - if (!glIsFramebuffer(framebuffer)) [[unlikely]] - { - last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; - return; - } - - if (target != WEBGL_FRAMEBUFFER && - target != WEBGL2_DRAW_FRAMEBUFFER && - target != WEBGL2_READ_FRAMEBUFFER) [[unlikely]] - { - last_error_ = WEBGL_INVALID_ENUM; - return; - } - - for (auto &binding : framebuffer_bindings_) - { - if (binding.framebuffer == framebuffer) - { - binding.target = target; - break; - } - } - } - - void TrContextWebGL::glBindRenderbuffer(WebGLenum target, WebGLuint renderbuffer) - { - if (!glIsRenderbuffer(renderbuffer)) [[unlikely]] - { - last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; - return; - } - - if (target != WEBGL_RENDERBUFFER) [[unlikely]] - { - last_error_ = WEBGL_INVALID_ENUM; - return; - } - - for (auto &binding : renderbuffer_bindings_) - { - if (binding.renderbuffer == renderbuffer) - { - binding.target = target; - break; - } - } - } - - void TrContextWebGL::glBlitFramebuffer(WebGLint srcX0, - WebGLint srcY0, - WebGLint srcX1, - WebGLint srcY1, - WebGLint dstX0, - WebGLint dstY0, - WebGLint dstX1, - WebGLint dstY1, - WebGLbitfield mask, - WebGLenum filter) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glCheckFramebufferStatus(WebGLenum target) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteFramebuffers(WebGLsizei n, const WebGLuint *framebuffers) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteRenderbuffers(WebGLsizei n, const WebGLuint *renderbuffers) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDrawBuffers(WebGLsizei n, const WebGLenum *buffers) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glFramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum renderbuffertarget, WebGLuint renderbuffer) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glFramebufferTexture2D(WebGLenum target, WebGLenum attachment, WebGLenum textarget, WebGLuint texture, WebGLint level) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glFramebufferTextureLayer(WebGLenum target, WebGLenum attachment, WebGLuint texture, WebGLint level, WebGLint layer) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGenFramebuffers(WebGLsizei n, WebGLuint *framebuffers) - { - glGenObjects(framebuffers_, n, framebuffers); - } - - void TrContextWebGL::glGenRenderbuffers(WebGLsizei n, WebGLuint *renderbuffers) - { - glGenObjects(renderbuffers_, n, renderbuffers); - } - - void TrContextWebGL::glGenerateMipmap(WebGLenum target) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetFramebufferAttachmentParameteriv(WebGLenum target, WebGLenum attachment, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetRenderbufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glInvalidateFramebuffer(WebGLenum target, WebGLsizei n, const WebGLenum *attachments) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glInvalidateSubFramebuffer(WebGLenum target, - WebGLsizei n, - const WebGLenum *attachments, - WebGLint x, - WebGLint y, - WebGLsizei width, - WebGLsizei height) - { - /* TODO(yorkie): implement */ - } - - WebGLboolean TrContextWebGL::glIsFramebuffer(WebGLuint framebuffer) - { - for (const auto &binding : framebuffer_bindings_) - { - if (binding.framebuffer == framebuffer) - { - return true; - } - } - return false; - } - - WebGLboolean TrContextWebGL::glIsRenderbuffer(WebGLuint renderbuffer) - { - for (const auto &binding : renderbuffer_bindings_) - { - if (binding.renderbuffer == renderbuffer) - { - return true; - } - } - return false; - } - - void TrContextWebGL::glRenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glRenderbufferStorageMultisample(WebGLenum target, - WebGLsizei samples, - WebGLenum internalformat, - WebGLsizei width, - WebGLsizei height) - { - /* TODO(yorkie): implement */ - } - - // --- Shaders --- - void TrContextWebGL::glBindAttribLocation(WebGLuint program, WebGLuint index, const WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glCompileShader(WebGLuint shader) - { - /* TODO(yorkie): implement */ - } - - WebGLuint TrContextWebGL::glCreateProgram() - { - WebGLuint id = programs_.size(); - const Program program = { - .id = id, // Use the index as the default id. - .vertex_shader = nullopt, - .fragment_shader = nullopt, - }; - programs_.push_back(program); - return program.id; - } - - WebGLuint TrContextWebGL::glCreateShader(WebGLenum type) - { - WebGLuint id = shader_modules_.size(); - const ShaderModule shader_module = { - .id = id, // Use the index as the default id. - .type = type, - }; - shader_modules_.push_back(shader_module); - return shader_module.id; - } - - void TrContextWebGL::glDeleteProgram(WebGLuint program) - { - for (auto it = programs_.begin(); it != programs_.end(); it++) - { - if (it->id == program) - { - programs_.erase(it); - return; - } - } - } - - void TrContextWebGL::glDeleteShader(WebGLuint shader) - { - for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) - { - if (it->id == shader) - { - shader_modules_.erase(it); - return; - } - } - } - - void TrContextWebGL::glAttachShader(WebGLuint program, WebGLuint shader) - { - ShaderModule *shader_module = nullptr; - for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) - { - if (it->id == shader) - { - shader_module = &*it; - break; - } - } - - if (shader_module == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - - for (auto it = programs_.begin(); it != programs_.end(); it++) - { - if (it->id == program) - { - if (shader_module->type == WEBGL_VERTEX_SHADER) - it->vertex_shader = make_optional(*shader_module); - else if (shader_module->type == WEBGL_FRAGMENT_SHADER) - it->fragment_shader = make_optional(*shader_module); - else [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - } - return; - } - } - } - - void TrContextWebGL::glDetachShader(WebGLuint program, WebGLuint shader) - { - ShaderModule *shader_module = nullptr; - for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) - { - if (it->id == shader) - { - shader_module = &*it; - break; - } - } - - if (shader_module == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - - for (auto it = programs_.begin(); it != programs_.end(); it++) - { - if (it->id == program) - { - if (shader_module->type == WEBGL_VERTEX_SHADER) - it->vertex_shader = nullopt; - else if (shader_module->type == WEBGL_FRAGMENT_SHADER) - it->fragment_shader = nullopt; - else [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - } - return; - } - } - } - - void TrContextWebGL::glGetActiveAttrib(WebGLuint program, - WebGLuint index, - WebGLsizei maxLength, - WebGLsizei *length, - WebGLint *size, - WebGLenum *type, - WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetActiveUniform(WebGLuint program, - WebGLuint index, - WebGLsizei maxLength, - WebGLsizei *length, - WebGLint *size, - WebGLenum *type, - WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetActiveUniformBlockName(WebGLuint program, - WebGLuint index, - WebGLsizei maxLength, - WebGLsizei *length, - WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetActiveUniformBlockiv(WebGLuint program, - WebGLuint index, - WebGLenum pname, - WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetActiveUniformsiv(WebGLuint program, - WebGLsizei count, - const WebGLuint *uniforms, - WebGLenum pname, - WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetAttachedShaders(WebGLuint program, WebGLsizei maxCount, WebGLsizei *count, WebGLuint *shaders) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetAttribLocation(WebGLuint program, const WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetFragDataLocation(WebGLuint program, const WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetProgramBinary(WebGLuint program, - WebGLsizei maxLength, - WebGLsizei *length, - WebGLenum binaryFormat, - WebGLsizei *binaryLength, - WebGLbyte *binary) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetProgramInfoLog(WebGLuint program, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetProgramiv(WebGLuint program, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetShaderInfoLog(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype, WebGLint *range, WebGLint *precision) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetShaderSource(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *source) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetShaderiv(WebGLuint shader, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetUniformfv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLfloat *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetUniformiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetUniformuiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLuint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetUniformBlockIndex(WebGLuint program, const WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetUniformIndices(WebGLuint program, WebGLsizei count, const WebGLchar **names, WebGLuint *indices) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetUniformLocation(WebGLuint program, const WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glIsProgram(WebGLuint program) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glIsShader(WebGLuint shader) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glLinkProgram(WebGLuint program) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glProgramBinary(WebGLuint program, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glProgramParameteri(WebGLuint program, WebGLenum pname, WebGLint param) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glReleaseShaderCompiler() - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glShaderBinary(WebGLuint shader, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glShaderSource(WebGLuint shader, WebGLsizei count, const WebGLchar **string, const WebGLint *length) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform1f(WebGLuint location, WebGLfloat v0) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform2f(WebGLuint location, WebGLfloat v0, WebGLfloat v1) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform3f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform4f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform1i(WebGLuint location, WebGLint v0) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform2i(WebGLuint location, WebGLint v0, WebGLint v1) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform3i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform4i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform1ui(WebGLuint location, WebGLuint v0) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform2ui(WebGLuint location, WebGLuint v0, WebGLuint v1) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform3ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform4ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2, WebGLuint v3) - { /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform1fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform2fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform3fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform4fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform1iv(WebGLuint location, WebGLsizei count, const WebGLint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform2iv(WebGLuint location, WebGLsizei count, const WebGLint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform3iv(WebGLuint location, WebGLsizei count, const WebGLint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform4iv(WebGLuint location, WebGLsizei count, const WebGLint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform1uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform2uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform3uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniform4uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix2x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix3x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix2x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix4x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix3x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformMatrix4x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUniformBlockBinding(WebGLuint program, WebGLuint uniformBlockIndex, WebGLuint bindingPoint) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUseProgram(WebGLuint program) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glValidateProgram(WebGLuint program) - { - /* TODO(yorkie): implement */ - } - - // --- Buffer Objects --- - void TrContextWebGL::glBindBuffer(WebGLenum target, WebGLuint buffer) - { - if (!glIsBuffer(buffer)) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - - for (auto &binding : buffer_bindings_) - { - if (binding.buffer == buffer) - { - binding.target = target; - break; - } - } - } - - void TrContextWebGL::glBindBufferBase(WebGLenum target, - WebGLuint bindingPoint, - WebGLuint buffer) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glBindBufferRange(WebGLenum target, - WebGLuint bindingPoint, - WebGLuint buffer, - WebGLintptr offset, - WebGLsizeiptr size) - { - /* TODO(yorkie): implement */ - } - void TrContextWebGL::glBufferData(WebGLenum target, - WebGLsizeiptr size, - const WebGLvoid *data, - WebGLenum usage) - { - /* TODO(yorkie): implement */ - } - void TrContextWebGL::glBufferSubData(WebGLenum target, - WebGLintptr offset, - WebGLsizeiptr size, - const WebGLvoid *data) - { - /* TODO(yorkie): implement */ - } - void TrContextWebGL::glCopyBufferSubData(WebGLenum readTarget, - WebGLenum writeTarget, - WebGLintptr readOffset, - WebGLintptr writeOffset, - WebGLsizeiptr size) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteBuffers(WebGLsizei count, const WebGLuint *buffers) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDisableVertexAttribArray(WebGLuint index) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDrawArrays(WebGLenum mode, WebGLint first, WebGLsizei count) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDrawArraysInstanced(WebGLenum mode, - WebGLint first, - WebGLsizei count, - WebGLsizei instanceCount) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDrawElements(WebGLenum mode, - WebGLsizei count, - WebGLenum type, - const WebGLvoid *indices) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type, const WebGLvoid *indices, WebGLsizei instanceCount) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDrawRangeElements(WebGLenum mode, WebGLuint start, WebGLuint end, WebGLsizei count, WebGLenum type, const WebGLvoid *indices) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glEnableVertexAttribArray(WebGLuint index) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glFlushMappedBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr size) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGenBuffers(WebGLsizei n, WebGLuint *buffers) - { - glGenObjects(buffers_, n, buffers); - } - - void TrContextWebGL::glGetBufferParameter(WebGLenum target, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetBufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetBufferPointerv(WebGLenum target, WebGLenum pname, WebGLvoid **params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetVertexAttrib(WebGLuint index, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetVertexAttribPointerv(WebGLuint index, WebGLenum pname, WebGLvoid **pointer) - { - /* TODO(yorkie): implement */ - } - - WebGLboolean TrContextWebGL::glIsBuffer(WebGLuint buffer) - { - for (const auto &binding : buffer_bindings_) - { - if (binding.buffer == buffer) - { - return true; - } - } - return false; - } - - void TrContextWebGL::glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access) - { /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glUnmapBuffer(WebGLenum target) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib1f(WebGLuint index, WebGLfloat x) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib2f(WebGLuint index, WebGLfloat x, WebGLfloat y) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib3f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib4f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z, WebGLfloat w) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib1fv(WebGLuint index, const WebGLfloat *v) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib2fv(WebGLuint index, const WebGLfloat *v) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib3fv(WebGLuint index, const WebGLfloat *v) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttrib4fv(WebGLuint index, const WebGLfloat *v) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttribDivisor(WebGLuint index, WebGLuint divisor) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttribPointer(WebGLuint index, - WebGLint size, - WebGLenum type, - WebGLboolean normalized, - WebGLsizei stride, - WebGLintptr offset) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glVertexAttribIPointer(WebGLuint index, - WebGLint size, - WebGLenum type, - WebGLsizei stride, - WebGLintptr offset) - { - /* TODO(yorkie): implement */ - } - - // --- State Management --- - void TrContextWebGL::glBlendColor(WebGLfloat red, - WebGLfloat green, - WebGLfloat blue, - WebGLfloat alpha) - { - blend_color_[0] = red; - blend_color_[1] = green; - blend_color_[2] = blue; - blend_color_[3] = alpha; - } - - void TrContextWebGL::glBlendEquation(WebGLenum mode) - { - blend_equation_rgb_ = mode; - blend_equation_alpha_ = mode; - } - - void TrContextWebGL::glBlendEquationSeparate(WebGLenum mode_rgb, WebGLenum mode_alpha) - { - blend_equation_rgb_ = mode_rgb; - blend_equation_alpha_ = mode_alpha; - } - - void TrContextWebGL::glBlendFunc(WebGLenum sfactor, WebGLenum dfactor) - { - blend_sfactor_rgb_ = sfactor; - blend_dfactor_rgb_ = dfactor; - blend_sfactor_alpha_ = sfactor; - blend_dfactor_alpha_ = dfactor; - } - - void TrContextWebGL::glBlendFuncSeparate(WebGLenum src_rgb, - WebGLenum dst_rgb, - WebGLenum src_alpha, - WebGLenum dst_alpha) - { - blend_sfactor_rgb_ = src_rgb; - blend_dfactor_rgb_ = dst_rgb; - blend_sfactor_alpha_ = src_alpha; - blend_dfactor_alpha_ = dst_alpha; - } - - void TrContextWebGL::glColorMask(WebGLboolean red, - WebGLboolean green, - WebGLboolean blue, - WebGLboolean alpha) - { - color_mask_[0] = red; - color_mask_[1] = green; - color_mask_[2] = blue; - color_mask_[3] = alpha; - } - - void TrContextWebGL::glCullFace(WebGLenum mode) - { - cull_face_ = mode; - } - - void TrContextWebGL::glDepthFunc(WebGLenum func) - { - depth_func_ = func; - } - - void TrContextWebGL::glDepthMask(WebGLboolean flag) - { - depth_mask_ = flag; - } - - void TrContextWebGL::glDepthRangef(WebGLfloat near, WebGLfloat far) - { - depth_range_[0] = near; - depth_range_[1] = far; - } - - void TrContextWebGL::glDisable(WebGLenum cap) - { - caps_.disable(cap); - } - - void TrContextWebGL::glEnable(WebGLenum cap) - { - caps_.enable(cap); - } - - void TrContextWebGL::glFrontFace(WebGLenum mode) - { - front_face_ = mode; - } - - void TrContextWebGL::glGet(WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - WebGLenum TrContextWebGL::glGetError() - { - WebGLenum error = last_error_; - last_error_ = WEBGL_NO_ERROR; - return error; - } - - void TrContextWebGL::glHint(WebGLenum target, WebGLenum mode) - { /* TODO(yorkie): implement */ - } - - WebGLboolean TrContextWebGL::glIsEnabled(WebGLenum cap) - { - return caps_.isEnabled(cap); - } - - void TrContextWebGL::glLineWidth(WebGLfloat width) - { - line_width_ = width; - } - - void TrContextWebGL::glPixelStorei(WebGLenum pname, WebGLint param) - { /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glPolygonOffset(WebGLfloat factor, WebGLfloat units) - { - polygon_offset_factor_ = factor; - polygon_offset_units_ = units; - } - - void TrContextWebGL::glSampleCoverage(WebGLfloat value, WebGLboolean invert) - { - sample_coverage_value_ = value; - sample_coverage_invert_ = invert; - } - - void TrContextWebGL::glScissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) - { - scissor_box_[0] = x; - scissor_box_[1] = y; - scissor_box_[2] = width; - scissor_box_[3] = height; - } - - void TrContextWebGL::glStencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask) - { - stencil_func_ = func; - stencil_ref_ = ref; - stencil_mask_ = mask; - } - - void TrContextWebGL::glStencilFuncSeparate(WebGLenum face, - WebGLenum func, - WebGLint ref, - WebGLuint mask) - { - stencil_func_ = func; - stencil_ref_ = ref; - stencil_mask_ = mask; - } - - void TrContextWebGL::glStencilMask(WebGLuint mask) - { - stencil_mask_ = mask; - } - - void TrContextWebGL::glStencilMaskSeparate(WebGLenum face, WebGLuint mask) - { /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glStencilOp(WebGLenum fail, WebGLenum zfail, WebGLenum zpass) - { /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glStencilOpSeparate(WebGLenum face, WebGLenum fail, WebGLenum zfail, WebGLenum zpass) - { /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glViewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) - { - viewport_[0] = x; - viewport_[1] = y; - viewport_[2] = width; - viewport_[3] = height; - } - - // --- Transform Feedback --- - void TrContextWebGL::glBeginTransformFeedback(WebGLenum primitiveMode) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glBindTransformFeedback(WebGLenum target, WebGLuint transformFeedback) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteTransformFeedbacks(WebGLsizei n, const WebGLuint *transformFeedbacks) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glEndTransformFeedback() - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGenTransformFeedbacks(WebGLsizei n, WebGLuint *transformFeedbacks) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetTransformFeedbackVarying(WebGLuint program, - WebGLuint index, - WebGLsizei bufSize, - WebGLsizei *length, - WebGLsizei *size, - WebGLenum *type, - WebGLchar *name) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glIsTransformFeedback(WebGLuint transformFeedback) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glPauseTransformFeedback() - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glResumeTransformFeedback() - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glTransformFeedbackVaryings(WebGLuint program, - WebGLsizei count, - const WebGLchar **varyings, - WebGLenum bufferMode) - { - /* TODO(yorkie): implement */ - } - - // --- Utility --- - void TrContextWebGL::glGetInternalformativ(WebGLenum target, WebGLenum internalformat, WebGLsizei propCount, WebGLenum *props, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetString(WebGLenum pname, WebGLchar *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetStringi(WebGLenum pname, WebGLuint index) - { - /* TODO(yorkie): implement */ - } - - // --- Queries --- - void TrContextWebGL::glBeginQuery(WebGLenum target, WebGLuint id) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteQueries(WebGLsizei n, const WebGLuint *ids) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glEndQuery(WebGLenum target) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGenQueries(WebGLsizei n, WebGLuint *ids) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetQueryObjectuiv(WebGLuint id, WebGLenum pname, WebGLuint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetQueryiv(WebGLenum target, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glIsQuery(WebGLuint id) - { - /* TODO(yorkie): implement */ - } - - // --- Syncing --- - void TrContextWebGL::glClientWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteSync(WebGLsync sync) - { - /* TODO(yorkie): implement */ - } - - WebGLsync TrContextWebGL::glFenceSync(WebGLenum condition, WebGLbitfield flags) - { - /* TODO(yorkie): implement */ - return nullptr; - } - - void TrContextWebGL::glGetSynciv(WebGLsync sync, WebGLenum pname, WebGLsizei bufSize, WebGLsizei *length, WebGLint *values) - { - /* TODO(yorkie): implement */ - } - - WebGLboolean TrContextWebGL::glIsSync(WebGLsync sync) - { - /* TODO(yorkie): implement */ - return false; - } - - void TrContextWebGL::glWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout) - { - /* TODO(yorkie): implement */ - } - - // --- Vertex Array Objects --- - void TrContextWebGL::glBindVertexArray(WebGLuint array) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteVertexArrays(WebGLsizei n, const WebGLuint *arrays) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGenVertexArrays(WebGLsizei n, WebGLuint *arrays) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glIsVertexArray(WebGLuint array) - { - /* TODO(yorkie): implement */ - } - - // --- Samplers --- - void TrContextWebGL::glBindSampler(WebGLuint unit, WebGLuint sampler) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glDeleteSamplers(WebGLsizei n, const WebGLuint *samplers) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGenSamplers(WebGLsizei n, WebGLuint *samplers) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glGetSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint *params) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glIsSampler(WebGLuint sampler) - { - /* TODO(yorkie): implement */ - } - - void TrContextWebGL::glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param) - { - /* TODO(yorkie): implement */ - } - void TrContextWebGL::glGenObjects(std::vector &source_list, WebGLsizei n, WebGLuint *generated_list) @@ -2523,7 +988,7 @@ namespace renderer programs_, depth, [](const Program &program) - { return std::to_string(program.id); }); + { return to_string(program.id); }); } void TrContextWebGL::debugPrintShaderModules(int depth) diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index 2ca2da7f8..93163569b 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -637,7 +637,7 @@ namespace renderer if (list.empty()) { - cerr << " (empty) "; + cerr << " (empty) }"; } else { @@ -645,8 +645,9 @@ namespace renderer int n = 0; for (const auto &obj : list) cerr << prefix << " ." << n++ << " = " << print_func(obj) << endl; + cerr << prefix << "}"; } - cerr << prefix << "}" << endl; + cerr << endl; } void debugPrintPrograms(int depth = 0); diff --git a/src/renderer/context_webgl_buffers.cpp b/src/renderer/context_webgl_buffers.cpp new file mode 100644 index 000000000..4717c4b66 --- /dev/null +++ b/src/renderer/context_webgl_buffers.cpp @@ -0,0 +1,245 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glBindBuffer(WebGLenum target, WebGLuint buffer) + { + if (!glIsBuffer(buffer)) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + for (auto &binding : buffer_bindings_) + { + if (binding.buffer == buffer) + { + binding.target = target; + break; + } + } + } + + void TrContextWebGL::glBindBufferBase(WebGLenum target, + WebGLuint bindingPoint, + WebGLuint buffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBindBufferRange(WebGLenum target, + WebGLuint bindingPoint, + WebGLuint buffer, + WebGLintptr offset, + WebGLsizeiptr size) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBufferData(WebGLenum target, + WebGLsizeiptr size, + const WebGLvoid *data, + WebGLenum usage) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBufferSubData(WebGLenum target, + WebGLintptr offset, + WebGLsizeiptr size, + const WebGLvoid *data) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glCopyBufferSubData(WebGLenum readTarget, + WebGLenum writeTarget, + WebGLintptr readOffset, + WebGLintptr writeOffset, + WebGLsizeiptr size) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteBuffers(WebGLsizei count, const WebGLuint *buffers) + { + for (WebGLsizei i = 0; i < count; i++) + { + for (auto it = buffers_.begin(); it != buffers_.end(); ++it) + { + if (*it == buffers[i]) + { + buffers_.erase(it); + break; + } + } + } + } + + void TrContextWebGL::glDisableVertexAttribArray(WebGLuint index) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawArrays(WebGLenum mode, WebGLint first, WebGLsizei count) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawArraysInstanced(WebGLenum mode, + WebGLint first, + WebGLsizei count, + WebGLsizei instanceCount) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawElements(WebGLenum mode, + WebGLsizei count, + WebGLenum type, + const WebGLvoid *indices) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawElementsInstanced(WebGLenum mode, WebGLsizei count, WebGLenum type, const WebGLvoid *indices, WebGLsizei instanceCount) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawRangeElements(WebGLenum mode, WebGLuint start, WebGLuint end, WebGLsizei count, WebGLenum type, const WebGLvoid *indices) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glEnableVertexAttribArray(WebGLuint index) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFlushMappedBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr size) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenBuffers(WebGLsizei n, WebGLuint *buffers) + { + glGenObjects(buffers_, n, buffers); + } + + void TrContextWebGL::glGetBufferParameter(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetBufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetBufferPointerv(WebGLenum target, WebGLenum pname, WebGLvoid **params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetVertexAttrib(WebGLuint index, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetVertexAttribPointerv(WebGLuint index, WebGLenum pname, WebGLvoid **pointer) + { + /* TODO(yorkie): implement */ + } + + WebGLboolean TrContextWebGL::glIsBuffer(WebGLuint buffer) + { + for (const auto &binding : buffer_bindings_) + { + if (binding.buffer == buffer) + { + return true; + } + } + return false; + } + + void TrContextWebGL::glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUnmapBuffer(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib1f(WebGLuint index, WebGLfloat x) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib2f(WebGLuint index, WebGLfloat x, WebGLfloat y) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib3f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib4f(WebGLuint index, WebGLfloat x, WebGLfloat y, WebGLfloat z, WebGLfloat w) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib1fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib2fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib3fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttrib4fv(WebGLuint index, const WebGLfloat *v) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttribDivisor(WebGLuint index, WebGLuint divisor) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttribPointer(WebGLuint index, + WebGLint size, + WebGLenum type, + WebGLboolean normalized, + WebGLsizei stride, + WebGLintptr offset) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glVertexAttribIPointer(WebGLuint index, + WebGLint size, + WebGLenum type, + WebGLsizei stride, + WebGLintptr offset) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_framebuffers.cpp b/src/renderer/context_webgl_framebuffers.cpp new file mode 100644 index 000000000..0c4a6dc6d --- /dev/null +++ b/src/renderer/context_webgl_framebuffers.cpp @@ -0,0 +1,188 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glBindFramebuffer(WebGLenum target, WebGLuint framebuffer) + { + if (!glIsFramebuffer(framebuffer)) [[unlikely]] + { + last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; + return; + } + + if (target != WEBGL_FRAMEBUFFER && + target != WEBGL2_DRAW_FRAMEBUFFER && + target != WEBGL2_READ_FRAMEBUFFER) [[unlikely]] + { + last_error_ = WEBGL_INVALID_ENUM; + return; + } + + for (auto &binding : framebuffer_bindings_) + { + if (binding.framebuffer == framebuffer) + { + binding.target = target; + break; + } + } + } + + void TrContextWebGL::glBindRenderbuffer(WebGLenum target, WebGLuint renderbuffer) + { + if (!glIsRenderbuffer(renderbuffer)) [[unlikely]] + { + last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; + return; + } + + if (target != WEBGL_RENDERBUFFER) [[unlikely]] + { + last_error_ = WEBGL_INVALID_ENUM; + return; + } + + for (auto &binding : renderbuffer_bindings_) + { + if (binding.renderbuffer == renderbuffer) + { + binding.target = target; + break; + } + } + } + + void TrContextWebGL::glBlitFramebuffer(WebGLint srcX0, + WebGLint srcY0, + WebGLint srcX1, + WebGLint srcY1, + WebGLint dstX0, + WebGLint dstY0, + WebGLint dstX1, + WebGLint dstY1, + WebGLbitfield mask, + WebGLenum filter) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glCheckFramebufferStatus(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteFramebuffers(WebGLsizei n, const WebGLuint *framebuffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteRenderbuffers(WebGLsizei n, const WebGLuint *renderbuffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDrawBuffers(WebGLsizei n, const WebGLenum *buffers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum renderbuffertarget, WebGLuint renderbuffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFramebufferTexture2D(WebGLenum target, WebGLenum attachment, WebGLenum textarget, WebGLuint texture, WebGLint level) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFramebufferTextureLayer(WebGLenum target, WebGLenum attachment, WebGLuint texture, WebGLint level, WebGLint layer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenFramebuffers(WebGLsizei n, WebGLuint *framebuffers) + { + glGenObjects(framebuffers_, n, framebuffers); + } + + void TrContextWebGL::glGenRenderbuffers(WebGLsizei n, WebGLuint *renderbuffers) + { + glGenObjects(renderbuffers_, n, renderbuffers); + } + + void TrContextWebGL::glGenerateMipmap(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetFramebufferAttachmentParameteriv(WebGLenum target, WebGLenum attachment, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetRenderbufferParameteriv(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glInvalidateFramebuffer(WebGLenum target, WebGLsizei n, const WebGLenum *attachments) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glInvalidateSubFramebuffer(WebGLenum target, + WebGLsizei n, + const WebGLenum *attachments, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height) + { + /* TODO(yorkie): implement */ + } + + WebGLboolean TrContextWebGL::glIsFramebuffer(WebGLuint framebuffer) + { + for (const auto &binding : framebuffer_bindings_) + { + if (binding.framebuffer == framebuffer) + { + return true; + } + } + return false; + } + + WebGLboolean TrContextWebGL::glIsRenderbuffer(WebGLuint renderbuffer) + { + for (const auto &binding : renderbuffer_bindings_) + { + if (binding.renderbuffer == renderbuffer) + { + return true; + } + } + return false; + } + + void TrContextWebGL::glRenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glRenderbufferStorageMultisample(WebGLenum target, + WebGLsizei samples, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_queries.cpp b/src/renderer/context_webgl_queries.cpp new file mode 100644 index 000000000..b59b2e007 --- /dev/null +++ b/src/renderer/context_webgl_queries.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glBeginQuery(WebGLenum target, WebGLuint id) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteQueries(WebGLsizei n, const WebGLuint *ids) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glEndQuery(WebGLenum target) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenQueries(WebGLsizei n, WebGLuint *ids) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetQueryObjectuiv(WebGLuint id, WebGLenum pname, WebGLuint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetQueryiv(WebGLenum target, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsQuery(WebGLuint id) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_rendering.cpp b/src/renderer/context_webgl_rendering.cpp new file mode 100644 index 000000000..2a75ab407 --- /dev/null +++ b/src/renderer/context_webgl_rendering.cpp @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + // --- Rendering --- + void TrContextWebGL::glClear(WebGLbitfield mask) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferiv(WebGLenum buffer, + WebGLint drawbuffer, + const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferuiv(WebGLenum buffer, + WebGLint drawbuffer, + const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferfv(WebGLenum buffer, + WebGLint drawbuffer, + const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearBufferfi(WebGLenum buffer, + WebGLint drawbuffer, + WebGLfloat depth, + WebGLint stencil) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glClearColor(WebGLfloat red, + WebGLfloat green, + WebGLfloat blue, + WebGLfloat alpha) + { + clear_color_[0] = red; + clear_color_[1] = green; + clear_color_[2] = blue; + clear_color_[3] = alpha; + } + + void TrContextWebGL::glClearDepthf(WebGLfloat depth) + { + clear_depth_ = depth; + } + + void TrContextWebGL::glClearStencil(WebGLint s) + { + clear_stencil_ = s; + } + + void TrContextWebGL::glFinish() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glFlush() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glReadBuffer(WebGLenum buffer) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glReadPixels(WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height, + WebGLenum format, + WebGLenum type, + WebGLvoid *pixels) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_samplers.cpp b/src/renderer/context_webgl_samplers.cpp new file mode 100644 index 000000000..ecd5aa024 --- /dev/null +++ b/src/renderer/context_webgl_samplers.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glBindSampler(WebGLuint unit, WebGLuint sampler) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteSamplers(WebGLsizei n, const WebGLuint *samplers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenSamplers(WebGLsizei n, WebGLuint *samplers) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsSampler(WebGLuint sampler) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_shaders.cpp b/src/renderer/context_webgl_shaders.cpp new file mode 100644 index 000000000..dbc725f10 --- /dev/null +++ b/src/renderer/context_webgl_shaders.cpp @@ -0,0 +1,488 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glBindAttribLocation(WebGLuint program, WebGLuint index, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glCompileShader(WebGLuint shader) + { + /* TODO(yorkie): implement */ + } + + WebGLuint TrContextWebGL::glCreateProgram() + { + WebGLuint id = programs_.size(); + const Program program = { + .id = id, // Use the index as the default id. + .vertex_shader = nullopt, + .fragment_shader = nullopt, + }; + programs_.push_back(program); + return program.id; + } + + WebGLuint TrContextWebGL::glCreateShader(WebGLenum type) + { + WebGLuint id = shader_modules_.size(); + const ShaderModule shader_module = { + .id = id, // Use the index as the default id. + .type = type, + }; + shader_modules_.push_back(shader_module); + return shader_module.id; + } + + void TrContextWebGL::glDeleteProgram(WebGLuint program) + { + for (auto it = programs_.begin(); it != programs_.end(); it++) + { + if (it->id == program) + { + programs_.erase(it); + return; + } + } + } + + void TrContextWebGL::glDeleteShader(WebGLuint shader) + { + for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) + { + if (it->id == shader) + { + shader_modules_.erase(it); + return; + } + } + } + + void TrContextWebGL::glAttachShader(WebGLuint program, WebGLuint shader) + { + ShaderModule *shader_module = nullptr; + for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) + { + if (it->id == shader) + { + shader_module = &*it; + break; + } + } + + if (shader_module == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + for (auto it = programs_.begin(); it != programs_.end(); it++) + { + if (it->id == program) + { + if (shader_module->type == WEBGL_VERTEX_SHADER) + it->vertex_shader = make_optional(*shader_module); + else if (shader_module->type == WEBGL_FRAGMENT_SHADER) + it->fragment_shader = make_optional(*shader_module); + else [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + } + return; + } + } + } + + void TrContextWebGL::glDetachShader(WebGLuint program, WebGLuint shader) + { + ShaderModule *shader_module = nullptr; + for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) + { + if (it->id == shader) + { + shader_module = &*it; + break; + } + } + + if (shader_module == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + for (auto it = programs_.begin(); it != programs_.end(); it++) + { + if (it->id == program) + { + if (shader_module->type == WEBGL_VERTEX_SHADER) + it->vertex_shader = nullopt; + else if (shader_module->type == WEBGL_FRAGMENT_SHADER) + it->fragment_shader = nullopt; + else [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + } + return; + } + } + } + + void TrContextWebGL::glGetActiveAttrib(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLint *size, + WebGLenum *type, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniform(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLint *size, + WebGLenum *type, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniformBlockName(WebGLuint program, + WebGLuint index, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniformBlockiv(WebGLuint program, + WebGLuint index, + WebGLenum pname, + WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetActiveUniformsiv(WebGLuint program, + WebGLsizei count, + const WebGLuint *uniforms, + WebGLenum pname, + WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetAttachedShaders(WebGLuint program, WebGLsizei maxCount, WebGLsizei *count, WebGLuint *shaders) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetAttribLocation(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetFragDataLocation(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetProgramBinary(WebGLuint program, + WebGLsizei maxLength, + WebGLsizei *length, + WebGLenum binaryFormat, + WebGLsizei *binaryLength, + WebGLbyte *binary) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetProgramInfoLog(WebGLuint program, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetProgramiv(WebGLuint program, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderInfoLog(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *infoLog) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype, WebGLint *range, WebGLint *precision) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderSource(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *source) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetShaderiv(WebGLuint shader, WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformfv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLfloat *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformuiv(WebGLuint program, WebGLuint location, WebGLsizei count, WebGLuint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformBlockIndex(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformIndices(WebGLuint program, WebGLsizei count, const WebGLchar **names, WebGLuint *indices) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetUniformLocation(WebGLuint program, const WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsShader(WebGLuint shader) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glLinkProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glProgramBinary(WebGLuint program, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glProgramParameteri(WebGLuint program, WebGLenum pname, WebGLint param) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glReleaseShaderCompiler() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glShaderBinary(WebGLuint shader, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glShaderSource(WebGLuint shader, WebGLsizei count, const WebGLchar **string, const WebGLint *length) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1f(WebGLuint location, WebGLfloat v0) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2f(WebGLuint location, WebGLfloat v0, WebGLfloat v1) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1i(WebGLuint location, WebGLint v0) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2i(WebGLuint location, WebGLint v0, WebGLint v1) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1ui(WebGLuint location, WebGLuint v0) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2ui(WebGLuint location, WebGLuint v0, WebGLuint v1) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2, WebGLuint v3) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4iv(WebGLuint location, WebGLsizei count, const WebGLint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform1uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform2uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform3uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniform4uiv(WebGLuint location, WebGLsizei count, const WebGLuint *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix2x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix3x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix2x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix4x2fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix3x4fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformMatrix4x3fv(WebGLuint location, WebGLsizei count, WebGLboolean transpose, const WebGLfloat *value) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUniformBlockBinding(WebGLuint program, WebGLuint uniformBlockIndex, WebGLuint bindingPoint) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glUseProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glValidateProgram(WebGLuint program) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_states.cpp b/src/renderer/context_webgl_states.cpp new file mode 100644 index 000000000..dc177d89a --- /dev/null +++ b/src/renderer/context_webgl_states.cpp @@ -0,0 +1,193 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + + // --- State Management --- + void TrContextWebGL::glBlendColor(WebGLfloat red, + WebGLfloat green, + WebGLfloat blue, + WebGLfloat alpha) + { + blend_color_[0] = red; + blend_color_[1] = green; + blend_color_[2] = blue; + blend_color_[3] = alpha; + } + + void TrContextWebGL::glBlendEquation(WebGLenum mode) + { + blend_equation_rgb_ = mode; + blend_equation_alpha_ = mode; + } + + void TrContextWebGL::glBlendEquationSeparate(WebGLenum mode_rgb, WebGLenum mode_alpha) + { + blend_equation_rgb_ = mode_rgb; + blend_equation_alpha_ = mode_alpha; + } + + void TrContextWebGL::glBlendFunc(WebGLenum sfactor, WebGLenum dfactor) + { + blend_sfactor_rgb_ = sfactor; + blend_dfactor_rgb_ = dfactor; + blend_sfactor_alpha_ = sfactor; + blend_dfactor_alpha_ = dfactor; + } + + void TrContextWebGL::glBlendFuncSeparate(WebGLenum src_rgb, + WebGLenum dst_rgb, + WebGLenum src_alpha, + WebGLenum dst_alpha) + { + blend_sfactor_rgb_ = src_rgb; + blend_dfactor_rgb_ = dst_rgb; + blend_sfactor_alpha_ = src_alpha; + blend_dfactor_alpha_ = dst_alpha; + } + + void TrContextWebGL::glColorMask(WebGLboolean red, + WebGLboolean green, + WebGLboolean blue, + WebGLboolean alpha) + { + color_mask_[0] = red; + color_mask_[1] = green; + color_mask_[2] = blue; + color_mask_[3] = alpha; + } + + void TrContextWebGL::glCullFace(WebGLenum mode) + { + cull_face_ = mode; + } + + void TrContextWebGL::glDepthFunc(WebGLenum func) + { + depth_func_ = func; + } + + void TrContextWebGL::glDepthMask(WebGLboolean flag) + { + depth_mask_ = flag; + } + + void TrContextWebGL::glDepthRangef(WebGLfloat near, WebGLfloat far) + { + depth_range_[0] = near; + depth_range_[1] = far; + } + + void TrContextWebGL::glDisable(WebGLenum cap) + { + caps_.disable(cap); + } + + void TrContextWebGL::glEnable(WebGLenum cap) + { + caps_.enable(cap); + } + + void TrContextWebGL::glFrontFace(WebGLenum mode) + { + front_face_ = mode; + } + + void TrContextWebGL::glGet(WebGLenum pname, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + WebGLenum TrContextWebGL::glGetError() + { + WebGLenum error = last_error_; + last_error_ = WEBGL_NO_ERROR; + return error; + } + + void TrContextWebGL::glHint(WebGLenum target, WebGLenum mode) + { /* TODO(yorkie): implement */ + } + + WebGLboolean TrContextWebGL::glIsEnabled(WebGLenum cap) + { + return caps_.isEnabled(cap); + } + + void TrContextWebGL::glLineWidth(WebGLfloat width) + { + line_width_ = width; + } + + void TrContextWebGL::glPixelStorei(WebGLenum pname, WebGLint param) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glPolygonOffset(WebGLfloat factor, WebGLfloat units) + { + polygon_offset_factor_ = factor; + polygon_offset_units_ = units; + } + + void TrContextWebGL::glSampleCoverage(WebGLfloat value, WebGLboolean invert) + { + sample_coverage_value_ = value; + sample_coverage_invert_ = invert; + } + + void TrContextWebGL::glScissor(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) + { + scissor_box_[0] = x; + scissor_box_[1] = y; + scissor_box_[2] = width; + scissor_box_[3] = height; + } + + void TrContextWebGL::glStencilFunc(WebGLenum func, WebGLint ref, WebGLuint mask) + { + stencil_func_ = func; + stencil_ref_ = ref; + stencil_mask_ = mask; + } + + void TrContextWebGL::glStencilFuncSeparate(WebGLenum face, + WebGLenum func, + WebGLint ref, + WebGLuint mask) + { + stencil_func_ = func; + stencil_ref_ = ref; + stencil_mask_ = mask; + } + + void TrContextWebGL::glStencilMask(WebGLuint mask) + { + stencil_mask_ = mask; + } + + void TrContextWebGL::glStencilMaskSeparate(WebGLenum face, WebGLuint mask) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glStencilOp(WebGLenum fail, WebGLenum zfail, WebGLenum zpass) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glStencilOpSeparate(WebGLenum face, WebGLenum fail, WebGLenum zfail, WebGLenum zpass) + { /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glViewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height) + { + viewport_[0] = x; + viewport_[1] = y; + viewport_[2] = width; + viewport_[3] = height; + } +} diff --git a/src/renderer/context_webgl_syncing.cpp b/src/renderer/context_webgl_syncing.cpp new file mode 100644 index 000000000..7d1c96fe0 --- /dev/null +++ b/src/renderer/context_webgl_syncing.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glClientWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteSync(WebGLsync sync) + { + /* TODO(yorkie): implement */ + } + + WebGLsync TrContextWebGL::glFenceSync(WebGLenum condition, WebGLbitfield flags) + { + /* TODO(yorkie): implement */ + return nullptr; + } + + void TrContextWebGL::glGetSynciv(WebGLsync sync, WebGLenum pname, WebGLsizei bufSize, WebGLsizei *length, WebGLint *values) + { + /* TODO(yorkie): implement */ + } + + WebGLboolean TrContextWebGL::glIsSync(WebGLsync sync) + { + /* TODO(yorkie): implement */ + return false; + } + + void TrContextWebGL::glWaitSync(WebGLsync sync, WebGLbitfield flags, WebGLuint64 timeout) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_texture.cpp b/src/renderer/context_webgl_texture.cpp new file mode 100644 index 000000000..c3618a698 --- /dev/null +++ b/src/renderer/context_webgl_texture.cpp @@ -0,0 +1,213 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glActiveTexture(WebGLenum texture) + { + active_texture_ = texture; + } + + void TrContextWebGL::glBindTexture(WebGLenum target, WebGLuint texture) + { + texture_bindings_[TextureTarget(target)] = {target, texture}; + } + + void TrContextWebGL::glCopyTexImage2D(WebGLenum target, + WebGLenum internalformat, + WebGLint level, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height, + WebGLint border) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCopyTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint x, + WebGLint y, + WebGLsizei width, + WebGLsizei height) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glDeleteTextures(WebGLsizei n, const WebGLuint *textures) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glGenTextures(WebGLsizei n, WebGLuint *textures) + { + glGenObjects(textures_, n, textures); + } + + void TrContextWebGL::glGetTexParameter(WebGLenum target, WebGLenum pname, WebGLint *params) + { + // TODO(yorkie): implement + } + + WebGLboolean TrContextWebGL::glIsTexture(WebGLuint texture) + { + // TODO(yorkie): implement + return true; + } + + void TrContextWebGL::glTexImage2D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei border, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexImage3D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLsizei border, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + // --- Additional texture APIs --- + void TrContextWebGL::glCompressedTexImage2D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei border, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCompressedTexImage3D(WebGLenum target, + WebGLint level, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLsizei border, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCompressedTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLsizei width, + WebGLsizei height, + WebGLenum format, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glCompressedTexSubImage3D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint zoffset, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLenum format, + WebGLsizei imageSize, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameterf(WebGLenum target, WebGLenum pname, WebGLfloat param) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameteri(WebGLenum target, WebGLenum pname, WebGLint param) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameterfv(WebGLenum target, WebGLenum pname, const WebGLfloat *params) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexParameteriv(WebGLenum target, WebGLenum pname, const WebGLint *params) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexStorage2D(WebGLenum target, + WebGLint levels, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexStorage3D(WebGLenum target, + WebGLint levels, + WebGLenum internalformat, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexSubImage2D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLsizei width, + WebGLsizei height, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } + + void TrContextWebGL::glTexSubImage3D(WebGLenum target, + WebGLint level, + WebGLint xoffset, + WebGLint yoffset, + WebGLint zoffset, + WebGLsizei width, + WebGLsizei height, + WebGLsizei depth, + WebGLenum format, + WebGLenum type, + const WebGLvoid *data) + { + // TODO(yorkie): implement + } +} diff --git a/src/renderer/context_webgl_transform_feedback.cpp b/src/renderer/context_webgl_transform_feedback.cpp new file mode 100644 index 000000000..ebda623bb --- /dev/null +++ b/src/renderer/context_webgl_transform_feedback.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glBeginTransformFeedback(WebGLenum primitiveMode) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glBindTransformFeedback(WebGLenum target, WebGLuint transformFeedback) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteTransformFeedbacks(WebGLsizei n, const WebGLuint *transformFeedbacks) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glEndTransformFeedback() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenTransformFeedbacks(WebGLsizei n, WebGLuint *transformFeedbacks) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetTransformFeedbackVarying(WebGLuint program, + WebGLuint index, + WebGLsizei bufSize, + WebGLsizei *length, + WebGLsizei *size, + WebGLenum *type, + WebGLchar *name) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsTransformFeedback(WebGLuint transformFeedback) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glPauseTransformFeedback() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glResumeTransformFeedback() + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glTransformFeedbackVaryings(WebGLuint program, + WebGLsizei count, + const WebGLchar **varyings, + WebGLenum bufferMode) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_utility.cpp b/src/renderer/context_webgl_utility.cpp new file mode 100644 index 000000000..a301f54f6 --- /dev/null +++ b/src/renderer/context_webgl_utility.cpp @@ -0,0 +1,25 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glGetInternalformativ(WebGLenum target, WebGLenum internalformat, WebGLsizei propCount, WebGLenum *props, WebGLint *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetString(WebGLenum pname, WebGLchar *params) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGetStringi(WebGLenum pname, WebGLuint index) + { + /* TODO(yorkie): implement */ + } +} diff --git a/src/renderer/context_webgl_vao.cpp b/src/renderer/context_webgl_vao.cpp new file mode 100644 index 000000000..907359577 --- /dev/null +++ b/src/renderer/context_webgl_vao.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +namespace renderer +{ + using namespace std; + using namespace commandbuffers; + + void TrContextWebGL::glBindVertexArray(WebGLuint array) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glDeleteVertexArrays(WebGLsizei n, const WebGLuint *arrays) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glGenVertexArrays(WebGLsizei n, WebGLuint *arrays) + { + /* TODO(yorkie): implement */ + } + + void TrContextWebGL::glIsVertexArray(WebGLuint array) + { + /* TODO(yorkie): implement */ + } +} From 84b7dccf8a94176dbdfe0430e137b848e16f6677 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Sat, 29 Nov 2025 02:57:11 +0800 Subject: [PATCH 34/37] implement texture --- .../command_buffers/gpu/gpu_texture.hpp | 9 + src/renderer/context_webgl.cpp | 142 ++++++--- src/renderer/context_webgl.hpp | 274 +++++++++++++----- src/renderer/context_webgl_buffers.cpp | 29 +- src/renderer/context_webgl_framebuffers.cpp | 52 +--- src/renderer/context_webgl_shaders.cpp | 110 ++----- src/renderer/context_webgl_texture.cpp | 66 ++++- 7 files changed, 409 insertions(+), 273 deletions(-) diff --git a/src/common/command_buffers/gpu/gpu_texture.hpp b/src/common/command_buffers/gpu/gpu_texture.hpp index 2fb9289f6..8a10499f0 100644 --- a/src/common/command_buffers/gpu/gpu_texture.hpp +++ b/src/common/command_buffers/gpu/gpu_texture.hpp @@ -8,6 +8,15 @@ namespace commandbuffers struct GPUTextureDescriptor { + std::string_view label; + GPUTextureUsage usage = GPUTextureUsage::kNone; + GPUTextureDimension dimension = GPUTextureDimension::k2D; + GPUExtent3D size; + GPUTextureFormat format = GPUTextureFormat::kUndefined; + uint32_t mipLevelCount = 1; + uint32_t sampleCount = 1; + size_t viewFormatCount = 0; + GPUTextureFormat const *viewFormats = nullptr; }; class GPUTextureBase : public GPUHandle diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index 9411876d5..f28bc629b 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -1,4 +1,3 @@ -#include #include #include @@ -12,14 +11,94 @@ namespace renderer using namespace std; using namespace commandbuffers; - string TrContextWebGL::ShaderModule::toString() const + namespace details { - string type_str = "Unknown"; - if (type == WEBGL_VERTEX_SHADER) - type_str = "Vertex"; - else if (type == WEBGL_FRAGMENT_SHADER) - type_str = "Fragment"; - return "ShaderModule(" + type_str + " id=" + to_string(id) + ")"; + ObjectBase::ObjectBase(WebGLuint id) + : id(id) + { + } + + bool ObjectBase::isTexture() const + { + return false; + } + + bool ObjectBase::isBuffer() const + { + return false; + } + + bool ObjectBase::isFramebuffer() const + { + return false; + } + + bool ObjectBase::isRenderbuffer() const + { + return false; + } + + string ObjectBase::toString() const + { + return to_string(id); + } + + void ObjectBase::set(WebGLuint id) + { + this->id = id; + } + + void BindableObject::setTarget(const ObjectTargetBase &target) + { + this->target = target.value(); + } + + ShaderModule::ShaderModule(WebGLuint id, WebGLenum type) + : ObjectBase(id) + , type(type) + { + assert(type == WEBGL_VERTEX_SHADER || + type == WEBGL_FRAGMENT_SHADER); + } + + string ShaderModule::toString() const + { + string type_str = "Unknown"; + if (type == WEBGL_VERTEX_SHADER) + type_str = "Vertex"; + else if (type == WEBGL_FRAGMENT_SHADER) + type_str = "Fragment"; + return "ShaderModule(" + type_str + " id=" + to_string(id) + ")"; + } + + Program::Program(WebGLuint id) + : ObjectBase(id) + , vertexShader(nullptr) + , fragmentShader(nullptr) + { + } + + string Texture::toString() const + { + string target_str = "Unknown"; + if (target == WEBGL_TEXTURE_2D) + target_str = "2D"; + else if (target == WEBGL2_TEXTURE_2D_ARRAY) + target_str = "2D[]"; + else if (target == WEBGL2_TEXTURE_3D) + target_str = "3D"; + else if (target == WEBGL_TEXTURE_CUBE_MAP) + target_str = "CubeMap"; + + return "Texture(" + target_str + " id=" + to_string(id) + ")"; + } + + void Texture::setSize(WebGLsizei width, WebGLsizei height, WebGLsizei depth) + { + size[0] = width; + size[1] = height; + size[2] = depth; + } } TrContextWebGL::TrContextWebGL(Ref content_renderer) @@ -84,7 +163,7 @@ namespace renderer } case COMMAND_BUFFER_CREATE_TEXTURE_REQ: { - glCreateTypedObject(textures_, req); + glCreateTypedObject(textures_, req); break; } case COMMAND_BUFFER_TEXTURE_IMAGE_2D_REQ: @@ -329,12 +408,14 @@ namespace renderer } case COMMAND_BUFFER_CREATE_FRAMEBUFFER_REQ: { - glCreateTypedObject(framebuffers_, req); + glCreateTypedObject(framebuffers_, req); break; } case COMMAND_BUFFER_CREATE_RENDERBUFFER_REQ: { - glCreateTypedObject(renderbuffers_, req); + glCreateTypedObject(renderbuffers_, req); break; } case COMMAND_BUFFER_GENERATE_MIPMAP_REQ: @@ -382,14 +463,14 @@ namespace renderer { const auto &typed_req = To(req); auto index = glCreateProgram(); - programs_[index].id = req.id; // Modify the id to the request id. + programs_[index]->set(req.id); break; } case COMMAND_BUFFER_CREATE_SHADER_REQ: { const auto &typed_req = To(req); auto index = glCreateShader(typed_req.shaderType); - shader_modules_[index].id = req.id; // Modify the id to the request id. + shader_modules_[index]->set(req.id); break; } case COMMAND_BUFFER_DELETE_PROGRAM_REQ: @@ -701,7 +782,8 @@ namespace renderer } case COMMAND_BUFFER_CREATE_BUFFER_REQ: { - glCreateTypedObject(buffers_, req); + glCreateTypedObject(buffers_, req); break; } case COMMAND_BUFFER_VERTEX_ATTRIB_1F_REQ: @@ -962,42 +1044,14 @@ namespace renderer } } - void TrContextWebGL::glGenObjects(std::vector &source_list, - WebGLsizei n, - WebGLuint *generated_list) - { - if (n <= 0 || generated_list == nullptr) - return; - - size_t old_size = source_list.size(); - WebGLuint initial_value = 0x0; - source_list.resize(old_size + static_cast(n)); - std::fill(source_list.begin() + old_size, - source_list.end(), - initial_value); - - for (size_t i = 0; i < n; i++) - { - generated_list[i] = source_list[old_size + i]; - } - } - void TrContextWebGL::debugPrintPrograms(int depth) { - debugPrintObjects("Programs", - programs_, - depth, - [](const Program &program) - { return to_string(program.id); }); + debugPrintObjects("Programs", programs_, depth); } void TrContextWebGL::debugPrintShaderModules(int depth) { - auto print_shader = [](const ShaderModule &module) - { - return module.toString(); - }; - debugPrintObjects("Shader Modules", shader_modules_, depth, print_shader); + debugPrintObjects("Shader Modules", shader_modules_, depth); } void TrContextWebGL::debugPrintBuffers(int depth) diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index 93163569b..be57ea5e4 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -1,21 +1,21 @@ #pragma once +#include #include -#include +#include #include + +#include #include #include +#include namespace renderer { class TrContentRenderer; - class TrContextWebGL + namespace details { - public: - TrContextWebGL(Ref content_renderer); - ~TrContextWebGL(); - class ObjectTargetBase { public: @@ -46,39 +46,39 @@ namespace renderer WebGLenum target_; }; - class TextureTarget final : public ObjectTargetBase + class BufferTarget final : public ObjectTargetBase { public: enum { - k2D = WEBGL_TEXTURE_2D, - k3D = WEBGL2_TEXTURE_3D, - k2DArray = WEBGL2_TEXTURE_2D_ARRAY, + kArrayBuffer = WEBGL_ARRAY_BUFFER, + kElementArrayBuffer = WEBGL_ELEMENT_ARRAY_BUFFER, }; - TextureTarget(WebGLenum target) + BufferTarget(WebGLenum target) : ObjectTargetBase(target) { - assert(target_ == k2D || - target_ == k3D || - target_ == k2DArray); + assert(target_ == kArrayBuffer || + target_ == kElementArrayBuffer); } }; - class BufferTarget final : public ObjectTargetBase + class TextureTarget final : public ObjectTargetBase { public: enum { - kArrayBuffer = WEBGL_ARRAY_BUFFER, - kElementArrayBuffer = WEBGL_ELEMENT_ARRAY_BUFFER, + k2D = WEBGL_TEXTURE_2D, + k3D = WEBGL2_TEXTURE_3D, + k2DArray = WEBGL2_TEXTURE_2D_ARRAY, }; - BufferTarget(WebGLenum target) + TextureTarget(WebGLenum target) : ObjectTargetBase(target) { - assert(target_ == kArrayBuffer || - target_ == kElementArrayBuffer); + assert(target_ == k2D || + target_ == k3D || + target_ == k2DArray); } }; @@ -116,28 +116,97 @@ namespace renderer } }; - struct TextureBinding + class ObjectBase { + public: + ObjectBase() = default; + ObjectBase(WebGLuint id); + virtual ~ObjectBase() = default; + + virtual bool isTexture() const; + virtual bool isBuffer() const; + virtual bool isFramebuffer() const; + virtual bool isRenderbuffer() const; + virtual std::string toString() const; + + void set(WebGLuint id); + WebGLuint id; + }; + + struct BindableObject : public ObjectBase + { + using ObjectBase::ObjectBase; + + public: + void setTarget(const ObjectTargetBase &); + WebGLenum target; - WebGLuint texture; }; - struct BufferBinding + struct ShaderModule final : public ObjectBase { - std::optional target; - WebGLuint buffer; + public: + ShaderModule(WebGLuint id, WebGLenum type); + std::string toString() const; + + WebGLenum type; }; - struct FramebufferBinding + struct Program final : public ObjectBase { - std::optional target; - WebGLuint framebuffer; + public: + Program(WebGLuint id); + + Ref vertexShader; + Ref fragmentShader; }; - struct RenderbufferBinding + struct Texture final : public BindableObject { - std::optional target; - WebGLuint renderbuffer; + using BindableObject::BindableObject; + + public: + bool isTexture() const override + { + return true; + } + std::string toString() const override; + void setSize(WebGLsizei width, WebGLsizei height, WebGLsizei depth = 0); + + WebGLsizei size[3]; + WebGLsizei mipLevels; + WebGLenum internalformat; + WebGLenum compressedInternalformat; + }; + + struct Buffer final : public BindableObject + { + using BindableObject::BindableObject; + + bool isBuffer() const override + { + return true; + } + }; + + struct Framebuffer final : public BindableObject + { + using BindableObject::BindableObject; + + bool isFramebuffer() const override + { + return true; + } + }; + + struct Renderbuffer final : public BindableObject + { + using BindableObject::BindableObject; + + bool isRenderbuffer() const override + { + return true; + } }; struct Capabilities @@ -163,6 +232,13 @@ namespace renderer private: Map caps_; }; + } + + class TrContextWebGL + { + public: + TrContextWebGL(Ref content_renderer); + ~TrContextWebGL(); void receiveIncomingCall(const commandbuffers::TrCommandBufferRequest &); @@ -593,9 +669,25 @@ namespace renderer void glSamplerParameter(WebGLuint sampler, WebGLenum pname, WebGLint param); // Internal Utilities - void glGenObjects(std::vector &source_list, - WebGLsizei n, - WebGLuint *generated_list); + template + requires std::is_base_of_v + void glGenTypedObjects(std::vector> &source_list, + WebGLsizei n, + WebGLuint *generated_list) + { + if (n <= 0 || generated_list == nullptr) + return; + + size_t old_size = source_list.size(); + source_list.resize(old_size + static_cast(n)); + + for (size_t i = 0; i < n; i++) + { + Ref object = AcquireRef(new ObjectType()); + source_list[old_size + i] = object; + generated_list[i] = object->id; + } + } /** * A convenience function to create a WebGL object such as buffer, texture, framebuffer, renderbuffer in this context implementation. @@ -604,28 +696,31 @@ namespace renderer * @param source_list A list of WebGL objects to store the created object. * @param req A request to create a WebGL object. */ - template - void glCreateTypedObject(std::vector &source_list, const commandbuffers::TrCommandBufferRequest &req) + template + requires std::is_base_of_v + void glCreateTypedObject(std::vector> &source_list, + const commandbuffers::TrCommandBufferRequest &req) { const auto &typed_req = To(req); size_t size_before = source_list.size(); { WebGLint obj; - glGenObjects(source_list, 1, (WebGLuint *)&obj); + glGenTypedObjects(source_list, 1, (WebGLuint *)&obj); assert(obj == 0 && "object must be the initial object"); } - source_list[size_before] = req.id; + + Ref created_object = source_list[size_before]; + assert(created_object != nullptr && "object must be created"); + created_object->set(req.id); debugPrint(); } // Debug Utilities template - void debugPrintObjects( - const string &label, - const vector &list, - int depth = 0, - std::function print_func = [](const ObjectType &obj) - { return std::to_string(obj); }) + requires std::is_base_of_v + void debugPrintObjects(const std::string &label, + const std::vector> &list, + int depth = 0) { const std::string prefix = std::string(depth, ' '); @@ -644,7 +739,7 @@ namespace renderer cerr << endl; int n = 0; for (const auto &obj : list) - cerr << prefix << " ." << n++ << " = " << print_func(obj) << endl; + cerr << prefix << " ." << n++ << " = " << obj->toString() << endl; cerr << prefix << "}"; } cerr << endl; @@ -660,34 +755,69 @@ namespace renderer Ref content_renderer_; - std::vector buffers_; - std::vector textures_; - std::vector framebuffers_; - std::vector renderbuffers_; - - std::vector buffer_bindings_; - std::vector framebuffer_bindings_; - std::vector renderbuffer_bindings_; - std::unordered_map texture_bindings_; - struct ShaderModule + template + class ObjectList : public std::vector> { - WebGLuint id; - WebGLenum type; + using Base = std::vector>; + using Base::Base; - std::string toString() const; + public: + Ref get(WebGLuint id) + { + for (const auto &obj : *this) + { + if (obj->id == id) + return obj; + } + return nullptr; + } + + bool has(WebGLuint id) + { + return get(id) != nullptr; + } + + bool remove(WebGLuint id) + { + for (auto it = this->begin(); it != this->end(); it++) + { + if ((*it)->id == id) + { + this->erase(it); + return true; + } + } + return false; + } }; - std::vector shader_modules_; - struct Program + + ObjectList shader_modules_; + ObjectList programs_; + + ObjectList buffers_; + ObjectList textures_; + ObjectList framebuffers_; + ObjectList renderbuffers_; + + template + class BindingMap : public std::unordered_map, typename Target::HashKey> { - WebGLuint id; - std::optional vertex_shader; - std::optional fragment_shader; + using Base = std::unordered_map, typename Target::HashKey>; + using Base::Base; }; - std::vector programs_; + using BufferBindingMap = BindingMap; + using TextureBindingMap = BindingMap; + using FramebufferBindingMap = BindingMap; + using RenderbufferBindingMap = BindingMap; + + BufferBindingMap buffer_bindings_; + TextureBindingMap texture_bindings_; + FramebufferBindingMap framebuffer_bindings_; + RenderbufferBindingMap renderbuffer_bindings_; WebGLenum last_error_ = WEBGL_NO_ERROR; - Capabilities caps_; - WebGLenum active_texture_; + details::Capabilities caps_; + WebGLenum active_texture_unit_ = WEBGL_TEXTURE0; WebGLfloat clear_color_[4]; WebGLfloat clear_depth_; @@ -721,15 +851,3 @@ namespace renderer WebGLint viewport_[4]; }; } - -namespace std -{ - template <> - struct hash - { - size_t operator()(const renderer::TrContextWebGL::TextureTarget &t) const noexcept - { - return std::hash{}(t.value()); - } - }; -} diff --git a/src/renderer/context_webgl_buffers.cpp b/src/renderer/context_webgl_buffers.cpp index 4717c4b66..00dacbf86 100644 --- a/src/renderer/context_webgl_buffers.cpp +++ b/src/renderer/context_webgl_buffers.cpp @@ -8,22 +8,17 @@ namespace renderer using namespace std; using namespace commandbuffers; - void TrContextWebGL::glBindBuffer(WebGLenum target, WebGLuint buffer) + void TrContextWebGL::glBindBuffer(WebGLenum target, WebGLuint id) { - if (!glIsBuffer(buffer)) [[unlikely]] + auto buffer = buffers_.get(id); + if (!buffer) [[unlikely]] { last_error_ = WEBGL_INVALID_OPERATION; return; } - for (auto &binding : buffer_bindings_) - { - if (binding.buffer == buffer) - { - binding.target = target; - break; - } - } + auto buffer_target = details::BufferTarget(target); + buffer_bindings_[buffer_target] = buffer; } void TrContextWebGL::glBindBufferBase(WebGLenum target, @@ -73,7 +68,8 @@ namespace renderer { for (auto it = buffers_.begin(); it != buffers_.end(); ++it) { - if (*it == buffers[i]) + Ref buffer = *it; + if (buffer->id == buffers[i]) { buffers_.erase(it); break; @@ -130,7 +126,7 @@ namespace renderer void TrContextWebGL::glGenBuffers(WebGLsizei n, WebGLuint *buffers) { - glGenObjects(buffers_, n, buffers); + glGenTypedObjects(buffers_, n, buffers); } void TrContextWebGL::glGetBufferParameter(WebGLenum target, WebGLenum pname, WebGLint *params) @@ -160,14 +156,7 @@ namespace renderer WebGLboolean TrContextWebGL::glIsBuffer(WebGLuint buffer) { - for (const auto &binding : buffer_bindings_) - { - if (binding.buffer == buffer) - { - return true; - } - } - return false; + return buffers_.has(buffer); } void TrContextWebGL::glMapBufferRange(WebGLenum target, WebGLintptr offset, WebGLsizeiptr length, WebGLbitfield access) diff --git a/src/renderer/context_webgl_framebuffers.cpp b/src/renderer/context_webgl_framebuffers.cpp index 0c4a6dc6d..769cd514b 100644 --- a/src/renderer/context_webgl_framebuffers.cpp +++ b/src/renderer/context_webgl_framebuffers.cpp @@ -8,9 +8,10 @@ namespace renderer using namespace std; using namespace commandbuffers; - void TrContextWebGL::glBindFramebuffer(WebGLenum target, WebGLuint framebuffer) + void TrContextWebGL::glBindFramebuffer(WebGLenum target, WebGLuint id) { - if (!glIsFramebuffer(framebuffer)) [[unlikely]] + auto framebuffer = framebuffers_.get(id); + if (!framebuffer) [[unlikely]] { last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; return; @@ -24,19 +25,14 @@ namespace renderer return; } - for (auto &binding : framebuffer_bindings_) - { - if (binding.framebuffer == framebuffer) - { - binding.target = target; - break; - } - } + auto framebuffer_target = details::FramebufferTarget(target); + framebuffer_bindings_[framebuffer_target] = framebuffer; } - void TrContextWebGL::glBindRenderbuffer(WebGLenum target, WebGLuint renderbuffer) + void TrContextWebGL::glBindRenderbuffer(WebGLenum target, WebGLuint id) { - if (!glIsRenderbuffer(renderbuffer)) [[unlikely]] + auto renderbuffer = renderbuffers_.get(id); + if (!renderbuffer) [[unlikely]] { last_error_ = WEBGL_INVALID_FRAMEBUFFER_OPERATION; return; @@ -48,14 +44,8 @@ namespace renderer return; } - for (auto &binding : renderbuffer_bindings_) - { - if (binding.renderbuffer == renderbuffer) - { - binding.target = target; - break; - } - } + auto renderbuffer_target = details::RenderbufferTarget(target); + renderbuffer_bindings_[renderbuffer_target] = renderbuffer; } void TrContextWebGL::glBlitFramebuffer(WebGLint srcX0, @@ -109,12 +99,12 @@ namespace renderer void TrContextWebGL::glGenFramebuffers(WebGLsizei n, WebGLuint *framebuffers) { - glGenObjects(framebuffers_, n, framebuffers); + glGenTypedObjects(framebuffers_, n, framebuffers); } void TrContextWebGL::glGenRenderbuffers(WebGLsizei n, WebGLuint *renderbuffers) { - glGenObjects(renderbuffers_, n, renderbuffers); + glGenTypedObjects(renderbuffers_, n, renderbuffers); } void TrContextWebGL::glGenerateMipmap(WebGLenum target) @@ -150,26 +140,12 @@ namespace renderer WebGLboolean TrContextWebGL::glIsFramebuffer(WebGLuint framebuffer) { - for (const auto &binding : framebuffer_bindings_) - { - if (binding.framebuffer == framebuffer) - { - return true; - } - } - return false; + return framebuffers_.has(framebuffer); } WebGLboolean TrContextWebGL::glIsRenderbuffer(WebGLuint renderbuffer) { - for (const auto &binding : renderbuffer_bindings_) - { - if (binding.renderbuffer == renderbuffer) - { - return true; - } - } - return false; + return renderbuffers_.has(renderbuffer); } void TrContextWebGL::glRenderbufferStorage(WebGLenum target, WebGLenum internalformat, WebGLsizei width, WebGLsizei height) diff --git a/src/renderer/context_webgl_shaders.cpp b/src/renderer/context_webgl_shaders.cpp index dbc725f10..1e94ccdc3 100644 --- a/src/renderer/context_webgl_shaders.cpp +++ b/src/renderer/context_webgl_shaders.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "utility.hpp" namespace renderer { @@ -21,118 +22,63 @@ namespace renderer WebGLuint TrContextWebGL::glCreateProgram() { WebGLuint id = programs_.size(); - const Program program = { - .id = id, // Use the index as the default id. - .vertex_shader = nullopt, - .fragment_shader = nullopt, - }; + auto program = AcquireRef(new details::Program(id)); programs_.push_back(program); - return program.id; + return program->id; } WebGLuint TrContextWebGL::glCreateShader(WebGLenum type) { WebGLuint id = shader_modules_.size(); - const ShaderModule shader_module = { - .id = id, // Use the index as the default id. - .type = type, - }; - shader_modules_.push_back(shader_module); - return shader_module.id; + auto shader = AcquireRef(new details::ShaderModule(id, type)); + shader_modules_.push_back(shader); + return shader->id; } void TrContextWebGL::glDeleteProgram(WebGLuint program) { - for (auto it = programs_.begin(); it != programs_.end(); it++) - { - if (it->id == program) - { - programs_.erase(it); - return; - } - } + programs_.remove(program); } void TrContextWebGL::glDeleteShader(WebGLuint shader) { - for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) - { - if (it->id == shader) - { - shader_modules_.erase(it); - return; - } - } + shader_modules_.remove(shader); } - void TrContextWebGL::glAttachShader(WebGLuint program, WebGLuint shader) + void TrContextWebGL::glAttachShader(WebGLuint program_id, WebGLuint shader_id) { - ShaderModule *shader_module = nullptr; - for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) - { - if (it->id == shader) - { - shader_module = &*it; - break; - } - } - - if (shader_module == nullptr) [[unlikely]] + auto program = programs_.get(program_id); + auto shader_module = shader_modules_.get(shader_id); + if (program == nullptr || shader_module == nullptr) [[unlikely]] { last_error_ = WEBGL_INVALID_OPERATION; return; } - for (auto it = programs_.begin(); it != programs_.end(); it++) - { - if (it->id == program) - { - if (shader_module->type == WEBGL_VERTEX_SHADER) - it->vertex_shader = make_optional(*shader_module); - else if (shader_module->type == WEBGL_FRAGMENT_SHADER) - it->fragment_shader = make_optional(*shader_module); - else [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - } - return; - } - } + if (shader_module->type == WEBGL_VERTEX_SHADER) + program->vertexShader = shader_module; + else if (shader_module->type == WEBGL_FRAGMENT_SHADER) + program->fragmentShader = shader_module; + else [[unlikely]] + last_error_ = WEBGL_INVALID_OPERATION; } - void TrContextWebGL::glDetachShader(WebGLuint program, WebGLuint shader) + void TrContextWebGL::glDetachShader(WebGLuint program_id, WebGLuint shader_id) { - ShaderModule *shader_module = nullptr; - for (auto it = shader_modules_.begin(); it != shader_modules_.end(); it++) - { - if (it->id == shader) - { - shader_module = &*it; - break; - } - } - - if (shader_module == nullptr) [[unlikely]] + auto program = programs_.get(program_id); + auto shader_module = shader_modules_.get(shader_id); + if (program == nullptr || shader_module == nullptr) [[unlikely]] { last_error_ = WEBGL_INVALID_OPERATION; return; } - for (auto it = programs_.begin(); it != programs_.end(); it++) - { - if (it->id == program) - { - if (shader_module->type == WEBGL_VERTEX_SHADER) - it->vertex_shader = nullopt; - else if (shader_module->type == WEBGL_FRAGMENT_SHADER) - it->fragment_shader = nullopt; - else [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - } - return; - } - } + if (shader_module->type == WEBGL_VERTEX_SHADER) + program->vertexShader = nullptr; + else if (shader_module->type == WEBGL_FRAGMENT_SHADER) + program->fragmentShader = nullptr; + else [[unlikely]] + last_error_ = WEBGL_INVALID_OPERATION; } void TrContextWebGL::glGetActiveAttrib(WebGLuint program, diff --git a/src/renderer/context_webgl_texture.cpp b/src/renderer/context_webgl_texture.cpp index c3618a698..06082f5a1 100644 --- a/src/renderer/context_webgl_texture.cpp +++ b/src/renderer/context_webgl_texture.cpp @@ -8,14 +8,23 @@ namespace renderer using namespace std; using namespace commandbuffers; - void TrContextWebGL::glActiveTexture(WebGLenum texture) + void TrContextWebGL::glActiveTexture(WebGLenum unit) { - active_texture_ = texture; + active_texture_unit_ = unit; } - void TrContextWebGL::glBindTexture(WebGLenum target, WebGLuint texture) + void TrContextWebGL::glBindTexture(WebGLenum target, WebGLuint id) { - texture_bindings_[TextureTarget(target)] = {target, texture}; + auto texture = textures_.get(id); + if (!texture) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + auto texture_target = details::TextureTarget(target); + texture->setTarget(texture_target); + texture_bindings_[texture_target] = texture; } void TrContextWebGL::glCopyTexImage2D(WebGLenum target, @@ -49,7 +58,7 @@ namespace renderer void TrContextWebGL::glGenTextures(WebGLsizei n, WebGLuint *textures) { - glGenObjects(textures_, n, textures); + glGenTypedObjects(textures_, n, textures); } void TrContextWebGL::glGetTexParameter(WebGLenum target, WebGLenum pname, WebGLint *params) @@ -59,8 +68,7 @@ namespace renderer WebGLboolean TrContextWebGL::glIsTexture(WebGLuint texture) { - // TODO(yorkie): implement - return true; + return textures_.has(texture); } void TrContextWebGL::glTexImage2D(WebGLenum target, @@ -73,7 +81,16 @@ namespace renderer WebGLenum type, const WebGLvoid *data) { - // TODO(yorkie): implement + auto texture = texture_bindings_.at(target); + if (!texture) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + texture->mipLevels = level; + texture->internalformat = internalformat; + texture->setSize(width, height); } void TrContextWebGL::glTexImage3D(WebGLenum target, @@ -87,7 +104,16 @@ namespace renderer WebGLenum type, const WebGLvoid *data) { - // TODO(yorkie): implement + auto texture = texture_bindings_.at(target); + if (!texture) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + texture->mipLevels = level; + texture->internalformat = internalformat; + texture->setSize(width, height, depth); } // --- Additional texture APIs --- @@ -100,7 +126,16 @@ namespace renderer WebGLsizei imageSize, const WebGLvoid *data) { - // TODO(yorkie): implement + auto texture = texture_bindings_.at(target); + if (!texture) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + texture->mipLevels = level; + texture->internalformat = internalformat; + texture->setSize(width, height); } void TrContextWebGL::glCompressedTexImage3D(WebGLenum target, @@ -113,7 +148,16 @@ namespace renderer WebGLsizei imageSize, const WebGLvoid *data) { - // TODO(yorkie): implement + auto texture = texture_bindings_.at(target); + if (!texture) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + texture->mipLevels = level; + texture->internalformat = internalformat; + texture->setSize(width, height, depth); } void TrContextWebGL::glCompressedTexSubImage2D(WebGLenum target, From 746a5ec19f8ee6d4f668a9872d94b21c5930d045 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Sat, 29 Nov 2025 03:34:18 +0800 Subject: [PATCH 35/37] fix --- src/renderer/context_webgl.hpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index be57ea5e4..ea5cc2b60 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -143,7 +143,7 @@ namespace renderer WebGLenum target; }; - struct ShaderModule final : public ObjectBase + class ShaderModule final : public ObjectBase { public: ShaderModule(WebGLuint id, WebGLenum type); @@ -152,7 +152,7 @@ namespace renderer WebGLenum type; }; - struct Program final : public ObjectBase + class Program final : public ObjectBase { public: Program(WebGLuint id); @@ -161,7 +161,7 @@ namespace renderer Ref fragmentShader; }; - struct Texture final : public BindableObject + class Texture final : public BindableObject { using BindableObject::BindableObject; @@ -179,30 +179,35 @@ namespace renderer WebGLenum compressedInternalformat; }; - struct Buffer final : public BindableObject + class Buffer final : public BindableObject { using BindableObject::BindableObject; + public: bool isBuffer() const override { return true; } + + WebGLsizei size; }; - struct Framebuffer final : public BindableObject + class Framebuffer final : public BindableObject { using BindableObject::BindableObject; + public: bool isFramebuffer() const override { return true; } }; - struct Renderbuffer final : public BindableObject + class Renderbuffer final : public BindableObject { using BindableObject::BindableObject; + public: bool isRenderbuffer() const override { return true; From 413efbe1265843d3c6f4dfef7236b3b3515bbd43 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Sat, 29 Nov 2025 18:30:46 +0800 Subject: [PATCH 36/37] fix --- src/renderer/context_webgl.cpp | 66 ++++++++- src/renderer/context_webgl.hpp | 76 +++++++++-- src/renderer/context_webgl_shaders.cpp | 180 ++++++++++++++++++++----- src/renderer/context_webgl_vao.cpp | 10 +- 4 files changed, 281 insertions(+), 51 deletions(-) diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index f28bc629b..04ee18b09 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -38,6 +39,11 @@ namespace renderer return false; } + bool ObjectBase::isVertexArrayObject() const + { + return false; + } + string ObjectBase::toString() const { return to_string(id); @@ -53,7 +59,7 @@ namespace renderer this->target = target.value(); } - ShaderModule::ShaderModule(WebGLuint id, WebGLenum type) + Shader::Shader(WebGLuint id, WebGLenum type) : ObjectBase(id) , type(type) { @@ -61,14 +67,64 @@ namespace renderer type == WEBGL_FRAGMENT_SHADER); } - string ShaderModule::toString() const + string Shader::toString() const { string type_str = "Unknown"; if (type == WEBGL_VERTEX_SHADER) type_str = "Vertex"; else if (type == WEBGL_FRAGMENT_SHADER) type_str = "Fragment"; - return "ShaderModule(" + type_str + " id=" + to_string(id) + ")"; + return "Shader(" + type_str + " id=" + to_string(id) + ")"; + } + + void Uniforms::set(WebGLint loc, WebGLfloat v0) + { + (*this)[loc] = SingleFloatValue{ { v0 } }; + } + + void Uniforms::set(WebGLint loc, WebGLfloat v0, WebGLfloat v1) + { + (*this)[loc] = TwoFloatValue{ { v0, v1 } }; + } + + void Uniforms::set(WebGLint loc, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2) + { + (*this)[loc] = ThreeFloatValue{ { v0, v1, v2 } }; + } + + void Uniforms::set(WebGLint loc, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3) + { + (*this)[loc] = FourFloatValue{ { v0, v1, v2, v3 } }; + } + + void Uniforms::set(WebGLint loc, const FloatValues &values) + { + (*this)[loc] = values; + } + + void Uniforms::set(WebGLint loc, WebGLint v0) + { + (*this)[loc] = SingleIntValue{ { v0 } }; + } + + void Uniforms::set(WebGLint loc, WebGLint v0, WebGLint v1) + { + (*this)[loc] = TwoIntValue{ { v0, v1 } }; + } + + void Uniforms::set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2) + { + (*this)[loc] = ThreeIntValue{ { v0, v1, v2 } }; + } + + void Uniforms::set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3) + { + (*this)[loc] = FourIntValue{ { v0, v1, v2, v3 } }; + } + + void Uniforms::set(WebGLint loc, const IntValues &values) + { + (*this)[loc] = values; } Program::Program(WebGLuint id) @@ -470,7 +526,7 @@ namespace renderer { const auto &typed_req = To(req); auto index = glCreateShader(typed_req.shaderType); - shader_modules_[index]->set(req.id); + shaders_[index]->set(req.id); break; } case COMMAND_BUFFER_DELETE_PROGRAM_REQ: @@ -1051,7 +1107,7 @@ namespace renderer void TrContextWebGL::debugPrintShaderModules(int depth) { - debugPrintObjects("Shader Modules", shader_modules_, depth); + debugPrintObjects("Shaders", shaders_, depth); } void TrContextWebGL::debugPrintBuffers(int depth) diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index ea5cc2b60..09657216d 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -1,7 +1,9 @@ #pragma once +#include #include #include +#include #include #include @@ -127,6 +129,7 @@ namespace renderer virtual bool isBuffer() const; virtual bool isFramebuffer() const; virtual bool isRenderbuffer() const; + virtual bool isVertexArrayObject() const; virtual std::string toString() const; void set(WebGLuint id); @@ -143,13 +146,54 @@ namespace renderer WebGLenum target; }; - class ShaderModule final : public ObjectBase + class Shader final : public ObjectBase { public: - ShaderModule(WebGLuint id, WebGLenum type); + Shader(WebGLuint id, WebGLenum type); std::string toString() const; WebGLenum type; + std::string source; + }; + + using SingleFloatValue = std::array; + using TwoFloatValue = std::array; + using ThreeFloatValue = std::array; + using FourFloatValue = std::array; + using FloatValues = std::vector; + + using SingleIntValue = std::array; + using TwoIntValue = std::array; + using ThreeIntValue = std::array; + using FourIntValue = std::array; + using IntValues = std::vector; + + using UniformValue = std::variant; + class Uniforms : public std::unordered_map + { + using std::unordered_map::unordered_map; + + public: + void set(WebGLint loc, WebGLfloat v0); + void set(WebGLint loc, WebGLfloat v0, WebGLfloat v1); + void set(WebGLint loc, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2); + void set(WebGLint loc, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3); + void set(WebGLint loc, const FloatValues &values); + + void set(WebGLint loc, WebGLint v0); + void set(WebGLint loc, WebGLint v0, WebGLint v1); + void set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2); + void set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3); + void set(WebGLint loc, const IntValues &values); }; class Program final : public ObjectBase @@ -157,8 +201,9 @@ namespace renderer public: Program(WebGLuint id); - Ref vertexShader; - Ref fragmentShader; + Ref vertexShader; + Ref fragmentShader; + Uniforms uniforms; }; class Texture final : public BindableObject @@ -214,6 +259,17 @@ namespace renderer } }; + class VertexArrayObject final : public BindableObject + { + using BindableObject::BindableObject; + + public: + bool isVertexArrayObject() const override + { + return true; + } + }; + struct Capabilities { using Map = std::unordered_map; @@ -490,8 +546,8 @@ namespace renderer void glGetUniformBlockIndex(WebGLuint program, const WebGLchar *name); void glGetUniformIndices(WebGLuint program, WebGLsizei count, const WebGLchar **names, WebGLuint *indices); void glGetUniformLocation(WebGLuint program, const WebGLchar *name); - void glIsProgram(WebGLuint program); - void glIsShader(WebGLuint shader); + WebGLboolean glIsProgram(WebGLuint program); + WebGLboolean glIsShader(WebGLuint shader); void glLinkProgram(WebGLuint program); void glProgramBinary(WebGLuint program, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength); void glProgramParameteri(WebGLuint program, WebGLenum pname, WebGLint param); @@ -663,7 +719,7 @@ namespace renderer void glBindVertexArray(WebGLuint array); void glDeleteVertexArrays(WebGLsizei n, const WebGLuint *arrays); void glGenVertexArrays(WebGLsizei n, WebGLuint *arrays); - void glIsVertexArray(WebGLuint array); + WebGLboolean glIsVertexArray(WebGLuint array); // Samplers void glBindSampler(WebGLuint unit, WebGLuint sampler); @@ -796,13 +852,14 @@ namespace renderer } }; - ObjectList shader_modules_; + ObjectList shaders_; ObjectList programs_; ObjectList buffers_; ObjectList textures_; ObjectList framebuffers_; ObjectList renderbuffers_; + ObjectList vertex_array_objects_; template class BindingMap : public std::unordered_map, typename Target::HashKey> @@ -820,6 +877,9 @@ namespace renderer FramebufferBindingMap framebuffer_bindings_; RenderbufferBindingMap renderbuffer_bindings_; + Ref current_vertex_array_object_; + Ref current_program_; + WebGLenum last_error_ = WEBGL_NO_ERROR; details::Capabilities caps_; WebGLenum active_texture_unit_ = WEBGL_TEXTURE0; diff --git a/src/renderer/context_webgl_shaders.cpp b/src/renderer/context_webgl_shaders.cpp index 1e94ccdc3..480e500b3 100644 --- a/src/renderer/context_webgl_shaders.cpp +++ b/src/renderer/context_webgl_shaders.cpp @@ -29,9 +29,9 @@ namespace renderer WebGLuint TrContextWebGL::glCreateShader(WebGLenum type) { - WebGLuint id = shader_modules_.size(); - auto shader = AcquireRef(new details::ShaderModule(id, type)); - shader_modules_.push_back(shader); + WebGLuint id = shaders_.size(); + auto shader = AcquireRef(new details::Shader(id, type)); + shaders_.push_back(shader); return shader->id; } @@ -42,23 +42,23 @@ namespace renderer void TrContextWebGL::glDeleteShader(WebGLuint shader) { - shader_modules_.remove(shader); + shaders_.remove(shader); } void TrContextWebGL::glAttachShader(WebGLuint program_id, WebGLuint shader_id) { auto program = programs_.get(program_id); - auto shader_module = shader_modules_.get(shader_id); - if (program == nullptr || shader_module == nullptr) [[unlikely]] + auto shader = shaders_.get(shader_id); + if (program == nullptr || shader == nullptr) [[unlikely]] { last_error_ = WEBGL_INVALID_OPERATION; return; } - if (shader_module->type == WEBGL_VERTEX_SHADER) - program->vertexShader = shader_module; - else if (shader_module->type == WEBGL_FRAGMENT_SHADER) - program->fragmentShader = shader_module; + if (shader->type == WEBGL_VERTEX_SHADER) + program->vertexShader = shader; + else if (shader->type == WEBGL_FRAGMENT_SHADER) + program->fragmentShader = shader; else [[unlikely]] last_error_ = WEBGL_INVALID_OPERATION; } @@ -66,16 +66,16 @@ namespace renderer void TrContextWebGL::glDetachShader(WebGLuint program_id, WebGLuint shader_id) { auto program = programs_.get(program_id); - auto shader_module = shader_modules_.get(shader_id); - if (program == nullptr || shader_module == nullptr) [[unlikely]] + auto shader = shaders_.get(shader_id); + if (program == nullptr || shader == nullptr) [[unlikely]] { last_error_ = WEBGL_INVALID_OPERATION; return; } - if (shader_module->type == WEBGL_VERTEX_SHADER) + if (shader->type == WEBGL_VERTEX_SHADER) program->vertexShader = nullptr; - else if (shader_module->type == WEBGL_FRAGMENT_SHADER) + else if (shader->type == WEBGL_FRAGMENT_SHADER) program->fragmentShader = nullptr; else [[unlikely]] last_error_ = WEBGL_INVALID_OPERATION; @@ -174,9 +174,38 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glGetShaderSource(WebGLuint shader, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *source) + void TrContextWebGL::glGetShaderSource(WebGLuint shader_id, WebGLsizei maxLength, WebGLsizei *length, WebGLchar *source) { - /* TODO(yorkie): implement */ + auto shader = shaders_.get(shader_id); + if (shader == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + if (length) + *length = 0; + if (source && maxLength > 0) + source[0] = '\0'; + return; + } + + const string &src = shader->source; + + if (maxLength <= 0 || source == nullptr) + { + if (length) + *length = 0; + return; + } + + // Reserve one byte for null-terminator. + size_t total_len = src.size(); + size_t copy_len = std::min(total_len, static_cast(std::max(0, maxLength - 1))); + + if (copy_len > 0) + src.copy(source, copy_len); + source[copy_len] = '\0'; + + if (length) + *length = static_cast(copy_len); } void TrContextWebGL::glGetShaderiv(WebGLuint shader, WebGLenum pname, WebGLint *params) @@ -214,14 +243,14 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glIsProgram(WebGLuint program) + WebGLboolean TrContextWebGL::glIsProgram(WebGLuint program) { - /* TODO(yorkie): implement */ + return programs_.has(program); } - void TrContextWebGL::glIsShader(WebGLuint shader) + WebGLboolean TrContextWebGL::glIsShader(WebGLuint shader) { - /* TODO(yorkie): implement */ + return shaders_.has(shader); } void TrContextWebGL::glLinkProgram(WebGLuint program) @@ -244,59 +273,137 @@ namespace renderer /* TODO(yorkie): implement */ } - void TrContextWebGL::glShaderBinary(WebGLuint shader, WebGLenum binaryFormat, const WebGLbyte *binary, WebGLsizei binaryLength) + void TrContextWebGL::glShaderBinary(WebGLuint shader, + WebGLenum binaryFormat, + const WebGLbyte *binary, + WebGLsizei binaryLength) { /* TODO(yorkie): implement */ } - void TrContextWebGL::glShaderSource(WebGLuint shader, WebGLsizei count, const WebGLchar **string, const WebGLint *length) + void TrContextWebGL::glShaderSource(WebGLuint shader_id, + WebGLsizei count, + const WebGLchar **string, + const WebGLint *length) { - /* TODO(yorkie): implement */ + auto shader = shaders_.get(shader_id); + if (shader == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + + // Concatenate provided strings into a single source, honoring optional lengths. + std::string src; + if (string != nullptr && count > 0) + { + for (WebGLsizei i = 0; i < count; ++i) + { + const WebGLchar *s = string[i]; + if (s == nullptr) + continue; + + if (length != nullptr) + { + WebGLint n = length[i]; + if (n < 0) + src.append(s); // Use full C-string when length is negative + else + src.append(s, static_cast(n)); + } + else + { + src.append(s); + } + } + } + + shader->source = std::move(src); } void TrContextWebGL::glUniform1f(WebGLuint location, WebGLfloat v0) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0); } void TrContextWebGL::glUniform2f(WebGLuint location, WebGLfloat v0, WebGLfloat v1) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0, v1); } void TrContextWebGL::glUniform3f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0, v1, v2); } void TrContextWebGL::glUniform4f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0, v1, v2, v3); } void TrContextWebGL::glUniform1i(WebGLuint location, WebGLint v0) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0); } void TrContextWebGL::glUniform2i(WebGLuint location, WebGLint v0, WebGLint v1) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0, v1); } void TrContextWebGL::glUniform3i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0, v1, v2); } void TrContextWebGL::glUniform4i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3) { - /* TODO(yorkie): implement */ + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, v0, v1, v2, v3); } void TrContextWebGL::glUniform1ui(WebGLuint location, WebGLuint v0) { - /* TODO(yorkie): implement */ + // TODO } void TrContextWebGL::glUniform2ui(WebGLuint location, WebGLuint v0, WebGLuint v1) @@ -424,7 +531,14 @@ namespace renderer void TrContextWebGL::glUseProgram(WebGLuint program) { - /* TODO(yorkie): implement */ + if (program == 0) + { + current_program_ = nullptr; + } + else + { + current_program_ = programs_.get(program); + } } void TrContextWebGL::glValidateProgram(WebGLuint program) diff --git a/src/renderer/context_webgl_vao.cpp b/src/renderer/context_webgl_vao.cpp index 907359577..3f78776ef 100644 --- a/src/renderer/context_webgl_vao.cpp +++ b/src/renderer/context_webgl_vao.cpp @@ -10,21 +10,21 @@ namespace renderer void TrContextWebGL::glBindVertexArray(WebGLuint array) { - /* TODO(yorkie): implement */ + current_vertex_array_object_ = vertex_array_objects_.get(array); } void TrContextWebGL::glDeleteVertexArrays(WebGLsizei n, const WebGLuint *arrays) { - /* TODO(yorkie): implement */ + // vertex_array_objects_.remove(arrays, n); } void TrContextWebGL::glGenVertexArrays(WebGLsizei n, WebGLuint *arrays) { - /* TODO(yorkie): implement */ + glGenTypedObjects(vertex_array_objects_, n, arrays); } - void TrContextWebGL::glIsVertexArray(WebGLuint array) + WebGLboolean TrContextWebGL::glIsVertexArray(WebGLuint array) { - /* TODO(yorkie): implement */ + return vertex_array_objects_.has(array); } } From af5ebca60395558bc00f8723098ce12675709778 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Mon, 1 Dec 2025 12:05:16 +0800 Subject: [PATCH 37/37] feat: update --- src/renderer/context_webgl.cpp | 42 +++++++++++---- src/renderer/context_webgl.hpp | 71 +++++++++++++++++++++----- src/renderer/context_webgl_shaders.cpp | 64 +++++------------------ 3 files changed, 102 insertions(+), 75 deletions(-) diff --git a/src/renderer/context_webgl.cpp b/src/renderer/context_webgl.cpp index 04ee18b09..750687470 100644 --- a/src/renderer/context_webgl.cpp +++ b/src/renderer/context_webgl.cpp @@ -1,4 +1,3 @@ -#include #include #include @@ -79,22 +78,22 @@ namespace renderer void Uniforms::set(WebGLint loc, WebGLfloat v0) { - (*this)[loc] = SingleFloatValue{ { v0 } }; + (*this)[loc] = SingleFloatValue{{v0}}; } void Uniforms::set(WebGLint loc, WebGLfloat v0, WebGLfloat v1) { - (*this)[loc] = TwoFloatValue{ { v0, v1 } }; + (*this)[loc] = TwoFloatValue{{v0, v1}}; } void Uniforms::set(WebGLint loc, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2) { - (*this)[loc] = ThreeFloatValue{ { v0, v1, v2 } }; + (*this)[loc] = ThreeFloatValue{{v0, v1, v2}}; } void Uniforms::set(WebGLint loc, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3) { - (*this)[loc] = FourFloatValue{ { v0, v1, v2, v3 } }; + (*this)[loc] = FourFloatValue{{v0, v1, v2, v3}}; } void Uniforms::set(WebGLint loc, const FloatValues &values) @@ -104,22 +103,22 @@ namespace renderer void Uniforms::set(WebGLint loc, WebGLint v0) { - (*this)[loc] = SingleIntValue{ { v0 } }; + (*this)[loc] = SingleIntValue{{v0}}; } void Uniforms::set(WebGLint loc, WebGLint v0, WebGLint v1) { - (*this)[loc] = TwoIntValue{ { v0, v1 } }; + (*this)[loc] = TwoIntValue{{v0, v1}}; } void Uniforms::set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2) { - (*this)[loc] = ThreeIntValue{ { v0, v1, v2 } }; + (*this)[loc] = ThreeIntValue{{v0, v1, v2}}; } void Uniforms::set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3) { - (*this)[loc] = FourIntValue{ { v0, v1, v2, v3 } }; + (*this)[loc] = FourIntValue{{v0, v1, v2, v3}}; } void Uniforms::set(WebGLint loc, const IntValues &values) @@ -127,6 +126,31 @@ namespace renderer (*this)[loc] = values; } + void Uniforms::set(WebGLint loc, WebGLuint v0) + { + (*this)[loc] = SingleUintValue{{v0}}; + } + + void Uniforms::set(WebGLint loc, WebGLuint v0, WebGLuint v1) + { + (*this)[loc] = TwoUintValue{{v0, v1}}; + } + + void Uniforms::set(WebGLint loc, WebGLuint v0, WebGLuint v1, WebGLuint v2) + { + (*this)[loc] = ThreeUintValue{{v0, v1, v2}}; + } + + void Uniforms::set(WebGLint loc, WebGLuint v0, WebGLuint v1, WebGLuint v2, WebGLuint v3) + { + (*this)[loc] = FourUintValue{{v0, v1, v2, v3}}; + } + + void Uniforms::set(WebGLint loc, const UintValues &values) + { + (*this)[loc] = values; + } + Program::Program(WebGLuint id) : ObjectBase(id) , vertexShader(nullptr) diff --git a/src/renderer/context_webgl.hpp b/src/renderer/context_webgl.hpp index 09657216d..ad39915e2 100644 --- a/src/renderer/context_webgl.hpp +++ b/src/renderer/context_webgl.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -168,16 +169,28 @@ namespace renderer using FourIntValue = std::array; using IntValues = std::vector; - using UniformValue = std::variant; + using SingleUintValue = std::array; + using TwoUintValue = std::array; + using ThreeUintValue = std::array; + using FourUintValue = std::array; + using UintValues = std::vector; + + using UniformValue = std::variant< + SingleFloatValue, + TwoFloatValue, + ThreeFloatValue, + FourFloatValue, + FloatValues, + SingleIntValue, + TwoIntValue, + ThreeIntValue, + FourIntValue, + IntValues, + SingleUintValue, + TwoUintValue, + ThreeUintValue, + FourUintValue, + UintValues>; class Uniforms : public std::unordered_map { using std::unordered_map::unordered_map; @@ -194,6 +207,12 @@ namespace renderer void set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2); void set(WebGLint loc, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3); void set(WebGLint loc, const IntValues &values); + + void set(WebGLint loc, WebGLuint v0); + void set(WebGLint loc, WebGLuint v0, WebGLuint v1); + void set(WebGLint loc, WebGLuint v0, WebGLuint v1, WebGLuint v2); + void set(WebGLint loc, WebGLuint v0, WebGLuint v1, WebGLuint v2, WebGLuint v3); + void set(WebGLint loc, const UintValues &values); }; class Program final : public ObjectBase @@ -237,26 +256,36 @@ namespace renderer WebGLsizei size; }; - class Framebuffer final : public BindableObject + class Renderbuffer final : public BindableObject { using BindableObject::BindableObject; public: - bool isFramebuffer() const override + bool isRenderbuffer() const override { return true; } }; - class Renderbuffer final : public BindableObject + class FramebufferAttachment + { + Ref texture; + Ref renderbuffer; + }; + + class Framebuffer final : public BindableObject { using BindableObject::BindableObject; public: - bool isRenderbuffer() const override + bool isFramebuffer() const override { return true; } + + Ref colorAttachment; + Ref depthAttachment; + Ref stencilAttachment; }; class VertexArrayObject final : public BindableObject @@ -776,6 +805,20 @@ namespace renderer debugPrint(); } + template + requires((sizeof...(Args) > 0) && (((std::is_same_v) && ...) || + ((std::is_same_v) && ...) || + ((std::is_same_v) && ...))) + void glSetUniform(WebGLuint location, Args... args) + { + if (current_program_ == nullptr) [[unlikely]] + { + last_error_ = WEBGL_INVALID_OPERATION; + return; + } + current_program_->uniforms.set(location, args...); + } + // Debug Utilities template requires std::is_base_of_v diff --git a/src/renderer/context_webgl_shaders.cpp b/src/renderer/context_webgl_shaders.cpp index 480e500b3..c6a2b3140 100644 --- a/src/renderer/context_webgl_shaders.cpp +++ b/src/renderer/context_webgl_shaders.cpp @@ -323,82 +323,42 @@ namespace renderer void TrContextWebGL::glUniform1f(WebGLuint location, WebGLfloat v0) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0); + glSetUniform(location, v0); } void TrContextWebGL::glUniform2f(WebGLuint location, WebGLfloat v0, WebGLfloat v1) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0, v1); + glSetUniform(location, v0, v1); } void TrContextWebGL::glUniform3f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0, v1, v2); + glSetUniform(location, v0, v1, v2); } void TrContextWebGL::glUniform4f(WebGLuint location, WebGLfloat v0, WebGLfloat v1, WebGLfloat v2, WebGLfloat v3) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0, v1, v2, v3); + glSetUniform(location, v0, v1, v2, v3); } void TrContextWebGL::glUniform1i(WebGLuint location, WebGLint v0) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0); + glSetUniform(location, v0); } void TrContextWebGL::glUniform2i(WebGLuint location, WebGLint v0, WebGLint v1) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0, v1); + glSetUniform(location, v0, v1); } void TrContextWebGL::glUniform3i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0, v1, v2); + glSetUniform(location, v0, v1, v2); } void TrContextWebGL::glUniform4i(WebGLuint location, WebGLint v0, WebGLint v1, WebGLint v2, WebGLint v3) { - if (current_program_ == nullptr) [[unlikely]] - { - last_error_ = WEBGL_INVALID_OPERATION; - return; - } - current_program_->uniforms.set(location, v0, v1, v2, v3); + glSetUniform(location, v0, v1, v2, v3); } void TrContextWebGL::glUniform1ui(WebGLuint location, WebGLuint v0) @@ -408,21 +368,21 @@ namespace renderer void TrContextWebGL::glUniform2ui(WebGLuint location, WebGLuint v0, WebGLuint v1) { - /* TODO(yorkie): implement */ + glSetUniform(location, v0, v1); } void TrContextWebGL::glUniform3ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2) { - /* TODO(yorkie): implement */ + glSetUniform(location, v0, v1, v2); } void TrContextWebGL::glUniform4ui(WebGLuint location, WebGLuint v0, WebGLuint v1, WebGLuint v2, WebGLuint v3) - { /* TODO(yorkie): implement */ + { + glSetUniform(location, v0, v1, v2, v3); } void TrContextWebGL::glUniform1fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value) { - /* TODO(yorkie): implement */ } void TrContextWebGL::glUniform2fv(WebGLuint location, WebGLsizei count, const WebGLfloat *value)

onPXG?&TvPjo(iq4@-M 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

yu0$XATh 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%0A9%FLRvJEH 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%0DF)!os<#Sb10KQwhK-+6uQQ^IX%Xet}(WPhxEEZ zcSjb*{kHC4?MvGwY~QAB!)Rjs*?6QWlUk#<5wk+R;TY>f;C>6-mGK){nI|#p$=6v+ z_#jQbRM8Kle>p4Bc`JEgiFM_?{ni@vhjqwj(f?~ksb?BztL4-2iRL&ZY5=a~0puXh=nZz>^<%&(uuSFs z>(~wo_+Jnh_IV%scY{0aDTh^u!{T-;Pv74;HZ0DMINJW z6aLC7@w>f5o`FeDd_a5lIjVDTZ}~2s^BwBe$=&PfZSMClzY~XpC!){QvtRgj7P#0i zq~J0*FyqtyZFsPk4rFdk8KD6gzwqjN|4l`j;KTWs1|#_^CPi-ZjHQ#fLfzJ|V^MRM zlnfkp5DVgk#pq-6JunG8_bl>hc!Ew62`^lfNL=&TAjt*C03dt<%$ehFXYTY^i)C-rXpUuuiT|!Y`vZt1`hg{yT-j`8wIyc``^pfKHtMmTaOO%z0Rq>X^`)F zd@EJ^`a!;TI`tnI@EBJ=sK>2MP ze&{$!d=C}qKxXX@Jd-k|P1f-GiMG7aect1X6lQ_xocD8=FOnRP^UvlJEsV#&>g7cu z7e(%!3BS=}S>%uW^1r%|YJcR_EPcd>kPC)SE@C_)6EtrtcJCqVbB6E@n+_O<9?#YO z$g^4c>KKAQW~JfJ`y(yqqMc>_$iwHNog4j;2eY&z;}^Lu`#A3!;@kY2_$EHqY~SwX zo8(>hev6`CKF&8UZOJ+?a?Z?;UK`MxTaMkkO|>r_0@fK>`ZTagejYD8@=ahJY>Wcy zU}JoNZ-b5TDBsR{jDM}#3m9Ws?-ZMoZTo6rPE0Jc*bhI&m);&TUf#E4`G$U0_6F}evV2o~>*IYq%eRi{YQCY_H0|4a zM$x$?XRE#MgQl2cLzjG;#NCPmzR8|QblTG5H>Tx|u52fFXKBvpKzsc|{zxG-;-$4( z^eEG}Y4;`iG(6J_kLI1|6>qc729wwBZ(6>M@kLIOXT#g~h~?Ys{zxKAJGIcN=u(_P zU0Ti_{8$!!yko$fF}6<9h>qxm$*k!pcrk0%=q-it9?|#1_!_<6w8S~?vvkbh!y+jf!VZe=J{9b0W3KK@#?@> z)S{o)^@)8M{_+Ta`fNjpIIvdsxEAj$&IhWW*JhLvzusW?as3vbULQ7T_kFT7xW8}y z_q2Xu>oM?)MGoHz`o3e!4@M)Ku%Vl_V_~Q5i-4!VZaWM-)t7Bqc5utn*vE6KOJ+y+Zj@)>OWDZt z)jTtA-nkW7Z0}+1`L%fhIZUC?^gYe?w?uOLGC7O8{z}#s@sBb#n;$%JM(4Yx)T%xI z?z3Y{gjXa&VuzJn7B-H=ce~>6(&viJ+9zMJlmKk>sS~c+qm$ZN@K^iX<2Y_6*T?J0d{OJKJ2!RUW{E$ zVoiLvKHG`yc*-qJZoyYJI#@?MK$dw~w*FG1=iB%n3U-;t$`S*+T|W7{@`f1~ zoZVdQS*G^Lx)GdO#6oA_6dXyO=b?Fm{hhm98*=3?>_C30@_qfU)y+i{)Phf6ZmCaP zEIe~Mw0v~BYM*kw+H;UTWo?Hp;?8I8eb;tMdu^;<$+{4l&dIgch4FWFbB|qGrr3S9 z7#jpJDTY@X+7|wpJQ-@3g)ho{n?t|eHagHHyz?Ub?o4@Ma*}EYVB2V0B2O=9%}JLYMHffka_rBpkY<$>~QpJ@RR%<@z?luIiECnr2I(YDmuxf zlE}%sqVp5b-)D!$$GV3y@qy1mw_#nEH;GvIQfcS41%vZ}Z1eC#hbImv*G>MK*X9ik zXT_RKIDZJ7W{(vt9vAV_^)byO2g-nv(0az&ffky!U9EFB^vL=}UWmLEKYk@Tzy|b~ zY%xQLfIQZ}+nSwa3<}pV;-*dsxFcjaO2}8F(bB>E7AB^baL(H-1SLEPKe0N#p zAbyc5e0Uc36N?>$_|=J}`1fjvvD<-Od;mERoHG831IPi<)%BcDAg>&`|7E`CO&NMT zJHC=Ro;_K{qYfwMHvKj0Hpg1^-tVz)6XY=xUGZgN(FR?+lo^g@?qaO6?*|`CC5ET! zdU%P}8J+xRtLyGV8Qc_QFW{9+x4|1kE;UY1+eD1aTI8GwVLyl(E@TTH0ApLwXheOG7pt+LQ` z%R>A%bJg6V|Ceez@%On4kihXhRw{vX0T4*VM9_`$w+MmhR&S%uz z3_W=SdylmKo?WjtdomMalgvRjvPMTTpZV~XqixvmK1k|$&8Bl49bj*@VQC~5RrfOl zpG(Oy@T|)gXZjH3EO^sv#0dUdL1;-&D3}2A(_s-BDy_j-|z~fGZ=X+viP;*gX88AaHIJVc|C<6?I16L zZu1QA@<djM2no*G{wPvgu-5SK2bd`Mmob8`i;iK-XoNYosg-?H0Wb-yepbrRMk9 zq373ny>Z!w|DySAIv4Z%?}N{80rTtCjm^5V{jRo-?4=vZOtNE-?C)pA^ZoFAp()nF zXPMN8Jh_(Yj-&yq^>;Qp( z5&K`JU1>15eZ=e=xF5;_W1KyRS?6XvGEc%+j(%Thcs7C8)V^rPxX5o04!xdMa2C?^ zY1+O$OW#HGee`~3>|^|q3h-likGH;;mV^iG`KO`bD2DHN+kr;%M$*S)`-kqsN4&AO zk8qZ;wm_@s^)?MoW1ju0;pvW%&E*baUrk@<(Z@*WV4us53@{_)U#s2fubv z|Aw)(FO-m@rxe?HO@nIigVP+!S5toR;*w1z6*YS$_tGn@!MWf#_{3G@O;CEjQFEti zC@nrXEf;+ymt1Ms)^e`;F6UI?MN(%xIF@rjW{wQ)8+^+e6`TqjivzVU@IFs|myf=s zm%Z6?=|}pggD1)U#@!e9vaReQf8jW%&SKxqFX-~CRYQXHnJSOYo=eU(DKGbb34R2& zYxylcAoIM7{nBgri;|VTLm%Gc=UjY%GxwunrvtubcPkzg-MD9kbVh%W;v9(<6 z>)2#ti-_4KUs9MmWF%h_wr-s-X$3fGb>*PIFQaownH&@=cy4oYP>7$wor7W><2N}d ziuLbw4vHPjON<;8^_zP&&`d zs-_X@5UDu?AAjT4eW3;8yJ{6bwUfUa9XpjTTwrbzz2OY^6VlF5dB8Y{mdX*tU8Fj% zZzbd84(5gqXi)6ITIX_dE(+ghl5l%yp^+-I}P;CoL>sV`p;qV=o&(Pq<_NCZ3 zboZC`ZP?#hp=0~*pFir2GvBS8U(vbu$U)zD7BpsZWvv@&UDvust}TxNhw!3mXt73g z6y9~ipJJsIkr?Z9M6_?(=I)|e;EHkPNceR*e6H#f@JQx=aq)p^Iqf-9RLvH=JPpp@ z4O~{bot$qzd1j4lCg8qg(NL zwtjGfO7mly64_hHt`8qQ|P+7VvuUPm-H)IIC90~}g@&f<(5 zu|{tB*-1`Bp+A}H|F_7`k>WYQJ)%Kmq}yNZ^M5dkoh$YKR3KkbbU9?HXcuo zY`$FdU5vl<28qufi9B}IkN1qQZ)nAG*4jGYzICL13qN#tTLpR0kBo4S^v{$R*)DpX zTgUr={1VBeFUD8Nk+a1s6C(DBTG)Z`0Xj1Q@eR@ z^yiRo++B-(8@ARPu#Mt##hv^ zlJ_Cs_`8aI8@IXpN%;P=EX=;&T4UWHdYpz2-*-JcmU(OskA9@Ab97@_-I%7b`N(Ip z|DWypeL26ugN}c~H`3hYjKh>go@!f~QXLCx{f!GPi#$QZD@a}q?pNtgu;)&2pLXI! z&KZvGD>L+LXn80+g+G3LeySfA{+dqyS=RThswv}reEq&F1+GNC4VSn7IQ9#fXAR%S z$@y{Cp*(xb2_5v+_{g0&Q0JH243e8l@@-W~+!pyHOnxTlV?f^8gsdI?-HwB{itK!% zE7)(xpx5xi=+@)J!7$f79r*TFk}tldxMbCx{C*z(_U0I5D{?J3?a^iRE9?8_uddt6 zySs!B*A25S$sGY)&b?Uh1r5tQfz^RUV4Y>>VVIhy+B0C4@2l?ttAE{{5NyPPE*YOSvbuWXn~L*5IqE{>k=ft149UwWHOc?ZoZ0Fy=c) zSL}s`o3|vBa-Tz90=%ZKWA>;Bz#$Cslu4QaX7-Kc}2rlM)WT3f-J%2LEec{AJ%9@PNQ2kHbN;@)7 zdOUVKql|}p{vttVOu^HYM~<(peYWauYtyvTwU0*NeU_~A)!f1Ll-&1Y$BZZbZc$8V z=&IbxlV4&is0fEM%Da&U|d^t z^x9pE#=rD*$LR81FO7fb>Gz2hTmfvy1LMh?9c<(NmmbB~h+}A5@||ekOzzr~zQqqL z>q_2tb9UB(=Ud2~#E~(v#8bZJ51$$vOTQZx`)G!*`J*cocL#B&8Q*P8X~y#8jB9e%zE_7j=J3aCv|9`wB}RNO`W3s8 z%(eUtm+Qx@V>!1h`o!cx)@{9WPo~brBQQI;c!pZHLZ>aRbt}){cTYL%R%kcdx~*ld z%(~5H=REbzN_d;!UZZQ#hbB8~6us#8UZa)iHTuDfir89md3o2UykiW@<-gdvrs8)p z>-CD%di_@4F;`o4W7MIw+y^Q;oUB*VcD#r?kK?$HCJ?KtscAHoyw z1J{~{zMG~Y$(I^2R-j459v&NA%)OAJTULyP9^8UZzg)nN&Vx* zGwSy-=}Y)AejnPNhTPOJ==YMd(tdvd@2h5D+vAUX8r4;nninU(Q&->uavwGx#?E$F zXpkHbbEB-s6?#po6PFZ3Pl`TaDPLO?^f4E>q#S$l`Cqvv+J7&9+u?6-PqWK4u@=Jc z^HRz+Nz5!dq}WLJ!M7UmC3Ue!lloD~X~1`}BkZ94M($kbB9>LY)dtl3s$BAJ@F%c_ zg2B7?F@Mn|z{MZFRt;AdYfIote3;xlf&Qw1Ik;5YFXz_tyOiHK_^e8}yFGR?IhUMo z?TlgGVdSOsQ}o-hW!Z43z?IOo(PbL{b8J~QoO;Ve-_PFOU~}T5ADII;{)^rNPN56W zyr%kc^e=R1_C9J-=sMM4Y%noj%QE7xazV_^*$N8WsHw3!ZvMqzu@h6?Emf~KIKf?^0r~xmbQeq$T}X1kBY1q zEH|Z*4d#xF|I<2M(E!NgnmSb1{lNq=Y}w3+nK5v;LP|jr=iu&n-(i8$Gvi4mtyWarn_b{zUF~ za9*K_ccLpCKo66tgXY1?b`Q~L?@m@!i}`Pk3O{E5B+ehyp2Vs-kh?+MHsfGG&f3YhCJuZ*pwy%zBP zE_m6vLLI7I_a9f@xvr+~8~om~F4Wh!?ys-x2~21c-_)Cw?P5Wt1r3dB}bR!UMuV`eryw&_hlPA&qJqtP3VTRtX14Iwuk+KjK}BP zjV^m(d6wL3#4g$UP@WS`-quB&*AqL23i7Kf)vxu= zV1TnG1#>J*wOgOYzeHX+>(khA-d5jKDzGbb%8FSXf49tP+yU^?6yp!MejA4GEp<3+Hiu}x4|0kwWbPROq-Ll`7a=vLcZsa^`<1xRk zD|l*>efDZ;&p!W(%>!K-I|6mwIBW&a1D2uVEl0VzJ5Ad3 zu4S?B89J-N=OA}b!55YjH!{FxypLRztt+u}!wc&K=2z3YEj-D|yJy>g&3!1Xw-NgR zZc6aw2E~ty-$nS3+=n8uPx#eR_n}nq9OF!riA9lpU)yy1J`@v&LeBa7yWw5OLoM8W z7CwHQ-|&bW$y4usZaW-})No$Md~fqt419h){k@d>v44w3fUBX0_9T9&2j9+G+E4IY z<+F5t>!2M|pVvy+R`|S^M+#1io^J4AbpFwYWPWYjxa+l`%Njd;Jv=8S_`%Ou#2!Bf zJN(L(EBh9&4rBKnn3HtKzL=N6`tr`b^>+5W#BQ5!)g_gYus#L5G6K^n{`7`)f4S&&f;9-h$zrk_D$CRjsQQ?aFM-|+9 zzxX08X^X!m?q!u&GRb#bvgX09<=7{?!D7a7k(zys z^YMpovu0~(9dQVp+0*UL zO1CRCu48(L)#$>fpucygzsJdspxy~>q6B|to81*Zd1!4C+{*ku(u!4A@sX1rpNh~Bd_ed z?)hyJYd)GaCp6`)FL=~(7TilJdatx+#+N>SV&9iDoi+mJNt~J;<7&oFe3t8cx&1AH z{-NiGd<0^z6* z3np2kFP?*Mx;@*N^}Tna*XnzmvVQk{eu!_^XZ@BRjjqmU>wNIAF#0Sx1+v~LXZ3$| zt2Ij5w!MogpjE+jK5N6iM@n)YF?WZBep{z6>Ia8=+Wixo&XGIwR1WNuqNv8dlS#-q{rdil7GRY5X)WbDx@&8xzds*e{7t~!D!if4 zj8X0!n2bMms-{mF-wTr#Ipdda_Pn>l4@z9VOU_p1iG2Nl z8PDBtzK+9Ez8INph2bSr#!m{Cx9Aw<9rCUK*@EmUMn{_sPGaCrc+5eEZ&h+WN#h&7 z&z*VN*J$`x5#{yxy3#x&j;&h1)BN1#Hyy7h=gA#A8s7K5l7`mXsrtolgTb-wq^FO>T8Vh|{od`1@eIZ{Y zzF##@q&-tE$-Cr!6_I_X7JbOw2fzP6vA>QdN5}M7R}1ah~icA z+e?t6!pmB7R6BeB_Si$JU5%>PK><|5|bHLjI{(px5SMvW49NG9?fzS5kch2YieD>N` z^Z#o8SM$G`|G+CSTWhA=5cK6<5d&sr+^xA|ji`J``p>en4LrXxotO_cd+RVH^4w zxmx%XF)0CQSH6orVV@HU7yo~uUBRo^mAhTEn{a5i+eN#_pxwAbyKxWg z>hdnyO+VYTn|`)wSDuA-6AtYr9NJAly9tp+ns%9AXu~R_9JFg)!+&Vk!Uvv!b}jtl z0<)prZfTQuhIZ4>HtnXLZQ4yg+q9d0wrN*CUjbem+U!yiL0`(P&L0-X4isl=6uZkC5`_WBrg;$I!ztX0N8e(I(? z?6qe9srw-2g1vE%=w^B7W>V)b(9K}fyPKrWrLx{_`HhU+E%BU_k#F8_wry^5TLpb< zxZ9z1&g$7mVX0#<9T}#}sEAqGNK;Q%c9w{f?h9Xw00^F{O^^m~Y5E zal#w)IP6%F-!O(E-amRV?>*nlIF4Nao|yyjk6+A~*5k~+I8ONV#m-i*wg9# zoZv-)7rmc$)%}S42#=$ee4px7O6dFFfD z{urKp65WOv?Y!;&$vufrZlAW+pVy;`w|`0REyxpKk$>n*&polN0NsLo7`uaS;?E*~ zR1V`5+s_TpY}h7sADZ*%wqvK0yCol4>G(ycV5%X?HyzW%959L^gaoUo$Etmep?|$(GREh14 zeXaPTlIzEyujN5cQ=qG<&{sZmR)D@%h^{<_xK*(qjlzyJRQ&3+zBoEy7iFZ+zV)iV ze^t)8_HBIi zt&jHamAeQj*C}I3*_|HTip~8*2X>3J4J0%FpW$a>|48RIG`10^yx1~0yJw&Gx4*s4 zSQ1YyiiB?A93uP4&{vsP`ZD_?Y<8)=QY(9b82nJ^<&tL}%g8xlV9@&MPFWj&UsjdV zT9!cXu!>n1;8VVZ>adGca9;k~;KgM>4Re=LYTVdQl$@?e2FH%cOcs?+WyP)vlHew$duCE(M zFupoume^mz&i@4RD#-Y%e8HD3?ByZs0CPzNFz-_hrQnhC zdfSc%&VQEQz1ZzHUh>`ONr{Ua4%V!Ap)Z4jMre$jc1taAfRA9F%!#oV>pc;0U}rV4 zXWN2BjfXk^+gqYKdWk{XNDSJ^t}~dQAUHcKSXm2o?9r#P7Mrx}uSnTi4Snle+|cp$ zXW2(LIluIpn3Y}=DH}4j&m! zxc#AlQ}{HR z=}*>b)8%&gnb3Yle=Zxm@Iv7q)=!p3I%)H4#@f$VvyJym-({QYaNrBiCy*IU4*#r@ z|3+pA@5C3jleH!|4bN0_pI}Yj%wAB_^s8x{7@thmbz8%@$s0ghCn~^$hJ(7o$9G7c zG4R-EY+NI3(_$`zs&Q*~Ah=E17k#E2->>Dvr^@{T?!Hz4yYwZtGY$WWO!(b%>#kdj zJe0a|d@%0!70&xqn|Gdhn_Uh(-Zp*SHdhbRrpR5+tN4Tl9b8-ZC{lPC4PG9%@zRYw z((-MX*2z5yBbr0{0M|=pZ6st4&#)ipYGnQV1N%dX8^)ihSc9R3+=GRjk+l=7sBAAG z?_aPY(Eb^CW@0Df9(}=G?A?}+WGpkKu2+}1gMP?q;ngKN4|)8z$lsZV@R<%H*B>DE zR`((MWJh0Vf$kE2h7M65jU{KmHv`jj%w8OOqPef7qkn8!!Fu+Qe5=4uYjPv_ILqD* z&clKm{Kg_%tI2=p%}3I4iCWHCoJh@L)v$u!8}U(9i+r9JI%fiWC`hgwd^RgvSR0y7 zfr)s6RNj*W`wSgd1Pu#+RGhoe?_$7j-c5jKN;z2z&O5ypKI^Q7fNL!T(rY2gJvQ#O z@YbIb7sQz-iA}qmeX)1^Peu~H)l<@S^$QUKA%B;D@lLOb>RkTw=4vWx=bbg(5 z4hfw@X625L*v|@n;mu~AT4e0TT``+LZ)@JuT6_Mk2Rge!Tr!;0{`x)vH z#AZYmRN~K33q}st<}_S8$347k(*(J1*oLbcUf8`2+x=O$==L5xbgd&4E6;Uul82Az1zzj4F@G=_~px*mMy7n z)$pNnx9L2{z?k@J&K!*p#X1^geu7xTxcJzs&AynUEG z&#GSZ4fZ@??wk1~@VLuKJd4TYRCHqO{A${{1=zx3f0I3ybB?b|Xu#nWQT(|2`}p*C zcYOXO&oriNKgI@Q_7SFUktqWEQEbf53%%;Sw6tgY9`Fb4wqt_~EjWH#;GoUCDcDI( zTPFU(``o(zOBrXni_oQIUWSv|)3}dE<}Tf)y$2Ql6E@F1(to!0i;2Ay-{0v6Zo#H_ zGq%N>urc0zM6l827J&0^YQ@s_`tiI znRDmn5PCFz6Y+0c;1d3@PBz5=h+b9|k| zGD!?EICX|xi!76D%cH2PzGcCA(DL9c7OoO@l*U|s9BTr$}3Faw{oZLdvP1DWl2 z&uG8%)Hi*shwNt-lKaOT`Yrew><+5d^@V*^Lf3^tvv%xC92;$?z^&iGCxF4)i+vd% zgXDc?Z;ql_f zGQXRo4OhEqda?Ps;8h7PC4af@Z=TGn3-_~Z7!!KEHXaVbD@%M=Ka2gm|9d0M>HfpO zs6$!Dbja>Q){ueEi|>)>6c+O+w(364lJs$wMB;c_1LyZyMUBf^*Pp-l#r@|mkTWYS zfzR%GF}XmWS!oRv>=oN=w9MF!3(w=V`>;jB!0*!1HL=^MyQ*($B;- z5ZkCGwSwQ)^-KF=fn^H}PTTe`+q*MxL*LWuZ`f<_>&9!&P3np^a4YuhHgLO<^FD1Z z+)A9J+qV7UjM=dm_~8cI&t#m;BYTc#T76lD{w8+FF;UL;c;g7DVsp zlsc0MN9!D&=-FvmVcUaeim%BF7j^1# z?K)xk@3A3o;#^NgKLXcM8!p?%k*=4I?O9?k%5#Ztk0+OZ2b;6-=!||nZ8W)kp0t6V zeU;?elk@) zO-A_HpmQ|7of8O51>9Kp~!jT(7fA#*x!{Nf{bJi%;zZW{m zHs;OT*K#(n@55(n30};q36V zzfSy0i2UOF{Sp0q6VKa;0j=~$`u7K#6a2li-{1VpO4+a2cW{fmn!(>CP8*5Pk0ad= z*uMGjGvCd)hbl~e8jsMJk-u&lilIxnX-M{9Dfq4t_<(1>9lshc6ZnX2t@OFz^8ugO z7tRhoqfZ#zp$`D3twR*C=DsEKDmXus=~FRvOnF(Ovd(JJ&x8-HfR8+WG5awO->~y} zAZ6BJ7ea8N##uBpx4ukNUdTg_9TKNKSnfcRm zG>kr|$2`b-cI$yT6^=iYuo8QLJr7D(Ffe(BA zEg7~1S^Ml)nzNm0IrYtoSoe&7zC-qadQPUKak9{Sv;P8O}>nwl`JipD$1I+xm*Ya4jaIv8z|e+Sr-@H0;-Kuc z9c8WdVT&1xCbW*xwR-Df_7P4TNSp9_U8mm0r;hult#@ckc<8Bb{*XPWk9}|E*^Oi% zct~Qu2H%5D>#GxatoNJtS℞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