Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gfx: refactor binding mappings #4195

Merged
merged 3 commits into from
Jan 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"external/sources",
"external/sources/khronos",
"external/win32/include",
"external/win32/include/glslang",
"external/win32/include/v8"
],
"compileCommands": "${workspaceFolder}/compile_commands.json"
Expand Down
259 changes: 217 additions & 42 deletions cocos/bindings/auto/jsb_gfx_auto.cpp

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions cocos/renderer/frame-graph/DevicePass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,18 @@
****************************************************************************/

#include "DevicePass.h"
#include <algorithm>
#include "CallbackPass.h"
#include "DevicePassResourceTable.h"
#include "FrameGraph.h"
#include "PassNode.h"
#include "ResourceNode.h"

#include "base/Utils.h"
#include "gfx-base/GFXCommandBuffer.h"
#include "gfx-base/GFXDef-common.h"

#include <algorithm>

namespace cc {
namespace framegraph {

Expand Down Expand Up @@ -225,8 +227,8 @@ void DevicePass::begin(gfx::CommandBuffer *cmdBuff) {
// calculate the union of all viewports as render area
_viewport.left = _scissor.x = std::min(_scissor.x, pass.viewport.left);
_viewport.top = _scissor.y = std::min(_scissor.y, pass.viewport.top);
_viewport.width = _scissor.width = std::max(_scissor.width, pass.viewport.width);
_viewport.height = _scissor.height = std::max(_scissor.height, pass.viewport.height);
_viewport.width = _scissor.width = std::max(_scissor.width, pass.viewport.width + pass.viewport.left - _scissor.x);
_viewport.height = _scissor.height = std::max(_scissor.height, pass.viewport.height + pass.viewport.top - _scissor.y);
}
}
}
Expand Down
7 changes: 1 addition & 6 deletions cocos/renderer/frame-graph/FrameGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,7 @@ void FrameGraph::move(const TextureHandle from, const TextureHandle to, uint8_t
}

bool FrameGraph::hasPass(StringHandle handle) {
for (const auto &passNode : _passNodes) {
if (passNode->_name == handle) {
return true;
}
}
return false;
return std::any_of(_passNodes.begin(), _passNodes.end(), [&](const auto &passNode) { return passNode->_name == handle; });
}

