From 1e8f6d24acc997864fe47a584cf747a1c5edde8e Mon Sep 17 00:00:00 2001 From: coulsonwang Date: Mon, 19 Aug 2019 10:12:00 +0800 Subject: [PATCH] fix render pipeline (#20041) --- cocos/renderer/CCPipelineDescriptor.h | 1 - cocos/renderer/CCRenderer.cpp | 112 +-------- cocos/renderer/CCRenderer.h | 4 +- cocos/renderer/CMakeLists.txt | 5 - cocos/renderer/backend/Backend.h | 1 - cocos/renderer/backend/BlendState.cpp | 29 --- cocos/renderer/backend/BlendState.h | 68 ------ cocos/renderer/backend/Device.h | 10 +- cocos/renderer/backend/ProgramState.h | 1 + cocos/renderer/backend/RenderPassDescriptor.h | 1 + cocos/renderer/backend/RenderPipeline.h | 6 +- cocos/renderer/backend/Types.h | 18 ++ cocos/renderer/backend/metal/BlendStateMTL.h | 78 ------ cocos/renderer/backend/metal/BlendStateMTL.mm | 107 --------- .../backend/metal/CommandBufferMTL.mm | 2 +- cocos/renderer/backend/metal/DeviceMTL.h | 9 +- cocos/renderer/backend/metal/DeviceMTL.mm | 14 +- .../backend/metal/RenderPipelineMTL.h | 18 +- .../backend/metal/RenderPipelineMTL.mm | 227 +++++++++++++++--- .../renderer/backend/opengl/BlendStateGL.cpp | 67 ------ cocos/renderer/backend/opengl/BlendStateGL.h | 71 ------ .../backend/opengl/CommandBufferGL.cpp | 10 +- cocos/renderer/backend/opengl/DeviceGL.cpp | 14 +- cocos/renderer/backend/opengl/DeviceGL.h | 9 +- cocos/renderer/backend/opengl/ProgramGL.cpp | 2 +- cocos/renderer/backend/opengl/ProgramGL.h | 2 +- .../backend/opengl/RenderPipelineGL.cpp | 46 +++- .../backend/opengl/RenderPipelineGL.h | 14 +- 28 files changed, 299 insertions(+), 647 deletions(-) delete mode 100644 cocos/renderer/backend/BlendState.cpp delete mode 100644 cocos/renderer/backend/BlendState.h delete mode 100644 cocos/renderer/backend/metal/BlendStateMTL.h delete mode 100644 cocos/renderer/backend/metal/BlendStateMTL.mm delete mode 100644 cocos/renderer/backend/opengl/BlendStateGL.cpp delete mode 100644 cocos/renderer/backend/opengl/BlendStateGL.h diff --git a/cocos/renderer/CCPipelineDescriptor.h b/cocos/renderer/CCPipelineDescriptor.h index 927f380aef..2c3f602e27 100644 --- a/cocos/renderer/CCPipelineDescriptor.h +++ b/cocos/renderer/CCPipelineDescriptor.h @@ -25,7 +25,6 @@ #include "platform/CCPlatformMacros.h" #include "renderer/backend/DepthStencilState.h" -#include "renderer/backend/BlendState.h" #include "renderer/backend/Texture.h" #include "renderer/backend/VertexLayout.h" #include "renderer/backend/RenderPassDescriptor.h" diff --git a/cocos/renderer/CCRenderer.cpp b/cocos/renderer/CCRenderer.cpp index 0fab37c441..d10275ba20 100644 --- a/cocos/renderer/CCRenderer.cpp +++ b/cocos/renderer/CCRenderer.cpp @@ -168,8 +168,6 @@ Renderer::Renderer() // for the batched TriangleCommand _triBatchesToDraw = (TriBatchToDraw*) malloc(sizeof(_triBatchesToDraw[0]) * _triBatchesToDrawCapacity); - - _renderPipelineCache.reserve(100); } Renderer::~Renderer() @@ -180,12 +178,7 @@ Renderer::~Renderer() free(_triBatchesToDraw); CC_SAFE_RELEASE(_commandBuffer); - - for (auto pipeline :_renderPipelineCache) - { - pipeline.second->release(); - } - _renderPipelineCache.clear(); + CC_SAFE_RELEASE(_renderPipeline); } void Renderer::init() @@ -197,6 +190,8 @@ void Renderer::init() auto device = backend::Device::getInstance(); _commandBuffer = device->newCommandBuffer(); + _renderPipeline = device->newRenderPipeline(); + _commandBuffer->setRenderPipeline(_renderPipeline); } void Renderer::addCommand(RenderCommand* command) @@ -752,113 +747,20 @@ bool Renderer::checkVisibility(const Mat4 &transform, const Size &size) return ret; } -backend::RenderPipeline* Renderer::getRenderPipeline(const backend::RenderPipelineDescriptor& renderPipelineDescriptor, const backend::BlendDescriptor blendDescriptor) -{ - struct - { - void* program; - unsigned int vertexLayoutInfo[32]; - backend::PixelFormat colorAttachment; - backend::PixelFormat depthAttachment; - backend::PixelFormat stencilAttachment; - bool blendEnabled; - unsigned int writeMask; - unsigned int rgbBlendOperation; - unsigned int alphaBlendOperation; - unsigned int sourceRGBBlendFactor; - unsigned int destinationRGBBlendFactor; - unsigned int sourceAlphaBlendFactor; - unsigned int destinationAlphaBlendFactor; - }hashMe; - - memset(&hashMe, 0, sizeof(hashMe)); - hashMe.program = renderPipelineDescriptor.programState->getProgram(); - hashMe.colorAttachment = renderPipelineDescriptor.colorAttachmentsFormat[0]; - hashMe.depthAttachment = renderPipelineDescriptor.depthAttachmentFormat; - hashMe.stencilAttachment = renderPipelineDescriptor.stencilAttachmentFormat; - hashMe.blendEnabled = blendDescriptor.blendEnabled; - hashMe.writeMask = (unsigned int)blendDescriptor.writeMask; - hashMe.rgbBlendOperation = (unsigned int)blendDescriptor.rgbBlendOperation; - hashMe.alphaBlendOperation = (unsigned int)blendDescriptor.alphaBlendOperation; - hashMe.sourceRGBBlendFactor = (unsigned int)blendDescriptor.sourceRGBBlendFactor; - hashMe.destinationRGBBlendFactor = (unsigned int)blendDescriptor.destinationRGBBlendFactor; - hashMe.sourceAlphaBlendFactor = (unsigned int)blendDescriptor.sourceAlphaBlendFactor; - hashMe.destinationAlphaBlendFactor = (unsigned int)blendDescriptor.destinationAlphaBlendFactor; - int index = 0; - auto vertexLayout = renderPipelineDescriptor.programState->getVertexLayout(); - const auto& attributes = vertexLayout->getAttributes(); - for (const auto& it : attributes) - { - auto &attribute = it.second; - /* - stepFunction:1 stride:15 offest:10 format:5 needNormalized:1 - bit31 bit30 ~ bit16 bit15 ~ bit6 bit5 ~ bit1 bit0 - */ - hashMe.vertexLayoutInfo[index++] = - ((unsigned int)vertexLayout->getVertexStepMode() & 0x1) << 31 | - ((unsigned int)(vertexLayout->getStride() & 0x7FFF)) << 16 | - ((unsigned int)attribute.offset & 0x3FF) << 6 | - ((unsigned int)attribute.format & 0x1F) << 1 | - ((unsigned int)attribute.needToBeNormallized & 0x1); - } - - unsigned int hash = XXH32((const void*)&hashMe, sizeof(hashMe), 0); - auto iter = _renderPipelineCache.find(hash); - if (_renderPipelineCache.end() == iter) - { - auto renderPipeline = backend::Device::getInstance()->newRenderPipeline(renderPipelineDescriptor); - _renderPipelineCache.emplace(hash, renderPipeline); - return renderPipeline; - } - else - { - return iter->second; - } -} - void Renderer::setRenderPipeline(const PipelineDescriptor& pipelineDescriptor, const backend::RenderPassDescriptor& renderPassDescriptor) { - backend::RenderPipelineDescriptor renderPipelineDescriptor; - renderPipelineDescriptor.programState = pipelineDescriptor.programState; - auto device = backend::Device::getInstance(); - auto blendState = device->createBlendState(pipelineDescriptor.blendDescriptor); - renderPipelineDescriptor.blendState = blendState; - - if (renderPassDescriptor.needColorAttachment) - { - // FIXME: now just handle color attachment 0. - if (renderPassDescriptor.colorAttachmentsTexture[0]) - renderPipelineDescriptor.colorAttachmentsFormat[0] = renderPassDescriptor.colorAttachmentsTexture[0]->getTextureFormat(); - } - + _renderPipeline->update(pipelineDescriptor, renderPassDescriptor); backend::DepthStencilState* depthStencilState = nullptr; auto needDepthStencilAttachment = renderPassDescriptor.depthTestEnabled || renderPassDescriptor.stencilTestEnabled; if (needDepthStencilAttachment) { depthStencilState = device->createDepthStencilState(_depthStencilDescriptor); - - if(renderPassDescriptor.depthAttachmentTexture) - { - renderPipelineDescriptor.depthAttachmentFormat = renderPassDescriptor.depthAttachmentTexture->getTextureFormat(); - } - else - { - renderPipelineDescriptor.depthAttachmentFormat = PixelFormat::D24S8; - } - - if (renderPassDescriptor.stencilAttachmentTexture) - { - renderPipelineDescriptor.stencilAttachmentFormat = renderPassDescriptor.stencilAttachmentTexture->getTextureFormat(); - } - else - { - renderPipelineDescriptor.stencilAttachmentFormat = PixelFormat::D24S8; - } } - - _commandBuffer->setRenderPipeline(getRenderPipeline(renderPipelineDescriptor, pipelineDescriptor.blendDescriptor)); _commandBuffer->setDepthStencilState(depthStencilState); +#ifdef CC_USE_METAL + _commandBuffer->setRenderPipeline(_renderPipeline); +#endif } void Renderer::beginRenderPass(RenderCommand* cmd) diff --git a/cocos/renderer/CCRenderer.h b/cocos/renderer/CCRenderer.h index 3149aed9ec..97624587f6 100644 --- a/cocos/renderer/CCRenderer.h +++ b/cocos/renderer/CCRenderer.h @@ -480,13 +480,11 @@ protected: */ void setRenderPipeline(const PipelineDescriptor&, const backend::RenderPassDescriptor&); - backend::RenderPipeline* getRenderPipeline(const backend::RenderPipelineDescriptor& renderPipelineDescriptor, const backend::BlendDescriptor blendDescriptor); - void pushStateBlock(); void popStateBlock(); - std::unordered_map _renderPipelineCache; + backend::RenderPipeline* _renderPipeline = nullptr; Viewport _viewport; CullMode _cullMode = CullMode::NONE; diff --git a/cocos/renderer/CMakeLists.txt b/cocos/renderer/CMakeLists.txt index 5f298fd083..d84c90d768 100644 --- a/cocos/renderer/CMakeLists.txt +++ b/cocos/renderer/CMakeLists.txt @@ -21,7 +21,6 @@ set(COCOS_RENDERER_HEADER renderer/ccShaders.h renderer/backend/Backend.h - renderer/backend/BlendState.h renderer/backend/Buffer.h renderer/backend/CommandBuffer.h renderer/backend/DepthStencilState.h @@ -61,7 +60,6 @@ set(COCOS_RENDERER_SRC renderer/CCTrianglesCommand.cpp renderer/ccShaders.cpp - renderer/backend/BlendState.cpp renderer/backend/CommandBuffer.cpp renderer/backend/DepthStencilState.cpp renderer/backend/Device.cpp @@ -92,7 +90,6 @@ list(APPEND COCOS_RENDERER_HEADER ) list(APPEND COCOS_RENDERER_SRC - renderer/backend/opengl/BlendStateGL.cpp renderer/backend/opengl/BufferGL.cpp renderer/backend/opengl/CommandBufferGL.cpp renderer/backend/opengl/DepthStencilStateGL.cpp @@ -108,7 +105,6 @@ list(APPEND COCOS_RENDERER_SRC else() list(APPEND COCOS_RENDERER_HEADER - renderer/backend/metal/BlendStateMTL.h renderer/backend/metal/BufferMTL.h renderer/backend/metal/BufferManager.h renderer/backend/metal/CommandBufferMTL.h @@ -123,7 +119,6 @@ list(APPEND COCOS_RENDERER_HEADER ) list(APPEND COCOS_RENDERER_SRC - renderer/backend/metal/BlendStateMTL.mm renderer/backend/metal/BufferMTL.mm renderer/backend/metal/BufferManager.mm renderer/backend/metal/CommandBufferMTL.mm diff --git a/cocos/renderer/backend/Backend.h b/cocos/renderer/backend/Backend.h index ff837a1cf6..755bc6614e 100644 --- a/cocos/renderer/backend/Backend.h +++ b/cocos/renderer/backend/Backend.h @@ -34,4 +34,3 @@ #include "renderer/backend/VertexLayout.h" #include "renderer/backend/Texture.h" #include "renderer/backend/DepthStencilState.h" -#include "renderer/backend/BlendState.h" diff --git a/cocos/renderer/backend/BlendState.cpp b/cocos/renderer/backend/BlendState.cpp deleted file mode 100644 index f27f232f2c..0000000000 --- a/cocos/renderer/backend/BlendState.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/**************************************************************************** - Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. - - http://www.cocos2d-x.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ - -#include "BlendState.h" - -CC_BACKEND_BEGIN - -CC_BACKEND_END diff --git a/cocos/renderer/backend/BlendState.h b/cocos/renderer/backend/BlendState.h deleted file mode 100644 index 46b2842128..0000000000 --- a/cocos/renderer/backend/BlendState.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** - Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. - - http://www.cocos2d-x.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ - -#pragma once - -#include "Macros.h" -#include "Types.h" -#include "base/CCRef.h" - -CC_BACKEND_BEGIN - -/** - * @addtogroup _backend - * @{ - */ - -/** - * @brief a structor to store blend descriptor - */ -struct BlendDescriptor -{ - ColorWriteMask writeMask = ColorWriteMask::ALL; - - bool blendEnabled = false; - - BlendOperation rgbBlendOperation = BlendOperation::ADD; - BlendOperation alphaBlendOperation = BlendOperation::ADD; - - BlendFactor sourceRGBBlendFactor = BlendFactor::ONE; - BlendFactor destinationRGBBlendFactor = BlendFactor::ZERO; - BlendFactor sourceAlphaBlendFactor = BlendFactor::ONE; - BlendFactor destinationAlphaBlendFactor = BlendFactor::ZERO; -}; - -/** - * @brief a class of blend state - */ -class BlendState : public cocos2d::Ref -{ -protected: - /// @name Constructor, Destructor and Initializers - virtual ~BlendState() = default; -}; - -// end of _backend group -/// @} -CC_BACKEND_END diff --git a/cocos/renderer/backend/Device.h b/cocos/renderer/backend/Device.h index 093fe5b5df..f43e38ee14 100644 --- a/cocos/renderer/backend/Device.h +++ b/cocos/renderer/backend/Device.h @@ -30,7 +30,6 @@ #include "RenderPassDescriptor.h" #include "Texture.h" #include "DepthStencilState.h" -#include "BlendState.h" #include "ProgramCache.h" #include "ShaderCache.h" #include "DeviceInfo.h" @@ -97,19 +96,12 @@ public: */ virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) = 0; - /** - * Create an auto released BlendState object. - * @param descriptor Specifies blend description. - * @return An auto release BlendState object. - */ - virtual BlendState* createBlendState(const BlendDescriptor& descriptor) = 0; - /** * New a RenderPipeline object, not auto released. * @param descriptor Specifies render pipeline description. * @return A RenderPipeline object. */ - virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) = 0; + virtual RenderPipeline* newRenderPipeline() = 0; /** * This property controls whether or not the drawables' diff --git a/cocos/renderer/backend/ProgramState.h b/cocos/renderer/backend/ProgramState.h index 817d144db1..f8226f50c4 100644 --- a/cocos/renderer/backend/ProgramState.h +++ b/cocos/renderer/backend/ProgramState.h @@ -39,6 +39,7 @@ CC_BACKEND_BEGIN class TextureBackend; +class VertexLayout; /** * @addtogroup _backend diff --git a/cocos/renderer/backend/RenderPassDescriptor.h b/cocos/renderer/backend/RenderPassDescriptor.h index f10f74eb76..67396c763a 100644 --- a/cocos/renderer/backend/RenderPassDescriptor.h +++ b/cocos/renderer/backend/RenderPassDescriptor.h @@ -45,6 +45,7 @@ struct RenderPassDescriptor { RenderPassDescriptor& operator=(const RenderPassDescriptor& descriptor); bool operator==(const RenderPassDescriptor& descriptor) const; + bool needDepthStencilAttachment() const { return depthTestEnabled || stencilTestEnabled; } float clearDepthValue = 0.f; float clearStencilValue = 0.f; diff --git a/cocos/renderer/backend/RenderPipeline.h b/cocos/renderer/backend/RenderPipeline.h index 4cc6f8159f..69bab64d11 100644 --- a/cocos/renderer/backend/RenderPipeline.h +++ b/cocos/renderer/backend/RenderPipeline.h @@ -27,9 +27,10 @@ #include "Macros.h" #include "Types.h" #include "base/CCRef.h" +#include "renderer/CCPipelineDescriptor.h" +#include "renderer/backend/RenderPassDescriptor.h" CC_BACKEND_BEGIN - /** * @addtogroup _backend * @{ @@ -40,6 +41,9 @@ CC_BACKEND_BEGIN */ class RenderPipeline : public cocos2d::Ref { +public: + virtual void update(const PipelineDescriptor & pipelineDescirptor, const RenderPassDescriptor& renderpassDescriptor) = 0; + protected: virtual ~RenderPipeline() = default; }; diff --git a/cocos/renderer/backend/Types.h b/cocos/renderer/backend/Types.h index 44ae63e0d5..99ceba4cb9 100644 --- a/cocos/renderer/backend/Types.h +++ b/cocos/renderer/backend/Types.h @@ -365,4 +365,22 @@ static const char* ATTRIBUTE_NAME_TEXCOORD = "a_texCoord"; static const char* ATTRIBUTE_NAME_TEXCOORD1 = "a_texCoord1"; static const char* ATTRIBUTE_NAME_TEXCOORD2 = "a_texCoord2"; static const char* ATTRIBUTE_NAME_TEXCOORD3 = "a_texCoord3"; + +/** + * @brief a structor to store blend descriptor + */ +struct BlendDescriptor +{ + ColorWriteMask writeMask = ColorWriteMask::ALL; + + bool blendEnabled = false; + + BlendOperation rgbBlendOperation = BlendOperation::ADD; + BlendOperation alphaBlendOperation = BlendOperation::ADD; + + BlendFactor sourceRGBBlendFactor = BlendFactor::ONE; + BlendFactor destinationRGBBlendFactor = BlendFactor::ZERO; + BlendFactor sourceAlphaBlendFactor = BlendFactor::ONE; + BlendFactor destinationAlphaBlendFactor = BlendFactor::ZERO; +}; CC_BACKEND_END diff --git a/cocos/renderer/backend/metal/BlendStateMTL.h b/cocos/renderer/backend/metal/BlendStateMTL.h deleted file mode 100644 index bfdd9da33f..0000000000 --- a/cocos/renderer/backend/metal/BlendStateMTL.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** - Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. - - http://www.cocos2d-x.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ - -#pragma once - -#include "../BlendState.h" -#import - -CC_BACKEND_BEGIN - -/** - * @addtogroup _metal - * @{ - */ - -/** - * @brief Blend descriptor - */ -struct BlendDescriptorMTL -{ - MTLColorWriteMask writeMask = MTLColorWriteMaskAll; - - bool blendEnabled = false; - - MTLBlendOperation rgbBlendOperation = MTLBlendOperationAdd; - MTLBlendOperation alphaBlendOperation = MTLBlendOperationAdd; - - MTLBlendFactor sourceRGBBlendFactor = MTLBlendFactorOne; - MTLBlendFactor destinationRGBBlendFactor = MTLBlendFactorZero; - MTLBlendFactor sourceAlphaBlendFactor = MTLBlendFactorOne; - MTLBlendFactor destinationAlphaBlendFactor = MTLBlendFactorZero; -}; - -/** - * @brief a class of BlendStateMTL - */ -class BlendStateMTL : public BlendState -{ -public: - /// @name Constructor, Destructor and Initializers - BlendStateMTL(const BlendDescriptor& descriptor); - - /// @name Setters & Getters - /** - * @brief get blend descritptor - * @return return a const reference of BlendDescriptorMTL - */ - inline const BlendDescriptorMTL& getBlendDescriptorMTL() const { return _blendDescriptorMTL; } - -private: - BlendDescriptorMTL _blendDescriptorMTL; -}; - -// end of metal group -/** @}*/ - -CC_BACKEND_END diff --git a/cocos/renderer/backend/metal/BlendStateMTL.mm b/cocos/renderer/backend/metal/BlendStateMTL.mm deleted file mode 100644 index dfda289ecb..0000000000 --- a/cocos/renderer/backend/metal/BlendStateMTL.mm +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** - Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. - - http://www.cocos2d-x.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ - -#include "BlendStateMTL.h" - -CC_BACKEND_BEGIN - - -namespace -{ - MTLColorWriteMask toMTLColorWriteMask(ColorWriteMask mask) - { - switch (mask) { - case ColorWriteMask::NONE: - return MTLColorWriteMaskNone; - case ColorWriteMask::RED: - return MTLColorWriteMaskRed; - case ColorWriteMask::GREEN: - return MTLColorWriteMaskGreen; - case ColorWriteMask::BLUE: - return MTLColorWriteMaskBlue; - case ColorWriteMask::ALPHA: - return MTLColorWriteMaskAlpha; - case ColorWriteMask::ALL: - return MTLColorWriteMaskAll; - } - } - - MTLBlendFactor toMTLBlendFactor(BlendFactor factor) - { - switch (factor) { - case BlendFactor::ZERO: - return MTLBlendFactorZero; - case BlendFactor::ONE: - return MTLBlendFactorOne; - case BlendFactor::SRC_COLOR: - return MTLBlendFactorSourceColor; - case BlendFactor::ONE_MINUS_SRC_COLOR: - return MTLBlendFactorOneMinusSourceColor; - case BlendFactor::SRC_ALPHA: - return MTLBlendFactorSourceAlpha; - case BlendFactor::ONE_MINUS_SRC_ALPHA: - return MTLBlendFactorOneMinusSourceAlpha; - case BlendFactor::DST_COLOR: - return MTLBlendFactorDestinationColor; - case BlendFactor::ONE_MINUS_DST_COLOR: - return MTLBlendFactorOneMinusDestinationColor; - case BlendFactor::DST_ALPHA: - return MTLBlendFactorDestinationAlpha; - case BlendFactor::ONE_MINUS_DST_ALPHA: - return MTLBlendFactorOneMinusDestinationAlpha; - case BlendFactor::SRC_ALPHA_SATURATE: - return MTLBlendFactorSourceAlphaSaturated; - case BlendFactor::BLEND_CLOLOR: - return MTLBlendFactorBlendColor; - } - } - - MTLBlendOperation toMTLBlendOperation(BlendOperation operation) - { - switch (operation) { - case BlendOperation::ADD: - return MTLBlendOperationAdd; - case BlendOperation::SUBTRACT: - return MTLBlendOperationSubtract; - case BlendOperation::RESERVE_SUBTRACT: - return MTLBlendOperationReverseSubtract; - } - } -} - -BlendStateMTL::BlendStateMTL(const BlendDescriptor& descriptor) -{ - _blendDescriptorMTL.writeMask = toMTLColorWriteMask(descriptor.writeMask); - _blendDescriptorMTL.blendEnabled = descriptor.blendEnabled; - - _blendDescriptorMTL.rgbBlendOperation = toMTLBlendOperation(descriptor.rgbBlendOperation); - _blendDescriptorMTL.alphaBlendOperation = toMTLBlendOperation(descriptor.alphaBlendOperation); - - _blendDescriptorMTL.sourceRGBBlendFactor = toMTLBlendFactor(descriptor.sourceRGBBlendFactor); - _blendDescriptorMTL.destinationRGBBlendFactor = toMTLBlendFactor(descriptor.destinationRGBBlendFactor); - _blendDescriptorMTL.sourceAlphaBlendFactor = toMTLBlendFactor(descriptor.sourceAlphaBlendFactor); - _blendDescriptorMTL.destinationAlphaBlendFactor = toMTLBlendFactor(descriptor.destinationAlphaBlendFactor); -} - -CC_BACKEND_END diff --git a/cocos/renderer/backend/metal/CommandBufferMTL.mm b/cocos/renderer/backend/metal/CommandBufferMTL.mm index 7694732f90..2df6d1b3fe 100644 --- a/cocos/renderer/backend/metal/CommandBufferMTL.mm +++ b/cocos/renderer/backend/metal/CommandBufferMTL.mm @@ -136,7 +136,7 @@ namespace mtlDescritpor.colorAttachments[0].storeAction = MTLStoreActionStore; } - if(descriptor.depthTestEnabled || descriptor.stencilTestEnabled) + if(descriptor.needDepthStencilAttachment()) { // Set depth attachment { diff --git a/cocos/renderer/backend/metal/DeviceMTL.h b/cocos/renderer/backend/metal/DeviceMTL.h index a638f64268..39805f2c96 100644 --- a/cocos/renderer/backend/metal/DeviceMTL.h +++ b/cocos/renderer/backend/metal/DeviceMTL.h @@ -103,19 +103,12 @@ public: */ virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) override; - /** - * Create a BlendState object. - * @param descriptor Specifies blend description. - * @return An auto release BlendState object. - */ - virtual BlendState* createBlendState(const BlendDescriptor& descriptor) override; - /** * New a RenderPipeline object. * @param descriptor Specifies render pipeline description. * @return A RenderPipeline object. */ - virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) override; + virtual RenderPipeline* newRenderPipeline() override; /** * This property controls whether or not the drawables' diff --git a/cocos/renderer/backend/metal/DeviceMTL.mm b/cocos/renderer/backend/metal/DeviceMTL.mm index 33cbc9e6d7..55a01b9b58 100644 --- a/cocos/renderer/backend/metal/DeviceMTL.mm +++ b/cocos/renderer/backend/metal/DeviceMTL.mm @@ -29,7 +29,6 @@ #include "ShaderModuleMTL.h" #include "DepthStencilStateMTL.h" #include "TextureMTL.h" -#include "BlendStateMTL.h" #include "Utils.h" #include "ProgramMTL.h" #include "DeviceInfoMTL.h" @@ -124,18 +123,9 @@ DepthStencilState* DeviceMTL::createDepthStencilState(const DepthStencilDescript return ret; } -BlendState* DeviceMTL::createBlendState(const BlendDescriptor& descriptor) +RenderPipeline* DeviceMTL::newRenderPipeline() { - auto ret = new (std::nothrow) BlendStateMTL(descriptor); - if (ret) - ret->autorelease(); - - return ret; -} - -RenderPipeline* DeviceMTL::newRenderPipeline(const RenderPipelineDescriptor& descriptor) -{ - return new (std::nothrow) RenderPipelineMTL(_mtlDevice, descriptor); + return new (std::nothrow) RenderPipelineMTL(_mtlDevice); } Program* DeviceMTL::newProgram(const std::string& vertexShader, const std::string& fragmentShader) diff --git a/cocos/renderer/backend/metal/RenderPipelineMTL.h b/cocos/renderer/backend/metal/RenderPipelineMTL.h index 179a4c4b45..323afd5f91 100644 --- a/cocos/renderer/backend/metal/RenderPipelineMTL.h +++ b/cocos/renderer/backend/metal/RenderPipelineMTL.h @@ -26,7 +26,6 @@ #include "../RenderPipeline.h" #include "../RenderPipelineDescriptor.h" -#include "BlendStateMTL.h" #include #include #include @@ -48,8 +47,9 @@ public: * @param mtlDevice The device for which MTLRenderPipelineState object was created. * @param descriptor Specify the render pipeline description. */ - RenderPipelineMTL(id mtlDevice, const RenderPipelineDescriptor& descriptor); + RenderPipelineMTL(id mtlDevice); ~RenderPipelineMTL(); + virtual void update(const PipelineDescriptor&, const RenderPassDescriptor&) override; /** * Get a MTLRenderPipelineState object. @@ -58,16 +58,20 @@ public: inline id getMTLRenderPipelineState() const { return _mtlRenderPipelineState; } private: - void setVertexLayout(MTLRenderPipelineDescriptor*, const RenderPipelineDescriptor&); - void setBlendState(MTLRenderPipelineColorAttachmentDescriptor*); - void setShaderModules(const RenderPipelineDescriptor&); - void setBlendStateAndFormat(const RenderPipelineDescriptor&); + void setVertexLayout(MTLRenderPipelineDescriptor*, const PipelineDescriptor&); + void setBlendState(MTLRenderPipelineColorAttachmentDescriptor*, const BlendDescriptor&); + void setShaderModules(const PipelineDescriptor&); + void setBlendStateAndFormat(const BlendDescriptor&, const RenderPassDescriptor&); + void getAttachmentFormat(const RenderPassDescriptor&, PixelFormat&, PixelFormat&, PixelFormat&); id _mtlRenderPipelineState = nil; id _mtlDevice = nil; MTLRenderPipelineDescriptor* _mtlRenderPipelineDescriptor = nil; - BlendDescriptorMTL _blendDescriptorMTL; + PixelFormat _colorAttachmentsFormat[MAX_COLOR_ATTCHMENT] = { PixelFormat::DEFAULT }; + PixelFormat _depthAttachmentFormat = PixelFormat::NONE; + PixelFormat _stencilAttachmentFormat = PixelFormat::NONE; + NSMutableDictionary* _mtlRenderPipelineStateCache = nil; }; // end of _metal group diff --git a/cocos/renderer/backend/metal/RenderPipelineMTL.mm b/cocos/renderer/backend/metal/RenderPipelineMTL.mm index 333a5e7045..fb680be6cf 100644 --- a/cocos/renderer/backend/metal/RenderPipelineMTL.mm +++ b/cocos/renderer/backend/metal/RenderPipelineMTL.mm @@ -28,6 +28,7 @@ #include "DepthStencilStateMTL.h" #include "Utils.h" #include "ProgramMTL.h" +#include "xxhash.h" CC_BACKEND_BEGIN @@ -88,36 +89,164 @@ namespace } return ret; } + + MTLColorWriteMask toMTLColorWriteMask(ColorWriteMask mask) + { + switch (mask) { + case ColorWriteMask::NONE: + return MTLColorWriteMaskNone; + case ColorWriteMask::RED: + return MTLColorWriteMaskRed; + case ColorWriteMask::GREEN: + return MTLColorWriteMaskGreen; + case ColorWriteMask::BLUE: + return MTLColorWriteMaskBlue; + case ColorWriteMask::ALPHA: + return MTLColorWriteMaskAlpha; + case ColorWriteMask::ALL: + return MTLColorWriteMaskAll; + } + } + + MTLBlendFactor toMTLBlendFactor(BlendFactor factor) + { + switch (factor) { + case BlendFactor::ZERO: + return MTLBlendFactorZero; + case BlendFactor::ONE: + return MTLBlendFactorOne; + case BlendFactor::SRC_COLOR: + return MTLBlendFactorSourceColor; + case BlendFactor::ONE_MINUS_SRC_COLOR: + return MTLBlendFactorOneMinusSourceColor; + case BlendFactor::SRC_ALPHA: + return MTLBlendFactorSourceAlpha; + case BlendFactor::ONE_MINUS_SRC_ALPHA: + return MTLBlendFactorOneMinusSourceAlpha; + case BlendFactor::DST_COLOR: + return MTLBlendFactorDestinationColor; + case BlendFactor::ONE_MINUS_DST_COLOR: + return MTLBlendFactorOneMinusDestinationColor; + case BlendFactor::DST_ALPHA: + return MTLBlendFactorDestinationAlpha; + case BlendFactor::ONE_MINUS_DST_ALPHA: + return MTLBlendFactorOneMinusDestinationAlpha; + case BlendFactor::SRC_ALPHA_SATURATE: + return MTLBlendFactorSourceAlphaSaturated; + case BlendFactor::BLEND_CLOLOR: + return MTLBlendFactorBlendColor; + } + } + + MTLBlendOperation toMTLBlendOperation(BlendOperation operation) + { + switch (operation) { + case BlendOperation::ADD: + return MTLBlendOperationAdd; + case BlendOperation::SUBTRACT: + return MTLBlendOperationSubtract; + case BlendOperation::RESERVE_SUBTRACT: + return MTLBlendOperationReverseSubtract; + } + } } -RenderPipelineMTL::RenderPipelineMTL(id mtlDevice, const RenderPipelineDescriptor& descriptor) +RenderPipelineMTL::RenderPipelineMTL(id mtlDevice) : _mtlDevice(mtlDevice) { + _mtlRenderPipelineStateCache = [NSMutableDictionary dictionaryWithCapacity:100]; + [_mtlRenderPipelineStateCache retain]; +} + +void RenderPipelineMTL::update(const PipelineDescriptor & pipelineDescirptor, + const RenderPassDescriptor& renderPassDescriptor) +{ + struct + { + void* program; + unsigned int vertexLayoutInfo[32]; + backend::PixelFormat colorAttachment; + backend::PixelFormat depthAttachment; + backend::PixelFormat stencilAttachment; + bool blendEnabled; + unsigned int writeMask; + unsigned int rgbBlendOperation; + unsigned int alphaBlendOperation; + unsigned int sourceRGBBlendFactor; + unsigned int destinationRGBBlendFactor; + unsigned int sourceAlphaBlendFactor; + unsigned int destinationAlphaBlendFactor; + }hashMe; + + memset(&hashMe, 0, sizeof(hashMe)); + const auto& blendDescriptor = pipelineDescirptor.blendDescriptor; + getAttachmentFormat(renderPassDescriptor, _colorAttachmentsFormat[0], _depthAttachmentFormat, _stencilAttachmentFormat); + hashMe.program = pipelineDescirptor.programState->getProgram(); + hashMe.colorAttachment = _colorAttachmentsFormat[0]; + hashMe.depthAttachment = _depthAttachmentFormat; + hashMe.stencilAttachment =_stencilAttachmentFormat; + hashMe.blendEnabled = blendDescriptor.blendEnabled; + hashMe.writeMask = (unsigned int)blendDescriptor.writeMask; + hashMe.rgbBlendOperation = (unsigned int)blendDescriptor.rgbBlendOperation; + hashMe.alphaBlendOperation = (unsigned int)blendDescriptor.alphaBlendOperation; + hashMe.sourceRGBBlendFactor = (unsigned int)blendDescriptor.sourceRGBBlendFactor; + hashMe.destinationRGBBlendFactor = (unsigned int)blendDescriptor.destinationRGBBlendFactor; + hashMe.sourceAlphaBlendFactor = (unsigned int)blendDescriptor.sourceAlphaBlendFactor; + hashMe.destinationAlphaBlendFactor = (unsigned int)blendDescriptor.destinationAlphaBlendFactor; + int index = 0; + auto vertexLayout = pipelineDescirptor.programState->getVertexLayout(); + const auto& attributes = vertexLayout->getAttributes(); + for (const auto& it : attributes) + { + auto &attribute = it.second; + /* + stepFunction:1 stride:15 offest:10 format:5 needNormalized:1 + bit31 bit30 ~ bit16 bit15 ~ bit6 bit5 ~ bit1 bit0 + */ + hashMe.vertexLayoutInfo[index++] = + ((unsigned int)vertexLayout->getVertexStepMode() & 0x1) << 31 | + ((unsigned int)(vertexLayout->getStride() & 0x7FFF)) << 16 | + ((unsigned int)attribute.offset & 0x3FF) << 6 | + ((unsigned int)attribute.format & 0x1F) << 1 | + ((unsigned int)attribute.needToBeNormallized & 0x1); + } + + NSUInteger hash = XXH32((const void*)&hashMe, sizeof(hashMe), 0); + NSNumber* key = [[NSNumber numberWithUnsignedInteger:hash] autorelease]; + id obj = [_mtlRenderPipelineStateCache objectForKey:key]; + if (obj != nil) + { + _mtlRenderPipelineState = obj; + return; + } + _mtlRenderPipelineDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; - setShaderModules(descriptor); - setVertexLayout(_mtlRenderPipelineDescriptor, descriptor); + setShaderModules(pipelineDescirptor); + setVertexLayout(_mtlRenderPipelineDescriptor, pipelineDescirptor); - auto blendState = static_cast(descriptor.blendState); - if (blendState) - _blendDescriptorMTL = blendState->getBlendDescriptorMTL(); + setBlendStateAndFormat(pipelineDescirptor.blendDescriptor, renderPassDescriptor); - setBlendStateAndFormat(descriptor); - NSError *error = nil; _mtlRenderPipelineState = [_mtlDevice newRenderPipelineStateWithDescriptor:_mtlRenderPipelineDescriptor error:&error]; if (error) NSLog(@"Can not create renderpipeline state: %@", error); - + [_mtlRenderPipelineDescriptor release]; + [_mtlRenderPipelineStateCache setObject:_mtlRenderPipelineState forKey:key]; } RenderPipelineMTL::~RenderPipelineMTL() { - [_mtlRenderPipelineState release]; + NSArray* values = [_mtlRenderPipelineStateCache allValues]; + for(id value in values) + { + [value release]; + } + [_mtlRenderPipelineStateCache release]; } -void RenderPipelineMTL::setVertexLayout(MTLRenderPipelineDescriptor* mtlDescriptor, const RenderPipelineDescriptor& descriptor) +void RenderPipelineMTL::setVertexLayout(MTLRenderPipelineDescriptor* mtlDescriptor, const PipelineDescriptor& descriptor) { int vertexIndex = 0; auto vertexLayout = descriptor.programState->getVertexLayout(); @@ -139,21 +268,22 @@ void RenderPipelineMTL::setVertexLayout(MTLRenderPipelineDescriptor* mtlDescript } -void RenderPipelineMTL::setBlendState(MTLRenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor) +void RenderPipelineMTL::setBlendState(MTLRenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor, + const BlendDescriptor& blendDescriptor) { - colorAttachmentDescriptor.blendingEnabled = _blendDescriptorMTL.blendEnabled; - colorAttachmentDescriptor.writeMask = _blendDescriptorMTL.writeMask; + colorAttachmentDescriptor.blendingEnabled = blendDescriptor.blendEnabled; + colorAttachmentDescriptor.writeMask = toMTLColorWriteMask(blendDescriptor.writeMask); - colorAttachmentDescriptor.rgbBlendOperation = _blendDescriptorMTL.rgbBlendOperation; - colorAttachmentDescriptor.alphaBlendOperation = _blendDescriptorMTL.alphaBlendOperation; + colorAttachmentDescriptor.rgbBlendOperation = toMTLBlendOperation(blendDescriptor.rgbBlendOperation); + colorAttachmentDescriptor.alphaBlendOperation = toMTLBlendOperation(blendDescriptor.alphaBlendOperation); - colorAttachmentDescriptor.sourceRGBBlendFactor = _blendDescriptorMTL.sourceRGBBlendFactor; - colorAttachmentDescriptor.destinationRGBBlendFactor = _blendDescriptorMTL.destinationRGBBlendFactor; - colorAttachmentDescriptor.sourceAlphaBlendFactor = _blendDescriptorMTL.sourceAlphaBlendFactor; - colorAttachmentDescriptor.destinationAlphaBlendFactor = _blendDescriptorMTL.destinationAlphaBlendFactor; + colorAttachmentDescriptor.sourceRGBBlendFactor = toMTLBlendFactor(blendDescriptor.sourceRGBBlendFactor); + colorAttachmentDescriptor.destinationRGBBlendFactor = toMTLBlendFactor(blendDescriptor.destinationRGBBlendFactor); + colorAttachmentDescriptor.sourceAlphaBlendFactor = toMTLBlendFactor(blendDescriptor.sourceAlphaBlendFactor); + colorAttachmentDescriptor.destinationAlphaBlendFactor = toMTLBlendFactor(blendDescriptor.destinationAlphaBlendFactor); } -void RenderPipelineMTL::setShaderModules(const RenderPipelineDescriptor& descriptor) +void RenderPipelineMTL::setShaderModules(const PipelineDescriptor& descriptor) { auto vertexShaderModule = static_cast(descriptor.programState->getProgram())->getVertexShader(); _mtlRenderPipelineDescriptor.vertexFunction = vertexShaderModule->getMTLFunction(); @@ -162,18 +292,61 @@ void RenderPipelineMTL::setShaderModules(const RenderPipelineDescriptor& descrip _mtlRenderPipelineDescriptor.fragmentFunction = fragShaderModule->getMTLFunction(); } -void RenderPipelineMTL::setBlendStateAndFormat(const RenderPipelineDescriptor& descriptor) +void RenderPipelineMTL::getAttachmentFormat(const RenderPassDescriptor& descriptor, + PixelFormat& colorFormat, + PixelFormat& depthFormat, + PixelFormat& stencilFormat) +{ + if (descriptor.needColorAttachment) + { + // FIXME: now just handle color attachment 0. + if (descriptor.colorAttachmentsTexture[0]) + colorFormat = descriptor.colorAttachmentsTexture[0]->getTextureFormat(); + } + else + { + colorFormat = PixelFormat::DEFAULT; + } + + if (descriptor.needDepthStencilAttachment()) + { + if(descriptor.depthAttachmentTexture) + { + depthFormat = descriptor.depthAttachmentTexture->getTextureFormat(); + } + else + { + depthFormat = PixelFormat::D24S8; + } + + if (descriptor.stencilAttachmentTexture) + { + stencilFormat = descriptor.stencilAttachmentTexture->getTextureFormat(); + } + else + { + stencilFormat = PixelFormat::D24S8; + } + } + else + { + depthFormat = stencilFormat = PixelFormat::NONE; + } +} + +void RenderPipelineMTL::setBlendStateAndFormat(const BlendDescriptor& blendDescriptor, + const RenderPassDescriptor& renderPassDescriptor) { for (int i = 0; i < MAX_COLOR_ATTCHMENT; ++i) { - if (PixelFormat::NONE == descriptor.colorAttachmentsFormat[i]) + if (PixelFormat::NONE == _colorAttachmentsFormat[i]) continue; - _mtlRenderPipelineDescriptor.colorAttachments[i].pixelFormat = Utils::toMTLPixelFormat(descriptor.colorAttachmentsFormat[i]); - setBlendState(_mtlRenderPipelineDescriptor.colorAttachments[i]); + _mtlRenderPipelineDescriptor.colorAttachments[i].pixelFormat = Utils::toMTLPixelFormat(_colorAttachmentsFormat[i]); + setBlendState(_mtlRenderPipelineDescriptor.colorAttachments[i], blendDescriptor); } - _mtlRenderPipelineDescriptor.depthAttachmentPixelFormat = Utils::toMTLPixelFormat(descriptor.depthAttachmentFormat); - _mtlRenderPipelineDescriptor.stencilAttachmentPixelFormat = Utils::toMTLPixelFormat(descriptor.stencilAttachmentFormat); + _mtlRenderPipelineDescriptor.depthAttachmentPixelFormat = Utils::toMTLPixelFormat(_depthAttachmentFormat); + _mtlRenderPipelineDescriptor.stencilAttachmentPixelFormat = Utils::toMTLPixelFormat(_stencilAttachmentFormat); } CC_BACKEND_END diff --git a/cocos/renderer/backend/opengl/BlendStateGL.cpp b/cocos/renderer/backend/opengl/BlendStateGL.cpp deleted file mode 100644 index bf99079095..0000000000 --- a/cocos/renderer/backend/opengl/BlendStateGL.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** - Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. - - http://www.cocos2d-x.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ - -#include "BlendStateGL.h" -#include "renderer/backend/opengl/UtilsGL.h" -CC_BACKEND_BEGIN - -void BlendStateGL::reset() -{ - glDisable(GL_BLEND); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -} - -BlendStateGL::BlendStateGL(const BlendDescriptor& descriptor) -: _blendEnabled(descriptor.blendEnabled) -, _rgbBlendOperation(UtilsGL::toGLBlendOperation(descriptor.rgbBlendOperation)) -, _alphaBlendOperation(UtilsGL::toGLBlendOperation(descriptor.alphaBlendOperation)) -, _sourceRGBBlendFactor(UtilsGL::toGLBlendFactor(descriptor.sourceRGBBlendFactor)) -, _destinationRGBBlendFactor(UtilsGL::toGLBlendFactor(descriptor.destinationRGBBlendFactor)) -, _sourceAlphaBlendFactor(UtilsGL::toGLBlendFactor(descriptor.sourceAlphaBlendFactor)) -, _destinationAlphaBlendFactor(UtilsGL::toGLBlendFactor(descriptor.destinationAlphaBlendFactor)) -, _writeMaskRed((uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::RED) -, _writeMaskGreen((uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::GREEN) -, _writeMaskBlue((uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::BLUE) -, _writeMaskAlpha((uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::ALPHA) -{ -} - -void BlendStateGL::apply() const -{ - if (_blendEnabled) - { - glEnable(GL_BLEND); - glBlendEquationSeparate(_rgbBlendOperation, _alphaBlendOperation); - glBlendFuncSeparate(_sourceRGBBlendFactor, - _destinationRGBBlendFactor, - _sourceAlphaBlendFactor, - _destinationAlphaBlendFactor); - } - else - glDisable(GL_BLEND); - - glColorMask(_writeMaskRed, _writeMaskGreen, _writeMaskBlue, _writeMaskAlpha); -} - -CC_BACKEND_END diff --git a/cocos/renderer/backend/opengl/BlendStateGL.h b/cocos/renderer/backend/opengl/BlendStateGL.h deleted file mode 100644 index b2c8ae225d..0000000000 --- a/cocos/renderer/backend/opengl/BlendStateGL.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** - Copyright (c) 2018-2019 Xiamen Yaji Software Co., Ltd. - - http://www.cocos2d-x.org - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ - -#pragma once - -#include "../BlendState.h" -#include "platform/CCGL.h" - -CC_BACKEND_BEGIN -/** - * @addtogroup _opengl - * @{ - */ - -/** - * Set blend state to pipeline - */ -class BlendStateGL : public BlendState -{ -public: - /// Reset to default state. - static void reset(); - - /** - * @descriptor Specifies the blend descriptor. - */ - BlendStateGL(const BlendDescriptor& descriptor); - - /// Set blend status to pipeline. - void apply() const; - -private: - GLboolean _writeMaskRed = GL_TRUE; - GLboolean _writeMaskGreen = GL_TRUE; - GLboolean _writeMaskBlue = GL_TRUE; - GLboolean _writeMaskAlpha = GL_TRUE; - - bool _blendEnabled = false; - - GLenum _rgbBlendOperation = GL_FUNC_ADD; - GLenum _alphaBlendOperation = GL_FUNC_ADD; - - GLenum _sourceRGBBlendFactor = GL_ONE; - GLenum _destinationRGBBlendFactor = GL_ZERO; - GLenum _sourceAlphaBlendFactor = GL_ONE; - GLenum _destinationAlphaBlendFactor = GL_ZERO; -}; -//end of _opengl group -/// @} -CC_BACKEND_END diff --git a/cocos/renderer/backend/opengl/CommandBufferGL.cpp b/cocos/renderer/backend/opengl/CommandBufferGL.cpp index 99f9163128..fb34916c90 100644 --- a/cocos/renderer/backend/opengl/CommandBufferGL.cpp +++ b/cocos/renderer/backend/opengl/CommandBufferGL.cpp @@ -28,7 +28,6 @@ #include "TextureGL.h" #include "DepthStencilStateGL.h" #include "ProgramGL.h" -#include "BlendStateGL.h" #include "base/ccMacros.h" #include "base/CCEventDispatcher.h" #include "base/CCEventType.h" @@ -88,6 +87,8 @@ CommandBufferGL::CommandBufferGL() CommandBufferGL::~CommandBufferGL() { glDeleteFramebuffers(1, &_generatedFBO); + CC_SAFE_RELEASE_NULL(_renderPipeline); + cleanResources(); #if CC_ENABLE_CACHE_TEXTURE_DATA @@ -390,12 +391,6 @@ void CommandBufferGL::prepareDrawing() const else DepthStencilStateGL::reset(); - // Set blend state. - if (_renderPipeline->getBlendState()) - _renderPipeline->getBlendState()->apply(); - else - BlendStateGL::reset(); - // Set cull mode. if (CullMode::NONE == _cullMode) { @@ -582,7 +577,6 @@ void CommandBufferGL::setUniform(bool isArray, GLuint location, unsigned int siz void CommandBufferGL::cleanResources() { CC_SAFE_RELEASE_NULL(_indexBuffer); - CC_SAFE_RELEASE_NULL(_renderPipeline); CC_SAFE_RELEASE_NULL(_programState); CC_SAFE_RELEASE_NULL(_vertexBuffer); } diff --git a/cocos/renderer/backend/opengl/DeviceGL.cpp b/cocos/renderer/backend/opengl/DeviceGL.cpp index 4dc75237fc..5fa719ea19 100644 --- a/cocos/renderer/backend/opengl/DeviceGL.cpp +++ b/cocos/renderer/backend/opengl/DeviceGL.cpp @@ -29,7 +29,6 @@ #include "CommandBufferGL.h" #include "TextureGL.h" #include "DepthStencilStateGL.h" -#include "BlendStateGL.h" #include "ProgramGL.h" #include "DeviceInfoGL.h" @@ -97,18 +96,9 @@ DepthStencilState* DeviceGL::createDepthStencilState(const DepthStencilDescripto return ret; } -BlendState* DeviceGL::createBlendState(const BlendDescriptor& descriptor) +RenderPipeline* DeviceGL::newRenderPipeline() { - auto ret = new (std::nothrow) BlendStateGL(descriptor); - if (ret) - ret->autorelease(); - - return ret; -} - -RenderPipeline* DeviceGL::newRenderPipeline(const RenderPipelineDescriptor& descriptor) -{ - return new (std::nothrow) RenderPipelineGL(descriptor); + return new (std::nothrow) RenderPipelineGL(); } Program* DeviceGL::newProgram(const std::string& vertexShader, const std::string& fragmentShader) diff --git a/cocos/renderer/backend/opengl/DeviceGL.h b/cocos/renderer/backend/opengl/DeviceGL.h index c82b40ef56..be752ac40b 100644 --- a/cocos/renderer/backend/opengl/DeviceGL.h +++ b/cocos/renderer/backend/opengl/DeviceGL.h @@ -68,19 +68,12 @@ public: */ virtual DepthStencilState* createDepthStencilState(const DepthStencilDescriptor& descriptor) override; - /** - * Create an auto released BlendState object. - * @param descriptor Specifies blend description. - * @return An auto release BlendState object. - */ - virtual BlendState* createBlendState(const BlendDescriptor& descriptor) override; - /** * New a RenderPipeline object, not auto released. * @param descriptor Specifies render pipeline description. * @return A RenderPipeline object. */ - virtual RenderPipeline* newRenderPipeline(const RenderPipelineDescriptor& descriptor) override; + virtual RenderPipeline* newRenderPipeline() override; /** * Design for metal. diff --git a/cocos/renderer/backend/opengl/ProgramGL.cpp b/cocos/renderer/backend/opengl/ProgramGL.cpp index 0142714b96..ae6f222d4c 100644 --- a/cocos/renderer/backend/opengl/ProgramGL.cpp +++ b/cocos/renderer/backend/opengl/ProgramGL.cpp @@ -335,7 +335,7 @@ int ProgramGL::getOriginalLocation(int location) const const UniformInfo& ProgramGL::getActiveUniformInfo(ShaderStage stage, int location) const { - return UniformInfo{}; + return std::move(UniformInfo{}); } const std::unordered_map& ProgramGL::getAllActiveUniformInfo(ShaderStage stage) const diff --git a/cocos/renderer/backend/opengl/ProgramGL.h b/cocos/renderer/backend/opengl/ProgramGL.h index 475d407282..d69c8f62b3 100644 --- a/cocos/renderer/backend/opengl/ProgramGL.h +++ b/cocos/renderer/backend/opengl/ProgramGL.h @@ -149,7 +149,7 @@ public: * @param location Specifies the uniform locaion. * @return The uniformInfo. */ - virtual const UniformInfo& getActiveUniformInfo(ShaderStage stage, int location) const; + virtual const UniformInfo& getActiveUniformInfo(ShaderStage stage, int location) const override; /** * Get all uniformInfos. diff --git a/cocos/renderer/backend/opengl/RenderPipelineGL.cpp b/cocos/renderer/backend/opengl/RenderPipelineGL.cpp index aa145cac3a..6889f20ce1 100644 --- a/cocos/renderer/backend/opengl/RenderPipelineGL.cpp +++ b/cocos/renderer/backend/opengl/RenderPipelineGL.cpp @@ -26,26 +26,56 @@ #include "ShaderModuleGL.h" #include "DepthStencilStateGL.h" #include "ProgramGL.h" -#include "BlendStateGL.h" +#include "UtilsGL.h" #include CC_BACKEND_BEGIN -RenderPipelineGL::RenderPipelineGL(const RenderPipelineDescriptor& descriptor) +void RenderPipelineGL::update(const PipelineDescriptor& pipelineDescirptor, const RenderPassDescriptor& renderpassDescriptor) { - _programGL = static_cast(descriptor.programState->getProgram()); - CC_SAFE_RETAIN(_programGL); + if(_programGL != pipelineDescirptor.programState->getProgram()) + { + CC_SAFE_RELEASE(_programGL); + _programGL = static_cast(pipelineDescirptor.programState->getProgram()); + CC_SAFE_RETAIN(_programGL); + } + + updateBlendState(pipelineDescirptor.blendDescriptor); +} - const auto& blendState = descriptor.blendState; - CC_SAFE_RETAIN(blendState); - _blendState = static_cast(blendState); +void RenderPipelineGL::updateBlendState(const BlendDescriptor& descriptor) +{ + auto blendEnabled = descriptor.blendEnabled; + auto rgbBlendOperation = UtilsGL::toGLBlendOperation(descriptor.rgbBlendOperation); + auto alphaBlendOperation = UtilsGL::toGLBlendOperation(descriptor.alphaBlendOperation); + auto sourceRGBBlendFactor = UtilsGL::toGLBlendFactor(descriptor.sourceRGBBlendFactor); + auto destinationRGBBlendFactor = UtilsGL::toGLBlendFactor(descriptor.destinationRGBBlendFactor); + auto sourceAlphaBlendFactor = UtilsGL::toGLBlendFactor(descriptor.sourceAlphaBlendFactor); + auto destinationAlphaBlendFactor = UtilsGL::toGLBlendFactor(descriptor.destinationAlphaBlendFactor); + auto writeMaskRed = (uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::RED; + auto writeMaskGreen = (uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::GREEN; + auto writeMaskBlue = (uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::BLUE; + auto writeMaskAlpha = (uint32_t)descriptor.writeMask & (uint32_t)ColorWriteMask::ALPHA; + + if (blendEnabled) + { + glEnable(GL_BLEND); + glBlendEquationSeparate(rgbBlendOperation, alphaBlendOperation); + glBlendFuncSeparate(sourceRGBBlendFactor, + destinationRGBBlendFactor, + sourceAlphaBlendFactor, + destinationAlphaBlendFactor); + } + else + glDisable(GL_BLEND); + + glColorMask(writeMaskRed, writeMaskGreen, writeMaskBlue, writeMaskAlpha); } RenderPipelineGL::~RenderPipelineGL() { CC_SAFE_RELEASE(_programGL); - CC_SAFE_RELEASE(_blendState); } CC_BACKEND_END diff --git a/cocos/renderer/backend/opengl/RenderPipelineGL.h b/cocos/renderer/backend/opengl/RenderPipelineGL.h index 15899dcc2d..f7986dd70b 100644 --- a/cocos/renderer/backend/opengl/RenderPipelineGL.h +++ b/cocos/renderer/backend/opengl/RenderPipelineGL.h @@ -34,7 +34,6 @@ CC_BACKEND_BEGIN class ProgramGL; -class BlendStateGL; /** * @addtogroup _opengl * @{ @@ -49,23 +48,20 @@ public: /** * @param descriptor Specifies render pipeline descriptor. */ - RenderPipelineGL(const RenderPipelineDescriptor& descriptor); + RenderPipelineGL() = default; ~RenderPipelineGL(); - + + virtual void update(const PipelineDescriptor & pipelineDescirptor, const RenderPassDescriptor& renderpassDescriptor) override; /** * Get program instance. * @return Program instance. */ inline ProgramGL* getProgram() const { return _programGL; } - /** - * Get blend state. - * @return Blend state. - */ - inline BlendStateGL* getBlendState() const { return _blendState; } private: + void updateBlendState(const BlendDescriptor& descriptor); + ProgramGL* _programGL = nullptr; - BlendStateGL* _blendState = nullptr; }; // end of _opengl group /// @}