no message
This commit is contained in:
96
cocos/renderer/gfx-gles2/GLES2Buffer.cpp
Normal file
96
cocos/renderer/gfx-gles2/GLES2Buffer.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Buffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "profiler/Profiler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Buffer::GLES2Buffer() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2Buffer::~GLES2Buffer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2Buffer::doInit(const BufferInfo & /*info*/) {
|
||||
_gpuBuffer = ccnew GLES2GPUBuffer;
|
||||
_gpuBuffer->usage = _usage;
|
||||
_gpuBuffer->memUsage = _memUsage;
|
||||
_gpuBuffer->size = _size;
|
||||
_gpuBuffer->stride = _stride;
|
||||
_gpuBuffer->count = _count;
|
||||
|
||||
if (hasFlag(_usage, BufferUsageBit::INDIRECT)) {
|
||||
_gpuBuffer->indirects.resize(_count);
|
||||
}
|
||||
|
||||
cmdFuncGLES2CreateBuffer(GLES2Device::getInstance(), _gpuBuffer);
|
||||
GLES2Device::getInstance()->getMemoryStatus().bufferSize += _size;
|
||||
CC_PROFILE_MEMORY_INC(Buffer, _size);
|
||||
}
|
||||
|
||||
void GLES2Buffer::doInit(const BufferViewInfo &info) {
|
||||
auto *buffer = static_cast<GLES2Buffer *>(info.buffer);
|
||||
_gpuBufferView = ccnew GLES2GPUBufferView;
|
||||
_gpuBufferView->gpuBuffer = buffer->gpuBuffer();
|
||||
_gpuBufferView->range = _size;
|
||||
_gpuBufferView->offset = info.offset;
|
||||
}
|
||||
|
||||
void GLES2Buffer::doDestroy() {
|
||||
if (_gpuBuffer) {
|
||||
GLES2Device::getInstance()->getMemoryStatus().bufferSize -= _size;
|
||||
CC_PROFILE_MEMORY_DEC(Buffer, _size);
|
||||
cmdFuncGLES2DestroyBuffer(GLES2Device::getInstance(), _gpuBuffer);
|
||||
delete _gpuBuffer;
|
||||
_gpuBuffer = nullptr;
|
||||
}
|
||||
|
||||
CC_SAFE_DELETE(_gpuBufferView);
|
||||
}
|
||||
|
||||
void GLES2Buffer::doResize(uint32_t size, uint32_t count) {
|
||||
GLES2Device::getInstance()->getMemoryStatus().bufferSize -= _size;
|
||||
CC_PROFILE_MEMORY_DEC(Buffer, _size);
|
||||
_gpuBuffer->size = size;
|
||||
_gpuBuffer->count = count;
|
||||
cmdFuncGLES2ResizeBuffer(GLES2Device::getInstance(), _gpuBuffer);
|
||||
GLES2Device::getInstance()->getMemoryStatus().bufferSize += size;
|
||||
CC_PROFILE_MEMORY_INC(Buffer, size);
|
||||
}
|
||||
|
||||
void GLES2Buffer::update(const void *buffer, uint32_t size) {
|
||||
CC_PROFILE(GLES2BufferUpdate);
|
||||
cmdFuncGLES2UpdateBuffer(GLES2Device::getInstance(), _gpuBuffer, buffer, 0U, size);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
57
cocos/renderer/gfx-gles2/GLES2Buffer.h
Normal file
57
cocos/renderer/gfx-gles2/GLES2Buffer.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXBuffer.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUBuffer;
|
||||
struct GLES2GPUBufferView;
|
||||
|
||||
class CC_GLES2_API GLES2Buffer final : public Buffer {
|
||||
public:
|
||||
GLES2Buffer();
|
||||
~GLES2Buffer() override;
|
||||
|
||||
void update(const void *buffer, uint32_t size) override;
|
||||
|
||||
inline GLES2GPUBuffer *gpuBuffer() const { return _gpuBuffer; }
|
||||
inline GLES2GPUBufferView *gpuBufferView() const { return _gpuBufferView; }
|
||||
|
||||
protected:
|
||||
void doInit(const BufferInfo &info) override;
|
||||
void doInit(const BufferViewInfo &info) override;
|
||||
void doDestroy() override;
|
||||
void doResize(uint32_t size, uint32_t count) override;
|
||||
|
||||
GLES2GPUBuffer *_gpuBuffer = nullptr;
|
||||
GLES2GPUBufferView *_gpuBufferView = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
424
cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp
Normal file
424
cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp
Normal file
@@ -0,0 +1,424 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Buffer.h"
|
||||
#include "GLES2CommandBuffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2DescriptorSet.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2Framebuffer.h"
|
||||
#include "GLES2InputAssembler.h"
|
||||
#include "GLES2PipelineState.h"
|
||||
#include "GLES2RenderPass.h"
|
||||
#include "GLES2Texture.h"
|
||||
#include "profiler/Profiler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2CommandBuffer::GLES2CommandBuffer() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2CommandBuffer::~GLES2CommandBuffer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::doInit(const CommandBufferInfo &info) {
|
||||
_type = info.type;
|
||||
_queue = info.queue;
|
||||
|
||||
_cmdAllocator = ccnew GLES2GPUCommandAllocator;
|
||||
_curCmdPackage = ccnew GLES2CmdPackage;
|
||||
|
||||
size_t setCount = GLES2Device::getInstance()->bindingMappingInfo().setIndices.size();
|
||||
_curGPUDescriptorSets.resize(setCount);
|
||||
_curDynamicOffsets.resize(setCount);
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::doDestroy() {
|
||||
if (!_cmdAllocator) return;
|
||||
|
||||
_cmdAllocator->clearCmds(_curCmdPackage);
|
||||
CC_SAFE_DELETE(_curCmdPackage);
|
||||
|
||||
while (!_pendingPackages.empty()) {
|
||||
GLES2CmdPackage *package = _pendingPackages.front();
|
||||
_cmdAllocator->clearCmds(package);
|
||||
CC_SAFE_DELETE(package);
|
||||
_pendingPackages.pop();
|
||||
}
|
||||
|
||||
while (!_freePackages.empty()) {
|
||||
GLES2CmdPackage *package = _freePackages.front();
|
||||
_cmdAllocator->clearCmds(package);
|
||||
CC_SAFE_DELETE(package);
|
||||
_freePackages.pop();
|
||||
}
|
||||
|
||||
_cmdAllocator->reset();
|
||||
CC_SAFE_DELETE(_cmdAllocator);
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::begin(RenderPass * /*renderPass*/, uint32_t /*subpass*/, Framebuffer * /*frameBuffer*/) {
|
||||
_cmdAllocator->clearCmds(_curCmdPackage);
|
||||
_curGPUPipelineState = nullptr;
|
||||
_curGPUInputAssember = nullptr;
|
||||
_curGPUDescriptorSets.assign(_curGPUDescriptorSets.size(), nullptr);
|
||||
|
||||
_numDrawCalls = 0;
|
||||
_numInstances = 0;
|
||||
_numTriangles = 0;
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::end() {
|
||||
if (_isStateInvalid) {
|
||||
bindStates();
|
||||
}
|
||||
|
||||
_pendingPackages.push(_curCmdPackage);
|
||||
if (!_freePackages.empty()) {
|
||||
_curCmdPackage = _freePackages.front();
|
||||
_freePackages.pop();
|
||||
} else {
|
||||
_curCmdPackage = ccnew GLES2CmdPackage;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil, CommandBuffer *const * /*secondaryCBs*/, uint32_t /*secondaryCBCount*/) {
|
||||
_curSubpassIdx = 0U;
|
||||
|
||||
GLES2CmdBeginRenderPass *cmd = _cmdAllocator->beginRenderPassCmdPool.alloc();
|
||||
cmd->subpassIdx = _curSubpassIdx;
|
||||
cmd->gpuRenderPass = static_cast<GLES2RenderPass *>(renderPass)->gpuRenderPass();
|
||||
cmd->gpuFBO = static_cast<GLES2Framebuffer *>(fbo)->gpuFBO();
|
||||
cmd->renderArea = renderArea;
|
||||
size_t numClearColors = cmd->gpuRenderPass->colorAttachments.size();
|
||||
memcpy(cmd->clearColors, colors, numClearColors * sizeof(Color));
|
||||
cmd->clearDepth = depth;
|
||||
cmd->clearStencil = stencil;
|
||||
_curCmdPackage->beginRenderPassCmds.push(cmd);
|
||||
_curCmdPackage->cmds.push(GLESCmdType::BEGIN_RENDER_PASS);
|
||||
_curDynamicStates.viewport = {renderArea.x, renderArea.y, renderArea.width, renderArea.height};
|
||||
_curDynamicStates.scissor = renderArea;
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::endRenderPass() {
|
||||
_curCmdPackage->cmds.push(GLESCmdType::END_RENDER_PASS);
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::nextSubpass() {
|
||||
_curCmdPackage->cmds.push(GLESCmdType::END_RENDER_PASS);
|
||||
GLES2CmdBeginRenderPass *cmd = _cmdAllocator->beginRenderPassCmdPool.alloc();
|
||||
cmd->subpassIdx = ++_curSubpassIdx;
|
||||
_curCmdPackage->beginRenderPassCmds.push(cmd);
|
||||
_curCmdPackage->cmds.push(GLESCmdType::BEGIN_RENDER_PASS);
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::insertMarker(const MarkerInfo &marker) {
|
||||
std::ignore = marker;
|
||||
}
|
||||
void GLES2CommandBuffer::beginMarker(const MarkerInfo &marker) {
|
||||
std::ignore = marker;
|
||||
}
|
||||
void GLES2CommandBuffer::endMarker() {
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::bindPipelineState(PipelineState *pso) {
|
||||
GLES2GPUPipelineState *gpuPipelineState = static_cast<GLES2PipelineState *>(pso)->gpuPipelineState();
|
||||
if (_curGPUPipelineState != gpuPipelineState) {
|
||||
_curGPUPipelineState = gpuPipelineState;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets) {
|
||||
CC_ASSERT(_curGPUDescriptorSets.size() > set);
|
||||
|
||||
GLES2GPUDescriptorSet *gpuDescriptorSet = static_cast<GLES2DescriptorSet *>(descriptorSet)->gpuDescriptorSet();
|
||||
if (_curGPUDescriptorSets[set] != gpuDescriptorSet) {
|
||||
_curGPUDescriptorSets[set] = gpuDescriptorSet;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
if (dynamicOffsetCount) {
|
||||
_curDynamicOffsets[set].assign(dynamicOffsets, dynamicOffsets + dynamicOffsetCount);
|
||||
_isStateInvalid = true;
|
||||
} else if (!_curDynamicOffsets[set].empty()) {
|
||||
_curDynamicOffsets[set].assign(_curDynamicOffsets[set].size(), 0);
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::bindInputAssembler(InputAssembler *ia) {
|
||||
_curGPUInputAssember = static_cast<GLES2InputAssembler *>(ia)->gpuInputAssembler();
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setViewport(const Viewport &vp) {
|
||||
if ((_curDynamicStates.viewport.left != vp.left) ||
|
||||
(_curDynamicStates.viewport.top != vp.top) ||
|
||||
(_curDynamicStates.viewport.width != vp.width) ||
|
||||
(_curDynamicStates.viewport.height != vp.height) ||
|
||||
math::isNotEqualF(_curDynamicStates.viewport.minDepth, vp.minDepth) ||
|
||||
math::isNotEqualF(_curDynamicStates.viewport.maxDepth, vp.maxDepth)) {
|
||||
_curDynamicStates.viewport = vp;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setScissor(const Rect &rect) {
|
||||
if ((_curDynamicStates.scissor.x != rect.x) ||
|
||||
(_curDynamicStates.scissor.y != rect.y) ||
|
||||
(_curDynamicStates.scissor.width != rect.width) ||
|
||||
(_curDynamicStates.scissor.height != rect.height)) {
|
||||
_curDynamicStates.scissor = rect;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setLineWidth(float width) {
|
||||
if (math::isNotEqualF(_curDynamicStates.lineWidth, width)) {
|
||||
_curDynamicStates.lineWidth = width;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setDepthBias(float constant, float clamp, float slope) {
|
||||
if (math::isNotEqualF(_curDynamicStates.depthBiasConstant, constant) ||
|
||||
math::isNotEqualF(_curDynamicStates.depthBiasClamp, clamp) ||
|
||||
math::isNotEqualF(_curDynamicStates.depthBiasSlope, slope)) {
|
||||
_curDynamicStates.depthBiasConstant = constant;
|
||||
_curDynamicStates.depthBiasClamp = clamp;
|
||||
_curDynamicStates.depthBiasSlope = slope;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setBlendConstants(const Color &constants) {
|
||||
if (math::isNotEqualF(_curDynamicStates.blendConstant.x, constants.x) ||
|
||||
math::isNotEqualF(_curDynamicStates.blendConstant.y, constants.y) ||
|
||||
math::isNotEqualF(_curDynamicStates.blendConstant.z, constants.z) ||
|
||||
math::isNotEqualF(_curDynamicStates.blendConstant.w, constants.w)) {
|
||||
_curDynamicStates.blendConstant.x = constants.x;
|
||||
_curDynamicStates.blendConstant.y = constants.y;
|
||||
_curDynamicStates.blendConstant.z = constants.z;
|
||||
_curDynamicStates.blendConstant.w = constants.w;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setDepthBound(float minBounds, float maxBounds) {
|
||||
if (math::isNotEqualF(_curDynamicStates.depthMinBounds, minBounds) ||
|
||||
math::isNotEqualF(_curDynamicStates.depthMaxBounds, maxBounds)) {
|
||||
_curDynamicStates.depthMinBounds = minBounds;
|
||||
_curDynamicStates.depthMaxBounds = maxBounds;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setStencilWriteMask(StencilFace face, uint32_t mask) {
|
||||
auto update = [&](DynamicStencilStates &stencilState) {
|
||||
if (stencilState.writeMask != mask) {
|
||||
stencilState.writeMask = mask;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
};
|
||||
if (hasFlag(face, StencilFace::FRONT)) update(_curDynamicStates.stencilStatesFront);
|
||||
if (hasFlag(face, StencilFace::BACK)) update(_curDynamicStates.stencilStatesBack);
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) {
|
||||
auto update = [&](DynamicStencilStates &stencilState) {
|
||||
if ((stencilState.reference != ref) ||
|
||||
(stencilState.compareMask != mask)) {
|
||||
stencilState.reference = ref;
|
||||
stencilState.compareMask = mask;
|
||||
_isStateInvalid = true;
|
||||
}
|
||||
};
|
||||
if (hasFlag(face, StencilFace::FRONT)) update(_curDynamicStates.stencilStatesFront);
|
||||
if (hasFlag(face, StencilFace::BACK)) update(_curDynamicStates.stencilStatesBack);
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::draw(const DrawInfo &info) {
|
||||
CC_PROFILE(GLES2CommandBufferDraw);
|
||||
if (_isStateInvalid) {
|
||||
bindStates();
|
||||
}
|
||||
|
||||
GLES2CmdDraw *cmd = _cmdAllocator->drawCmdPool.alloc();
|
||||
cmd->drawInfo = info;
|
||||
_curCmdPackage->drawCmds.push(cmd);
|
||||
_curCmdPackage->cmds.push(GLESCmdType::DRAW);
|
||||
|
||||
++_numDrawCalls;
|
||||
_numInstances += info.instanceCount;
|
||||
uint32_t indexCount = info.indexCount ? info.indexCount : info.vertexCount;
|
||||
if (_curGPUPipelineState) {
|
||||
switch (_curGPUPipelineState->glPrimitive) {
|
||||
case GL_TRIANGLES: {
|
||||
_numTriangles += indexCount / 3 * std::max(info.instanceCount, 1U);
|
||||
break;
|
||||
}
|
||||
case GL_TRIANGLE_STRIP:
|
||||
case GL_TRIANGLE_FAN: {
|
||||
_numTriangles += (indexCount - 2) * std::max(info.instanceCount, 1U);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::updateBuffer(Buffer *buff, const void *data, uint32_t size) {
|
||||
GLES2GPUBuffer *gpuBuffer = static_cast<GLES2Buffer *>(buff)->gpuBuffer();
|
||||
if (gpuBuffer) {
|
||||
GLES2CmdUpdateBuffer *cmd = _cmdAllocator->updateBufferCmdPool.alloc();
|
||||
cmd->gpuBuffer = gpuBuffer;
|
||||
cmd->size = size;
|
||||
cmd->buffer = static_cast<const uint8_t *>(data);
|
||||
|
||||
_curCmdPackage->updateBufferCmds.push(cmd);
|
||||
_curCmdPackage->cmds.push(GLESCmdType::UPDATE_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) {
|
||||
GLES2GPUTexture *gpuTexture = static_cast<GLES2Texture *>(texture)->gpuTexture();
|
||||
if (gpuTexture) {
|
||||
GLES2CmdCopyBufferToTexture *cmd = _cmdAllocator->copyBufferToTextureCmdPool.alloc();
|
||||
cmd->gpuTexture = gpuTexture;
|
||||
cmd->regions = regions;
|
||||
cmd->count = count;
|
||||
cmd->buffers = buffers;
|
||||
|
||||
_curCmdPackage->copyBufferToTextureCmds.push(cmd);
|
||||
_curCmdPackage->cmds.push(GLESCmdType::COPY_BUFFER_TO_TEXTURE);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) {
|
||||
// should not copy texture in a secondary command buffer
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) {
|
||||
// should not copy texture in a secondary command buffer
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) {
|
||||
GLES2CmdBlitTexture *cmd = _cmdAllocator->blitTextureCmdPool.alloc();
|
||||
if (srcTexture) cmd->gpuTextureSrc = static_cast<GLES2Texture *>(srcTexture)->gpuTexture();
|
||||
if (dstTexture) cmd->gpuTextureDst = static_cast<GLES2Texture *>(dstTexture)->gpuTexture();
|
||||
cmd->regions = regions;
|
||||
cmd->count = count;
|
||||
cmd->filter = filter;
|
||||
|
||||
++_numDrawCalls; // blit is also seen as draw call in GLES2
|
||||
|
||||
_curCmdPackage->blitTextureCmds.push(cmd);
|
||||
_curCmdPackage->cmds.push(GLESCmdType::BLIT_TEXTURE);
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::execute(CommandBuffer *const *cmdBuffs, uint32_t count) {
|
||||
CC_ABORT(); // Command 'execute' must be recorded in primary command buffers.
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
auto *cmdBuff = static_cast<GLES2CommandBuffer *>(cmdBuffs[i]);
|
||||
GLES2CmdPackage *cmdPackage = cmdBuff->_pendingPackages.front();
|
||||
|
||||
for (uint32_t j = 0; j < cmdPackage->beginRenderPassCmds.size(); ++j) {
|
||||
GLES2CmdBeginRenderPass *cmd = cmdPackage->beginRenderPassCmds[j];
|
||||
++cmd->refCount;
|
||||
_curCmdPackage->beginRenderPassCmds.push(cmd);
|
||||
}
|
||||
for (uint32_t j = 0; j < cmdPackage->bindStatesCmds.size(); ++j) {
|
||||
GLES2CmdBindStates *cmd = cmdPackage->bindStatesCmds[j];
|
||||
++cmd->refCount;
|
||||
_curCmdPackage->bindStatesCmds.push(cmd);
|
||||
}
|
||||
for (uint32_t j = 0; j < cmdPackage->drawCmds.size(); ++j) {
|
||||
GLES2CmdDraw *cmd = cmdPackage->drawCmds[j];
|
||||
++cmd->refCount;
|
||||
_curCmdPackage->drawCmds.push(cmd);
|
||||
}
|
||||
for (uint32_t j = 0; j < cmdPackage->updateBufferCmds.size(); ++j) {
|
||||
GLES2CmdUpdateBuffer *cmd = cmdPackage->updateBufferCmds[j];
|
||||
++cmd->refCount;
|
||||
_curCmdPackage->updateBufferCmds.push(cmd);
|
||||
}
|
||||
for (uint32_t j = 0; j < cmdPackage->copyBufferToTextureCmds.size(); ++j) {
|
||||
GLES2CmdCopyBufferToTexture *cmd = cmdPackage->copyBufferToTextureCmds[j];
|
||||
++cmd->refCount;
|
||||
_curCmdPackage->copyBufferToTextureCmds.push(cmd);
|
||||
}
|
||||
for (uint32_t j = 0; j < cmdPackage->blitTextureCmds.size(); ++j) {
|
||||
GLES2CmdBlitTexture *cmd = cmdPackage->blitTextureCmds[j];
|
||||
++cmd->refCount;
|
||||
_curCmdPackage->blitTextureCmds.push(cmd);
|
||||
}
|
||||
_curCmdPackage->cmds.concat(cmdPackage->cmds);
|
||||
|
||||
_numDrawCalls += cmdBuff->_numDrawCalls;
|
||||
_numInstances += cmdBuff->_numInstances;
|
||||
_numTriangles += cmdBuff->_numTriangles;
|
||||
|
||||
cmdBuff->_pendingPackages.pop();
|
||||
cmdBuff->_freePackages.push(cmdPackage);
|
||||
|
||||
// current cmd allocator strategy will not work here: (but it doesn't matter anyways)
|
||||
// allocators are designed to only free the cmds they allocated
|
||||
// but here we are essentially <20><>transfering' the owner ship
|
||||
// cmdBuff->_cmdAllocator->clearCmds(cmdPackage);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2CommandBuffer::bindStates() {
|
||||
GLES2CmdBindStates *cmd = _cmdAllocator->bindStatesCmdPool.alloc();
|
||||
|
||||
cmd->gpuPipelineState = _curGPUPipelineState;
|
||||
cmd->gpuInputAssembler = _curGPUInputAssember;
|
||||
cmd->gpuDescriptorSets = _curGPUDescriptorSets;
|
||||
|
||||
if (_curGPUPipelineState) {
|
||||
ccstd::vector<uint32_t> &dynamicOffsetOffsets = _curGPUPipelineState->gpuPipelineLayout->dynamicOffsetOffsets;
|
||||
cmd->dynamicOffsets.resize(_curGPUPipelineState->gpuPipelineLayout->dynamicOffsetCount);
|
||||
for (size_t i = 0U; i < _curDynamicOffsets.size(); i++) {
|
||||
size_t count = dynamicOffsetOffsets[i + 1] - dynamicOffsetOffsets[i];
|
||||
// CC_ASSERT(_curDynamicOffsets[i].size() >= count);
|
||||
count = std::min(count, _curDynamicOffsets[i].size());
|
||||
if (count) memcpy(&cmd->dynamicOffsets[dynamicOffsetOffsets[i]], _curDynamicOffsets[i].data(), count * sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
cmd->dynamicStates = _curDynamicStates;
|
||||
|
||||
_curCmdPackage->bindStatesCmds.push(cmd);
|
||||
_curCmdPackage->cmds.push(GLESCmdType::BIND_STATES);
|
||||
_isStateInvalid = false;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
100
cocos/renderer/gfx-gles2/GLES2CommandBuffer.h
Normal file
100
cocos/renderer/gfx-gles2/GLES2CommandBuffer.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "base/std/container/queue.h"
|
||||
#include "gfx-base/GFXCommandBuffer.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2CmdPackage;
|
||||
struct GLES2GPUPipelineState;
|
||||
struct GLES2GPUDescriptorSet;
|
||||
struct GLES2GPUInputAssembler;
|
||||
class GLES2GPUCommandAllocator;
|
||||
|
||||
class CC_GLES2_API GLES2CommandBuffer : public CommandBuffer {
|
||||
public:
|
||||
GLES2CommandBuffer();
|
||||
~GLES2CommandBuffer() override;
|
||||
|
||||
friend class GLES2Queue;
|
||||
|
||||
void begin(RenderPass *renderPass, uint32_t subpass, Framebuffer *frameBuffer) override;
|
||||
void end() override;
|
||||
void beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil, CommandBuffer *const *secondaryCBs, uint32_t secondaryCBCount) override;
|
||||
void endRenderPass() override;
|
||||
void insertMarker(const MarkerInfo &marker) override;
|
||||
void beginMarker(const MarkerInfo &marker) override;
|
||||
void endMarker() override;
|
||||
void bindPipelineState(PipelineState *pso) override;
|
||||
void bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets) override;
|
||||
void bindInputAssembler(InputAssembler *ia) override;
|
||||
void setViewport(const Viewport &vp) override;
|
||||
void setScissor(const Rect &rect) override;
|
||||
void setLineWidth(float width) override;
|
||||
void setDepthBias(float constant, float clamp, float slope) override;
|
||||
void setBlendConstants(const Color &constants) override;
|
||||
void setDepthBound(float minBounds, float maxBounds) override;
|
||||
void setStencilWriteMask(StencilFace face, uint32_t mask) override;
|
||||
void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) override;
|
||||
void nextSubpass() override;
|
||||
void draw(const DrawInfo &info) override;
|
||||
void updateBuffer(Buffer *buff, const void *data, uint32_t size) override;
|
||||
void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override;
|
||||
void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override;
|
||||
void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override;
|
||||
void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override;
|
||||
void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override;
|
||||
void dispatch(const DispatchInfo &info) override {}
|
||||
void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) override {}
|
||||
void beginQuery(QueryPool *queryPool, uint32_t id) override {}
|
||||
void endQuery(QueryPool *queryPool, uint32_t id) override {}
|
||||
void resetQueryPool(QueryPool *queryPool) override {}
|
||||
|
||||
protected:
|
||||
void doInit(const CommandBufferInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
virtual void bindStates();
|
||||
|
||||
GLES2GPUCommandAllocator *_cmdAllocator = nullptr;
|
||||
GLES2CmdPackage *_curCmdPackage = nullptr;
|
||||
ccstd::queue<GLES2CmdPackage *> _pendingPackages, _freePackages;
|
||||
|
||||
uint32_t _curSubpassIdx = 0U;
|
||||
GLES2GPUPipelineState *_curGPUPipelineState = nullptr;
|
||||
ccstd::vector<GLES2GPUDescriptorSet *> _curGPUDescriptorSets;
|
||||
ccstd::vector<ccstd::vector<uint32_t>> _curDynamicOffsets;
|
||||
GLES2GPUInputAssembler *_curGPUInputAssember = nullptr;
|
||||
DynamicStates _curDynamicStates;
|
||||
|
||||
bool _isStateInvalid = false;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
3242
cocos/renderer/gfx-gles2/GLES2Commands.cpp
Normal file
3242
cocos/renderer/gfx-gles2/GLES2Commands.cpp
Normal file
File diff suppressed because it is too large
Load Diff
256
cocos/renderer/gfx-gles2/GLES2Commands.h
Normal file
256
cocos/renderer/gfx-gles2/GLES2Commands.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2GPUObjects.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
class GLES2Device;
|
||||
|
||||
class GLES2CmdBeginRenderPass final : public GLESCmd {
|
||||
public:
|
||||
GLES2GPURenderPass *gpuRenderPass = nullptr;
|
||||
GLES2GPUFramebuffer *gpuFBO = nullptr;
|
||||
Rect renderArea;
|
||||
Color clearColors[MAX_ATTACHMENTS];
|
||||
float clearDepth = 1.0F;
|
||||
uint32_t clearStencil = 0;
|
||||
uint32_t subpassIdx = 0U;
|
||||
|
||||
GLES2CmdBeginRenderPass() : GLESCmd(GLESCmdType::BEGIN_RENDER_PASS) {}
|
||||
|
||||
void clear() override {
|
||||
gpuFBO = nullptr;
|
||||
gpuRenderPass = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class GLES2CmdBindStates final : public GLESCmd {
|
||||
public:
|
||||
GLES2GPUPipelineState *gpuPipelineState = nullptr;
|
||||
GLES2GPUInputAssembler *gpuInputAssembler = nullptr;
|
||||
ccstd::vector<GLES2GPUDescriptorSet *> gpuDescriptorSets;
|
||||
ccstd::vector<uint32_t> dynamicOffsets;
|
||||
DynamicStates dynamicStates;
|
||||
|
||||
GLES2CmdBindStates() : GLESCmd(GLESCmdType::BIND_STATES) {}
|
||||
|
||||
void clear() override {
|
||||
gpuPipelineState = nullptr;
|
||||
gpuInputAssembler = nullptr;
|
||||
gpuDescriptorSets.clear();
|
||||
dynamicOffsets.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class GLES2CmdDraw final : public GLESCmd {
|
||||
public:
|
||||
DrawInfo drawInfo;
|
||||
|
||||
GLES2CmdDraw() : GLESCmd(GLESCmdType::DRAW) {}
|
||||
void clear() override {}
|
||||
};
|
||||
|
||||
class GLES2CmdUpdateBuffer final : public GLESCmd {
|
||||
public:
|
||||
GLES2GPUBuffer *gpuBuffer = nullptr;
|
||||
const uint8_t *buffer = nullptr;
|
||||
uint32_t size = 0;
|
||||
uint32_t offset = 0;
|
||||
|
||||
GLES2CmdUpdateBuffer() : GLESCmd(GLESCmdType::UPDATE_BUFFER) {}
|
||||
|
||||
void clear() override {
|
||||
gpuBuffer = nullptr;
|
||||
buffer = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class GLES2CmdCopyBufferToTexture final : public GLESCmd {
|
||||
public:
|
||||
GLES2GPUTexture *gpuTexture = nullptr;
|
||||
const BufferTextureCopy *regions = nullptr;
|
||||
uint32_t count = 0U;
|
||||
const uint8_t *const *buffers = nullptr;
|
||||
|
||||
GLES2CmdCopyBufferToTexture() : GLESCmd(GLESCmdType::COPY_BUFFER_TO_TEXTURE) {}
|
||||
|
||||
void clear() override {
|
||||
gpuTexture = nullptr;
|
||||
regions = nullptr;
|
||||
count = 0U;
|
||||
buffers = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
class GLES2CmdBlitTexture final : public GLESCmd {
|
||||
public:
|
||||
GLES2GPUTexture *gpuTextureSrc = nullptr;
|
||||
GLES2GPUTexture *gpuTextureDst = nullptr;
|
||||
const TextureBlit *regions = nullptr;
|
||||
uint32_t count = 0U;
|
||||
Filter filter = Filter::POINT;
|
||||
|
||||
GLES2CmdBlitTexture() : GLESCmd(GLESCmdType::BLIT_TEXTURE) {}
|
||||
|
||||
void clear() override {
|
||||
gpuTextureSrc = nullptr;
|
||||
gpuTextureDst = nullptr;
|
||||
regions = nullptr;
|
||||
count = 0U;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLES2CmdPackage {
|
||||
CachedArray<GLESCmdType> cmds;
|
||||
CachedArray<GLES2CmdBeginRenderPass *> beginRenderPassCmds;
|
||||
CachedArray<GLES2CmdBindStates *> bindStatesCmds;
|
||||
CachedArray<GLES2CmdDraw *> drawCmds;
|
||||
CachedArray<GLES2CmdUpdateBuffer *> updateBufferCmds;
|
||||
CachedArray<GLES2CmdCopyBufferToTexture *> copyBufferToTextureCmds;
|
||||
CachedArray<GLES2CmdBlitTexture *> blitTextureCmds;
|
||||
};
|
||||
|
||||
class GLES2GPUCommandAllocator final {
|
||||
public:
|
||||
CommandPool<GLES2CmdBeginRenderPass> beginRenderPassCmdPool;
|
||||
CommandPool<GLES2CmdBindStates> bindStatesCmdPool;
|
||||
CommandPool<GLES2CmdDraw> drawCmdPool;
|
||||
CommandPool<GLES2CmdUpdateBuffer> updateBufferCmdPool;
|
||||
CommandPool<GLES2CmdCopyBufferToTexture> copyBufferToTextureCmdPool;
|
||||
CommandPool<GLES2CmdBlitTexture> blitTextureCmdPool;
|
||||
|
||||
void clearCmds(GLES2CmdPackage *cmdPackage) {
|
||||
if (cmdPackage->beginRenderPassCmds.size()) {
|
||||
beginRenderPassCmdPool.freeCmds(cmdPackage->beginRenderPassCmds);
|
||||
}
|
||||
if (cmdPackage->bindStatesCmds.size()) {
|
||||
bindStatesCmdPool.freeCmds(cmdPackage->bindStatesCmds);
|
||||
}
|
||||
if (cmdPackage->drawCmds.size()) {
|
||||
drawCmdPool.freeCmds(cmdPackage->drawCmds);
|
||||
}
|
||||
if (cmdPackage->updateBufferCmds.size()) {
|
||||
updateBufferCmdPool.freeCmds(cmdPackage->updateBufferCmds);
|
||||
}
|
||||
if (cmdPackage->copyBufferToTextureCmds.size()) {
|
||||
copyBufferToTextureCmdPool.freeCmds(cmdPackage->copyBufferToTextureCmds);
|
||||
}
|
||||
if (cmdPackage->blitTextureCmds.size()) {
|
||||
blitTextureCmdPool.freeCmds(cmdPackage->blitTextureCmds);
|
||||
}
|
||||
|
||||
cmdPackage->cmds.clear();
|
||||
}
|
||||
|
||||
inline void reset() {
|
||||
beginRenderPassCmdPool.release();
|
||||
bindStatesCmdPool.release();
|
||||
drawCmdPool.release();
|
||||
updateBufferCmdPool.release();
|
||||
copyBufferToTextureCmdPool.release();
|
||||
blitTextureCmdPool.release();
|
||||
}
|
||||
};
|
||||
|
||||
void cmdFuncGLES2CreateBuffer(GLES2Device *device, GLES2GPUBuffer *gpuBuffer);
|
||||
void cmdFuncGLES2DestroyBuffer(GLES2Device *device, GLES2GPUBuffer *gpuBuffer);
|
||||
void cmdFuncGLES2ResizeBuffer(GLES2Device *device, GLES2GPUBuffer *gpuBuffer);
|
||||
void cmdFuncGLES2CreateTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture);
|
||||
void cmdFuncGLES2DestroyTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture);
|
||||
void cmdFuncGLES2ResizeTexture(GLES2Device *device, GLES2GPUTexture *gpuTexture);
|
||||
void cmdFuncGLES2CreateSampler(GLES2Device *device, GLES2GPUSampler *gpuSampler);
|
||||
void cmdFuncGLES2DestroySampler(GLES2Device *device, GLES2GPUSampler *gpuSampler);
|
||||
void cmdFuncGLES2CreateShader(GLES2Device *device, GLES2GPUShader *gpuShader);
|
||||
void cmdFuncGLES2DestroyShader(GLES2Device *device, GLES2GPUShader *gpuShader);
|
||||
void cmdFuncGLES2CreateRenderPass(GLES2Device *device, GLES2GPURenderPass *gpuRenderPass);
|
||||
void cmdFuncGLES2DestroyRenderPass(GLES2Device *device, GLES2GPURenderPass *gpuRenderPass);
|
||||
void cmdFuncGLES2CreateInputAssembler(GLES2Device *device, GLES2GPUInputAssembler *gpuInputAssembler);
|
||||
void cmdFuncGLES2DestroyInputAssembler(GLES2Device *device, GLES2GPUInputAssembler *gpuInputAssembler);
|
||||
void cmdFuncGLES2CreateFramebuffer(GLES2Device *device, GLES2GPUFramebuffer *gpuFBO);
|
||||
void cmdFuncGLES2DestroyFramebuffer(GLES2Device *device, GLES2GPUFramebuffer *gpuFBO);
|
||||
|
||||
void cmdFuncGLES2BeginRenderPass(GLES2Device *device, uint32_t subpassIdx,
|
||||
GLES2GPURenderPass *gpuRenderPass = nullptr,
|
||||
GLES2GPUFramebuffer *gpuFramebuffer = nullptr,
|
||||
const Rect *renderArea = nullptr,
|
||||
const Color *clearColors = nullptr,
|
||||
float clearDepth = 1.F,
|
||||
uint32_t clearStencil = 0);
|
||||
|
||||
void cmdFuncGLES2EndRenderPass(GLES2Device *device);
|
||||
|
||||
void cmdFuncGLES2BindState(GLES2Device *device,
|
||||
GLES2GPUPipelineState *gpuPipelineState,
|
||||
GLES2GPUInputAssembler *gpuInputAssembler,
|
||||
const GLES2GPUDescriptorSet *const *gpuDescriptorSets,
|
||||
const uint32_t *dynamicOffsets = nullptr,
|
||||
const DynamicStates *dynamicStates = nullptr);
|
||||
|
||||
void cmdFuncGLES2Draw(GLES2Device *device, const DrawInfo &drawInfo);
|
||||
|
||||
void cmdFuncGLES2UpdateBuffer(GLES2Device *device,
|
||||
GLES2GPUBuffer *gpuBuffer,
|
||||
const void *buffer,
|
||||
uint32_t offset,
|
||||
uint32_t size);
|
||||
|
||||
void cmdFuncGLES2CopyBuffersToTexture(GLES2Device *device,
|
||||
const uint8_t *const *buffers,
|
||||
GLES2GPUTexture *gpuTexture,
|
||||
const BufferTextureCopy *regions,
|
||||
uint32_t count);
|
||||
|
||||
void cmdFuncGLES2CopyTextureToBuffers(GLES2Device *device,
|
||||
GLES2GPUTexture *gpuTexture,
|
||||
uint8_t *const *buffers,
|
||||
const BufferTextureCopy *regions,
|
||||
uint32_t count);
|
||||
|
||||
void cmdFuncGLES2CopyTexture(GLES2Device *device,
|
||||
GLES2GPUTexture *gpuTextureSrc,
|
||||
GLES2GPUTexture *gpuTextureDst,
|
||||
const TextureCopy *regions,
|
||||
uint32_t count);
|
||||
|
||||
void cmdFuncGLES2BlitTexture(GLES2Device *device,
|
||||
GLES2GPUTexture *gpuTextureSrc,
|
||||
GLES2GPUTexture *gpuTextureDst,
|
||||
const TextureBlit *regions,
|
||||
uint32_t count,
|
||||
Filter filter);
|
||||
|
||||
void cmdFuncGLES2ExecuteCmds(GLES2Device *device, GLES2CmdPackage *cmdPackage);
|
||||
|
||||
void cmdFuncGLES2InsertMarker(GLES2Device *device, GLsizei length, const char *marker);
|
||||
void cmdFuncGLES2PushGroupMarker(GLES2Device *device, GLsizei length, const char *marker);
|
||||
void cmdFuncGLES2PopGroupMarker(GLES2Device *device);
|
||||
|
||||
GLint cmdFuncGLES2GetMaxSampleCount();
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
102
cocos/renderer/gfx-gles2/GLES2DescriptorSet.cpp
Normal file
102
cocos/renderer/gfx-gles2/GLES2DescriptorSet.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Buffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2DescriptorSet.h"
|
||||
#include "GLES2DescriptorSetLayout.h"
|
||||
#include "GLES2Texture.h"
|
||||
#include "states/GLES2Sampler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2DescriptorSet::GLES2DescriptorSet() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2DescriptorSet::~GLES2DescriptorSet() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2DescriptorSet::doInit(const DescriptorSetInfo & /*info*/) {
|
||||
const GLES2GPUDescriptorSetLayout *gpuDescriptorSetLayout = static_cast<const GLES2DescriptorSetLayout *>(_layout)->gpuDescriptorSetLayout();
|
||||
const size_t descriptorCount = gpuDescriptorSetLayout->descriptorCount;
|
||||
const size_t bindingCount = gpuDescriptorSetLayout->bindings.size();
|
||||
|
||||
_buffers.resize(descriptorCount);
|
||||
_textures.resize(descriptorCount);
|
||||
_samplers.resize(descriptorCount);
|
||||
|
||||
_gpuDescriptorSet = ccnew GLES2GPUDescriptorSet;
|
||||
_gpuDescriptorSet->gpuDescriptors.resize(descriptorCount);
|
||||
for (size_t i = 0U, k = 0U; i < bindingCount; i++) {
|
||||
const DescriptorSetLayoutBinding &binding = gpuDescriptorSetLayout->bindings[i];
|
||||
for (uint32_t j = 0; j < binding.count; j++, k++) {
|
||||
_gpuDescriptorSet->gpuDescriptors[k].type = binding.descriptorType;
|
||||
}
|
||||
}
|
||||
|
||||
_gpuDescriptorSet->descriptorIndices = &gpuDescriptorSetLayout->descriptorIndices;
|
||||
}
|
||||
|
||||
void GLES2DescriptorSet::doDestroy() {
|
||||
CC_SAFE_DELETE(_gpuDescriptorSet);
|
||||
}
|
||||
|
||||
void GLES2DescriptorSet::update() {
|
||||
if (_isDirty && _gpuDescriptorSet) {
|
||||
auto &descriptors = _gpuDescriptorSet->gpuDescriptors;
|
||||
for (size_t i = 0; i < descriptors.size(); i++) {
|
||||
if (hasAnyFlags(descriptors[i].type, DESCRIPTOR_BUFFER_TYPE)) {
|
||||
auto *buffer = static_cast<GLES2Buffer *>(_buffers[i].ptr);
|
||||
if (buffer) {
|
||||
if (buffer->gpuBuffer()) {
|
||||
descriptors[i].gpuBuffer = buffer->gpuBuffer();
|
||||
} else if (buffer->gpuBufferView()) {
|
||||
descriptors[i].gpuBufferView = buffer->gpuBufferView();
|
||||
}
|
||||
}
|
||||
} else if (hasAnyFlags(descriptors[i].type, DESCRIPTOR_TEXTURE_TYPE)) {
|
||||
if (_textures[i].ptr) {
|
||||
descriptors[i].gpuTexture = static_cast<GLES2Texture *>(_textures[i].ptr)->gpuTexture();
|
||||
}
|
||||
if (_samplers[i].ptr) {
|
||||
descriptors[i].gpuSampler = static_cast<GLES2Sampler *>(_samplers[i].ptr)->gpuSampler();
|
||||
}
|
||||
}
|
||||
}
|
||||
_isDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2DescriptorSet::forceUpdate() {
|
||||
_isDirty = true;
|
||||
update();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
53
cocos/renderer/gfx-gles2/GLES2DescriptorSet.h
Normal file
53
cocos/renderer/gfx-gles2/GLES2DescriptorSet.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXDescriptorSet.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUDescriptorSet;
|
||||
|
||||
class CC_GLES2_API GLES2DescriptorSet final : public DescriptorSet {
|
||||
public:
|
||||
GLES2DescriptorSet();
|
||||
~GLES2DescriptorSet() override;
|
||||
|
||||
void update() override;
|
||||
void forceUpdate() override;
|
||||
|
||||
inline GLES2GPUDescriptorSet *gpuDescriptorSet() const { return _gpuDescriptorSet; }
|
||||
|
||||
protected:
|
||||
void doInit(const DescriptorSetInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPUDescriptorSet *_gpuDescriptorSet = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
62
cocos/renderer/gfx-gles2/GLES2DescriptorSetLayout.cpp
Normal file
62
cocos/renderer/gfx-gles2/GLES2DescriptorSetLayout.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2DescriptorSetLayout.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2DescriptorSetLayout::GLES2DescriptorSetLayout() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2DescriptorSetLayout::~GLES2DescriptorSetLayout() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2DescriptorSetLayout::doInit(const DescriptorSetLayoutInfo & /*info*/) {
|
||||
_gpuDescriptorSetLayout = ccnew GLES2GPUDescriptorSetLayout;
|
||||
_gpuDescriptorSetLayout->descriptorCount = _descriptorCount;
|
||||
_gpuDescriptorSetLayout->bindingIndices = _bindingIndices;
|
||||
_gpuDescriptorSetLayout->descriptorIndices = _descriptorIndices;
|
||||
_gpuDescriptorSetLayout->bindings = _bindings;
|
||||
|
||||
for (auto &binding : _bindings) {
|
||||
if (hasAnyFlags(binding.descriptorType, DESCRIPTOR_DYNAMIC_TYPE)) {
|
||||
for (uint32_t j = 0U; j < binding.count; j++) {
|
||||
_gpuDescriptorSetLayout->dynamicBindings.push_back(binding.binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2DescriptorSetLayout::doDestroy() {
|
||||
CC_SAFE_DELETE(_gpuDescriptorSetLayout);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
50
cocos/renderer/gfx-gles2/GLES2DescriptorSetLayout.h
Normal file
50
cocos/renderer/gfx-gles2/GLES2DescriptorSetLayout.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXDescriptorSetLayout.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUDescriptorSetLayout;
|
||||
|
||||
class CC_GLES2_API GLES2DescriptorSetLayout final : public DescriptorSetLayout {
|
||||
public:
|
||||
GLES2DescriptorSetLayout();
|
||||
~GLES2DescriptorSetLayout() override;
|
||||
|
||||
inline GLES2GPUDescriptorSetLayout *gpuDescriptorSetLayout() const { return _gpuDescriptorSetLayout; }
|
||||
|
||||
protected:
|
||||
void doInit(const DescriptorSetLayoutInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPUDescriptorSetLayout *_gpuDescriptorSetLayout = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
550
cocos/renderer/gfx-gles2/GLES2Device.cpp
Normal file
550
cocos/renderer/gfx-gles2/GLES2Device.cpp
Normal file
@@ -0,0 +1,550 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Buffer.h"
|
||||
#include "GLES2CommandBuffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2DescriptorSet.h"
|
||||
#include "GLES2DescriptorSetLayout.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2Framebuffer.h"
|
||||
#include "GLES2GPUObjects.h"
|
||||
#include "GLES2InputAssembler.h"
|
||||
#include "GLES2PipelineLayout.h"
|
||||
#include "GLES2PipelineState.h"
|
||||
#include "GLES2PrimaryCommandBuffer.h"
|
||||
#include "GLES2QueryPool.h"
|
||||
#include "GLES2Queue.h"
|
||||
#include "GLES2RenderPass.h"
|
||||
#include "GLES2Shader.h"
|
||||
#include "GLES2Swapchain.h"
|
||||
#include "GLES2Texture.h"
|
||||
#include "base/memory/Memory.h"
|
||||
#include "profiler/Profiler.h"
|
||||
#include "states/GLES2Sampler.h"
|
||||
|
||||
// when capturing GLES commands (RENDERDOC_HOOK_EGL=1, default value)
|
||||
// renderdoc doesn't support this extension during replay
|
||||
#define ALLOW_MULTISAMPLED_RENDER_TO_TEXTURE_ON_DESKTOP 0
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Device *GLES2Device::instance = nullptr;
|
||||
|
||||
GLES2Device *GLES2Device::getInstance() {
|
||||
return GLES2Device::instance;
|
||||
}
|
||||
|
||||
GLES2Device::GLES2Device() {
|
||||
_api = API::GLES2;
|
||||
_deviceName = "GLES2";
|
||||
|
||||
GLES2Device::instance = this;
|
||||
}
|
||||
|
||||
GLES2Device::~GLES2Device() {
|
||||
GLES2Device::instance = nullptr;
|
||||
}
|
||||
|
||||
bool GLES2Device::doInit(const DeviceInfo & /*info*/) {
|
||||
_gpuContext = ccnew GLES2GPUContext;
|
||||
_gpuStateCache = ccnew GLES2GPUStateCache;
|
||||
_gpuBlitManager = ccnew GLES2GPUBlitManager;
|
||||
_gpuFramebufferHub = ccnew GLES2GPUFramebufferHub;
|
||||
_gpuConstantRegistry = ccnew GLES2GPUConstantRegistry;
|
||||
_gpuFramebufferCacheMap = ccnew GLES2GPUFramebufferCacheMap(_gpuStateCache);
|
||||
|
||||
if (!_gpuContext->initialize(_gpuStateCache, _gpuConstantRegistry)) {
|
||||
destroy();
|
||||
return false;
|
||||
};
|
||||
|
||||
_bindingMappings.blockOffsets.resize(_bindingMappingInfo.setIndices.size());
|
||||
_bindingMappings.samplerTextureOffsets.resize(_bindingMappingInfo.setIndices.size());
|
||||
for (size_t i = 0; i < _bindingMappingInfo.setIndices.size(); ++i) {
|
||||
uint32_t curSet{_bindingMappingInfo.setIndices[i]};
|
||||
uint32_t prevSet{i ? _bindingMappingInfo.setIndices[i - 1] : curSet};
|
||||
// accumulate the per set offset according to the specified capacity
|
||||
_bindingMappings.blockOffsets[curSet] = i ? static_cast<int32_t>(_bindingMappingInfo.maxBlockCounts[prevSet]) + _bindingMappings.blockOffsets[prevSet] : 0;
|
||||
_bindingMappings.samplerTextureOffsets[curSet] = i ? static_cast<int32_t>(_bindingMappingInfo.maxSamplerTextureCounts[prevSet]) + _bindingMappings.samplerTextureOffsets[prevSet] : 0;
|
||||
}
|
||||
for (uint32_t curSet : _bindingMappingInfo.setIndices) {
|
||||
// textures always come after UBOs
|
||||
_bindingMappings.samplerTextureOffsets[curSet] -= static_cast<int32_t>(_bindingMappingInfo.maxBlockCounts[curSet]);
|
||||
}
|
||||
_bindingMappings.flexibleSet = _bindingMappingInfo.setIndices.back();
|
||||
|
||||
ccstd::string extStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
|
||||
_extensions = StringUtil::split(extStr, " ");
|
||||
|
||||
_multithreadedCommandRecording = false;
|
||||
|
||||
initFormatFeature();
|
||||
|
||||
if (checkExtension("element_index_uint")) {
|
||||
_features[toNumber(Feature::ELEMENT_INDEX_UINT)] = true;
|
||||
}
|
||||
|
||||
if (checkExtension("draw_buffers")) {
|
||||
_features[toNumber(Feature::MULTIPLE_RENDER_TARGETS)] = true;
|
||||
glGetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, reinterpret_cast<GLint *>(&_caps.maxColorRenderTargets));
|
||||
}
|
||||
|
||||
if (checkExtension("blend_minmax")) {
|
||||
_features[toNumber(Feature::BLEND_MINMAX)] = true;
|
||||
}
|
||||
|
||||
_gpuConstantRegistry->useVAO = checkExtension("vertex_array_object");
|
||||
_gpuConstantRegistry->useDrawInstanced = checkExtension("draw_instanced");
|
||||
_gpuConstantRegistry->useInstancedArrays = checkExtension("instanced_arrays");
|
||||
_gpuConstantRegistry->useDiscardFramebuffer = checkExtension("discard_framebuffer");
|
||||
|
||||
_features[toNumber(Feature::INSTANCED_ARRAYS)] = _gpuConstantRegistry->useInstancedArrays;
|
||||
_features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = false;
|
||||
|
||||
ccstd::string fbfLevelStr = "NONE";
|
||||
// PVRVFrame has issues on their support
|
||||
#ifndef ENABLE_GLES2_SUBPASS
|
||||
_features[toNumber(Feature::INPUT_ATTACHMENT_BENEFIT)] = false;
|
||||
_features[toNumber(Feature::SUBPASS_COLOR_INPUT)] = false;
|
||||
_features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = false;
|
||||
_features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = false;
|
||||
#elif CC_PLATFORM != CC_PLATFORM_WINDOWS
|
||||
if (checkExtension("framebuffer_fetch")) {
|
||||
ccstd::string nonCoherent = "framebuffer_fetch_non";
|
||||
|
||||
auto it = std::find_if(_extensions.begin(), _extensions.end(), [&nonCoherent](auto &ext) {
|
||||
return ext.find(nonCoherent) != ccstd::string::npos;
|
||||
});
|
||||
|
||||
if (it != _extensions.end()) {
|
||||
if (*it == CC_TOSTR(GL_EXT_shader_framebuffer_fetch_non_coherent)) {
|
||||
_gpuConstantRegistry->mFBF = FBFSupportLevel::NON_COHERENT_EXT;
|
||||
fbfLevelStr = "NON_COHERENT_EXT";
|
||||
_features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = true;
|
||||
} else if (*it == CC_TOSTR(GL_QCOM_shader_framebuffer_fetch_noncoherent)) {
|
||||
_gpuConstantRegistry->mFBF = FBFSupportLevel::NON_COHERENT_QCOM;
|
||||
fbfLevelStr = "NON_COHERENT_QCOM";
|
||||
GL_CHECK(glEnable(GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM));
|
||||
_features[toNumber(Feature::RASTERIZATION_ORDER_NOCOHERENT)] = true;
|
||||
}
|
||||
} else if (checkExtension(CC_TOSTR(GL_EXT_shader_framebuffer_fetch))) {
|
||||
// we only care about EXT_shader_framebuffer_fetch, the ARM version does not support MRT
|
||||
_gpuConstantRegistry->mFBF = FBFSupportLevel::COHERENT;
|
||||
fbfLevelStr = "COHERENT";
|
||||
}
|
||||
_features[toNumber(Feature::INPUT_ATTACHMENT_BENEFIT)] = _gpuConstantRegistry->mFBF != FBFSupportLevel::NONE;
|
||||
_features[toNumber(Feature::SUBPASS_COLOR_INPUT)] = true;
|
||||
}
|
||||
|
||||
if (checkExtension(CC_TOSTR(ARM_shader_framebuffer_fetch_depth_stencil))) {
|
||||
_features[toNumber(Feature::SUBPASS_DEPTH_STENCIL_INPUT)] = true;
|
||||
fbfLevelStr += "_DEPTH_STENCIL";
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CC_PLATFORM != CC_PLATFORM_WINDOWS || ALLOW_MULTISAMPLED_RENDER_TO_TEXTURE_ON_DESKTOP
|
||||
if (checkExtension("multisampled_render_to_texture")) {
|
||||
if (checkExtension("multisampled_render_to_texture2")) {
|
||||
_gpuConstantRegistry->mMSRT = MSRTSupportLevel::LEVEL2;
|
||||
} else {
|
||||
_gpuConstantRegistry->mMSRT = MSRTSupportLevel::LEVEL1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_features[toNumber(Feature::MULTI_SAMPLE_RESOLVE_DEPTH_STENCIL)] = false; // not implement yet.
|
||||
|
||||
if (checkExtension(CC_TOSTR(GL_EXT_debug_marker))) {
|
||||
_gpuConstantRegistry->debugMarker = true;
|
||||
}
|
||||
|
||||
ccstd::string compressedFmts;
|
||||
if (getFormatFeatures(Format::ETC_RGB8) != FormatFeature::NONE) {
|
||||
compressedFmts += "etc1 ";
|
||||
}
|
||||
|
||||
if (getFormatFeatures(Format::PVRTC_RGB2) != FormatFeature::NONE) {
|
||||
compressedFmts += "pvrtc ";
|
||||
}
|
||||
|
||||
if (getFormatFeatures(Format::ASTC_RGBA_4X4) != FormatFeature::NONE) {
|
||||
compressedFmts += "astc ";
|
||||
}
|
||||
|
||||
_renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
|
||||
_vendor = reinterpret_cast<const char *>(glGetString(GL_VENDOR));
|
||||
_version = reinterpret_cast<const char *>(glGetString(GL_VERSION));
|
||||
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, reinterpret_cast<GLint *>(&_caps.maxVertexAttributes));
|
||||
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, reinterpret_cast<GLint *>(&_caps.maxVertexUniformVectors));
|
||||
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, reinterpret_cast<GLint *>(&_caps.maxFragmentUniformVectors));
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, reinterpret_cast<GLint *>(&_caps.maxTextureUnits));
|
||||
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, reinterpret_cast<GLint *>(&_caps.maxVertexTextureUnits));
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, reinterpret_cast<GLint *>(&_caps.maxTextureSize));
|
||||
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, reinterpret_cast<GLint *>(&_caps.maxCubeMapTextureSize));
|
||||
_caps.uboOffsetAlignment = 16;
|
||||
|
||||
if (checkExtension("GL_OES_texture_3D")) {
|
||||
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_OES, reinterpret_cast<GLint *>(&_caps.max3DTextureSize));
|
||||
// texture2DArray fallback to texture3DOES
|
||||
_caps.maxArrayTextureLayers = _caps.max3DTextureSize;
|
||||
} else {
|
||||
_caps.max3DTextureSize = 0;
|
||||
_caps.maxArrayTextureLayers = 0;
|
||||
}
|
||||
|
||||
QueueInfo queueInfo;
|
||||
queueInfo.type = QueueType::GRAPHICS;
|
||||
_queue = createQueue(queueInfo);
|
||||
|
||||
QueryPoolInfo queryPoolInfo{QueryType::OCCLUSION, DEFAULT_MAX_QUERY_OBJECTS, true};
|
||||
_queryPool = createQueryPool(queryPoolInfo);
|
||||
|
||||
CommandBufferInfo cmdBuffInfo;
|
||||
cmdBuffInfo.type = CommandBufferType::PRIMARY;
|
||||
cmdBuffInfo.queue = _queue;
|
||||
_cmdBuff = createCommandBuffer(cmdBuffInfo);
|
||||
|
||||
_gpuStateCache->initialize(_caps.maxTextureUnits, _caps.maxVertexAttributes);
|
||||
_gpuBlitManager->initialize();
|
||||
|
||||
CC_LOG_INFO("GLES2 device initialized.");
|
||||
CC_LOG_INFO("RENDERER: %s", _renderer.c_str());
|
||||
CC_LOG_INFO("VENDOR: %s", _vendor.c_str());
|
||||
CC_LOG_INFO("VERSION: %s", _version.c_str());
|
||||
CC_LOG_INFO("COMPRESSED_FORMATS: %s", compressedFmts.c_str());
|
||||
CC_LOG_INFO("USE_VAO: %s", _gpuConstantRegistry->useVAO ? "true" : "false");
|
||||
CC_LOG_INFO("FRAMEBUFFER_FETCH: %s", fbfLevelStr.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLES2Device::doDestroy() {
|
||||
_gpuBlitManager->destroy();
|
||||
|
||||
CC_SAFE_DELETE(_stagingBuffer);
|
||||
CC_SAFE_DELETE(_gpuFramebufferCacheMap)
|
||||
CC_SAFE_DELETE(_gpuConstantRegistry)
|
||||
CC_SAFE_DELETE(_gpuFramebufferHub)
|
||||
CC_SAFE_DELETE(_gpuBlitManager)
|
||||
CC_SAFE_DELETE(_gpuStateCache)
|
||||
|
||||
CC_ASSERT(!_memoryStatus.bufferSize); // Buffer memory leaked.
|
||||
CC_ASSERT(!_memoryStatus.textureSize); // Texture memory leaked.
|
||||
|
||||
CC_SAFE_DESTROY_AND_DELETE(_cmdBuff)
|
||||
CC_SAFE_DESTROY_AND_DELETE(_queryPool)
|
||||
CC_SAFE_DESTROY_AND_DELETE(_queue)
|
||||
CC_SAFE_DESTROY_AND_DELETE(_gpuContext)
|
||||
}
|
||||
|
||||
void GLES2Device::acquire(Swapchain *const *swapchains, uint32_t count) {
|
||||
_gpuContext->makeCurrent();
|
||||
|
||||
if (_onAcquire) _onAcquire->execute();
|
||||
|
||||
_swapchains.clear();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
_swapchains.push_back(static_cast<GLES2Swapchain *>(swapchains[i])->gpuSwapchain());
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2Device::present() {
|
||||
CC_PROFILE(GLES2DevicePresent);
|
||||
auto *queue = static_cast<GLES2Queue *>(_queue);
|
||||
_numDrawCalls = queue->_numDrawCalls;
|
||||
_numInstances = queue->_numInstances;
|
||||
_numTriangles = queue->_numTriangles;
|
||||
|
||||
for (auto *swapchain : _swapchains) {
|
||||
_gpuContext->present(swapchain);
|
||||
}
|
||||
|
||||
// Clear queue stats
|
||||
queue->_numDrawCalls = 0;
|
||||
queue->_numInstances = 0;
|
||||
queue->_numTriangles = 0;
|
||||
}
|
||||
|
||||
void GLES2Device::bindContext(bool bound) {
|
||||
_gpuContext->bindContext(bound);
|
||||
}
|
||||
|
||||
void GLES2Device::initFormatFeature() {
|
||||
_textureExclusive.fill(true);
|
||||
|
||||
const FormatFeature completeFeature = FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE | FormatFeature::LINEAR_FILTER;
|
||||
|
||||
// builtin formatFeatures
|
||||
_formatFeatures[toNumber(Format::RGB8)] = completeFeature;
|
||||
_formatFeatures[toNumber(Format::R5G6B5)] = completeFeature;
|
||||
_textureExclusive[toNumber(Format::R5G6B5)] = false;
|
||||
|
||||
_formatFeatures[toNumber(Format::RGBA8)] = completeFeature;
|
||||
_formatFeatures[toNumber(Format::RGBA4)] = completeFeature;
|
||||
_textureExclusive[toNumber(Format::RGBA4)] = false;
|
||||
|
||||
_formatFeatures[toNumber(Format::RGB5A1)] = completeFeature;
|
||||
_textureExclusive[toNumber(Format::RGB5A1)] = false;
|
||||
|
||||
_formatFeatures[toNumber(Format::R8)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RG8)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGB8)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGBA8)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
|
||||
_formatFeatures[toNumber(Format::R8I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RG8I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGB8I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGBA8I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
|
||||
_formatFeatures[toNumber(Format::R8UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RG8UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGB8UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGBA8UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
|
||||
_formatFeatures[toNumber(Format::R16I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RG16I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGB16I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGBA16I)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
|
||||
_formatFeatures[toNumber(Format::R16UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RG16UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGB16UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGBA16UI)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
|
||||
_formatFeatures[toNumber(Format::R32F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RG32F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGB32F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGBA32F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
|
||||
if (checkExtension("OES_vertex_half_float")) {
|
||||
_formatFeatures[toNumber(Format::R16F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RG16F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGB16F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
_formatFeatures[toNumber(Format::RGBA16F)] |= FormatFeature::VERTEX_ATTRIBUTE;
|
||||
}
|
||||
|
||||
_formatFeatures[toNumber(Format::DEPTH)] |= FormatFeature::RENDER_TARGET;
|
||||
_textureExclusive[toNumber(Format::DEPTH)] = false;
|
||||
|
||||
_formatFeatures[toNumber(Format::DEPTH_STENCIL)] |= FormatFeature::RENDER_TARGET;
|
||||
_textureExclusive[toNumber(Format::DEPTH_STENCIL)] = false;
|
||||
|
||||
if (checkExtension("EXT_sRGB")) {
|
||||
_formatFeatures[toNumber(Format::SRGB8)] |= completeFeature;
|
||||
_formatFeatures[toNumber(Format::SRGB8_A8)] |= completeFeature;
|
||||
_textureExclusive[toNumber(Format::SRGB8_A8)] = false;
|
||||
}
|
||||
|
||||
if (checkExtension("texture_rg")) {
|
||||
_formatFeatures[toNumber(Format::R8)] |= completeFeature;
|
||||
_formatFeatures[toNumber(Format::RG8)] |= completeFeature;
|
||||
}
|
||||
|
||||
if (checkExtension("texture_float")) {
|
||||
_formatFeatures[toNumber(Format::RGB32F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
_formatFeatures[toNumber(Format::RGBA32F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
if (checkExtension("texture_rg")) {
|
||||
_formatFeatures[toNumber(Format::R32F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
_formatFeatures[toNumber(Format::RG32F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkExtension("texture_half_float")) {
|
||||
_formatFeatures[toNumber(Format::RGB16F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
_formatFeatures[toNumber(Format::RGBA16F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
if (checkExtension("texture_rg")) {
|
||||
_formatFeatures[toNumber(Format::R16F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
_formatFeatures[toNumber(Format::RG16F)] |= FormatFeature::RENDER_TARGET | FormatFeature::SAMPLED_TEXTURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkExtension("color_buffer_half_float")) {
|
||||
_formatFeatures[toNumber(Format::RGB16F)] |= FormatFeature::RENDER_TARGET;
|
||||
_textureExclusive[toNumber(Format::RGB16F)] = false;
|
||||
_formatFeatures[toNumber(Format::RGBA16F)] |= FormatFeature::RENDER_TARGET;
|
||||
_textureExclusive[toNumber(Format::RGBA16F)] = false;
|
||||
if (checkExtension("texture_rg")) {
|
||||
_formatFeatures[toNumber(Format::R16F)] |= FormatFeature::RENDER_TARGET;
|
||||
_textureExclusive[toNumber(Format::R16F)] = false;
|
||||
_formatFeatures[toNumber(Format::RG16F)] |= FormatFeature::RENDER_TARGET;
|
||||
_textureExclusive[toNumber(Format::RG16F)] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkExtension("texture_float_linear")) {
|
||||
_formatFeatures[toNumber(Format::RGB32F)] |= FormatFeature::LINEAR_FILTER;
|
||||
_formatFeatures[toNumber(Format::RGBA32F)] |= FormatFeature::LINEAR_FILTER;
|
||||
if (checkExtension("texture_rg")) {
|
||||
_formatFeatures[toNumber(Format::R32F)] |= FormatFeature::LINEAR_FILTER;
|
||||
_formatFeatures[toNumber(Format::RG32F)] |= FormatFeature::LINEAR_FILTER;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkExtension("OES_texture_half_float_linear")) {
|
||||
_formatFeatures[toNumber(Format::RGB16F)] |= FormatFeature::LINEAR_FILTER;
|
||||
_formatFeatures[toNumber(Format::RGBA16F)] |= FormatFeature::LINEAR_FILTER;
|
||||
if (checkExtension("texture_rg")) {
|
||||
_formatFeatures[toNumber(Format::R16F)] |= FormatFeature::LINEAR_FILTER;
|
||||
_formatFeatures[toNumber(Format::RG16F)] |= FormatFeature::LINEAR_FILTER;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkExtension("depth_texture")) {
|
||||
_formatFeatures[toNumber(Format::DEPTH)] |= completeFeature;
|
||||
}
|
||||
|
||||
if (checkExtension("packed_depth_stencil")) {
|
||||
_formatFeatures[toNumber(Format::DEPTH_STENCIL)] |= completeFeature;
|
||||
}
|
||||
|
||||
// compressed texture feature
|
||||
const FormatFeature compressedFeature = FormatFeature::SAMPLED_TEXTURE | FormatFeature::LINEAR_FILTER;
|
||||
if (checkExtension("compressed_ETC1")) {
|
||||
_formatFeatures[toNumber(Format::ETC_RGB8)] |= compressedFeature;
|
||||
}
|
||||
|
||||
if (checkExtension("texture_compression_pvrtc")) {
|
||||
_formatFeatures[toNumber(Format::PVRTC_RGB2)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::PVRTC_RGBA2)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::PVRTC_RGB4)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::PVRTC_RGBA4)] |= compressedFeature;
|
||||
}
|
||||
|
||||
if (checkExtension("texture_compression_astc")) {
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_4X4)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_5X4)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_5X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_6X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_6X6)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_8X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_8X6)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_8X8)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_10X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_10X6)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_10X8)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_10X10)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_12X10)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_RGBA_12X12)] |= compressedFeature;
|
||||
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_4X4)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_5X4)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_5X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_6X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_6X6)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_8X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_8X6)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_8X8)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_10X5)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_10X6)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_10X8)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_10X10)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_12X10)] |= compressedFeature;
|
||||
_formatFeatures[toNumber(Format::ASTC_SRGBA_12X12)] |= compressedFeature;
|
||||
}
|
||||
}
|
||||
|
||||
CommandBuffer *GLES2Device::createCommandBuffer(const CommandBufferInfo &info, bool hasAgent) {
|
||||
if (hasAgent || info.type == CommandBufferType::PRIMARY) return ccnew GLES2PrimaryCommandBuffer;
|
||||
return ccnew GLES2CommandBuffer;
|
||||
}
|
||||
|
||||
Queue *GLES2Device::createQueue() {
|
||||
return ccnew GLES2Queue;
|
||||
}
|
||||
|
||||
QueryPool *GLES2Device::createQueryPool() {
|
||||
return ccnew GLES2QueryPool;
|
||||
}
|
||||
|
||||
Swapchain *GLES2Device::createSwapchain() {
|
||||
return ccnew GLES2Swapchain;
|
||||
}
|
||||
|
||||
Buffer *GLES2Device::createBuffer() {
|
||||
return ccnew GLES2Buffer;
|
||||
}
|
||||
|
||||
Texture *GLES2Device::createTexture() {
|
||||
return ccnew GLES2Texture;
|
||||
}
|
||||
|
||||
Shader *GLES2Device::createShader() {
|
||||
return ccnew GLES2Shader;
|
||||
}
|
||||
|
||||
InputAssembler *GLES2Device::createInputAssembler() {
|
||||
return ccnew GLES2InputAssembler;
|
||||
}
|
||||
|
||||
RenderPass *GLES2Device::createRenderPass() {
|
||||
return ccnew GLES2RenderPass;
|
||||
}
|
||||
|
||||
Framebuffer *GLES2Device::createFramebuffer() {
|
||||
return ccnew GLES2Framebuffer;
|
||||
}
|
||||
|
||||
DescriptorSet *GLES2Device::createDescriptorSet() {
|
||||
return ccnew GLES2DescriptorSet;
|
||||
}
|
||||
|
||||
DescriptorSetLayout *GLES2Device::createDescriptorSetLayout() {
|
||||
return ccnew GLES2DescriptorSetLayout;
|
||||
}
|
||||
|
||||
PipelineLayout *GLES2Device::createPipelineLayout() {
|
||||
return ccnew GLES2PipelineLayout;
|
||||
}
|
||||
|
||||
PipelineState *GLES2Device::createPipelineState() {
|
||||
return ccnew GLES2PipelineState;
|
||||
}
|
||||
|
||||
Sampler *GLES2Device::createSampler(const SamplerInfo &info) {
|
||||
return ccnew GLES2Sampler(info);
|
||||
}
|
||||
|
||||
void GLES2Device::copyBuffersToTexture(const uint8_t *const *buffers, Texture *dst, const BufferTextureCopy *regions, uint32_t count) {
|
||||
CC_PROFILE(GLES2DeviceCopyBuffersToTexture);
|
||||
cmdFuncGLES2CopyBuffersToTexture(this, buffers, static_cast<GLES2Texture *>(dst)->gpuTexture(), regions, count);
|
||||
}
|
||||
|
||||
void GLES2Device::copyTextureToBuffers(Texture *src, uint8_t *const *buffers, const BufferTextureCopy *region, uint32_t count) {
|
||||
CC_PROFILE(GLES2DeviceCopyTextureToBuffers);
|
||||
cmdFuncGLES2CopyTextureToBuffers(this, static_cast<GLES2Texture *>(src)->gpuTexture(), buffers, region, count);
|
||||
}
|
||||
|
||||
SampleCount GLES2Device::getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const {
|
||||
std::ignore = format;
|
||||
std::ignore = usage;
|
||||
std::ignore = flags;
|
||||
return static_cast<SampleCount>(cmdFuncGLES2GetMaxSampleCount());
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
153
cocos/renderer/gfx-gles2/GLES2Device.h
Normal file
153
cocos/renderer/gfx-gles2/GLES2Device.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXDevice.h"
|
||||
#include "gfx-base/GFXSwapchain.h"
|
||||
#include "gfx-gles-common/GLESCommandPool.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
class GLES2GPUContext;
|
||||
struct GLES2GPUSwapchain;
|
||||
class GLES2GPUStateCache;
|
||||
class GLES2GPUBlitManager;
|
||||
class GLES2GPUFramebufferHub;
|
||||
struct GLES2GPUConstantRegistry;
|
||||
class GLES2GPUFramebufferCacheMap;
|
||||
|
||||
class CC_GLES2_API GLES2Device final : public Device {
|
||||
public:
|
||||
static GLES2Device *getInstance();
|
||||
|
||||
~GLES2Device() override;
|
||||
|
||||
using Device::copyBuffersToTexture;
|
||||
using Device::createBuffer;
|
||||
using Device::createCommandBuffer;
|
||||
using Device::createDescriptorSet;
|
||||
using Device::createDescriptorSetLayout;
|
||||
using Device::createFramebuffer;
|
||||
using Device::createGeneralBarrier;
|
||||
using Device::createInputAssembler;
|
||||
using Device::createPipelineLayout;
|
||||
using Device::createPipelineState;
|
||||
using Device::createQueryPool;
|
||||
using Device::createQueue;
|
||||
using Device::createRenderPass;
|
||||
using Device::createSampler;
|
||||
using Device::createShader;
|
||||
using Device::createTexture;
|
||||
using Device::createTextureBarrier;
|
||||
|
||||
void frameSync() override{};
|
||||
void acquire(Swapchain *const *swapchains, uint32_t count) override;
|
||||
void present() override;
|
||||
|
||||
inline const GLESBindingMapping &bindingMappings() const { return _bindingMappings; }
|
||||
|
||||
inline GLES2GPUContext *context() const { return _gpuContext; }
|
||||
inline GLES2GPUStateCache *stateCache() const { return _gpuStateCache; }
|
||||
inline GLES2GPUBlitManager *blitManager() const { return _gpuBlitManager; }
|
||||
inline GLES2GPUFramebufferHub *framebufferHub() const { return _gpuFramebufferHub; }
|
||||
inline GLES2GPUConstantRegistry *constantRegistry() const { return _gpuConstantRegistry; }
|
||||
inline GLES2GPUFramebufferCacheMap *framebufferCacheMap() const { return _gpuFramebufferCacheMap; }
|
||||
|
||||
inline bool checkExtension(const ccstd::string &extension) const {
|
||||
return std::any_of(_extensions.begin(), _extensions.end(), [&extension](auto &ext) {
|
||||
return ext.find(extension) != ccstd::string::npos;
|
||||
});
|
||||
}
|
||||
|
||||
inline uint8_t *getStagingBuffer(uint32_t size = 0) {
|
||||
if (size > _stagingBufferSize) {
|
||||
CC_FREE(_stagingBuffer);
|
||||
_stagingBuffer = static_cast<uint8_t *>(CC_MALLOC(size));
|
||||
_stagingBufferSize = size;
|
||||
}
|
||||
|
||||
return _stagingBuffer;
|
||||
}
|
||||
|
||||
// check the specified format is texture-exclusive (no renderbuffers allowed)
|
||||
inline bool isTextureExclusive(const Format &format) { return _textureExclusive[static_cast<size_t>(format)]; };
|
||||
SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const override;
|
||||
protected:
|
||||
static GLES2Device *instance;
|
||||
|
||||
friend class DeviceManager;
|
||||
|
||||
GLES2Device();
|
||||
|
||||
bool doInit(const DeviceInfo &info) override;
|
||||
void doDestroy() override;
|
||||
CommandBuffer *createCommandBuffer(const CommandBufferInfo &info, bool hasAgent) override;
|
||||
Queue *createQueue() override;
|
||||
QueryPool *createQueryPool() override;
|
||||
Swapchain *createSwapchain() override;
|
||||
Buffer *createBuffer() override;
|
||||
Texture *createTexture() override;
|
||||
Shader *createShader() override;
|
||||
InputAssembler *createInputAssembler() override;
|
||||
RenderPass *createRenderPass() override;
|
||||
Framebuffer *createFramebuffer() override;
|
||||
DescriptorSet *createDescriptorSet() override;
|
||||
DescriptorSetLayout *createDescriptorSetLayout() override;
|
||||
PipelineLayout *createPipelineLayout() override;
|
||||
PipelineState *createPipelineState() override;
|
||||
|
||||
Sampler *createSampler(const SamplerInfo &info) override;
|
||||
|
||||
void copyBuffersToTexture(const uint8_t *const *buffers, Texture *dst, const BufferTextureCopy *regions, uint32_t count) override;
|
||||
void copyTextureToBuffers(Texture *src, uint8_t *const *buffers, const BufferTextureCopy *region, uint32_t count) override;
|
||||
void getQueryPoolResults(QueryPool *queryPool) override {}
|
||||
|
||||
void bindContext(bool bound) override;
|
||||
|
||||
void initFormatFeature();
|
||||
|
||||
GLES2GPUContext *_gpuContext{nullptr};
|
||||
GLES2GPUStateCache *_gpuStateCache{nullptr};
|
||||
GLES2GPUBlitManager *_gpuBlitManager{nullptr};
|
||||
GLES2GPUFramebufferHub *_gpuFramebufferHub{nullptr};
|
||||
GLES2GPUConstantRegistry *_gpuConstantRegistry{nullptr};
|
||||
GLES2GPUFramebufferCacheMap *_gpuFramebufferCacheMap{nullptr};
|
||||
|
||||
ccstd::vector<GLES2GPUSwapchain *> _swapchains;
|
||||
|
||||
ccstd::array<bool, static_cast<size_t>(Format::COUNT)> _textureExclusive;
|
||||
|
||||
GLESBindingMapping _bindingMappings;
|
||||
|
||||
ccstd::vector<ccstd::string> _extensions;
|
||||
|
||||
uint8_t *_stagingBuffer{nullptr};
|
||||
uint32_t _stagingBufferSize{0};
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
85
cocos/renderer/gfx-gles2/GLES2Framebuffer.cpp
Normal file
85
cocos/renderer/gfx-gles2/GLES2Framebuffer.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2Framebuffer.h"
|
||||
#include "GLES2RenderPass.h"
|
||||
#include "GLES2Texture.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Framebuffer::GLES2Framebuffer() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2Framebuffer::~GLES2Framebuffer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2Framebuffer::doInit(const FramebufferInfo & /*info*/) {
|
||||
_gpuFBO = ccnew GLES2GPUFramebuffer;
|
||||
_gpuFBO->gpuRenderPass = static_cast<GLES2RenderPass *>(_renderPass)->gpuRenderPass();
|
||||
|
||||
_gpuFBO->gpuColorTextures.resize(_colorTextures.size());
|
||||
for (size_t i = 0; i < _colorTextures.size(); ++i) {
|
||||
auto *colorTexture = static_cast<GLES2Texture *>(_colorTextures.at(i));
|
||||
_gpuFBO->gpuColorTextures[i] = colorTexture->gpuTexture();
|
||||
_gpuFBO->lodLevel = colorTexture->getViewInfo().baseLevel;
|
||||
GLES2Device::getInstance()->framebufferHub()->connect(colorTexture->gpuTexture(), _gpuFBO);
|
||||
}
|
||||
|
||||
if (_depthStencilTexture) {
|
||||
auto *depthTexture = static_cast<GLES2Texture *>(_depthStencilTexture);
|
||||
_gpuFBO->gpuDepthStencilTexture = depthTexture->gpuTexture();
|
||||
_gpuFBO->lodLevel = depthTexture->getViewInfo().baseLevel;
|
||||
GLES2Device::getInstance()->framebufferHub()->connect(depthTexture->gpuTexture(), _gpuFBO);
|
||||
}
|
||||
|
||||
cmdFuncGLES2CreateFramebuffer(GLES2Device::getInstance(), _gpuFBO);
|
||||
}
|
||||
|
||||
void GLES2Framebuffer::doDestroy() {
|
||||
if (_gpuFBO) {
|
||||
cmdFuncGLES2DestroyFramebuffer(GLES2Device::getInstance(), _gpuFBO);
|
||||
|
||||
for (auto &texture : _colorTextures) {
|
||||
auto *colorTexture = static_cast<GLES2Texture *>(texture);
|
||||
GLES2Device::getInstance()->framebufferHub()->disengage(colorTexture->gpuTexture(), _gpuFBO);
|
||||
}
|
||||
if (_depthStencilTexture) {
|
||||
auto *depthTexture = static_cast<GLES2Texture *>(_depthStencilTexture);
|
||||
GLES2Device::getInstance()->framebufferHub()->disengage(depthTexture->gpuTexture(), _gpuFBO);
|
||||
}
|
||||
|
||||
delete _gpuFBO;
|
||||
_gpuFBO = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
50
cocos/renderer/gfx-gles2/GLES2Framebuffer.h
Normal file
50
cocos/renderer/gfx-gles2/GLES2Framebuffer.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXFramebuffer.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
class GLES2GPUFramebuffer;
|
||||
|
||||
class CC_GLES2_API GLES2Framebuffer final : public Framebuffer {
|
||||
public:
|
||||
GLES2Framebuffer();
|
||||
~GLES2Framebuffer() override;
|
||||
|
||||
inline GLES2GPUFramebuffer *gpuFBO() const { return _gpuFBO; }
|
||||
|
||||
protected:
|
||||
void doInit(const FramebufferInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPUFramebuffer *_gpuFBO = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
424
cocos/renderer/gfx-gles2/GLES2GPUContext.cpp
Normal file
424
cocos/renderer/gfx-gles2/GLES2GPUContext.cpp
Normal file
@@ -0,0 +1,424 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 <thread>
|
||||
#include "GLES2GPUObjects.h"
|
||||
#include "base/StringUtil.h"
|
||||
|
||||
#if CC_SWAPPY_ENABLED
|
||||
#include "swappy/swappyGL.h"
|
||||
#endif
|
||||
|
||||
#define FORCE_DISABLE_VALIDATION 1
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION
|
||||
constexpr uint32_t DISABLE_VALIDATION_ASSERTIONS = 1; // 0 for default behavior, otherwise assertions will be disabled
|
||||
|
||||
void GL_APIENTRY GLES2EGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) {
|
||||
String sourceDesc;
|
||||
switch (source) {
|
||||
case GL_DEBUG_SOURCE_API_KHR: sourceDesc = "API"; break;
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_KHR: sourceDesc = "SHADER_COMPILER"; break;
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR: sourceDesc = "WINDOW_SYSTEM"; break;
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY_KHR: sourceDesc = "THIRD_PARTY"; break;
|
||||
case GL_DEBUG_SOURCE_APPLICATION_KHR: sourceDesc = "APPLICATION"; break;
|
||||
default: sourceDesc = "OTHER";
|
||||
}
|
||||
|
||||
String typeDesc;
|
||||
switch (type) {
|
||||
case GL_DEBUG_TYPE_ERROR_KHR: typeDesc = "ERROR"; break;
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR: typeDesc = "PEPRECATED_BEHAVIOR"; break;
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR: typeDesc = "UNDEFINED_BEHAVIOR"; break;
|
||||
case GL_DEBUG_TYPE_PERFORMANCE_KHR: typeDesc = "PERFORMANCE"; break;
|
||||
case GL_DEBUG_TYPE_PORTABILITY_KHR: typeDesc = "PORTABILITY"; break;
|
||||
case GL_DEBUG_TYPE_MARKER_KHR: typeDesc = "MARKER"; break;
|
||||
case GL_DEBUG_TYPE_PUSH_GROUP_KHR: typeDesc = "PUSH_GROUP"; break;
|
||||
case GL_DEBUG_TYPE_POP_GROUP_KHR: typeDesc = "POP_GROUP"; break;
|
||||
default: typeDesc = "OTHER";
|
||||
}
|
||||
|
||||
String severityDesc;
|
||||
switch (severity) {
|
||||
case GL_DEBUG_SEVERITY_HIGH_KHR: severityDesc = "HIGH"; break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM_KHR: severityDesc = "MEDIUM"; break;
|
||||
case GL_DEBUG_SEVERITY_LOW_KHR: severityDesc = "LOW"; break;
|
||||
default: severityDesc = "NOTIFICATION";
|
||||
}
|
||||
|
||||
String msg = StringUtil::format("source: %s, type: %s, severity: %s, message: %s",
|
||||
sourceDesc.c_str(), typeDesc.c_str(), severityDesc.c_str(), message);
|
||||
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH_KHR) {
|
||||
CC_LOG_ERROR(msg.c_str());
|
||||
CC_ASSERT(DISABLE_VALIDATION_ASSERTIONS);
|
||||
} else if (severity == GL_DEBUG_SEVERITY_MEDIUM_KHR) {
|
||||
CC_LOG_WARNING(msg.c_str());
|
||||
} else {
|
||||
CC_LOG_DEBUG(msg.c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GLES2GPUContext::initialize(GLES2GPUStateCache *stateCache, GLES2GPUConstantRegistry *constantRegistry) {
|
||||
_stateCache = stateCache;
|
||||
_constantRegistry = constantRegistry;
|
||||
|
||||
if (!gles2wInit()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EGL_CHECK(eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY));
|
||||
|
||||
if (eglDisplay == EGL_NO_DISPLAY) {
|
||||
CC_LOG_ERROR("eglGetDisplay() - FAILED.");
|
||||
return false;
|
||||
}
|
||||
|
||||
EGLBoolean success{false};
|
||||
EGL_CHECK(success = eglInitialize(eglDisplay, &eglMajorVersion, &eglMinorVersion));
|
||||
|
||||
if (!success) {
|
||||
CC_LOG_ERROR("eglInitialize() - FAILED.");
|
||||
return false;
|
||||
}
|
||||
|
||||
EGL_CHECK(eglBindAPI(EGL_OPENGL_ES_API));
|
||||
|
||||
bool msaaEnabled{false};
|
||||
bool qualityPreferred{false};
|
||||
|
||||
EGLint redSize{8};
|
||||
EGLint greenSize{8};
|
||||
EGLint blueSize{8};
|
||||
EGLint alphaSize{8};
|
||||
EGLint depthSize{24};
|
||||
EGLint stencilSize{8};
|
||||
EGLint sampleBufferSize{msaaEnabled ? EGL_DONT_CARE : 0};
|
||||
EGLint sampleSize{msaaEnabled ? EGL_DONT_CARE : 0};
|
||||
|
||||
EGLint defaultAttribs[]{
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_BLUE_SIZE, blueSize,
|
||||
EGL_GREEN_SIZE, greenSize,
|
||||
EGL_RED_SIZE, redSize,
|
||||
EGL_ALPHA_SIZE, alphaSize,
|
||||
EGL_DEPTH_SIZE, depthSize,
|
||||
EGL_STENCIL_SIZE, stencilSize,
|
||||
EGL_SAMPLE_BUFFERS, sampleBufferSize,
|
||||
EGL_SAMPLES, sampleSize,
|
||||
EGL_NONE};
|
||||
|
||||
int numConfig{0};
|
||||
ccstd::vector<EGLConfig> eglConfigs;
|
||||
|
||||
EGL_CHECK(success = eglChooseConfig(eglDisplay, defaultAttribs, nullptr, 0, &numConfig));
|
||||
if (success) {
|
||||
eglConfigs.resize(numConfig);
|
||||
} else {
|
||||
CC_LOG_ERROR("Query GLES2 configuration failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = numConfig;
|
||||
EGL_CHECK(success = eglChooseConfig(eglDisplay, defaultAttribs, eglConfigs.data(), count, &numConfig));
|
||||
if (!success || !numConfig) {
|
||||
CC_LOG_ERROR("eglChooseConfig configuration failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
EGLint depth{0};
|
||||
EGLint stencil{0};
|
||||
EGLint sampleBuffers{0};
|
||||
EGLint sampleCount{0};
|
||||
EGLint params[8]{0};
|
||||
uint64_t lastScore = qualityPreferred ? std::numeric_limits<uint64_t>::min() : std::numeric_limits<uint64_t>::max();
|
||||
|
||||
for (int i = 0; i < numConfig; i++) {
|
||||
int depthValue{0};
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_RED_SIZE, ¶ms[0]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_GREEN_SIZE, ¶ms[1]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_BLUE_SIZE, ¶ms[2]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_ALPHA_SIZE, ¶ms[3]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_DEPTH_SIZE, ¶ms[4]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_STENCIL_SIZE, ¶ms[5]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_SAMPLE_BUFFERS, ¶ms[6]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_SAMPLES, ¶ms[7]);
|
||||
eglGetConfigAttrib(eglDisplay, eglConfigs[i], EGL_DEPTH_ENCODING_NV, &depthValue);
|
||||
|
||||
int bNonLinearDepth = (depthValue == EGL_DEPTH_ENCODING_NONLINEAR_NV) ? 1 : 0;
|
||||
|
||||
/*------------------------------------------ANGLE's priority-----------------------------------------------*/
|
||||
// Favor EGLConfigLists by RGB, then Depth, then Non-linear Depth, then Stencil, then Alpha
|
||||
uint64_t currScore{0};
|
||||
EGLint colorScore = std::abs(params[0] - redSize) + std::abs(params[1] - greenSize) + std::abs(params[2] - blueSize);
|
||||
currScore |= static_cast<uint64_t>(std::min(std::max(params[6], 0), 15)) << 29;
|
||||
currScore |= static_cast<uint64_t>(std::min(std::max(params[7], 0), 31)) << 24;
|
||||
currScore |= static_cast<uint64_t>(std::min(colorScore, 127)) << 17;
|
||||
currScore |= static_cast<uint64_t>(std::min(std::abs(params[4] - depthSize), 63)) << 11;
|
||||
currScore |= static_cast<uint64_t>(std::min(std::abs(1 - bNonLinearDepth), 1)) << 10;
|
||||
currScore |= static_cast<uint64_t>(std::min(std::abs(params[5] - stencilSize), 31)) << 6;
|
||||
currScore |= static_cast<uint64_t>(std::min(std::abs(params[3] - alphaSize), 31)) << 0;
|
||||
/*------------------------------------------ANGLE's priority-----------------------------------------------*/
|
||||
|
||||
// if msaaEnabled, sampleBuffers and sampleCount should be greater than 0, until iterate to the last one(can't find).
|
||||
bool msaaLimit = (msaaEnabled ? (params[6] > 0 && params[7] > 0) : (params[6] == 0 && params[7] == 0));
|
||||
// performancePreferred ? [>=] : [<] , egl configurations store in "ascending order"
|
||||
bool filter = (currScore < lastScore) ^ qualityPreferred;
|
||||
if ((filter && msaaLimit) || (!eglConfig && i == numConfig - 1)) {
|
||||
eglConfig = eglConfigs[i];
|
||||
depth = params[4];
|
||||
stencil = params[5];
|
||||
sampleBuffers = params[6];
|
||||
sampleCount = params[7];
|
||||
lastScore = currScore;
|
||||
}
|
||||
}
|
||||
|
||||
CC_LOG_INFO("Setup EGLConfig: depth [%d] stencil [%d] sampleBuffer [%d] sampleCount [%d]", depth, stencil, sampleBuffers, sampleCount);
|
||||
|
||||
EGL_CHECK(_extensions = StringUtil::split(eglQueryString(eglDisplay, EGL_EXTENSIONS), " "));
|
||||
|
||||
bool hasKHRCreateCtx = checkExtension(CC_TOSTR(EGL_KHR_create_context));
|
||||
if (hasKHRCreateCtx) {
|
||||
eglAttributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
|
||||
eglAttributes.push_back(2);
|
||||
eglAttributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR);
|
||||
eglAttributes.push_back(0);
|
||||
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION
|
||||
eglAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
|
||||
eglAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
|
||||
#endif
|
||||
eglAttributes.push_back(EGL_NONE);
|
||||
|
||||
EGL_CHECK(eglDefaultContext = eglCreateContext(eglDisplay, eglConfig, nullptr, eglAttributes.data()));
|
||||
} else {
|
||||
eglAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
|
||||
eglAttributes.push_back(2);
|
||||
eglAttributes.push_back(EGL_NONE);
|
||||
|
||||
EGL_CHECK(eglDefaultContext = eglCreateContext(eglDisplay, eglConfig, nullptr, eglAttributes.data()));
|
||||
}
|
||||
|
||||
if (!eglDefaultContext) {
|
||||
CC_LOG_ERROR("Create EGL context failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
EGLint pbufferAttribs[]{
|
||||
EGL_WIDTH, 1,
|
||||
EGL_HEIGHT, 1,
|
||||
EGL_NONE};
|
||||
EGL_CHECK(eglDefaultSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs));
|
||||
|
||||
size_t threadID{std::hash<std::thread::id>{}(std::this_thread::get_id())};
|
||||
_sharedContexts[threadID] = eglDefaultContext;
|
||||
|
||||
bindContext(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLES2GPUContext::destroy() {
|
||||
if (eglDisplay) {
|
||||
makeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
if (eglDefaultSurface) {
|
||||
EGL_CHECK(eglDestroySurface(eglDisplay, eglDefaultSurface));
|
||||
eglDefaultSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
for (auto pair : _sharedContexts) {
|
||||
if (pair.second != eglDefaultContext) {
|
||||
EGL_CHECK(eglDestroyContext(eglDisplay, pair.second));
|
||||
}
|
||||
}
|
||||
_sharedContexts.clear();
|
||||
|
||||
if (eglDefaultContext) {
|
||||
EGL_CHECK(eglDestroyContext(eglDisplay, eglDefaultContext));
|
||||
eglDefaultContext = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (eglDisplay) {
|
||||
EGL_CHECK(eglTerminate(eglDisplay));
|
||||
eglDisplay = EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
gles2wExit();
|
||||
}
|
||||
|
||||
void GLES2GPUContext::bindContext(bool bound) {
|
||||
if (bound) {
|
||||
makeCurrent(eglDefaultSurface, eglDefaultSurface, eglDefaultContext);
|
||||
resetStates();
|
||||
} else {
|
||||
makeCurrent(EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT, false);
|
||||
_eglCurrentDrawSurface = EGL_NO_SURFACE;
|
||||
_eglCurrentReadSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2GPUContext::makeCurrent(const GLES2GPUSwapchain *drawSwapchain, const GLES2GPUSwapchain *readSwapchain) {
|
||||
EGLSurface drawSurface = drawSwapchain ? drawSwapchain->eglSurface : _eglCurrentDrawSurface;
|
||||
EGLSurface readSurface = readSwapchain ? readSwapchain->eglSurface : _eglCurrentReadSurface;
|
||||
EGLContext prevContext = eglGetCurrentContext();
|
||||
|
||||
if (_eglCurrentDrawSurface == drawSurface && _eglCurrentReadSurface == readSurface && _eglCurrentContext == prevContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
makeCurrent(drawSurface, readSurface, _eglCurrentContext);
|
||||
|
||||
if (prevContext != _eglCurrentContext) {
|
||||
resetStates();
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2GPUContext::present(const GLES2GPUSwapchain *swapchain) {
|
||||
#if CC_SWAPPY_ENABLED
|
||||
if (swapchain->swappyEnabled) {
|
||||
//fallback to normal eglswap if swappy_swap failed
|
||||
if (SwappyGL_swap(eglDisplay, swapchain->eglSurface)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (_eglCurrentInterval != swapchain->eglSwapInterval) {
|
||||
if (!eglSwapInterval(eglDisplay, swapchain->eglSwapInterval)) {
|
||||
CC_LOG_ERROR("eglSwapInterval() - FAILED.");
|
||||
}
|
||||
_eglCurrentInterval = swapchain->eglSwapInterval;
|
||||
}
|
||||
EGL_CHECK(eglSwapBuffers(eglDisplay, swapchain->eglSurface));
|
||||
}
|
||||
|
||||
EGLContext GLES2GPUContext::getSharedContext() {
|
||||
size_t threadID{std::hash<std::thread::id>{}(std::this_thread::get_id())};
|
||||
if (_sharedContexts.count(threadID)) return _sharedContexts[threadID];
|
||||
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
EGL_CHECK(context = eglCreateContext(eglDisplay, eglConfig, eglDefaultContext, eglAttributes.data()));
|
||||
|
||||
if (!context) {
|
||||
CC_LOG_ERROR("Create shared context failed.");
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
_sharedContexts[threadID] = context;
|
||||
return context;
|
||||
}
|
||||
|
||||
bool GLES2GPUContext::makeCurrent(EGLSurface drawSurface, EGLSurface readSurface, EGLContext context, bool updateCache) {
|
||||
bool succeeded;
|
||||
EGL_CHECK(succeeded = eglMakeCurrent(eglDisplay, drawSurface, readSurface, context));
|
||||
if (succeeded && updateCache) {
|
||||
_eglCurrentDrawSurface = drawSurface;
|
||||
_eglCurrentReadSurface = readSurface;
|
||||
_eglCurrentContext = context;
|
||||
}
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
void GLES2GPUContext::resetStates() const {
|
||||
GL_CHECK(glPixelStorei(GL_PACK_ALIGNMENT, 1));
|
||||
GL_CHECK(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
GL_CHECK(glActiveTexture(GL_TEXTURE0));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GL_CHECK(glEnable(GL_SCISSOR_TEST));
|
||||
GL_CHECK(glEnable(GL_CULL_FACE));
|
||||
GL_CHECK(glCullFace(GL_BACK));
|
||||
|
||||
GL_CHECK(glFrontFace(GL_CCW));
|
||||
|
||||
GL_CHECK(glDisable(GL_SAMPLE_COVERAGE));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GL_CHECK(glEnable(GL_DEPTH_TEST));
|
||||
GL_CHECK(glDepthMask(GL_TRUE));
|
||||
GL_CHECK(glDepthFunc(GL_LESS));
|
||||
|
||||
GL_CHECK(glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 1, 0xffffffff));
|
||||
GL_CHECK(glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP));
|
||||
GL_CHECK(glStencilMaskSeparate(GL_FRONT, 0xffffffff));
|
||||
GL_CHECK(glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 1, 0xffffffff));
|
||||
GL_CHECK(glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP));
|
||||
GL_CHECK(glStencilMaskSeparate(GL_BACK, 0xffffffff));
|
||||
|
||||
GL_CHECK(glDisable(GL_STENCIL_TEST));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GL_CHECK(glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE));
|
||||
GL_CHECK(glDisable(GL_BLEND));
|
||||
GL_CHECK(glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD));
|
||||
GL_CHECK(glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO));
|
||||
GL_CHECK(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
|
||||
GL_CHECK(glBlendColor(0.0F, 0.0F, 0.0F, 0.0F));
|
||||
|
||||
GL_CHECK(glUseProgram(0));
|
||||
|
||||
if (_constantRegistry->useVAO) {
|
||||
GL_CHECK(glBindVertexArrayOES(0));
|
||||
}
|
||||
|
||||
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
GL_CHECK(glBindTexture(GL_TEXTURE_CUBE_MAP, 0));
|
||||
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
|
||||
#if CC_DEBUG > 0 && !FORCE_DISABLE_VALIDATION
|
||||
GL_CHECK(glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR));
|
||||
if (glDebugMessageControlKHR) {
|
||||
GL_CHECK(glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE));
|
||||
}
|
||||
if (glDebugMessageCallbackKHR) {
|
||||
GL_CHECK(glDebugMessageCallbackKHR(GLES2EGLDebugProc, NULL));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_constantRegistry->mFBF == FBFSupportLevel::NON_COHERENT_QCOM) {
|
||||
GL_CHECK(glEnable(GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM));
|
||||
}
|
||||
|
||||
_stateCache->reset();
|
||||
|
||||
_constantRegistry->currentBoundThreadID = std::hash<std::thread::id>{}(std::this_thread::get_id());
|
||||
|
||||
CC_LOG_DEBUG("EGL context bounded to thread %llx", _constantRegistry->currentBoundThreadID);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
597
cocos/renderer/gfx-gles2/GLES2GPUObjects.h
Normal file
597
cocos/renderer/gfx-gles2/GLES2GPUObjects.h
Normal file
@@ -0,0 +1,597 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
http://www.cocos.com
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 <algorithm>
|
||||
#include "GLES2Std.h"
|
||||
#include "GLES2Wrangler.h"
|
||||
#include "base/std/container/unordered_map.h"
|
||||
#include "gfx-base/GFXDef.h"
|
||||
#include "gfx-gles-common/GLESCommandPool.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUConstantRegistry {
|
||||
size_t currentBoundThreadID{0U};
|
||||
|
||||
MSRTSupportLevel mMSRT{MSRTSupportLevel::NONE};
|
||||
FBFSupportLevel mFBF{FBFSupportLevel::NONE};
|
||||
|
||||
bool useVAO = false;
|
||||
bool useDrawInstanced = false;
|
||||
bool useInstancedArrays = false;
|
||||
bool useDiscardFramebuffer = false;
|
||||
bool debugMarker = false;
|
||||
};
|
||||
|
||||
class GLES2GPUStateCache;
|
||||
struct GLES2GPUSwapchain;
|
||||
class GLES2GPUContext final {
|
||||
public:
|
||||
bool initialize(GLES2GPUStateCache *stateCache, GLES2GPUConstantRegistry *constantRegistry);
|
||||
void destroy();
|
||||
|
||||
EGLint eglMajorVersion{0};
|
||||
EGLint eglMinorVersion{0};
|
||||
EGLDisplay eglDisplay{EGL_NO_DISPLAY};
|
||||
EGLConfig eglConfig{nullptr};
|
||||
ccstd::vector<EGLint> eglAttributes;
|
||||
|
||||
EGLSurface eglDefaultSurface{EGL_NO_SURFACE};
|
||||
EGLContext eglDefaultContext{EGL_NO_CONTEXT};
|
||||
|
||||
// pass nullptr to keep the current surface
|
||||
void makeCurrent(const GLES2GPUSwapchain *drawSwapchain = nullptr, const GLES2GPUSwapchain *readSwapchain = nullptr);
|
||||
void bindContext(bool bound); // for context switching between threads
|
||||
|
||||
void present(const GLES2GPUSwapchain *swapchain);
|
||||
|
||||
inline bool checkExtension(const ccstd::string &extension) const {
|
||||
return std::find(_extensions.begin(), _extensions.end(), extension) != _extensions.end();
|
||||
}
|
||||
|
||||
private:
|
||||
bool makeCurrent(EGLSurface drawSurface, EGLSurface readSurface, EGLContext context, bool updateCache = true);
|
||||
EGLContext getSharedContext();
|
||||
void resetStates() const;
|
||||
|
||||
// state caches
|
||||
EGLSurface _eglCurrentDrawSurface{EGL_NO_SURFACE};
|
||||
EGLSurface _eglCurrentReadSurface{EGL_NO_SURFACE};
|
||||
EGLContext _eglCurrentContext{EGL_NO_CONTEXT};
|
||||
EGLint _eglCurrentInterval{0};
|
||||
|
||||
GLES2GPUStateCache *_stateCache{nullptr};
|
||||
GLES2GPUConstantRegistry *_constantRegistry{nullptr};
|
||||
|
||||
ccstd::unordered_map<size_t, EGLContext> _sharedContexts;
|
||||
|
||||
ccstd::vector<ccstd::string> _extensions;
|
||||
};
|
||||
|
||||
struct GLES2GPUBuffer {
|
||||
BufferUsage usage = BufferUsage::NONE;
|
||||
MemoryUsage memUsage = MemoryUsage::NONE;
|
||||
uint32_t size = 0;
|
||||
uint32_t stride = 0;
|
||||
uint32_t count = 0;
|
||||
GLenum glTarget = 0;
|
||||
GLuint glBuffer = 0;
|
||||
uint8_t *buffer = nullptr;
|
||||
DrawInfoList indirects;
|
||||
};
|
||||
using GLES2GPUBufferList = ccstd::vector<GLES2GPUBuffer *>;
|
||||
|
||||
struct GLES2GPUBufferView {
|
||||
GLES2GPUBuffer *gpuBuffer = nullptr;
|
||||
uint32_t offset = 0U;
|
||||
uint32_t range = 0U;
|
||||
};
|
||||
|
||||
struct GLES2GPUTexture {
|
||||
TextureType type{TextureType::TEX2D};
|
||||
Format format{Format::UNKNOWN};
|
||||
TextureUsage usage{TextureUsageBit::NONE};
|
||||
uint32_t width{0};
|
||||
uint32_t height{0};
|
||||
uint32_t depth{1};
|
||||
uint32_t size{0};
|
||||
uint32_t arrayLayer{1};
|
||||
uint32_t mipLevel{1};
|
||||
SampleCount samples{SampleCount::X1};
|
||||
TextureFlags flags{TextureFlagBit::NONE};
|
||||
bool isPowerOf2{false};
|
||||
bool memoryAllocated{true}; // false if swapchain image or implicit ms render buffer.
|
||||
GLenum glTarget{0};
|
||||
GLenum glInternalFmt{0};
|
||||
GLenum glFormat{0};
|
||||
GLenum glType{0};
|
||||
GLenum glUsage{0};
|
||||
GLint glSamples{0};
|
||||
GLuint glTexture{0};
|
||||
GLuint glRenderbuffer{0};
|
||||
GLenum glWrapS{0};
|
||||
GLenum glWrapT{0};
|
||||
GLenum glMinFilter{0};
|
||||
GLenum glMagFilter{0};
|
||||
GLES2GPUSwapchain *swapchain{nullptr};
|
||||
};
|
||||
|
||||
using GLES2GPUTextureList = ccstd::vector<GLES2GPUTexture *>;
|
||||
|
||||
struct GLES2GPUSwapchain {
|
||||
#if CC_SWAPPY_ENABLED
|
||||
bool swappyEnabled{false};
|
||||
#endif
|
||||
EGLSurface eglSurface{EGL_NO_SURFACE};
|
||||
EGLint eglSwapInterval{0};
|
||||
GLuint glFramebuffer{0};
|
||||
GLES2GPUTexture *gpuColorTexture{nullptr};
|
||||
};
|
||||
|
||||
struct GLES2GPUSampler {
|
||||
Filter minFilter = Filter::NONE;
|
||||
Filter magFilter = Filter::NONE;
|
||||
Filter mipFilter = Filter::NONE;
|
||||
Address addressU = Address::CLAMP;
|
||||
Address addressV = Address::CLAMP;
|
||||
Address addressW = Address::CLAMP;
|
||||
GLenum glMinFilter = 0;
|
||||
GLenum glMagFilter = 0;
|
||||
GLenum glWrapS = 0;
|
||||
GLenum glWrapT = 0;
|
||||
GLenum glWrapR = 0;
|
||||
};
|
||||
|
||||
struct GLES2GPUInput {
|
||||
uint32_t binding = 0;
|
||||
ccstd::string name;
|
||||
Type type = Type::UNKNOWN;
|
||||
uint32_t stride = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t size = 0;
|
||||
GLenum glType = 0;
|
||||
GLint glLoc = -1;
|
||||
};
|
||||
using GLES2GPUInputList = ccstd::vector<GLES2GPUInput>;
|
||||
|
||||
struct GLES2GPUUniform {
|
||||
uint32_t binding = INVALID_BINDING;
|
||||
ccstd::string name;
|
||||
Type type = Type::UNKNOWN;
|
||||
uint32_t stride = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t size = 0;
|
||||
uint32_t offset = 0;
|
||||
GLenum glType = 0;
|
||||
GLint glLoc = -1;
|
||||
ccstd::vector<uint8_t> buff;
|
||||
};
|
||||
using GLES2GPUUniformList = ccstd::vector<GLES2GPUUniform>;
|
||||
|
||||
struct GLES2GPUUniformBlock {
|
||||
uint32_t set = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t idx = 0;
|
||||
ccstd::string name;
|
||||
uint32_t size = 0;
|
||||
GLES2GPUUniformList glUniforms;
|
||||
GLES2GPUUniformList glActiveUniforms;
|
||||
ccstd::vector<uint32_t> activeUniformIndices;
|
||||
};
|
||||
using GLES2GPUUniformBlockList = ccstd::vector<GLES2GPUUniformBlock>;
|
||||
|
||||
struct GLES2GPUUniformSamplerTexture {
|
||||
uint32_t set = 0;
|
||||
uint32_t binding = 0;
|
||||
ccstd::string name;
|
||||
Type type = Type::UNKNOWN;
|
||||
uint32_t count = 0U;
|
||||
|
||||
ccstd::vector<GLint> units;
|
||||
GLenum glType = 0;
|
||||
GLint glLoc = -1;
|
||||
};
|
||||
using GLES2GPUUniformSamplerTextureList = ccstd::vector<GLES2GPUUniformSamplerTexture>;
|
||||
|
||||
struct GLES2GPUShaderStage {
|
||||
ShaderStageFlagBit type = ShaderStageFlagBit::NONE;
|
||||
ccstd::string source;
|
||||
GLuint glShader = 0;
|
||||
};
|
||||
using GLES2GPUShaderStageList = ccstd::vector<GLES2GPUShaderStage>;
|
||||
|
||||
struct GLES2GPUShader {
|
||||
ccstd::string name;
|
||||
UniformBlockList blocks;
|
||||
UniformSamplerTextureList samplerTextures;
|
||||
UniformInputAttachmentList subpassInputs;
|
||||
GLuint glProgram = 0;
|
||||
GLES2GPUShaderStageList gpuStages;
|
||||
GLES2GPUInputList glInputs;
|
||||
GLES2GPUUniformBlockList glBlocks;
|
||||
GLES2GPUUniformSamplerTextureList glSamplerTextures;
|
||||
};
|
||||
|
||||
struct GLES2GPUAttribute {
|
||||
ccstd::string name;
|
||||
GLuint glBuffer = 0;
|
||||
GLenum glType = 0;
|
||||
uint32_t size = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t stride = 1;
|
||||
uint32_t componentCount = 1;
|
||||
bool isNormalized = false;
|
||||
bool isInstanced = false;
|
||||
uint32_t offset = 0;
|
||||
};
|
||||
using GLES2GPUAttributeList = ccstd::vector<GLES2GPUAttribute>;
|
||||
|
||||
struct GLES2GPUInputAssembler {
|
||||
AttributeList attributes;
|
||||
GLES2GPUBufferList gpuVertexBuffers;
|
||||
GLES2GPUBuffer *gpuIndexBuffer = nullptr;
|
||||
GLES2GPUBuffer *gpuIndirectBuffer = nullptr;
|
||||
GLES2GPUAttributeList glAttribs;
|
||||
GLenum glIndexType = 0;
|
||||
ccstd::unordered_map<size_t, GLuint> glVAOs;
|
||||
};
|
||||
|
||||
struct GLES2GPURenderPass {
|
||||
struct AttachmentStatistics {
|
||||
uint32_t loadSubpass{SUBPASS_EXTERNAL};
|
||||
uint32_t storeSubpass{SUBPASS_EXTERNAL};
|
||||
};
|
||||
|
||||
ColorAttachmentList colorAttachments;
|
||||
DepthStencilAttachment depthStencilAttachment;
|
||||
SubpassInfoList subpasses;
|
||||
|
||||
ccstd::vector<AttachmentStatistics> statistics; // per attachment
|
||||
};
|
||||
|
||||
class GLES2GPUFramebufferCacheMap;
|
||||
class GLES2GPUFramebuffer final {
|
||||
public:
|
||||
GLES2GPURenderPass *gpuRenderPass{nullptr};
|
||||
GLES2GPUTextureList gpuColorTextures;
|
||||
GLES2GPUTexture *gpuDepthStencilTexture{nullptr};
|
||||
bool usesFBF{false};
|
||||
uint32_t lodLevel{0};
|
||||
|
||||
struct GLFramebufferInfo {
|
||||
GLuint glFramebuffer{0U};
|
||||
uint32_t width{UINT_MAX};
|
||||
uint32_t height{UINT_MAX};
|
||||
};
|
||||
|
||||
struct GLFramebuffer {
|
||||
inline void initialize(GLES2GPUSwapchain *sc) { swapchain = sc; }
|
||||
inline void initialize(const GLFramebufferInfo &info) {
|
||||
_glFramebuffer = info.glFramebuffer;
|
||||
_width = info.width;
|
||||
_height = info.height;
|
||||
}
|
||||
inline GLuint getFramebuffer() const { return swapchain ? swapchain->glFramebuffer : _glFramebuffer; }
|
||||
inline uint32_t getWidth() const { return swapchain ? swapchain->gpuColorTexture->width : _width; }
|
||||
inline uint32_t getHeight() const { return swapchain ? swapchain->gpuColorTexture->height : _height; }
|
||||
|
||||
void destroy(GLES2GPUStateCache *cache, GLES2GPUFramebufferCacheMap *framebufferCacheMap);
|
||||
|
||||
GLES2GPUSwapchain *swapchain{nullptr};
|
||||
|
||||
private:
|
||||
GLuint _glFramebuffer{0U};
|
||||
uint32_t _width{0U};
|
||||
uint32_t _height{0U};
|
||||
};
|
||||
|
||||
struct Framebuffer {
|
||||
GLFramebuffer framebuffer;
|
||||
|
||||
// for blit-based manual resolving
|
||||
GLbitfield resolveMask{0U};
|
||||
GLFramebuffer resolveFramebuffer;
|
||||
};
|
||||
|
||||
// one per subpass, if not using FBF
|
||||
ccstd::vector<Framebuffer> instances;
|
||||
|
||||
ccstd::vector<uint32_t> uberColorAttachmentIndices;
|
||||
uint32_t uberDepthStencil{INVALID_BINDING};
|
||||
Framebuffer uberInstance;
|
||||
|
||||
// the assumed shader output, may differ from actual subpass output
|
||||
// see Feature::INPUT_ATTACHMENT_BENEFIT for more
|
||||
uint32_t uberOnChipOutput{INVALID_BINDING};
|
||||
uint32_t uberFinalOutput{INVALID_BINDING};
|
||||
};
|
||||
|
||||
struct GLES2GPUDescriptorSetLayout {
|
||||
DescriptorSetLayoutBindingList bindings;
|
||||
ccstd::vector<uint32_t> dynamicBindings;
|
||||
|
||||
ccstd::vector<uint32_t> bindingIndices;
|
||||
ccstd::vector<uint32_t> descriptorIndices;
|
||||
uint32_t descriptorCount = 0U;
|
||||
};
|
||||
using GLES2GPUDescriptorSetLayoutList = ccstd::vector<GLES2GPUDescriptorSetLayout *>;
|
||||
|
||||
struct GLES2GPUPipelineLayout {
|
||||
GLES2GPUDescriptorSetLayoutList setLayouts;
|
||||
|
||||
// helper storages
|
||||
ccstd::vector<ccstd::vector<int>> dynamicOffsetIndices;
|
||||
ccstd::vector<uint32_t> dynamicOffsetOffsets;
|
||||
ccstd::vector<uint32_t> dynamicOffsets;
|
||||
uint32_t dynamicOffsetCount = 0U;
|
||||
};
|
||||
|
||||
struct GLES2GPUPipelineState {
|
||||
GLenum glPrimitive = GL_TRIANGLES;
|
||||
GLES2GPUShader *gpuShader = nullptr;
|
||||
RasterizerState rs;
|
||||
DepthStencilState dss;
|
||||
BlendState bs;
|
||||
DynamicStateList dynamicStates;
|
||||
GLES2GPUPipelineLayout *gpuLayout = nullptr;
|
||||
GLES2GPURenderPass *gpuRenderPass = nullptr;
|
||||
GLES2GPUPipelineLayout *gpuPipelineLayout = nullptr;
|
||||
};
|
||||
|
||||
struct GLES2GPUDescriptor {
|
||||
DescriptorType type = DescriptorType::UNKNOWN;
|
||||
GLES2GPUBuffer *gpuBuffer = nullptr;
|
||||
GLES2GPUBufferView *gpuBufferView = nullptr;
|
||||
GLES2GPUTexture *gpuTexture = nullptr;
|
||||
GLES2GPUSampler *gpuSampler = nullptr;
|
||||
};
|
||||
using GLES2GPUDescriptorList = ccstd::vector<GLES2GPUDescriptor>;
|
||||
|
||||
struct GLES2GPUDescriptorSet {
|
||||
GLES2GPUDescriptorList gpuDescriptors;
|
||||
const ccstd::vector<uint32_t> *descriptorIndices = nullptr;
|
||||
};
|
||||
|
||||
class GLES2GPUFence final {
|
||||
public:
|
||||
};
|
||||
|
||||
struct GLES2ObjectCache {
|
||||
uint32_t subpassIdx = 0U;
|
||||
GLES2GPURenderPass *gpuRenderPass = nullptr;
|
||||
GLES2GPUFramebuffer *gpuFramebuffer = nullptr;
|
||||
GLES2GPUPipelineState *gpuPipelineState = nullptr;
|
||||
GLES2GPUInputAssembler *gpuInputAssembler = nullptr;
|
||||
GLenum glPrimitive = 0;
|
||||
Rect renderArea;
|
||||
ColorList clearColors;
|
||||
float clearDepth = 1.F;
|
||||
uint32_t clearStencil = 0U;
|
||||
};
|
||||
|
||||
class GLES2GPUStateCache {
|
||||
public:
|
||||
GLuint glArrayBuffer = 0;
|
||||
GLuint glElementArrayBuffer = 0;
|
||||
GLuint glUniformBuffer = 0;
|
||||
GLuint glVAO = 0;
|
||||
uint32_t texUint = 0;
|
||||
ccstd::vector<GLuint> glTextures;
|
||||
GLuint glProgram = 0;
|
||||
ccstd::vector<bool> glEnabledAttribLocs;
|
||||
ccstd::vector<bool> glCurrentAttribLocs;
|
||||
GLuint glFramebuffer = 0;
|
||||
GLuint glRenderbuffer = 0;
|
||||
GLuint glReadFBO = 0;
|
||||
Viewport viewport;
|
||||
Rect scissor;
|
||||
RasterizerState rs;
|
||||
DepthStencilState dss;
|
||||
BlendState bs;
|
||||
bool isCullFaceEnabled = true;
|
||||
bool isStencilTestEnabled = false;
|
||||
ccstd::unordered_map<ccstd::string, uint32_t> texUnitCacheMap;
|
||||
GLES2ObjectCache gfxStateCache;
|
||||
|
||||
void initialize(size_t texUnits, size_t vertexAttributes) {
|
||||
glTextures.resize(texUnits, 0U);
|
||||
glEnabledAttribLocs.resize(vertexAttributes, false);
|
||||
glCurrentAttribLocs.resize(vertexAttributes, false);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
glArrayBuffer = 0;
|
||||
glElementArrayBuffer = 0;
|
||||
glUniformBuffer = 0;
|
||||
glVAO = 0;
|
||||
texUint = 0;
|
||||
glTextures.assign(glTextures.size(), 0U);
|
||||
glProgram = 0;
|
||||
glEnabledAttribLocs.assign(glEnabledAttribLocs.size(), false);
|
||||
glCurrentAttribLocs.assign(glCurrentAttribLocs.size(), false);
|
||||
glFramebuffer = 0;
|
||||
glReadFBO = 0;
|
||||
isCullFaceEnabled = true;
|
||||
isStencilTestEnabled = false;
|
||||
|
||||
viewport = Viewport();
|
||||
scissor = Rect();
|
||||
rs = RasterizerState();
|
||||
dss = DepthStencilState();
|
||||
bs = BlendState();
|
||||
|
||||
gfxStateCache.gpuRenderPass = nullptr;
|
||||
gfxStateCache.gpuFramebuffer = nullptr;
|
||||
gfxStateCache.gpuPipelineState = nullptr;
|
||||
gfxStateCache.gpuInputAssembler = nullptr;
|
||||
gfxStateCache.glPrimitive = 0U;
|
||||
gfxStateCache.subpassIdx = 0U;
|
||||
}
|
||||
};
|
||||
|
||||
class GLES2GPUBlitManager final {
|
||||
public:
|
||||
void initialize();
|
||||
void destroy();
|
||||
void draw(GLES2GPUTexture *gpuTextureSrc, GLES2GPUTexture *gpuTextureDst, const TextureBlit *regions, uint32_t count, Filter filter);
|
||||
|
||||
private:
|
||||
GLES2GPUShader _gpuShader;
|
||||
GLES2GPUDescriptorSetLayout _gpuDescriptorSetLayout;
|
||||
GLES2GPUPipelineLayout _gpuPipelineLayout;
|
||||
GLES2GPUPipelineState _gpuPipelineState;
|
||||
|
||||
GLES2GPUBuffer _gpuVertexBuffer;
|
||||
GLES2GPUInputAssembler _gpuInputAssembler;
|
||||
GLES2GPUSampler _gpuPointSampler;
|
||||
GLES2GPUSampler _gpuLinearSampler;
|
||||
GLES2GPUBuffer _gpuUniformBuffer;
|
||||
GLES2GPUDescriptorSet _gpuDescriptorSet;
|
||||
DrawInfo _drawInfo;
|
||||
float _uniformBuffer[8];
|
||||
};
|
||||
|
||||
class GLES2GPUFramebufferCacheMap final {
|
||||
public:
|
||||
explicit GLES2GPUFramebufferCacheMap(GLES2GPUStateCache *cache) : _cache(cache) {}
|
||||
|
||||
void registerExternal(GLuint glFramebuffer, const GLES2GPUTexture *gpuTexture) {
|
||||
bool isTexture = gpuTexture->glTexture;
|
||||
GLuint glResource = isTexture ? gpuTexture->glTexture : gpuTexture->glRenderbuffer;
|
||||
auto &cacheMap = isTexture ? _textureMap : _renderbufferMap;
|
||||
|
||||
if (!cacheMap[glResource].glFramebuffer) {
|
||||
cacheMap[glResource] = {glFramebuffer, true};
|
||||
}
|
||||
}
|
||||
|
||||
void unregisterExternal(GLuint glFramebuffer) {
|
||||
for (auto &fbos : _textureMap) {
|
||||
if (fbos.second.glFramebuffer == glFramebuffer) {
|
||||
fbos.second.glFramebuffer = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (auto &fbos : _renderbufferMap) {
|
||||
if (fbos.second.glFramebuffer == glFramebuffer) {
|
||||
fbos.second.glFramebuffer = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLuint getFramebufferFromTexture(const GLES2GPUTexture *gpuTexture) {
|
||||
bool isTexture = gpuTexture->glTexture;
|
||||
GLuint glResource = isTexture ? gpuTexture->glTexture : gpuTexture->glRenderbuffer;
|
||||
auto &cacheMap = isTexture ? _textureMap : _renderbufferMap;
|
||||
|
||||
if (!cacheMap.count(glResource)) {
|
||||
GLuint glFramebuffer = 0U;
|
||||
GL_CHECK(glGenFramebuffers(1, &glFramebuffer));
|
||||
if (_cache->glFramebuffer != glFramebuffer) {
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, glFramebuffer));
|
||||
_cache->glFramebuffer = glFramebuffer;
|
||||
}
|
||||
|
||||
const FormatInfo &info = GFX_FORMAT_INFOS[static_cast<uint32_t>(gpuTexture->format)];
|
||||
if (isTexture) {
|
||||
if (info.hasDepth) {
|
||||
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, gpuTexture->glTarget, glResource, 0));
|
||||
if (info.hasStencil) GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, gpuTexture->glTarget, glResource, 0));
|
||||
} else {
|
||||
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gpuTexture->glTarget, glResource, 0));
|
||||
}
|
||||
} else {
|
||||
if (info.hasDepth) {
|
||||
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, gpuTexture->glTarget, glResource));
|
||||
if (info.hasStencil) GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, gpuTexture->glTarget, glResource));
|
||||
} else {
|
||||
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gpuTexture->glTarget, glResource));
|
||||
}
|
||||
}
|
||||
|
||||
GLenum status;
|
||||
GL_CHECK(status = glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
CC_ASSERT_EQ(status, GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
cacheMap[glResource].glFramebuffer = glFramebuffer;
|
||||
}
|
||||
|
||||
return cacheMap[glResource].glFramebuffer;
|
||||
}
|
||||
|
||||
void onTextureDestroy(const GLES2GPUTexture *gpuTexture) {
|
||||
bool isTexture = gpuTexture->glTexture;
|
||||
GLuint glResource = isTexture ? gpuTexture->glTexture : gpuTexture->glRenderbuffer;
|
||||
auto &cacheMap = isTexture ? _textureMap : _renderbufferMap;
|
||||
|
||||
if (cacheMap.count(glResource)) {
|
||||
GLuint glFramebuffer = cacheMap[glResource].glFramebuffer;
|
||||
if (!glFramebuffer) return;
|
||||
|
||||
if (_cache->glFramebuffer == glFramebuffer) {
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
_cache->glFramebuffer = 0;
|
||||
}
|
||||
GL_CHECK(glDeleteFramebuffers(1, &glFramebuffer));
|
||||
cacheMap.erase(glResource);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GLES2GPUStateCache *_cache = nullptr;
|
||||
|
||||
struct FramebufferRecord {
|
||||
GLuint glFramebuffer{0};
|
||||
bool isExternal{false};
|
||||
};
|
||||
using CacheMap = ccstd::unordered_map<GLuint, FramebufferRecord>;
|
||||
CacheMap _renderbufferMap; // renderbuffer -> framebuffer
|
||||
CacheMap _textureMap; // texture -> framebuffer
|
||||
};
|
||||
|
||||
class GLES2GPUFramebufferHub final {
|
||||
public:
|
||||
void connect(GLES2GPUTexture *texture, GLES2GPUFramebuffer *framebuffer) {
|
||||
_framebuffers[texture].push_back(framebuffer);
|
||||
}
|
||||
|
||||
void disengage(GLES2GPUTexture *texture) {
|
||||
_framebuffers.erase(texture);
|
||||
}
|
||||
|
||||
void disengage(GLES2GPUTexture *texture, GLES2GPUFramebuffer *framebuffer) {
|
||||
auto &pool = _framebuffers[texture];
|
||||
pool.erase(std::remove(pool.begin(), pool.end(), framebuffer), pool.end());
|
||||
}
|
||||
|
||||
void update(GLES2GPUTexture *texture);
|
||||
|
||||
private:
|
||||
ccstd::unordered_map<GLES2GPUTexture *, ccstd::vector<GLES2GPUFramebuffer *>> _framebuffers;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
71
cocos/renderer/gfx-gles2/GLES2InputAssembler.cpp
Normal file
71
cocos/renderer/gfx-gles2/GLES2InputAssembler.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Buffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2InputAssembler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2InputAssembler::GLES2InputAssembler() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2InputAssembler::~GLES2InputAssembler() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2InputAssembler::doInit(const InputAssemblerInfo &info) {
|
||||
_gpuInputAssembler = ccnew GLES2GPUInputAssembler;
|
||||
_gpuInputAssembler->attributes = _attributes;
|
||||
_gpuInputAssembler->gpuVertexBuffers.resize(_vertexBuffers.size());
|
||||
for (size_t i = 0; i < _gpuInputAssembler->gpuVertexBuffers.size(); ++i) {
|
||||
auto *vb = static_cast<GLES2Buffer *>(_vertexBuffers[i]);
|
||||
_gpuInputAssembler->gpuVertexBuffers[i] = vb->gpuBuffer();
|
||||
}
|
||||
if (info.indexBuffer) {
|
||||
_gpuInputAssembler->gpuIndexBuffer = static_cast<GLES2Buffer *>(info.indexBuffer)->gpuBuffer();
|
||||
}
|
||||
|
||||
if (info.indirectBuffer) {
|
||||
_gpuInputAssembler->gpuIndirectBuffer = static_cast<GLES2Buffer *>(info.indirectBuffer)->gpuBuffer();
|
||||
}
|
||||
|
||||
cmdFuncGLES2CreateInputAssembler(GLES2Device::getInstance(), _gpuInputAssembler);
|
||||
}
|
||||
|
||||
void GLES2InputAssembler::doDestroy() {
|
||||
if (_gpuInputAssembler) {
|
||||
cmdFuncGLES2DestroyInputAssembler(GLES2Device::getInstance(), _gpuInputAssembler);
|
||||
delete _gpuInputAssembler;
|
||||
_gpuInputAssembler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
51
cocos/renderer/gfx-gles2/GLES2InputAssembler.h
Normal file
51
cocos/renderer/gfx-gles2/GLES2InputAssembler.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXInputAssembler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUInputAssembler;
|
||||
class GLES2CmdDraw;
|
||||
|
||||
class CC_GLES2_API GLES2InputAssembler final : public InputAssembler {
|
||||
public:
|
||||
GLES2InputAssembler();
|
||||
~GLES2InputAssembler() override;
|
||||
|
||||
inline GLES2GPUInputAssembler *gpuInputAssembler() const { return _gpuInputAssembler; }
|
||||
|
||||
protected:
|
||||
void doInit(const InputAssemblerInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPUInputAssembler *_gpuInputAssembler = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
74
cocos/renderer/gfx-gles2/GLES2PipelineLayout.cpp
Normal file
74
cocos/renderer/gfx-gles2/GLES2PipelineLayout.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "base/Utils.h"
|
||||
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2DescriptorSetLayout.h"
|
||||
#include "GLES2PipelineLayout.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2PipelineLayout::GLES2PipelineLayout() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2PipelineLayout::~GLES2PipelineLayout() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2PipelineLayout::doInit(const PipelineLayoutInfo & /*info*/) {
|
||||
_gpuPipelineLayout = ccnew GLES2GPUPipelineLayout;
|
||||
|
||||
uint32_t offset = 0U;
|
||||
_gpuPipelineLayout->dynamicOffsetIndices.resize(_setLayouts.size());
|
||||
for (uint32_t i = 0U; i < _setLayouts.size(); i++) {
|
||||
DescriptorSetLayout *setLayout = _setLayouts[i];
|
||||
GLES2GPUDescriptorSetLayout *gpuSetLayout = static_cast<GLES2DescriptorSetLayout *>(setLayout)->gpuDescriptorSetLayout();
|
||||
uint32_t dynamicCount = utils::toUint(gpuSetLayout->dynamicBindings.size());
|
||||
ccstd::vector<int> &indices = _gpuPipelineLayout->dynamicOffsetIndices[i];
|
||||
indices.assign(setLayout->getBindingIndices().size(), -1);
|
||||
|
||||
for (uint32_t j = 0U; j < dynamicCount; j++) {
|
||||
uint32_t binding = gpuSetLayout->dynamicBindings[j];
|
||||
if (indices[binding] < 0) indices[binding] = offset + j;
|
||||
}
|
||||
_gpuPipelineLayout->dynamicOffsetOffsets.push_back(offset);
|
||||
_gpuPipelineLayout->setLayouts.push_back(gpuSetLayout);
|
||||
offset += dynamicCount;
|
||||
}
|
||||
_gpuPipelineLayout->dynamicOffsetOffsets.push_back(offset);
|
||||
_gpuPipelineLayout->dynamicOffsetCount = offset;
|
||||
_gpuPipelineLayout->dynamicOffsets.resize(offset);
|
||||
}
|
||||
|
||||
void GLES2PipelineLayout::doDestroy() {
|
||||
CC_SAFE_DELETE(_gpuPipelineLayout);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
50
cocos/renderer/gfx-gles2/GLES2PipelineLayout.h
Normal file
50
cocos/renderer/gfx-gles2/GLES2PipelineLayout.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXPipelineLayout.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUPipelineLayout;
|
||||
|
||||
class CC_GLES2_API GLES2PipelineLayout final : public PipelineLayout {
|
||||
public:
|
||||
GLES2PipelineLayout();
|
||||
~GLES2PipelineLayout() override;
|
||||
|
||||
inline GLES2GPUPipelineLayout *gpuPipelineLayout() const { return _gpuPipelineLayout; }
|
||||
|
||||
protected:
|
||||
void doInit(const PipelineLayoutInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPUPipelineLayout *_gpuPipelineLayout = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
83
cocos/renderer/gfx-gles2/GLES2PipelineState.cpp
Normal file
83
cocos/renderer/gfx-gles2/GLES2PipelineState.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2PipelineLayout.h"
|
||||
#include "GLES2PipelineState.h"
|
||||
#include "GLES2RenderPass.h"
|
||||
#include "GLES2Shader.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
const GLenum GLE_S2_PRIMITIVES[] = {
|
||||
GL_POINTS,
|
||||
GL_LINES,
|
||||
GL_LINE_STRIP,
|
||||
GL_LINE_LOOP,
|
||||
GL_NONE,
|
||||
GL_NONE,
|
||||
GL_NONE,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_TRIANGLE_FAN,
|
||||
GL_NONE,
|
||||
GL_NONE,
|
||||
GL_NONE,
|
||||
GL_NONE,
|
||||
};
|
||||
|
||||
GLES2PipelineState::GLES2PipelineState() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2PipelineState::~GLES2PipelineState() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2PipelineState::doInit(const PipelineStateInfo & /*info*/) {
|
||||
_gpuPipelineState = ccnew GLES2GPUPipelineState;
|
||||
_gpuPipelineState->glPrimitive = GLE_S2_PRIMITIVES[static_cast<int>(_primitive)];
|
||||
_gpuPipelineState->gpuShader = static_cast<GLES2Shader *>(_shader)->gpuShader();
|
||||
_gpuPipelineState->rs = _rasterizerState;
|
||||
_gpuPipelineState->dss = _depthStencilState;
|
||||
_gpuPipelineState->bs = _blendState;
|
||||
_gpuPipelineState->gpuPipelineLayout = static_cast<GLES2PipelineLayout *>(_pipelineLayout)->gpuPipelineLayout();
|
||||
if (_renderPass) _gpuPipelineState->gpuRenderPass = static_cast<GLES2RenderPass *>(_renderPass)->gpuRenderPass();
|
||||
|
||||
for (uint32_t i = 0; i < 31; i++) {
|
||||
if (static_cast<uint32_t>(_dynamicStates) & (1 << i)) {
|
||||
_gpuPipelineState->dynamicStates.push_back(static_cast<DynamicStateFlagBit>(1 << i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PipelineState::doDestroy() {
|
||||
CC_SAFE_DELETE(_gpuPipelineState);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
50
cocos/renderer/gfx-gles2/GLES2PipelineState.h
Normal file
50
cocos/renderer/gfx-gles2/GLES2PipelineState.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXPipelineState.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUPipelineState;
|
||||
|
||||
class CC_GLES2_API GLES2PipelineState final : public PipelineState {
|
||||
public:
|
||||
GLES2PipelineState();
|
||||
~GLES2PipelineState() override;
|
||||
|
||||
inline GLES2GPUPipelineState *gpuPipelineState() const { return _gpuPipelineState; }
|
||||
|
||||
protected:
|
||||
void doInit(const PipelineStateInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPUPipelineState *_gpuPipelineState = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
236
cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp
Normal file
236
cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Buffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2DescriptorSet.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2Framebuffer.h"
|
||||
#include "GLES2InputAssembler.h"
|
||||
#include "GLES2PipelineState.h"
|
||||
#include "GLES2PrimaryCommandBuffer.h"
|
||||
#include "GLES2RenderPass.h"
|
||||
#include "GLES2Texture.h"
|
||||
#include "profiler/Profiler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2PrimaryCommandBuffer::~GLES2PrimaryCommandBuffer() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::begin(RenderPass * /*renderPass*/, uint32_t /*subpass*/, Framebuffer * /*frameBuffer*/) {
|
||||
_curGPUPipelineState = nullptr;
|
||||
_curGPUInputAssember = nullptr;
|
||||
_curGPUDescriptorSets.assign(_curGPUDescriptorSets.size(), nullptr);
|
||||
|
||||
_numDrawCalls = 0;
|
||||
_numInstances = 0;
|
||||
_numTriangles = 0;
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::end() {
|
||||
if (_isStateInvalid) {
|
||||
bindStates();
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil, CommandBuffer *const * /*secondaryCBs*/, uint32_t /*secondaryCBCount*/) {
|
||||
_curSubpassIdx = 0U;
|
||||
|
||||
GLES2GPURenderPass *gpuRenderPass = static_cast<GLES2RenderPass *>(renderPass)->gpuRenderPass();
|
||||
GLES2GPUFramebuffer *gpuFramebuffer = static_cast<GLES2Framebuffer *>(fbo)->gpuFBO();
|
||||
|
||||
cmdFuncGLES2BeginRenderPass(GLES2Device::getInstance(), _curSubpassIdx, gpuRenderPass, gpuFramebuffer,
|
||||
&renderArea, colors, depth, stencil);
|
||||
_curDynamicStates.viewport = {renderArea.x, renderArea.y, renderArea.width, renderArea.height};
|
||||
_curDynamicStates.scissor = renderArea;
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::endRenderPass() {
|
||||
cmdFuncGLES2EndRenderPass(GLES2Device::getInstance());
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::nextSubpass() {
|
||||
cmdFuncGLES2EndRenderPass(GLES2Device::getInstance());
|
||||
cmdFuncGLES2BeginRenderPass(GLES2Device::getInstance(), ++_curSubpassIdx);
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::insertMarker(const MarkerInfo &marker) {
|
||||
cmdFuncGLES2InsertMarker(GLES2Device::getInstance(), marker.name.size(), marker.name.data());
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::beginMarker(const MarkerInfo &marker) {
|
||||
cmdFuncGLES2PushGroupMarker(GLES2Device::getInstance(), marker.name.size(), marker.name.data());
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::endMarker() {
|
||||
cmdFuncGLES2PopGroupMarker(GLES2Device::getInstance());
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::draw(const DrawInfo &info) {
|
||||
CC_PROFILE(GLES2PrimaryCommandBufferDraw);
|
||||
if (_isStateInvalid) {
|
||||
ccstd::vector<uint32_t> &dynamicOffsetOffsets = _curGPUPipelineState->gpuPipelineLayout->dynamicOffsetOffsets;
|
||||
ccstd::vector<uint32_t> &dynamicOffsets = _curGPUPipelineState->gpuPipelineLayout->dynamicOffsets;
|
||||
for (size_t i = 0U; i < _curDynamicOffsets.size(); i++) {
|
||||
size_t count = dynamicOffsetOffsets[i + 1] - dynamicOffsetOffsets[i];
|
||||
// CC_ASSERT(_curDynamicOffsets[i].size() >= count);
|
||||
count = std::min(count, _curDynamicOffsets[i].size());
|
||||
if (count) memcpy(&dynamicOffsets[dynamicOffsetOffsets[i]], _curDynamicOffsets[i].data(), count * sizeof(uint32_t));
|
||||
}
|
||||
cmdFuncGLES2BindState(GLES2Device::getInstance(), _curGPUPipelineState, _curGPUInputAssember,
|
||||
_curGPUDescriptorSets.data(), dynamicOffsets.data(), &_curDynamicStates);
|
||||
|
||||
_isStateInvalid = false;
|
||||
}
|
||||
|
||||
cmdFuncGLES2Draw(GLES2Device::getInstance(), info);
|
||||
|
||||
++_numDrawCalls;
|
||||
_numInstances += info.instanceCount;
|
||||
uint32_t indexCount = info.indexCount ? info.indexCount : info.vertexCount;
|
||||
if (_curGPUPipelineState) {
|
||||
switch (_curGPUPipelineState->glPrimitive) {
|
||||
case GL_TRIANGLES: {
|
||||
_numTriangles += indexCount / 3 * std::max(info.instanceCount, 1U);
|
||||
break;
|
||||
}
|
||||
case GL_TRIANGLE_STRIP:
|
||||
case GL_TRIANGLE_FAN: {
|
||||
_numTriangles += (indexCount - 2) * std::max(info.instanceCount, 1U);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::setViewport(const Viewport &vp) {
|
||||
auto *cache = GLES2Device::getInstance()->stateCache();
|
||||
if (cache->viewport != vp) {
|
||||
cache->viewport = vp;
|
||||
GL_CHECK(glViewport(vp.left, vp.top, vp.width, vp.height));
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::setScissor(const Rect &rect) {
|
||||
auto *cache = GLES2Device::getInstance()->stateCache();
|
||||
if (cache->scissor != rect) {
|
||||
cache->scissor = rect;
|
||||
GL_CHECK(glScissor(rect.x, rect.y, rect.width, rect.height));
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::updateBuffer(Buffer *buff, const void *data, uint32_t size) {
|
||||
GLES2GPUBuffer *gpuBuffer = static_cast<GLES2Buffer *>(buff)->gpuBuffer();
|
||||
if (gpuBuffer) {
|
||||
cmdFuncGLES2UpdateBuffer(GLES2Device::getInstance(), gpuBuffer, data, 0U, size);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) {
|
||||
GLES2GPUTexture *gpuTexture = static_cast<GLES2Texture *>(texture)->gpuTexture();
|
||||
if (gpuTexture) {
|
||||
cmdFuncGLES2CopyBuffersToTexture(GLES2Device::getInstance(), buffers, gpuTexture, regions, count);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) {
|
||||
copyTexture(srcTexture, dstTexture, regions, count);
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) {
|
||||
GLES2GPUTexture *gpuTextureSrc = nullptr;
|
||||
GLES2GPUTexture *gpuTextureDst = nullptr;
|
||||
if (srcTexture) gpuTextureSrc = static_cast<GLES2Texture *>(srcTexture)->gpuTexture();
|
||||
if (dstTexture) gpuTextureDst = static_cast<GLES2Texture *>(dstTexture)->gpuTexture();
|
||||
ccstd::vector<TextureBlit> blitRegions(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
auto &blit = blitRegions[i];
|
||||
const auto © = regions[i];
|
||||
|
||||
blit.srcSubres = copy.srcSubres;
|
||||
blit.dstSubres = copy.dstSubres;
|
||||
|
||||
blit.srcOffset = copy.srcOffset;
|
||||
blit.dstOffset = copy.dstOffset;
|
||||
|
||||
blit.srcExtent = copy.extent;
|
||||
blit.dstExtent = copy.extent;
|
||||
}
|
||||
cmdFuncGLES2BlitTexture(GLES2Device::getInstance(), gpuTextureSrc, gpuTextureDst, blitRegions.data(), count, Filter::POINT);
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) {
|
||||
GLES2GPUTexture *gpuTextureSrc = nullptr;
|
||||
GLES2GPUTexture *gpuTextureDst = nullptr;
|
||||
if (srcTexture) gpuTextureSrc = static_cast<GLES2Texture *>(srcTexture)->gpuTexture();
|
||||
if (dstTexture) gpuTextureDst = static_cast<GLES2Texture *>(dstTexture)->gpuTexture();
|
||||
|
||||
cmdFuncGLES2BlitTexture(GLES2Device::getInstance(), gpuTextureSrc, gpuTextureDst, regions, count, filter);
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::execute(CommandBuffer *const *cmdBuffs, uint32_t count) {
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
auto *cmdBuff = static_cast<GLES2PrimaryCommandBuffer *>(cmdBuffs[i]);
|
||||
|
||||
if (!cmdBuff->_pendingPackages.empty()) {
|
||||
GLES2CmdPackage *cmdPackage = cmdBuff->_pendingPackages.front();
|
||||
|
||||
cmdFuncGLES2ExecuteCmds(GLES2Device::getInstance(), cmdPackage);
|
||||
|
||||
cmdBuff->_pendingPackages.pop();
|
||||
cmdBuff->_freePackages.push(cmdPackage);
|
||||
cmdBuff->_cmdAllocator->clearCmds(cmdPackage);
|
||||
cmdBuff->_cmdAllocator->reset();
|
||||
}
|
||||
|
||||
_numDrawCalls += cmdBuff->_numDrawCalls;
|
||||
_numInstances += cmdBuff->_numInstances;
|
||||
_numTriangles += cmdBuff->_numTriangles;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2PrimaryCommandBuffer::bindStates() {
|
||||
if (_curGPUPipelineState) {
|
||||
ccstd::vector<uint32_t> &dynamicOffsetOffsets = _curGPUPipelineState->gpuPipelineLayout->dynamicOffsetOffsets;
|
||||
ccstd::vector<uint32_t> &dynamicOffsets = _curGPUPipelineState->gpuPipelineLayout->dynamicOffsets;
|
||||
for (size_t i = 0U; i < _curDynamicOffsets.size(); i++) {
|
||||
size_t count = dynamicOffsetOffsets[i + 1] - dynamicOffsetOffsets[i];
|
||||
// CC_ASSERT(_curDynamicOffsets[i].size() >= count);
|
||||
count = std::min(count, _curDynamicOffsets[i].size());
|
||||
if (count) memcpy(&dynamicOffsets[dynamicOffsetOffsets[i]], _curDynamicOffsets[i].data(), count * sizeof(uint32_t));
|
||||
}
|
||||
cmdFuncGLES2BindState(GLES2Device::getInstance(), _curGPUPipelineState, _curGPUInputAssember, _curGPUDescriptorSets.data(), dynamicOffsets.data(), &_curDynamicStates);
|
||||
}
|
||||
_isStateInvalid = false;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
62
cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h
Normal file
62
cocos/renderer/gfx-gles2/GLES2PrimaryCommandBuffer.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2CommandBuffer.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
class CC_GLES2_API GLES2PrimaryCommandBuffer final : public GLES2CommandBuffer {
|
||||
public:
|
||||
GLES2PrimaryCommandBuffer() = default;
|
||||
~GLES2PrimaryCommandBuffer() override;
|
||||
|
||||
void begin(RenderPass *renderPass, uint32_t subpass, Framebuffer *frameBuffer) override;
|
||||
void end() override;
|
||||
void beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil, CommandBuffer *const *secondaryCBs, uint32_t secondaryCBCount) override;
|
||||
void endRenderPass() override;
|
||||
void nextSubpass() override;
|
||||
void insertMarker(const MarkerInfo &marker) override;
|
||||
void beginMarker(const MarkerInfo &marker) override;
|
||||
void endMarker() override;
|
||||
void draw(const DrawInfo &info) override;
|
||||
void setViewport(const Viewport &vp) override;
|
||||
void setScissor(const Rect &rect) override;
|
||||
void updateBuffer(Buffer *buff, const void *data, uint32_t size) override;
|
||||
void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) override;
|
||||
void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) override;
|
||||
void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override;
|
||||
void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) override;
|
||||
void execute(CommandBuffer *const *cmdBuffs, uint32_t count) override;
|
||||
|
||||
protected:
|
||||
friend class GLES2Queue;
|
||||
|
||||
void bindStates() override;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
50
cocos/renderer/gfx-gles2/GLES2QueryPool.cpp
Normal file
50
cocos/renderer/gfx-gles2/GLES2QueryPool.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2CommandBuffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2QueryPool.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2QueryPool::GLES2QueryPool() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2QueryPool::~GLES2QueryPool() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2QueryPool::doInit(const QueryPoolInfo &info) {
|
||||
}
|
||||
|
||||
void GLES2QueryPool::doDestroy() {
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
46
cocos/renderer/gfx-gles2/GLES2QueryPool.h
Normal file
46
cocos/renderer/gfx-gles2/GLES2QueryPool.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXQueryPool.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
class CC_GLES2_API GLES2QueryPool final : public QueryPool {
|
||||
public:
|
||||
GLES2QueryPool();
|
||||
~GLES2QueryPool() override;
|
||||
|
||||
protected:
|
||||
friend class GLES2Device;
|
||||
|
||||
void doInit(const QueryPoolInfo &info) override;
|
||||
void doDestroy() override;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
71
cocos/renderer/gfx-gles2/GLES2Queue.cpp
Normal file
71
cocos/renderer/gfx-gles2/GLES2Queue.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2CommandBuffer.h"
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2Queue.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Queue::GLES2Queue() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2Queue::~GLES2Queue() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2Queue::doInit(const QueueInfo &info) {
|
||||
}
|
||||
|
||||
void GLES2Queue::doDestroy() {
|
||||
}
|
||||
|
||||
void GLES2Queue::submit(CommandBuffer *const *cmdBuffs, uint32_t count) {
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
auto *cmdBuff = static_cast<GLES2CommandBuffer *>(cmdBuffs[i]);
|
||||
|
||||
if (!cmdBuff->_pendingPackages.empty()) {
|
||||
GLES2CmdPackage *cmdPackage = cmdBuff->_pendingPackages.front();
|
||||
|
||||
cmdFuncGLES2ExecuteCmds(GLES2Device::getInstance(), cmdPackage);
|
||||
|
||||
cmdBuff->_pendingPackages.pop();
|
||||
cmdBuff->_freePackages.push(cmdPackage);
|
||||
cmdBuff->_cmdAllocator->clearCmds(cmdPackage);
|
||||
cmdBuff->_cmdAllocator->reset();
|
||||
}
|
||||
|
||||
_numDrawCalls += cmdBuff->_numDrawCalls;
|
||||
_numInstances += cmdBuff->_numInstances;
|
||||
_numTriangles += cmdBuff->_numTriangles;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
52
cocos/renderer/gfx-gles2/GLES2Queue.h
Normal file
52
cocos/renderer/gfx-gles2/GLES2Queue.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXQueue.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
class CC_GLES2_API GLES2Queue final : public Queue {
|
||||
public:
|
||||
GLES2Queue();
|
||||
~GLES2Queue() override;
|
||||
|
||||
void submit(CommandBuffer *const *cmdBuffs, uint32_t count) override;
|
||||
|
||||
protected:
|
||||
friend class GLES2Device;
|
||||
|
||||
void doInit(const QueueInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
uint32_t _numDrawCalls = 0;
|
||||
uint32_t _numInstances = 0;
|
||||
uint32_t _numTriangles = 0;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
84
cocos/renderer/gfx-gles2/GLES2RenderPass.cpp
Normal file
84
cocos/renderer/gfx-gles2/GLES2RenderPass.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2RenderPass.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2RenderPass::GLES2RenderPass() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2RenderPass::~GLES2RenderPass() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2RenderPass::doInit(const RenderPassInfo & /*info*/) {
|
||||
_gpuRenderPass = ccnew GLES2GPURenderPass;
|
||||
_gpuRenderPass->colorAttachments = _colorAttachments;
|
||||
_gpuRenderPass->depthStencilAttachment = _depthStencilAttachment;
|
||||
_gpuRenderPass->subpasses = _subpasses;
|
||||
|
||||
// assign a dummy subpass if not specified
|
||||
uint32_t colorCount = utils::toUint(_gpuRenderPass->colorAttachments.size());
|
||||
if (_gpuRenderPass->subpasses.empty()) {
|
||||
_gpuRenderPass->subpasses.emplace_back();
|
||||
auto &subpass = _gpuRenderPass->subpasses.back();
|
||||
subpass.colors.resize(_colorAttachments.size());
|
||||
for (uint32_t i = 0U; i < _colorAttachments.size(); ++i) {
|
||||
subpass.colors[i] = i;
|
||||
}
|
||||
if (_depthStencilAttachment.format != Format::UNKNOWN) {
|
||||
subpass.depthStencil = colorCount;
|
||||
}
|
||||
} else {
|
||||
// unify depth stencil index
|
||||
for (auto &subpass : _gpuRenderPass->subpasses) {
|
||||
if (subpass.depthStencil != INVALID_BINDING && subpass.depthStencil > colorCount) {
|
||||
subpass.depthStencil = colorCount;
|
||||
}
|
||||
if (subpass.depthStencilResolve != INVALID_BINDING && subpass.depthStencilResolve > colorCount) {
|
||||
subpass.depthStencilResolve = colorCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmdFuncGLES2CreateRenderPass(GLES2Device::getInstance(), _gpuRenderPass);
|
||||
}
|
||||
|
||||
void GLES2RenderPass::doDestroy() {
|
||||
if (_gpuRenderPass) {
|
||||
cmdFuncGLES2CreateRenderPass(GLES2Device::getInstance(), _gpuRenderPass);
|
||||
delete _gpuRenderPass;
|
||||
_gpuRenderPass = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
50
cocos/renderer/gfx-gles2/GLES2RenderPass.h
Normal file
50
cocos/renderer/gfx-gles2/GLES2RenderPass.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXRenderPass.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPURenderPass;
|
||||
|
||||
class CC_GLES2_API GLES2RenderPass final : public RenderPass {
|
||||
public:
|
||||
GLES2RenderPass();
|
||||
~GLES2RenderPass() override;
|
||||
|
||||
inline GLES2GPURenderPass *gpuRenderPass() const { return _gpuRenderPass; }
|
||||
|
||||
protected:
|
||||
void doInit(const RenderPassInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPURenderPass *_gpuRenderPass = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
91
cocos/renderer/gfx-gles2/GLES2Shader.cpp
Normal file
91
cocos/renderer/gfx-gles2/GLES2Shader.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2Shader.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Shader::GLES2Shader() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2Shader::~GLES2Shader() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void initGpuShader(GLES2GPUShader *gpuShader) {
|
||||
cmdFuncGLES2CreateShader(GLES2Device::getInstance(), gpuShader);
|
||||
CC_ASSERT(gpuShader->glProgram);
|
||||
|
||||
// Clear shader source after they're uploaded to GPU
|
||||
for (auto &stage : gpuShader->gpuStages) {
|
||||
stage.source.clear();
|
||||
stage.source.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
GLES2GPUShader *GLES2Shader::gpuShader() const {
|
||||
if (!_gpuShader->glProgram) {
|
||||
initGpuShader(_gpuShader);
|
||||
}
|
||||
return _gpuShader;
|
||||
}
|
||||
|
||||
void GLES2Shader::doInit(const ShaderInfo & /*info*/) {
|
||||
_gpuShader = ccnew GLES2GPUShader;
|
||||
CC_ASSERT(!_gpuShader->glProgram);
|
||||
_gpuShader->name = _name;
|
||||
_gpuShader->blocks = _blocks;
|
||||
_gpuShader->samplerTextures = _samplerTextures;
|
||||
_gpuShader->subpassInputs = _subpassInputs;
|
||||
|
||||
for (const auto &stage : _stages) {
|
||||
_gpuShader->gpuStages.push_back({stage.stage, stage.source});
|
||||
}
|
||||
|
||||
for (auto &stage : _stages) {
|
||||
stage.source.clear();
|
||||
stage.source.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2Shader::doDestroy() {
|
||||
if (_gpuShader) {
|
||||
cmdFuncGLES2DestroyShader(GLES2Device::getInstance(), _gpuShader);
|
||||
delete _gpuShader;
|
||||
_gpuShader = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
50
cocos/renderer/gfx-gles2/GLES2Shader.h
Normal file
50
cocos/renderer/gfx-gles2/GLES2Shader.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXShader.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUShader;
|
||||
|
||||
class CC_GLES2_API GLES2Shader final : public Shader {
|
||||
public:
|
||||
GLES2Shader();
|
||||
~GLES2Shader() override;
|
||||
|
||||
GLES2GPUShader *gpuShader() const;
|
||||
|
||||
protected:
|
||||
void doInit(const ShaderInfo &info) override;
|
||||
void doDestroy() override;
|
||||
|
||||
GLES2GPUShader *_gpuShader = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
65
cocos/renderer/gfx-gles2/GLES2Std.h
Normal file
65
cocos/renderer/gfx-gles2/GLES2Std.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "base/Log.h"
|
||||
|
||||
#if (CC_PLATFORM == CC_PLATFORM_WINDOWS)
|
||||
#if defined(CC_STATIC)
|
||||
#define CC_GLES2_API
|
||||
#else
|
||||
#ifdef CC_GLES2_EXPORTS
|
||||
#define CC_GLES2_API __declspec(dllexport)
|
||||
#else
|
||||
#define CC_GLES2_API __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define CC_GLES2_API
|
||||
#endif
|
||||
|
||||
#if CC_DEBUG > 0
|
||||
#define GL_CHECK(x) \
|
||||
do { \
|
||||
x; \
|
||||
GLenum err = glGetError(); \
|
||||
if (err != GL_NO_ERROR) { \
|
||||
CC_LOG_ERROR("%s returned GL error: 0x%x", #x, err); \
|
||||
CC_ABORT(); \
|
||||
} \
|
||||
} while (0)
|
||||
#define EGL_CHECK(x) \
|
||||
do { \
|
||||
x; \
|
||||
EGLint err = eglGetError(); \
|
||||
if (err != EGL_SUCCESS) { \
|
||||
CC_LOG_ERROR("%s returned EGL error: 0x%x", #x, err); \
|
||||
CC_ABORT(); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define GL_CHECK(x) x
|
||||
#define EGL_CHECK(x) x
|
||||
#endif
|
||||
201
cocos/renderer/gfx-gles2/GLES2Swapchain.cpp
Normal file
201
cocos/renderer/gfx-gles2/GLES2Swapchain.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Swapchain.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2GPUObjects.h"
|
||||
#include "GLES2Texture.h"
|
||||
|
||||
#if CC_SWAPPY_ENABLED
|
||||
#include "platform/android/AndroidPlatform.h"
|
||||
#include "swappy/swappyGL.h"
|
||||
#endif
|
||||
|
||||
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||
#include "android/native_window.h"
|
||||
#elif CC_PLATFORM == CC_PLATFORM_OHOS
|
||||
#include <native_layer.h>
|
||||
#include <native_layer_jni.h>
|
||||
#endif
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Swapchain::GLES2Swapchain() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2Swapchain::~GLES2Swapchain() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2Swapchain::doInit(const SwapchainInfo &info) {
|
||||
const auto *context = GLES2Device::getInstance()->context();
|
||||
_gpuSwapchain = ccnew GLES2GPUSwapchain;
|
||||
auto window = reinterpret_cast<EGLNativeWindowType>(info.windowHandle); //NOLINT[readability-qualified-auto]
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID || CC_PLATFORM == CC_PLATFORM_OHOS
|
||||
EGLint nFmt;
|
||||
if (eglGetConfigAttrib(context->eglDisplay, context->eglConfig, EGL_NATIVE_VISUAL_ID, &nFmt) == EGL_FALSE) {
|
||||
CC_LOG_ERROR("Getting configuration attributes failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
#if CC_SWAPPY_ENABLED
|
||||
bool enableSwappy = true;
|
||||
auto *platform = static_cast<AndroidPlatform *>(cc::BasePlatform::getPlatform());
|
||||
enableSwappy &= SwappyGL_init(static_cast<JNIEnv *>(platform->getEnv()), static_cast<jobject>(platform->getActivity()));
|
||||
int32_t fps = cc::BasePlatform::getPlatform()->getFps();
|
||||
if (enableSwappy) {
|
||||
if (!fps)
|
||||
SwappyGL_setSwapIntervalNS(SWAPPY_SWAP_60FPS);
|
||||
else
|
||||
SwappyGL_setSwapIntervalNS(1000000000L / fps); //ns
|
||||
enableSwappy &= SwappyGL_setWindow(window);
|
||||
_gpuSwapchain->swappyEnabled = enableSwappy;
|
||||
} else {
|
||||
CC_LOG_ERROR("Failed to enable Swappy in current GL swapchain, fallback instead.");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
auto width = static_cast<int32_t>(info.width);
|
||||
auto height = static_cast<int32_t>(info.height);
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
ANativeWindow_setBuffersGeometry(window, width, height, nFmt);
|
||||
#elif CC_PLATFORM == CC_PLATFORM_OHOS
|
||||
NativeLayerHandle(window, NativeLayerOps::SET_WIDTH_AND_HEIGHT, width, height);
|
||||
NativeLayerHandle(window, NativeLayerOps::SET_FORMAT, nFmt);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
EGL_CHECK(_gpuSwapchain->eglSurface = eglCreateWindowSurface(context->eglDisplay, context->eglConfig, window, nullptr));
|
||||
if (_gpuSwapchain->eglSurface == EGL_NO_SURFACE) {
|
||||
CC_LOG_ERROR("Create window surface failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (_vsyncMode) {
|
||||
case VsyncMode::OFF: _gpuSwapchain->eglSwapInterval = 0; break;
|
||||
case VsyncMode::ON:
|
||||
case VsyncMode::RELAXED: _gpuSwapchain->eglSwapInterval = 1; break;
|
||||
case VsyncMode::MAILBOX: _gpuSwapchain->eglSwapInterval = 0; break;
|
||||
case VsyncMode::HALF: _gpuSwapchain->eglSwapInterval = 2; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
///////////////////// Texture Creation /////////////////////
|
||||
|
||||
_colorTexture = ccnew GLES2Texture;
|
||||
_depthStencilTexture = ccnew GLES2Texture;
|
||||
|
||||
SwapchainTextureInfo textureInfo;
|
||||
textureInfo.swapchain = this;
|
||||
textureInfo.format = Format::RGBA8;
|
||||
textureInfo.width = info.width;
|
||||
textureInfo.height = info.height;
|
||||
initTexture(textureInfo, _colorTexture);
|
||||
|
||||
textureInfo.format = Format::DEPTH_STENCIL;
|
||||
initTexture(textureInfo, _depthStencilTexture);
|
||||
|
||||
_gpuSwapchain->gpuColorTexture = static_cast<GLES2Texture *>(_colorTexture.get())->gpuTexture();
|
||||
}
|
||||
|
||||
void GLES2Swapchain::doDestroy() {
|
||||
if (!_gpuSwapchain) return;
|
||||
|
||||
#if CC_SWAPPY_ENABLED
|
||||
if (_gpuSwapchain->swappyEnabled) {
|
||||
SwappyGL_destroy();
|
||||
}
|
||||
#endif
|
||||
|
||||
CC_SAFE_DESTROY(_depthStencilTexture)
|
||||
CC_SAFE_DESTROY(_colorTexture)
|
||||
|
||||
doDestroySurface();
|
||||
CC_SAFE_DELETE(_gpuSwapchain);
|
||||
}
|
||||
|
||||
void GLES2Swapchain::doResize(uint32_t width, uint32_t height, SurfaceTransform /*transform*/) {
|
||||
_colorTexture->resize(width, height);
|
||||
_depthStencilTexture->resize(width, height);
|
||||
|
||||
if (_windowHandle) {
|
||||
doCreateSurface(_windowHandle);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2Swapchain::doDestroySurface() {
|
||||
if (_gpuSwapchain->eglSurface != EGL_NO_SURFACE) {
|
||||
auto *context = GLES2Device::getInstance()->context();
|
||||
eglDestroySurface(context->eglDisplay, _gpuSwapchain->eglSurface);
|
||||
_gpuSwapchain->eglSurface = EGL_NO_SURFACE;
|
||||
context->bindContext(true);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2Swapchain::doCreateSurface(void *windowHandle) {
|
||||
auto *context = GLES2Device::getInstance()->context();
|
||||
auto window = reinterpret_cast<EGLNativeWindowType>(windowHandle); //NOLINT [readability-qualified-auto]
|
||||
|
||||
EGLint nFmt = 0;
|
||||
if (eglGetConfigAttrib(context->eglDisplay, context->eglConfig, EGL_NATIVE_VISUAL_ID, &nFmt) == EGL_FALSE) {
|
||||
CC_LOG_ERROR("Getting configuration attributes failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto width = static_cast<int>(_colorTexture->getWidth());
|
||||
auto height = static_cast<int>(_colorTexture->getHeight());
|
||||
CC_UNUSED_PARAM(width);
|
||||
CC_UNUSED_PARAM(height);
|
||||
|
||||
#if CC_SWAPPY_ENABLED
|
||||
if (_gpuSwapchain->swappyEnabled) {
|
||||
_gpuSwapchain->swappyEnabled &= SwappyGL_setWindow(window);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CC_PLATFORM == CC_PLATFORM_ANDROID
|
||||
ANativeWindow_setBuffersGeometry(window, width, height, nFmt);
|
||||
#elif CC_PLATFORM == CC_PLATFORM_OHOS
|
||||
NativeLayerHandle(window, NativeLayerOps::SET_WIDTH_AND_HEIGHT, width, height);
|
||||
NativeLayerHandle(window, SET_FORMAT, nFmt);
|
||||
#endif
|
||||
|
||||
if (_gpuSwapchain->eglSurface == EGL_NO_SURFACE) {
|
||||
EGL_CHECK(_gpuSwapchain->eglSurface = eglCreateWindowSurface(context->eglDisplay, context->eglConfig, window, nullptr));
|
||||
if (_gpuSwapchain->eglSurface == EGL_NO_SURFACE) {
|
||||
CC_LOG_ERROR("Recreate window surface failed.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
context->makeCurrent(_gpuSwapchain, _gpuSwapchain);
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
53
cocos/renderer/gfx-gles2/GLES2Swapchain.h
Normal file
53
cocos/renderer/gfx-gles2/GLES2Swapchain.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2021-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXSwapchain.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUSwapchain;
|
||||
|
||||
class CC_GLES2_API GLES2Swapchain final : public Swapchain {
|
||||
public:
|
||||
GLES2Swapchain();
|
||||
~GLES2Swapchain() override;
|
||||
|
||||
inline GLES2GPUSwapchain *gpuSwapchain() const { return _gpuSwapchain; }
|
||||
|
||||
protected:
|
||||
void doInit(const SwapchainInfo &info) override;
|
||||
void doDestroy() override;
|
||||
void doResize(uint32_t width, uint32_t height, SurfaceTransform transform) override;
|
||||
void doDestroySurface() override;
|
||||
void doCreateSurface(void *windowHandle) override;
|
||||
|
||||
GLES2GPUSwapchain *_gpuSwapchain{nullptr};
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
143
cocos/renderer/gfx-gles2/GLES2Texture.cpp
Normal file
143
cocos/renderer/gfx-gles2/GLES2Texture.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
|
||||
#include "GLES2Commands.h"
|
||||
#include "GLES2Device.h"
|
||||
#include "GLES2Swapchain.h"
|
||||
#include "GLES2Texture.h"
|
||||
#include "profiler/Profiler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Texture::GLES2Texture() {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
}
|
||||
|
||||
GLES2Texture::~GLES2Texture() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void GLES2Texture::doInit(const TextureInfo & /*info*/) {
|
||||
_gpuTexture = ccnew GLES2GPUTexture;
|
||||
_gpuTexture->type = _info.type;
|
||||
_gpuTexture->format = _info.format;
|
||||
_gpuTexture->usage = _info.usage;
|
||||
_gpuTexture->width = _info.width;
|
||||
_gpuTexture->height = _info.height;
|
||||
_gpuTexture->depth = _info.depth;
|
||||
_gpuTexture->arrayLayer = _info.layerCount;
|
||||
_gpuTexture->mipLevel = _info.levelCount;
|
||||
_gpuTexture->samples = _info.samples;
|
||||
_gpuTexture->flags = _info.flags;
|
||||
_gpuTexture->size = _size;
|
||||
_gpuTexture->isPowerOf2 = math::isPowerOfTwo(_info.width) && math::isPowerOfTwo(_info.height);
|
||||
_gpuTexture->glTexture = static_cast<GLuint>(reinterpret_cast<size_t>(_info.externalRes));
|
||||
|
||||
cmdFuncGLES2CreateTexture(GLES2Device::getInstance(), _gpuTexture);
|
||||
|
||||
if (_gpuTexture->memoryAllocated) {
|
||||
GLES2Device::getInstance()->getMemoryStatus().textureSize += _size;
|
||||
CC_PROFILE_MEMORY_INC(Texture, _size);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2Texture::doInit(const TextureViewInfo &info) {
|
||||
_gpuTexture = static_cast<GLES2Texture *>(info.texture)->gpuTexture();
|
||||
}
|
||||
|
||||
void GLES2Texture::doDestroy() {
|
||||
if (_gpuTexture) {
|
||||
if (!_isTextureView) {
|
||||
if (_gpuTexture->memoryAllocated) {
|
||||
GLES2Device::getInstance()->getMemoryStatus().textureSize -= _size;
|
||||
CC_PROFILE_MEMORY_DEC(Texture, _size);
|
||||
}
|
||||
cmdFuncGLES2DestroyTexture(GLES2Device::getInstance(), _gpuTexture);
|
||||
GLES2Device::getInstance()->framebufferHub()->disengage(_gpuTexture);
|
||||
delete _gpuTexture;
|
||||
}
|
||||
_gpuTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GLES2Texture::doResize(uint32_t width, uint32_t height, uint32_t size) {
|
||||
if (_gpuTexture->memoryAllocated) {
|
||||
GLES2Device::getInstance()->getMemoryStatus().textureSize -= _size;
|
||||
CC_PROFILE_MEMORY_DEC(Texture, _size);
|
||||
}
|
||||
_gpuTexture->width = width;
|
||||
_gpuTexture->height = height;
|
||||
_gpuTexture->size = size;
|
||||
_gpuTexture->mipLevel = _info.levelCount;
|
||||
cmdFuncGLES2ResizeTexture(GLES2Device::getInstance(), _gpuTexture);
|
||||
|
||||
GLES2Device::getInstance()->framebufferHub()->update(_gpuTexture);
|
||||
|
||||
if (_gpuTexture->memoryAllocated) {
|
||||
GLES2Device::getInstance()->getMemoryStatus().textureSize += size;
|
||||
CC_PROFILE_MEMORY_INC(Texture, size);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t GLES2Texture::getGLTextureHandle() const noexcept {
|
||||
const auto *gpuTexture = _gpuTexture;
|
||||
if (!gpuTexture) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gpuTexture->glTexture) {
|
||||
return gpuTexture->glTexture;
|
||||
}
|
||||
|
||||
if (gpuTexture->glRenderbuffer) {
|
||||
return gpuTexture->glRenderbuffer;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////// Swapchain Specific /////////////////////////////
|
||||
|
||||
void GLES2Texture::doInit(const SwapchainTextureInfo & /*info*/) {
|
||||
_gpuTexture = ccnew GLES2GPUTexture;
|
||||
_gpuTexture->type = _info.type;
|
||||
_gpuTexture->format = _info.format;
|
||||
_gpuTexture->usage = _info.usage;
|
||||
_gpuTexture->width = _info.width;
|
||||
_gpuTexture->height = _info.height;
|
||||
_gpuTexture->depth = _info.depth;
|
||||
_gpuTexture->arrayLayer = _info.layerCount;
|
||||
_gpuTexture->mipLevel = _info.levelCount;
|
||||
_gpuTexture->samples = _info.samples;
|
||||
_gpuTexture->flags = _info.flags;
|
||||
_gpuTexture->size = _size;
|
||||
_gpuTexture->memoryAllocated = false;
|
||||
_gpuTexture->swapchain = static_cast<GLES2Swapchain *>(_swapchain)->gpuSwapchain();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
55
cocos/renderer/gfx-gles2/GLES2Texture.h
Normal file
55
cocos/renderer/gfx-gles2/GLES2Texture.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Std.h"
|
||||
#include "gfx-base/GFXTexture.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUTexture;
|
||||
|
||||
class CC_GLES2_API GLES2Texture final : public Texture {
|
||||
public:
|
||||
GLES2Texture();
|
||||
~GLES2Texture() override;
|
||||
|
||||
inline GLES2GPUTexture *gpuTexture() const { return _gpuTexture; }
|
||||
|
||||
uint32_t getGLTextureHandle() const noexcept override;
|
||||
|
||||
protected:
|
||||
void doInit(const TextureInfo &info) override;
|
||||
void doInit(const TextureViewInfo &info) override;
|
||||
void doDestroy() override;
|
||||
void doResize(uint32_t width, uint32_t height, uint32_t size) override;
|
||||
void doInit(const SwapchainTextureInfo &info) override;
|
||||
|
||||
GLES2GPUTexture *_gpuTexture = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
119
cocos/renderer/gfx-gles2/GLES2Wrangler.cpp
Normal file
119
cocos/renderer/gfx-gles2/GLES2Wrangler.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Wrangler.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(ANDROID)
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
|
||||
static HMODULE libegl = NULL;
|
||||
static HMODULE libgles = NULL;
|
||||
|
||||
bool gles2wOpen() {
|
||||
libegl = LoadLibraryA("libEGL.dll");
|
||||
libgles = LoadLibraryA("libGLESv2.dll");
|
||||
return (libegl && libgles);
|
||||
}
|
||||
|
||||
bool gles2wClose() {
|
||||
bool ret = true;
|
||||
if (libegl) {
|
||||
ret &= FreeLibrary(libegl) ? true : false;
|
||||
libegl = NULL;
|
||||
}
|
||||
|
||||
if (libgles) {
|
||||
ret &= FreeLibrary(libgles) ? true : false;
|
||||
libgles = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *gles2wLoad(const char *proc) {
|
||||
void *res = nullptr;
|
||||
if (eglGetProcAddress) res = (void *)eglGetProcAddress(proc);
|
||||
if (!res) res = (void *)GetProcAddress(libegl, proc);
|
||||
return res;
|
||||
}
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
bool gles2wOpen() { return true; }
|
||||
bool gles2wClose() { return true; }
|
||||
void *gles2wLoad(const char *proc) {
|
||||
return (void *)eglGetProcAddress(proc);
|
||||
}
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void *libegl = nullptr;
|
||||
static void *libgles = nullptr;
|
||||
|
||||
bool gles2wOpen() {
|
||||
libegl = dlopen("libEGL.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
#if __OHOS__
|
||||
libgles = dlopen("libGLESv3.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
#else
|
||||
libgles = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
#endif
|
||||
return (libegl && libgles);
|
||||
}
|
||||
|
||||
bool gles2wClose() {
|
||||
bool ret = true;
|
||||
if (libegl) {
|
||||
ret &= dlclose(libegl) == 0;
|
||||
libegl = nullptr;
|
||||
}
|
||||
|
||||
if (libgles) {
|
||||
ret &= dlclose(libgles) == 0;
|
||||
libgles = nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *gles2wLoad(const char *proc) {
|
||||
void *res = nullptr;
|
||||
if (eglGetProcAddress) res = reinterpret_cast<void *>(eglGetProcAddress(proc));
|
||||
if (!res) res = dlsym(libegl, proc);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool gles2wInit() {
|
||||
if (!gles2wOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
eglwLoadProcs(gles2wLoad);
|
||||
gles2wLoadProcs(gles2wLoad);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool gles2wExit() {
|
||||
return gles2wClose();
|
||||
}
|
||||
31
cocos/renderer/gfx-gles2/GLES2Wrangler.h
Normal file
31
cocos/renderer/gfx-gles2/GLES2Wrangler.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "../gfx-gles-common/eglw.h"
|
||||
#include "../gfx-gles-common/gles2w.h"
|
||||
|
||||
bool gles2wInit();
|
||||
bool gles2wExit();
|
||||
55
cocos/renderer/gfx-gles2/states/GLES2Sampler.cpp
Normal file
55
cocos/renderer/gfx-gles2/states/GLES2Sampler.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "GLES2Sampler.h"
|
||||
#include "../GLES2Commands.h"
|
||||
#include "../GLES2Device.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
GLES2Sampler::GLES2Sampler(const SamplerInfo &info) : Sampler(info) {
|
||||
_typedID = generateObjectID<decltype(this)>();
|
||||
|
||||
_gpuSampler = ccnew GLES2GPUSampler;
|
||||
_gpuSampler->minFilter = _info.minFilter;
|
||||
_gpuSampler->magFilter = _info.magFilter;
|
||||
_gpuSampler->mipFilter = _info.mipFilter;
|
||||
_gpuSampler->addressU = _info.addressU;
|
||||
_gpuSampler->addressV = _info.addressV;
|
||||
_gpuSampler->addressW = _info.addressW;
|
||||
|
||||
cmdFuncGLES2CreateSampler(GLES2Device::getInstance(), _gpuSampler);
|
||||
}
|
||||
|
||||
GLES2Sampler::~GLES2Sampler() {
|
||||
if (_gpuSampler) {
|
||||
cmdFuncGLES2DestroySampler(GLES2Device::getInstance(), _gpuSampler);
|
||||
delete _gpuSampler;
|
||||
_gpuSampler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
48
cocos/renderer/gfx-gles2/states/GLES2Sampler.h
Normal file
48
cocos/renderer/gfx-gles2/states/GLES2Sampler.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/****************************************************************************
|
||||
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
||||
|
||||
http://www.cocos.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated 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 "../GLES2Std.h"
|
||||
#include "gfx-base/GFXDef-common.h"
|
||||
#include "gfx-base/states/GFXSampler.h"
|
||||
|
||||
namespace cc {
|
||||
namespace gfx {
|
||||
|
||||
struct GLES2GPUSampler;
|
||||
|
||||
class CC_GLES2_API GLES2Sampler final : public Sampler {
|
||||
public:
|
||||
explicit GLES2Sampler(const SamplerInfo &info);
|
||||
~GLES2Sampler() override;
|
||||
|
||||
inline GLES2GPUSampler *gpuSampler() const { return _gpuSampler; }
|
||||
|
||||
protected:
|
||||
GLES2GPUSampler *_gpuSampler = nullptr;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace cc
|
||||
Reference in New Issue
Block a user