Handle FrameGraph::create(VirtualResource *const virtualResource) {
Expand Down
19 changes: 15 additions & 4 deletions cocos/renderer/gfx-base/GFXDef-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ enum class API : uint32_t {
GLES3,
METAL,
VULKAN,
NVN,
WEBGL,
WEBGL2,
WEBGPU,
Expand Down Expand Up @@ -884,12 +885,22 @@ using ColorList = vector<Color>;
* The GFX layer assumes the binding numbers for each descriptor type inside each set
* are guaranteed to be consecutive, so the mapping procedure is reduced
* to a simple shifting operation. This data structure specifies the
* offsets for each descriptor type in each set.
* capacity for each descriptor type in each set.
*
* The `setIndices` field defines the binding ordering between different sets.
* The last set index is treated as the 'flexible set', whose capacity is dynamically
* assigned based on the total available descriptor slots on the runtime device.
*/
struct BindingMappingInfo {
std::vector<int32_t> bufferOffsets;
std::vector<int32_t> samplerOffsets;
uint32_t flexibleSet{0U};
std::vector<uint32_t> maxBlockCounts{0};
std::vector<uint32_t> maxSamplerTextureCounts{0};
std::vector<uint32_t> maxSamplerCounts{0};
std::vector<uint32_t> maxTextureCounts{0};
std::vector<uint32_t> maxBufferCounts{0};
std::vector<uint32_t> maxImageCounts{0};
std::vector<uint32_t> maxSubpassInputCounts{0};

std::vector<uint32_t> setIndices{0};
};

struct SwapchainInfo {
Expand Down
9 changes: 0 additions & 9 deletions cocos/renderer/gfx-base/GFXDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,6 @@ Device::~Device() {

bool Device::initialize(const DeviceInfo &info) {
_bindingMappingInfo = info.bindingMappingInfo;
if (_bindingMappingInfo.bufferOffsets.empty()) {
_bindingMappingInfo.bufferOffsets.push_back(0);
}
if (_bindingMappingInfo.samplerOffsets.empty()) {
_bindingMappingInfo.samplerOffsets.push_back(0);
}

#if CC_CPU_ARCH == CC_CPU_ARCH_32
static_assert(sizeof(void*) == 4, "pointer size assumption broken");
Expand All @@ -78,9 +72,6 @@ void Device::destroy() {
CC_SAFE_DELETE(pair.second);
}

_bindingMappingInfo.bufferOffsets.clear();
_bindingMappingInfo.samplerOffsets.clear();

doDestroy();

CC_SAFE_DELETE(_onAcquire);
Expand Down
7 changes: 7 additions & 0 deletions cocos/renderer/gfx-gles-common/GLESCommandPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ enum class GLESCmdType : uint8_t {
COUNT,
};

class GLESBindingMapping {
public:
vector<int32_t> blockOffsets;
vector<int32_t> samplerTextureOffsets;
uint32_t flexibleSet{0};
};

class GLESCmd : public Object {
public:
GLESCmdType type;
Expand Down
2 changes: 1 addition & 1 deletion cocos/renderer/gfx-gles2/GLES2CommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void GLES2CommandBuffer::doInit(const CommandBufferInfo &info) {
_cmdAllocator = CC_NEW(GLES2GPUCommandAllocator);
_curCmdPackage = CC_NEW(GLES2CmdPackage);

size_t setCount = GLES2Device::getInstance()->bindingMappingInfo().bufferOffsets.size();
size_t setCount = GLES2Device::getInstance()->bindingMappingInfo().setIndices.size();
_curGPUDescriptorSets.resize(setCount);
_curDynamicOffsets.resize(setCount);
}
Expand Down
13 changes: 7 additions & 6 deletions cocos/renderer/gfx-gles2/GLES2Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "GLES2Commands.h"
#include "GLES2Device.h"
#include "gfx-gles-common/GLESCommandPool.h"

#define BUFFER_OFFSET(idx) (static_cast<char *>(0) + (idx))

Expand Down Expand Up @@ -1100,14 +1101,14 @@ void cmdFuncGLES2CreateShader(GLES2Device *device, GLES2GPUShader *gpuShader) {
// texture unit index mapping optimization
vector<GLES2GPUUniformSamplerTexture> glActiveSamplerTextures;
vector<GLint> glActiveSamplerLocations;
const BindingMappingInfo & bindingMappingInfo = device->bindingMappingInfo();
unordered_map<String, uint32_t> & texUnitCacheMap = device->stateCache()->texUnitCacheMap;
const GLESBindingMapping & bindingMappings = device->bindingMappings();
unordered_map<String, uint32_t> & texUnitCacheMap = device->stateCache()->texUnitCacheMap;

// sampler bindings in the flexible set comes strictly after buffer bindings
// so we need to subtract the buffer count for these samplers
uint32_t flexibleSetBaseOffset = 0U;
for (auto &block : gpuShader->blocks) {
if (block.set == bindingMappingInfo.flexibleSet) {
for (const auto &block : gpuShader->blocks) {
if (block.set == bindingMappings.flexibleSet) {
flexibleSetBaseOffset++;
}
}
Expand All @@ -1122,8 +1123,8 @@ void cmdFuncGLES2CreateShader(GLES2Device *device, GLES2GPUShader *gpuShader) {
glActiveSamplerLocations.push_back(glLoc);
}
if (!texUnitCacheMap.count(samplerTexture.name)) {
uint32_t binding = samplerTexture.binding + bindingMappingInfo.samplerOffsets[samplerTexture.set] + arrayOffset;
if (samplerTexture.set == bindingMappingInfo.flexibleSet) binding -= flexibleSetBaseOffset;
uint32_t binding = samplerTexture.binding + bindingMappings.samplerTextureOffsets[samplerTexture.set] + arrayOffset;
if (samplerTexture.set == bindingMappings.flexibleSet) binding -= flexibleSetBaseOffset;
texUnitCacheMap[samplerTexture.name] = binding % device->getCapabilities().maxTextureUnits;
arrayOffset += samplerTexture.count - 1;
}
Expand Down
10 changes: 5 additions & 5 deletions cocos/renderer/gfx-gles2/GLES2DescriptorSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,23 @@ void GLES2DescriptorSet::doDestroy() {

void GLES2DescriptorSet::update() {
if (_isDirty && _gpuDescriptorSet) {
const GLES2GPUDescriptorList &descriptors = _gpuDescriptorSet->gpuDescriptors;
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]);
if (buffer) {
if (buffer->gpuBuffer()) {
_gpuDescriptorSet->gpuDescriptors[i].gpuBuffer = buffer->gpuBuffer();
descriptors[i].gpuBuffer = buffer->gpuBuffer();
} else if (buffer->gpuBufferView()) {
_gpuDescriptorSet->gpuDescriptors[i].gpuBufferView = buffer->gpuBufferView();
descriptors[i].gpuBufferView = buffer->gpuBufferView();
}
}
} else if (hasAnyFlags(descriptors[i].type, DESCRIPTOR_TEXTURE_TYPE)) {
if (_textures[i]) {
_gpuDescriptorSet->gpuDescriptors[i].gpuTexture = static_cast<GLES2Texture *>(_textures[i])->gpuTexture();
descriptors[i].gpuTexture = static_cast<GLES2Texture *>(_textures[i])->gpuTexture();
}
if (_samplers[i]) {
_gpuDescriptorSet->gpuDescriptors[i].gpuSampler = static_cast<GLES2Sampler *>(_samplers[i])->gpuSampler();
descriptors[i].gpuSampler = static_cast<GLES2Sampler *>(_samplers[i])->gpuSampler();
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions cocos/renderer/gfx-gles2/GLES2Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ bool GLES2Device::doInit(const DeviceInfo & /*info*/) {
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();

String extStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
_extensions = StringUtil::split(extStr, " ");

Expand Down
5 changes: 5 additions & 0 deletions cocos/renderer/gfx-gles2/GLES2Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "GLES2Std.h"
#include "gfx-base/GFXDevice.h"
#include "gfx-base/GFXSwapchain.h"
#include "gfx-gles-common/GLESCommandPool.h"

namespace cc {
namespace gfx {
Expand Down Expand Up @@ -67,6 +68,8 @@ class CC_GLES2_API GLES2Device final : public Device {
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; }
Expand Down Expand Up @@ -123,6 +126,8 @@ class CC_GLES2_API GLES2Device final : public Device {

vector<GLES2GPUSwapchain *> _swapchains;

GLESBindingMapping _bindingMappings;

StringArray _extensions;
};

Expand Down
2 changes: 1 addition & 1 deletion cocos/renderer/gfx-gles3/GLES3CommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void GLES3CommandBuffer::doInit(const CommandBufferInfo & /*info*/) {
_cmdAllocator = CC_NEW(GLES3GPUCommandAllocator);
_curCmdPackage = CC_NEW(GLES3CmdPackage);

size_t setCount = GLES3Device::getInstance()->bindingMappingInfo().bufferOffsets.size();
size_t setCount = GLES3Device::getInstance()->bindingMappingInfo().setIndices.size();
_curGPUDescriptorSets.resize(setCount);
_curDynamicOffsets.resize(setCount);
}
Expand Down
15 changes: 8 additions & 7 deletions cocos/renderer/gfx-gles3/GLES3Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "GLES3Device.h"
#include "GLES3QueryPool.h"
#include "gfx-base/GFXDef-common.h"
#include "gfx-gles-common/GLESCommandPool.h"

#define BUFFER_OFFSET(idx) (static_cast<char *>(0) + (idx))

Expand Down Expand Up @@ -1147,7 +1148,7 @@ void cmdFuncGLES3CreateShader(GLES3Device *device, GLES3GPUShader *gpuShader) {
if (block.name == glBlock.name) {
glBlock.set = block.set;
glBlock.binding = block.binding;
glBlock.glBinding = block.binding + device->bindingMappingInfo().bufferOffsets[block.set];
glBlock.glBinding = block.binding + device->bindingMappings().blockOffsets[block.set];
GL_CHECK(glUniformBlockBinding(gpuShader->glProgram, i, glBlock.glBinding));
break;
}
Expand Down Expand Up @@ -1216,14 +1217,14 @@ void cmdFuncGLES3CreateShader(GLES3Device *device, GLES3GPUShader *gpuShader) {
// texture unit index mapping optimization
vector<GLES3GPUUniformSamplerTexture> glActiveSamplerTextures;
vector<GLint> glActiveSamplerLocations;
const BindingMappingInfo & bindingMappingInfo = device->bindingMappingInfo();
unordered_map<String, uint32_t> & texUnitCacheMap = device->stateCache()->texUnitCacheMap;
const GLESBindingMapping & bindingMappings = device->bindingMappings();
unordered_map<String, uint32_t> & texUnitCacheMap = device->stateCache()->texUnitCacheMap;

// sampler bindings in the flexible set comes strictly after buffer bindings
// so we need to subtract the buffer count for these samplers
uint32_t flexibleSetBaseOffset = 0U;
for (GLES3GPUUniformBuffer &buffer : gpuShader->glBuffers) {
if (buffer.set == bindingMappingInfo.flexibleSet) {
for (const auto &buffer : gpuShader->blocks) {
if (buffer.set == bindingMappings.flexibleSet) {
flexibleSetBaseOffset++;
}
}
Expand All @@ -1239,8 +1240,8 @@ void cmdFuncGLES3CreateShader(GLES3Device *device, GLES3GPUShader *gpuShader) {
glActiveSamplerLocations.push_back(glLoc);

if (texUnitCacheMap.count(samplerTexture.name) == 0U) {
uint32_t binding = samplerTexture.binding + bindingMappingInfo.samplerOffsets[samplerTexture.set] + arrayOffset;
if (samplerTexture.set == bindingMappingInfo.flexibleSet) binding -= flexibleSetBaseOffset;
uint32_t binding = samplerTexture.binding + bindingMappings.samplerTextureOffsets[samplerTexture.set] + arrayOffset;
if (samplerTexture.set == bindingMappings.flexibleSet) binding -= flexibleSetBaseOffset;
texUnitCacheMap[samplerTexture.name] = binding % device->getCapabilities().maxTextureUnits;
arrayOffset += samplerTexture.count - 1;
}
Expand Down
8 changes: 4 additions & 4 deletions cocos/renderer/gfx-gles3/GLES3DescriptorSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ void GLES3DescriptorSet::doDestroy() {

void GLES3DescriptorSet::update() {
if (_isDirty && _gpuDescriptorSet) {
const GLES3GPUDescriptorList &descriptors = _gpuDescriptorSet->gpuDescriptors;
auto &descriptors = _gpuDescriptorSet->gpuDescriptors;
for (size_t i = 0; i < descriptors.size(); i++) {
if (hasAnyFlags(descriptors[i].type, DESCRIPTOR_BUFFER_TYPE)) {
if (_buffers[i]) {
_gpuDescriptorSet->gpuDescriptors[i].gpuBuffer = static_cast<GLES3Buffer *>(_buffers[i])->gpuBuffer();
descriptors[i].gpuBuffer = static_cast<GLES3Buffer *>(_buffers[i])->gpuBuffer();
}
} else if (hasAnyFlags(descriptors[i].type, DESCRIPTOR_TEXTURE_TYPE)) {
if (_textures[i]) {
_gpuDescriptorSet->gpuDescriptors[i].gpuTexture = static_cast<GLES3Texture *>(_textures[i])->gpuTexture();
descriptors[i].gpuTexture = static_cast<GLES3Texture *>(_textures[i])->gpuTexture();
}
if (_samplers[i]) {
_gpuDescriptorSet->gpuDescriptors[i].gpuSampler = static_cast<GLES3Sampler *>(_samplers[i])->gpuSampler();
descriptors[i].gpuSampler = static_cast<GLES3Sampler *>(_samplers[i])->gpuSampler();
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions cocos/renderer/gfx-gles3/GLES3Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ bool GLES3Device::doInit(const DeviceInfo & /*info*/) {
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();

String extStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
_extensions = StringUtil::split(extStr, " ");

Expand Down
5 changes: 5 additions & 0 deletions cocos/renderer/gfx-gles3/GLES3Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "GLES3Std.h"
#include "gfx-base/GFXDevice.h"
#include "gfx-gles-common/GLESCommandPool.h"

namespace cc {
namespace gfx {
Expand Down Expand Up @@ -67,6 +68,8 @@ class CC_GLES3_API GLES3Device final : public Device {
void acquire(Swapchain *const *swapchains, uint32_t count) override;
void present() override;

inline const GLESBindingMapping &bindingMappings() const { return _bindingMappings; }

inline GLES3GPUContext * context() const { return _gpuContext; }
inline GLES3GPUStateCache * stateCache() const { return _gpuStateCache; }
inline GLES3GPUFramebufferHub * framebufferHub() const { return _gpuFramebufferHub; }
Expand Down Expand Up @@ -122,6 +125,8 @@ class CC_GLES3_API GLES3Device final : public Device {

vector<GLES3GPUSwapchain *> _swapchains;

GLESBindingMapping _bindingMappings;

StringArray _extensions;
};

Expand Down
Loading