mirror of https://github.com/axmolengine/axmol.git
fix render pipeline (#20041)
This commit is contained in:
parent
3c08471bab
commit
1e8f6d24ac
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<unsigned int, backend::RenderPipeline*> _renderPipelineCache;
|
||||
backend::RenderPipeline* _renderPipeline = nullptr;
|
||||
|
||||
Viewport _viewport;
|
||||
CullMode _cullMode = CullMode::NONE;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -34,4 +34,3 @@
|
|||
#include "renderer/backend/VertexLayout.h"
|
||||
#include "renderer/backend/Texture.h"
|
||||
#include "renderer/backend/DepthStencilState.h"
|
||||
#include "renderer/backend/BlendState.h"
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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'
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
CC_BACKEND_BEGIN
|
||||
|
||||
class TextureBackend;
|
||||
class VertexLayout;
|
||||
|
||||
/**
|
||||
* @addtogroup _backend
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <Metal/Metal.h>
|
||||
|
||||
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
|
|
@ -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
|
|
@ -136,7 +136,7 @@ namespace
|
|||
mtlDescritpor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
}
|
||||
|
||||
if(descriptor.depthTestEnabled || descriptor.stencilTestEnabled)
|
||||
if(descriptor.needDepthStencilAttachment())
|
||||
{
|
||||
// Set depth attachment
|
||||
{
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "../RenderPipeline.h"
|
||||
#include "../RenderPipelineDescriptor.h"
|
||||
#include "BlendStateMTL.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
@ -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> mtlDevice, const RenderPipelineDescriptor& descriptor);
|
||||
RenderPipelineMTL(id<MTLDevice> mtlDevice);
|
||||
~RenderPipelineMTL();
|
||||
virtual void update(const PipelineDescriptor&, const RenderPassDescriptor&) override;
|
||||
|
||||
/**
|
||||
* Get a MTLRenderPipelineState object.
|
||||
|
@ -58,16 +58,20 @@ public:
|
|||
inline id<MTLRenderPipelineState> 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> _mtlRenderPipelineState = nil;
|
||||
id<MTLDevice> _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
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "DepthStencilStateMTL.h"
|
||||
#include "Utils.h"
|
||||
#include "ProgramMTL.h"
|
||||
#include "xxhash.h"
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
|
@ -88,21 +89,143 @@ 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> mtlDevice, const RenderPipelineDescriptor& descriptor)
|
||||
RenderPipelineMTL::RenderPipelineMTL(id<MTLDevice> 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<BlendStateMTL*>(descriptor.blendState);
|
||||
if (blendState)
|
||||
_blendDescriptorMTL = blendState->getBlendDescriptorMTL();
|
||||
|
||||
setBlendStateAndFormat(descriptor);
|
||||
setBlendStateAndFormat(pipelineDescirptor.blendDescriptor, renderPassDescriptor);
|
||||
|
||||
NSError *error = nil;
|
||||
_mtlRenderPipelineState = [_mtlDevice newRenderPipelineStateWithDescriptor:_mtlRenderPipelineDescriptor error:&error];
|
||||
|
@ -110,14 +233,20 @@ RenderPipelineMTL::RenderPipelineMTL(id<MTLDevice> mtlDevice, const RenderPipeli
|
|||
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<ProgramMTL*>(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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<std::string, UniformInfo>& ProgramGL::getAllActiveUniformInfo(ShaderStage stage) const
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -26,26 +26,56 @@
|
|||
#include "ShaderModuleGL.h"
|
||||
#include "DepthStencilStateGL.h"
|
||||
#include "ProgramGL.h"
|
||||
#include "BlendStateGL.h"
|
||||
#include "UtilsGL.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
CC_BACKEND_BEGIN
|
||||
|
||||
RenderPipelineGL::RenderPipelineGL(const RenderPipelineDescriptor& descriptor)
|
||||
void RenderPipelineGL::update(const PipelineDescriptor& pipelineDescirptor, const RenderPassDescriptor& renderpassDescriptor)
|
||||
{
|
||||
_programGL = static_cast<ProgramGL*>(descriptor.programState->getProgram());
|
||||
CC_SAFE_RETAIN(_programGL);
|
||||
if(_programGL != pipelineDescirptor.programState->getProgram())
|
||||
{
|
||||
CC_SAFE_RELEASE(_programGL);
|
||||
_programGL = static_cast<ProgramGL*>(pipelineDescirptor.programState->getProgram());
|
||||
CC_SAFE_RETAIN(_programGL);
|
||||
}
|
||||
|
||||
const auto& blendState = descriptor.blendState;
|
||||
CC_SAFE_RETAIN(blendState);
|
||||
_blendState = static_cast<BlendStateGL*>(blendState);
|
||||
updateBlendState(pipelineDescirptor.blendDescriptor);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
/// @}
|
||||
|
|
Loading…
Reference in New Issue