From 017f12c86322c3a898d3594ba424c11cfd729ca2 Mon Sep 17 00:00:00 2001 From: ChiaNing Date: Wed, 29 Sep 2021 22:32:54 +0800 Subject: [PATCH] Add drawCall to UI batch (#3912) * Add drawCall to UI batch * fix DynamicOffsets bind bug * remove uiphase in forward * debug remove * fix VK device _caps --- native/cocos/bindings/auto/jsb_scene_auto.cpp | 368 +++++++++++++++++- native/cocos/bindings/auto/jsb_scene_auto.h | 13 + native/cocos/renderer/gfx-vulkan/VKDevice.cpp | 4 +- .../renderer/pipeline/common/UIPhase.cpp | 10 +- .../renderer/pipeline/forward/UIPhase.cpp | 64 --- native/cocos/scene/DrawBatch2D.h | 21 + native/tools/tojs/scene.ini | 2 +- 7 files changed, 392 insertions(+), 90 deletions(-) delete mode 100644 native/cocos/renderer/pipeline/forward/UIPhase.cpp diff --git a/native/cocos/bindings/auto/jsb_scene_auto.cpp b/native/cocos/bindings/auto/jsb_scene_auto.cpp index 80c5dc704ad..470deca5eea 100644 --- a/native/cocos/bindings/auto/jsb_scene_auto.cpp +++ b/native/cocos/bindings/auto/jsb_scene_auto.cpp @@ -5942,9 +5942,326 @@ bool js_register_scene_BakedSkinningModel(se::Object* obj) // NOLINT(readability se::ScriptEngine::getInstance()->clearException(); return true; } +se::Object* __jsb_cc_scene_DrawCall_proto = nullptr; +se::Class* __jsb_cc_scene_DrawCall_class = nullptr; + +static bool js_scene_DrawCall_setDynamicOffsets(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_setDynamicOffsets : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + HolderType arg0 = {}; + ok &= sevalue_to_native(args[0], &arg0, s.thisObject()); + SE_PRECONDITION2(ok, false, "js_scene_DrawCall_setDynamicOffsets : Error processing arguments"); + cobj->setDynamicOffsets(arg0.value()); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_scene_DrawCall_setDynamicOffsets) + +static bool js_scene_DrawCall_get_bufferView(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_get_bufferView : Invalid Native Object"); + + CC_UNUSED bool ok = true; + se::Value jsret; + ok &= nativevalue_to_se(cobj->bufferView, jsret, s.thisObject() /*ctx*/); + s.rval() = jsret; + SE_HOLD_RETURN_VALUE(cobj->bufferView, s.thisObject(), s.rval()); + return true; +} +SE_BIND_PROP_GET(js_scene_DrawCall_get_bufferView) + +static bool js_scene_DrawCall_set_bufferView(se::State& s) // NOLINT(readability-identifier-naming) +{ + const auto& args = s.args(); + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_set_bufferView : Invalid Native Object"); + + CC_UNUSED bool ok = true; + ok &= sevalue_to_native(args[0], &cobj->bufferView, s.thisObject()); + SE_PRECONDITION2(ok, false, "js_scene_DrawCall_set_bufferView : Error processing new value"); + return true; +} +SE_BIND_PROP_SET(js_scene_DrawCall_set_bufferView) + +static bool js_scene_DrawCall_get_descriptorSet(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_get_descriptorSet : Invalid Native Object"); + + CC_UNUSED bool ok = true; + se::Value jsret; + ok &= nativevalue_to_se(cobj->descriptorSet, jsret, s.thisObject() /*ctx*/); + s.rval() = jsret; + SE_HOLD_RETURN_VALUE(cobj->descriptorSet, s.thisObject(), s.rval()); + return true; +} +SE_BIND_PROP_GET(js_scene_DrawCall_get_descriptorSet) + +static bool js_scene_DrawCall_set_descriptorSet(se::State& s) // NOLINT(readability-identifier-naming) +{ + const auto& args = s.args(); + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_set_descriptorSet : Invalid Native Object"); + + CC_UNUSED bool ok = true; + ok &= sevalue_to_native(args[0], &cobj->descriptorSet, s.thisObject()); + SE_PRECONDITION2(ok, false, "js_scene_DrawCall_set_descriptorSet : Error processing new value"); + return true; +} +SE_BIND_PROP_SET(js_scene_DrawCall_set_descriptorSet) + +static bool js_scene_DrawCall_get_dynamicOffsets(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_get_dynamicOffsets : Invalid Native Object"); + + CC_UNUSED bool ok = true; + se::Value jsret; + ok &= nativevalue_to_se(cobj->dynamicOffsets, jsret, s.thisObject() /*ctx*/); + s.rval() = jsret; + SE_HOLD_RETURN_VALUE(cobj->dynamicOffsets, s.thisObject(), s.rval()); + return true; +} +SE_BIND_PROP_GET(js_scene_DrawCall_get_dynamicOffsets) + +static bool js_scene_DrawCall_set_dynamicOffsets(se::State& s) // NOLINT(readability-identifier-naming) +{ + const auto& args = s.args(); + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_set_dynamicOffsets : Invalid Native Object"); + + CC_UNUSED bool ok = true; + ok &= sevalue_to_native(args[0], &cobj->dynamicOffsets, s.thisObject()); + SE_PRECONDITION2(ok, false, "js_scene_DrawCall_set_dynamicOffsets : Error processing new value"); + return true; +} +SE_BIND_PROP_SET(js_scene_DrawCall_set_dynamicOffsets) + +static bool js_scene_DrawCall_get_drawInfo(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_get_drawInfo : Invalid Native Object"); + + CC_UNUSED bool ok = true; + se::Value jsret; + ok &= nativevalue_to_se(cobj->drawInfo, jsret, s.thisObject() /*ctx*/); + s.rval() = jsret; + SE_HOLD_RETURN_VALUE(cobj->drawInfo, s.thisObject(), s.rval()); + return true; +} +SE_BIND_PROP_GET(js_scene_DrawCall_get_drawInfo) + +static bool js_scene_DrawCall_set_drawInfo(se::State& s) // NOLINT(readability-identifier-naming) +{ + const auto& args = s.args(); + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawCall_set_drawInfo : Invalid Native Object"); + + CC_UNUSED bool ok = true; + ok &= sevalue_to_native(args[0], &cobj->drawInfo, s.thisObject()); + SE_PRECONDITION2(ok, false, "js_scene_DrawCall_set_drawInfo : Error processing new value"); + return true; +} +SE_BIND_PROP_SET(js_scene_DrawCall_set_drawInfo) + + +template<> +bool sevalue_to_native(const se::Value &from, cc::scene::DrawCall * to, se::Object *ctx) +{ + assert(from.isObject()); + se::Object *json = from.toObject(); + auto* data = reinterpret_cast(json->getPrivateData()); + if (data) { + *to = *data; + return true; + } + se::Value field; + bool ok = true; + json->getProperty("bufferView", &field); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->bufferView), ctx); + } + json->getProperty("descriptorSet", &field); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->descriptorSet), ctx); + } + json->getProperty("dynamicOffsets", &field); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->dynamicOffsets), ctx); + } + json->getProperty("drawInfo", &field); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->drawInfo), ctx); + } + return ok; +} + +SE_DECLARE_FINALIZE_FUNC(js_cc_scene_DrawCall_finalize) + +static bool js_scene_DrawCall_constructor(se::State& s) // NOLINT(readability-identifier-naming) +{ + CC_UNUSED bool ok = true; + const auto& args = s.args(); + size_t argc = args.size(); + + if(argc == 0) + { + cc::scene::DrawCall* cobj = JSB_ALLOC(cc::scene::DrawCall); + s.thisObject()->setPrivateData(cobj); + se::NonRefNativePtrCreatedByCtorMap::emplace(cobj); + return true; + } + + if(argc == 1 && args[0].isObject()) + { + se::Object *json = args[0].toObject(); + se::Value field; + + cc::scene::DrawCall* cobj = JSB_ALLOC(cc::scene::DrawCall); + ok &= sevalue_to_native(args[0], cobj, s.thisObject()); + if(!ok) { + JSB_FREE(cobj); + SE_REPORT_ERROR("argument convertion error"); + return false; + } + + s.thisObject()->setPrivateData(cobj); + se::NonRefNativePtrCreatedByCtorMap::emplace(cobj); + return true; + } + + cc::scene::DrawCall* cobj = JSB_ALLOC(cc::scene::DrawCall); + if (argc > 0 && !args[0].isUndefined()) { + ok &= sevalue_to_native(args[0], &(cobj->bufferView), nullptr); + } + if (argc > 1 && !args[1].isUndefined()) { + ok &= sevalue_to_native(args[1], &(cobj->descriptorSet), nullptr); + } + if (argc > 2 && !args[2].isUndefined()) { + ok &= sevalue_to_native(args[2], &(cobj->dynamicOffsets), nullptr); + } + if (argc > 3 && !args[3].isUndefined()) { + ok &= sevalue_to_native(args[3], &(cobj->drawInfo), nullptr); + } + + if(!ok) { + JSB_FREE(cobj); + SE_REPORT_ERROR("Argument convertion error"); + return false; + } + + s.thisObject()->setPrivateData(cobj); + se::NonRefNativePtrCreatedByCtorMap::emplace(cobj); + return true; +} +SE_BIND_CTOR(js_scene_DrawCall_constructor, __jsb_cc_scene_DrawCall_class, js_cc_scene_DrawCall_finalize) + + + +static bool js_cc_scene_DrawCall_finalize(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto iter = se::NonRefNativePtrCreatedByCtorMap::find(SE_THIS_OBJECT(s)); + if (iter != se::NonRefNativePtrCreatedByCtorMap::end()) + { + se::NonRefNativePtrCreatedByCtorMap::erase(iter); + auto* cobj = SE_THIS_OBJECT(s); + JSB_FREE(cobj); + } + return true; +} +SE_BIND_FINALIZE_FUNC(js_cc_scene_DrawCall_finalize) + +bool js_register_scene_DrawCall(se::Object* obj) // NOLINT(readability-identifier-naming) +{ + auto* cls = se::Class::create("DrawCall", obj, nullptr, _SE(js_scene_DrawCall_constructor)); + + cls->defineProperty("bufferView", _SE(js_scene_DrawCall_get_bufferView), _SE(js_scene_DrawCall_set_bufferView)); + cls->defineProperty("descriptorSet", _SE(js_scene_DrawCall_get_descriptorSet), _SE(js_scene_DrawCall_set_descriptorSet)); + cls->defineProperty("dynamicOffsets", _SE(js_scene_DrawCall_get_dynamicOffsets), _SE(js_scene_DrawCall_set_dynamicOffsets)); + cls->defineProperty("drawInfo", _SE(js_scene_DrawCall_get_drawInfo), _SE(js_scene_DrawCall_set_drawInfo)); + cls->defineFunction("setDynamicOffsets", _SE(js_scene_DrawCall_setDynamicOffsets)); + cls->defineFinalizeFunction(_SE(js_cc_scene_DrawCall_finalize)); + cls->install(); + JSBClassType::registerClass(cls); + + __jsb_cc_scene_DrawCall_proto = cls->getProto(); + __jsb_cc_scene_DrawCall_class = cls; + + se::ScriptEngine::getInstance()->clearException(); + return true; +} se::Object* __jsb_cc_scene_DrawBatch2D_proto = nullptr; se::Class* __jsb_cc_scene_DrawBatch2D_class = nullptr; +static bool js_scene_DrawBatch2D_clearDrawCalls(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawBatch2D_clearDrawCalls : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + if (argc == 0) { + cobj->clearDrawCalls(); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0); + return false; +} +SE_BIND_FUNC(js_scene_DrawBatch2D_clearDrawCalls) + +static bool js_scene_DrawBatch2D_pushDrawCall(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawBatch2D_pushDrawCall : Invalid Native Object"); + const auto& args = s.args(); + size_t argc = args.size(); + CC_UNUSED bool ok = true; + if (argc == 1) { + HolderType arg0 = {}; + ok &= sevalue_to_native(args[0], &arg0, s.thisObject()); + SE_PRECONDITION2(ok, false, "js_scene_DrawBatch2D_pushDrawCall : Error processing arguments"); + cobj->pushDrawCall(arg0.value()); + return true; + } + SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1); + return false; +} +SE_BIND_FUNC(js_scene_DrawBatch2D_pushDrawCall) + +static bool js_scene_DrawBatch2D_get_drawCalls(se::State& s) // NOLINT(readability-identifier-naming) +{ + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawBatch2D_get_drawCalls : Invalid Native Object"); + + CC_UNUSED bool ok = true; + se::Value jsret; + ok &= nativevalue_to_se(cobj->drawCalls, jsret, s.thisObject() /*ctx*/); + s.rval() = jsret; + SE_HOLD_RETURN_VALUE(cobj->drawCalls, s.thisObject(), s.rval()); + return true; +} +SE_BIND_PROP_GET(js_scene_DrawBatch2D_get_drawCalls) + +static bool js_scene_DrawBatch2D_set_drawCalls(se::State& s) // NOLINT(readability-identifier-naming) +{ + const auto& args = s.args(); + auto* cobj = SE_THIS_OBJECT(s); + SE_PRECONDITION2(cobj, false, "js_scene_DrawBatch2D_set_drawCalls : Invalid Native Object"); + + CC_UNUSED bool ok = true; + ok &= sevalue_to_native(args[0], &cobj->drawCalls, s.thisObject()); + SE_PRECONDITION2(ok, false, "js_scene_DrawBatch2D_set_drawCalls : Error processing new value"); + return true; +} +SE_BIND_PROP_SET(js_scene_DrawBatch2D_set_drawCalls) + template<> bool sevalue_to_native(const se::Value &from, cc::scene::DrawBatch2D * to, se::Object *ctx) @@ -5978,6 +6295,10 @@ bool sevalue_to_native(const se::Value &from, cc::scene::DrawBatch2D * to, se::O if(!field.isNullOrUndefined()) { ok &= sevalue_to_native(field, &(to->shaders), ctx); } + json->getProperty("drawCalls", &field); + if(!field.isNullOrUndefined()) { + ok &= sevalue_to_native(field, &(to->drawCalls), ctx); + } return ok; } @@ -6031,6 +6352,9 @@ static bool js_scene_DrawBatch2D_constructor(se::State& s) // NOLINT(readability if (argc > 4 && !args[4].isUndefined()) { ok &= sevalue_to_native(args[4], &(cobj->shaders), nullptr); } + if (argc > 5 && !args[5].isUndefined()) { + ok &= sevalue_to_native(args[5], &(cobj->drawCalls), nullptr); + } if(!ok) { JSB_FREE(cobj); @@ -6063,6 +6387,9 @@ bool js_register_scene_DrawBatch2D(se::Object* obj) // NOLINT(readability-identi { auto* cls = se::Class::create("DrawBatch2D", obj, nullptr, _SE(js_scene_DrawBatch2D_constructor)); + cls->defineProperty("drawCalls", _SE(js_scene_DrawBatch2D_get_drawCalls), _SE(js_scene_DrawBatch2D_set_drawCalls)); + cls->defineFunction("clearDrawCalls", _SE(js_scene_DrawBatch2D_clearDrawCalls)); + cls->defineFunction("pushDrawCall", _SE(js_scene_DrawBatch2D_pushDrawCall)); cls->defineFinalizeFunction(_SE(js_cc_scene_DrawBatch2D_finalize)); cls->install(); JSBClassType::registerClass(cls); @@ -8155,35 +8482,36 @@ bool register_all_scene(se::Object* obj) } se::Object* ns = nsVal.toObject(); - js_register_scene_RenderScene(ns); - js_register_scene_Camera(ns); - js_register_scene_Fog(ns); js_register_scene_BaseNode(ns); + js_register_scene_Scene(ns); js_register_scene_Node(ns); - js_register_scene_Frustum(ns); - js_register_scene_DrawBatch2D(ns); js_register_scene_Light(ns); + js_register_scene_DirectionalLight(ns); + js_register_scene_Plane(ns); + js_register_scene_Frustum(ns); + js_register_scene_AABB(ns); + js_register_scene_SpotLight(ns); js_register_scene_SphereLight(ns); js_register_scene_Model(ns); - js_register_scene_BakedSkinningModel(ns); - js_register_scene_Plane(ns); - js_register_scene_JointTransform(ns); - js_register_scene_RenderWindow(ns); + js_register_scene_Fog(ns); js_register_scene_Shadow(ns); - js_register_scene_SubModel(ns); - js_register_scene_BakedJointInfo(ns); - js_register_scene_AABB(ns); + js_register_scene_Skybox(ns); js_register_scene_Ambient(ns); - js_register_scene_SkinningModel(ns); - js_register_scene_DirectionalLight(ns); - js_register_scene_JointInfo(ns); + js_register_scene_PipelineSharedSceneData(ns); js_register_scene_Root(ns); - js_register_scene_Scene(ns); - js_register_scene_BakedAnimInfo(ns); + js_register_scene_SubModel(ns); js_register_scene_Pass(ns); - js_register_scene_Skybox(ns); - js_register_scene_PipelineSharedSceneData(ns); - js_register_scene_SpotLight(ns); + js_register_scene_BakedAnimInfo(ns); + js_register_scene_BakedJointInfo(ns); + js_register_scene_BakedSkinningModel(ns); + js_register_scene_DrawCall(ns); + js_register_scene_DrawBatch2D(ns); + js_register_scene_JointTransform(ns); + js_register_scene_JointInfo(ns); + js_register_scene_SkinningModel(ns); + js_register_scene_RenderScene(ns); + js_register_scene_RenderWindow(ns); + js_register_scene_Camera(ns); return true; } diff --git a/native/cocos/bindings/auto/jsb_scene_auto.h b/native/cocos/bindings/auto/jsb_scene_auto.h index 146eeffbf21..190570321fd 100644 --- a/native/cocos/bindings/auto/jsb_scene_auto.h +++ b/native/cocos/bindings/auto/jsb_scene_auto.h @@ -336,6 +336,17 @@ SE_DECLARE_FUNC(js_scene_BakedSkinningModel_setJointMedium); SE_DECLARE_FUNC(js_scene_BakedSkinningModel_updateModelBounds); SE_DECLARE_FUNC(js_scene_BakedSkinningModel_BakedSkinningModel); +extern se::Object* __jsb_cc_scene_DrawCall_proto; +extern se::Class* __jsb_cc_scene_DrawCall_class; + +bool js_register_cc_scene_DrawCall(se::Object* obj); +bool register_all_scene(se::Object* obj); + +template<> +bool sevalue_to_native(const se::Value &, cc::scene::DrawCall *, se::Object *ctx); +JSB_REGISTER_OBJECT_TYPE(cc::scene::DrawCall); +SE_DECLARE_FUNC(js_scene_DrawCall_setDynamicOffsets); + extern se::Object* __jsb_cc_scene_DrawBatch2D_proto; extern se::Class* __jsb_cc_scene_DrawBatch2D_class; @@ -345,6 +356,8 @@ bool register_all_scene(se::Object* obj); template<> bool sevalue_to_native(const se::Value &, cc::scene::DrawBatch2D *, se::Object *ctx); JSB_REGISTER_OBJECT_TYPE(cc::scene::DrawBatch2D); +SE_DECLARE_FUNC(js_scene_DrawBatch2D_clearDrawCalls); +SE_DECLARE_FUNC(js_scene_DrawBatch2D_pushDrawCall); extern se::Object* __jsb_cc_scene_JointTransform_proto; extern se::Class* __jsb_cc_scene_JointTransform_class; diff --git a/native/cocos/renderer/gfx-vulkan/VKDevice.cpp b/native/cocos/renderer/gfx-vulkan/VKDevice.cpp index c1e343853fa..47242737925 100644 --- a/native/cocos/renderer/gfx-vulkan/VKDevice.cpp +++ b/native/cocos/renderer/gfx-vulkan/VKDevice.cpp @@ -270,8 +270,8 @@ bool CCVKDevice::doInit(const DeviceInfo & /*info*/) { const VkPhysicalDeviceLimits &limits = _gpuContext->physicalDeviceProperties.limits; _caps.maxVertexAttributes = limits.maxVertexInputAttributes; - _caps.maxVertexUniformVectors = limits.maxPerStageDescriptorUniformBuffers; - _caps.maxFragmentUniformVectors = limits.maxPerStageDescriptorUniformBuffers; + _caps.maxVertexUniformVectors = limits.maxUniformBufferRange / 16; + _caps.maxFragmentUniformVectors = limits.maxUniformBufferRange / 16; _caps.maxUniformBufferBindings = limits.maxDescriptorSetUniformBuffers; _caps.maxUniformBlockSize = limits.maxUniformBufferRange; _caps.maxShaderStorageBlockSize = limits.maxStorageBufferRange; diff --git a/native/cocos/renderer/pipeline/common/UIPhase.cpp b/native/cocos/renderer/pipeline/common/UIPhase.cpp index bb367169c32..5dd981f0696 100644 --- a/native/cocos/renderer/pipeline/common/UIPhase.cpp +++ b/native/cocos/renderer/pipeline/common/UIPhase.cpp @@ -41,6 +41,7 @@ void UIPhase::render(scene::Camera *camera, gfx::RenderPass *renderPass) { auto *cmdBuff = _pipeline->getCommandBuffers()[0]; const auto &batches = camera->scene->getDrawBatch2Ds(); + // Notice: The batches[0] is batchCount for (auto *batch : batches) { if (!(camera->visibility & batch->visFlags)) continue; for (size_t i = 0; i < batch->shaders.size(); ++i) { @@ -48,13 +49,16 @@ void UIPhase::render(scene::Camera *camera, gfx::RenderPass *renderPass) { if (pass->getPhase() != _phaseID) continue; auto *shader = batch->shaders[i]; auto *inputAssembler = batch->inputAssembler; - auto *ds = batch->descriptorSet; + // auto *ds = batch->descriptorSet; auto *pso = PipelineStateManager::getOrCreatePipelineState(pass, shader, inputAssembler, renderPass); cmdBuff->bindPipelineState(pso); cmdBuff->bindDescriptorSet(materialSet, pass->getDescriptorSet()); - cmdBuff->bindDescriptorSet(localSet, ds); cmdBuff->bindInputAssembler(inputAssembler); - cmdBuff->draw(inputAssembler); + for (auto *drawCall : batch->drawCalls) { + auto *ds = drawCall->descriptorSet; + cmdBuff->bindDescriptorSet(localSet, ds, drawCall->dynamicOffsets); + cmdBuff->draw(*drawCall->drawInfo); + } } } } diff --git a/native/cocos/renderer/pipeline/forward/UIPhase.cpp b/native/cocos/renderer/pipeline/forward/UIPhase.cpp deleted file mode 100644 index a1ac83ad21c..00000000000 --- a/native/cocos/renderer/pipeline/forward/UIPhase.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** - Copyright (c) 2020-2021 Xiamen Yaji Software Co., Ltd. - - http://www.cocos.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated engine source code (the "Software"), a limited, - worldwide, royalty-free, non-assignable, revocable and non-exclusive license - to use Cocos Creator solely to develop games on your target platforms. You shall - not use Cocos Creator software for developing other software or tools that's - used for developing games. You are not granted to publish, distribute, - sublicense, and/or sell copies of Cocos Creator. - - The software or tools in this License Agreement are licensed, not sold. - Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -****************************************************************************/ - -#include "UIPhase.h" -#include "gfx-base/GFXCommandBuffer.h" -#include "pipeline/PipelineStateManager.h" -#include "scene/RenderScene.h" -#include "scene/SubModel.h" - -namespace cc { -namespace pipeline { - -void UIPhase::activate(RenderPipeline *pipeline) { - _pipeline = pipeline; - _phaseID = getPhaseID("default"); -}; - -void UIPhase::render(scene::Camera *camera, gfx::RenderPass *renderPass) { - auto *cmdBuff = _pipeline->getCommandBuffers()[0]; - - const auto &batches = camera->scene->getDrawBatch2Ds(); - // Notice: The batches[0] is batchCount - for (auto *batch : batches) { - if (!(camera->visibility & batch->visFlags)) continue; - for (size_t i = 0; i < batch->shaders.size(); ++i) { - const auto *pass = batch->passes[i]; - if (pass->getPhase() != _phaseID) continue; - auto *shader = batch->shaders[i]; - auto *inputAssembler = batch->inputAssembler; - auto *ds = batch->descriptorSet; - auto *pso = PipelineStateManager::getOrCreatePipelineState(pass, shader, inputAssembler, renderPass); - cmdBuff->bindPipelineState(pso); - cmdBuff->bindDescriptorSet(materialSet, pass->getDescriptorSet()); - cmdBuff->bindDescriptorSet(localSet, ds); - cmdBuff->bindInputAssembler(inputAssembler); - cmdBuff->draw(inputAssembler); - } - } -} - -} // namespace pipeline -} // namespace cc diff --git a/native/cocos/scene/DrawBatch2D.h b/native/cocos/scene/DrawBatch2D.h index 30a9eeac8d2..a777b571e5f 100644 --- a/native/cocos/scene/DrawBatch2D.h +++ b/native/cocos/scene/DrawBatch2D.h @@ -34,12 +34,33 @@ namespace scene { class Pass; +struct DrawCall final { + gfx::Buffer * bufferView{nullptr}; + gfx::DescriptorSet * descriptorSet{nullptr}; + std::vector dynamicOffsets; + gfx::DrawInfo * drawInfo; + + void setDynamicOffsets(uint32_t value) { + dynamicOffsets.push_back(0); + dynamicOffsets.push_back(value); + } +}; + struct DrawBatch2D final { uint32_t visFlags{0}; gfx::DescriptorSet * descriptorSet{nullptr}; gfx::InputAssembler * inputAssembler{nullptr}; std::vector passes; std::vector shaders; + std::vector drawCalls; + + void pushDrawCall(DrawCall *dc) { + drawCalls.push_back(dc); + } + + void clearDrawCalls(){ + drawCalls.clear(); + } }; } // namespace scene diff --git a/native/tools/tojs/scene.ini b/native/tools/tojs/scene.ini index 82d7c3ace24..68a9d7deae3 100644 --- a/native/tools/tojs/scene.ini +++ b/native/tools/tojs/scene.ini @@ -32,7 +32,7 @@ hpp_headers = cocos/bindings/auto/jsb_gfx_auto.h # what classes to produce code for. You can use regular expressions here. When testing the regular # expression, it will be enclosed in "^$", like this: "^Menu*$". -classes = Light BaseNode Node Scene DirectionalLight SpotLight SphereLight Model SubModel Pass RenderScene DrawBatch2D Camera RenderWindow Frustum Plane AABB Fog Skybox Shadow PipelineSharedSceneData Ambient Root SkinningModel JointInfo JointTransform BakedSkinningModel BakedJointInfo BakedAnimInfo +classes = Light BaseNode Node Scene DirectionalLight SpotLight SphereLight Model SubModel Pass RenderScene DrawBatch2D Camera RenderWindow Frustum Plane AABB Fog Skybox Shadow PipelineSharedSceneData Ambient Root SkinningModel JointInfo JointTransform BakedSkinningModel BakedJointInfo BakedAnimInfo DrawCall # what should we skip? in the format ClassName::[function function] # ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also