no message

This commit is contained in:
gem
2025-02-18 15:21:31 +08:00
commit 2d133e56d7
1980 changed files with 465595 additions and 0 deletions

View File

@@ -0,0 +1,905 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
https://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 "GFXBarrier.h"
#include <algorithm>
#include <array>
namespace cc {
namespace gfx {
namespace {
template <unsigned char... indices>
constexpr uint64_t setbit() {
return ((1ULL << indices) | ... | 0ULL);
}
template <typename T, size_t... indices>
constexpr uint64_t setbits(const std::integer_sequence<T, indices...>& intSeq) {
std::ignore = intSeq;
return setbit<indices...>();
}
template <std::size_t N>
constexpr uint64_t setbits() {
using index_seq = std::make_index_sequence<N>;
return setbits(index_seq{});
}
template <unsigned char first, unsigned char end>
constexpr uint64_t setbitBetween() {
static_assert(first >= end);
return setbits<first>() ^ setbits<end>();
}
template <uint32_t N>
constexpr uint8_t highestBitPosOffset() {
if constexpr (N == 0) {
return 0;
} else {
return highestBitPosOffset<(N >> 1)>() + 1;
}
}
enum class ResourceType : uint32_t {
UNKNOWN,
BUFFER,
TEXTURE,
};
enum class CommonUsage : uint32_t {
NONE = 0,
COPY_SRC = 1 << 1,
COPY_DST = 1 << 2,
ROM = 1 << 3, // sampled or UNIFORM
STORAGE = 1 << 4,
IB_OR_CA = 1 << 5,
VB_OR_DS = 1 << 6,
INDIRECT_OR_INPUT = 1 << 7,
SHADING_RATE = 1 << 8,
LAST_ONE = SHADING_RATE,
};
CC_ENUM_BITWISE_OPERATORS(CommonUsage);
constexpr CommonUsage textureUsageToCommonUsage(TextureUsage usage) {
CommonUsage res{0};
if (hasFlag(usage, TextureUsage::TRANSFER_SRC)) {
res |= CommonUsage::COPY_SRC;
}
if (hasFlag(usage, TextureUsage::TRANSFER_DST)) {
res |= CommonUsage::COPY_DST;
}
if (hasFlag(usage, TextureUsage::SAMPLED)) {
res |= CommonUsage::ROM;
}
if (hasFlag(usage, TextureUsage::STORAGE)) {
res |= CommonUsage::STORAGE;
}
if (hasFlag(usage, TextureUsage::COLOR_ATTACHMENT)) {
res |= CommonUsage::IB_OR_CA;
}
if (hasFlag(usage, TextureUsage::DEPTH_STENCIL_ATTACHMENT)) {
res |= CommonUsage::VB_OR_DS;
}
if (hasFlag(usage, TextureUsage::INPUT_ATTACHMENT)) {
res |= CommonUsage::INDIRECT_OR_INPUT;
}
if (hasFlag(usage, TextureUsage::SHADING_RATE)) {
res |= CommonUsage::SHADING_RATE;
}
return res;
}
constexpr CommonUsage bufferUsageToCommonUsage(BufferUsage usage) {
CommonUsage res{0};
if (hasFlag(usage, BufferUsage::NONE)) {
res |= CommonUsage::NONE;
}
if (hasFlag(usage, BufferUsage::TRANSFER_SRC)) {
res |= CommonUsage::COPY_SRC;
}
if (hasFlag(usage, BufferUsage::TRANSFER_DST)) {
res |= CommonUsage::COPY_DST;
}
if (hasFlag(usage, BufferUsage::UNIFORM)) {
res |= CommonUsage::ROM;
}
if (hasFlag(usage, BufferUsage::STORAGE)) {
res |= CommonUsage::STORAGE;
}
if (hasFlag(usage, BufferUsage::INDEX)) {
res |= CommonUsage::IB_OR_CA;
}
if (hasFlag(usage, BufferUsage::VERTEX)) {
res |= CommonUsage::VB_OR_DS;
}
if (hasFlag(usage, BufferUsage::INDIRECT)) {
res |= CommonUsage::INDIRECT_OR_INPUT;
}
return res;
}
struct AccessElem {
uint32_t mask{0xFFFFFFFF};
uint32_t key{0xFFFFFFFF};
AccessFlags access{AccessFlags::NONE};
uint32_t mutex{0x0}; // optional mutually exclusive flag
};
#define OPERABLE(val) static_cast<std::underlying_type<decltype(val)>::type>(val)
constexpr uint8_t COMMON_USAGE_COUNT = highestBitPosOffset<OPERABLE(CommonUsage::LAST_ONE)>();
constexpr uint8_t SHADER_STAGE_RESERVE_COUNT = 6;
constexpr uint8_t RESOURCE_TYPE_COUNT = 2;
constexpr uint8_t MEM_TYPE_COUNT = 2;
constexpr uint8_t ACCESS_TYPE_COUNT = 2;
constexpr auto CMN_NONE = OPERABLE(CommonUsage::NONE);
constexpr auto CMN_COPY_SRC = OPERABLE(CommonUsage::COPY_SRC);
constexpr auto CMN_COPY_DST = OPERABLE(CommonUsage::COPY_DST);
constexpr auto CMN_ROM = OPERABLE(CommonUsage::ROM);
constexpr auto CMN_STORAGE = OPERABLE(CommonUsage::STORAGE);
constexpr auto CMN_IB_OR_CA = OPERABLE(CommonUsage::IB_OR_CA);
constexpr auto CMN_VB_OR_DS = OPERABLE(CommonUsage::VB_OR_DS);
constexpr auto CMN_INDIRECT_OR_INPUT = OPERABLE(CommonUsage::INDIRECT_OR_INPUT);
constexpr auto CMN_SHADING_RATE = OPERABLE(CommonUsage::SHADING_RATE);
constexpr auto SHADER_STAGE_BIT_POPS = COMMON_USAGE_COUNT;
constexpr auto SHADERSTAGE_NONE = 0;
constexpr auto SHADERSTAGE_VERT = 1 << (0 + SHADER_STAGE_BIT_POPS);
constexpr auto SHADERSTAGE_CTRL = 1 << (1 + SHADER_STAGE_BIT_POPS);
constexpr auto SHADERSTAGE_EVAL = 1 << (2 + SHADER_STAGE_BIT_POPS);
constexpr auto SHADERSTAGE_GEOM = 1 << (3 + SHADER_STAGE_BIT_POPS);
constexpr auto SHADERSTAGE_FRAG = 1 << (4 + SHADER_STAGE_BIT_POPS);
constexpr auto SHADERSTAGE_COMP = 1 << (5 + SHADER_STAGE_BIT_POPS);
constexpr auto RESOURCE_TYPE_BIT_POS = COMMON_USAGE_COUNT + SHADER_STAGE_RESERVE_COUNT;
constexpr auto RES_TEXTURE = OPERABLE(ResourceType::TEXTURE) << RESOURCE_TYPE_BIT_POS;
constexpr auto RES_BUFFER = OPERABLE(ResourceType::BUFFER) << RESOURCE_TYPE_BIT_POS;
constexpr auto MEM_TYPE_BIT_POS = COMMON_USAGE_COUNT + SHADER_STAGE_RESERVE_COUNT + RESOURCE_TYPE_COUNT;
constexpr auto MEM_HOST = OPERABLE(MemoryUsage::HOST) << MEM_TYPE_BIT_POS;
constexpr auto MEM_DEVICE = OPERABLE(MemoryUsage::DEVICE) << MEM_TYPE_BIT_POS;
constexpr auto ACCESS_TYPE_BIT_POS = COMMON_USAGE_COUNT + SHADER_STAGE_RESERVE_COUNT + RESOURCE_TYPE_COUNT + MEM_TYPE_COUNT;
constexpr auto ACCESS_WRITE = OPERABLE(MemoryAccess::WRITE_ONLY) << ACCESS_TYPE_BIT_POS;
constexpr auto ACCESS_READ = OPERABLE(MemoryAccess::READ_ONLY) << ACCESS_TYPE_BIT_POS;
constexpr uint8_t USED_BIT_COUNT = COMMON_USAGE_COUNT + SHADER_STAGE_RESERVE_COUNT + RESOURCE_TYPE_COUNT + MEM_TYPE_COUNT + ACCESS_TYPE_COUNT;
// 20 and above :reserved
// 18 ~ 19: MemoryAccess
// 16 ~ 17: MemoryUsage
// 14 ~ 15: ResourceType
// 8 ~ 13: ShaderStageFlags
// 0 ~ 7: CommonUsage
constexpr uint32_t CARE_NONE = 0x0;
constexpr uint32_t CARE_CMNUSAGE = setbitBetween<SHADER_STAGE_BIT_POPS, 0>();
constexpr uint32_t CARE_SHADERSTAGE = setbitBetween<RESOURCE_TYPE_BIT_POS, SHADER_STAGE_BIT_POPS>();
constexpr uint32_t CARE_RESTYPE = setbitBetween<MEM_TYPE_BIT_POS, RESOURCE_TYPE_BIT_POS>();
constexpr uint32_t CARE_MEMUSAGE = setbitBetween<ACCESS_TYPE_BIT_POS, MEM_TYPE_BIT_POS>();
constexpr uint32_t CARE_MEMACCESS = setbitBetween<USED_BIT_COUNT, ACCESS_TYPE_BIT_POS>();
constexpr uint32_t IGNORE_NONE = 0xFFFFFFFF;
constexpr uint32_t IGNORE_CMNUSAGE = ~CARE_CMNUSAGE;
constexpr uint32_t IGNORE_SHADERSTAGE = ~CARE_SHADERSTAGE;
constexpr uint32_t IGNORE_RESTYPE = ~CARE_RESTYPE;
constexpr uint32_t IGNORE_MEMUSAGE = ~CARE_MEMUSAGE;
constexpr uint32_t IGNORE_MEMACCESS = ~CARE_MEMACCESS;
constexpr AccessElem ACCESS_MAP[] = {
{CARE_MEMACCESS,
0x0,
AccessFlags::NONE},
{CARE_MEMUSAGE,
0x0,
AccessFlags::NONE},
{CARE_RESTYPE | CARE_CMNUSAGE,
RES_BUFFER | CMN_INDIRECT_OR_INPUT,
AccessFlags::INDIRECT_BUFFER},
{CARE_RESTYPE | CARE_CMNUSAGE,
RES_BUFFER | CMN_IB_OR_CA,
AccessFlags::INDEX_BUFFER}, // buffer usage indicates what it is, so shader stage ignored.
{CARE_RESTYPE | CARE_CMNUSAGE,
ACCESS_READ | RES_BUFFER | CMN_VB_OR_DS,
AccessFlags::VERTEX_BUFFER}, // ditto
{IGNORE_MEMUSAGE,
ACCESS_READ | RES_BUFFER | SHADERSTAGE_VERT | CMN_ROM,
AccessFlags::VERTEX_SHADER_READ_UNIFORM_BUFFER},
{IGNORE_MEMUSAGE,
ACCESS_READ | RES_TEXTURE | SHADERSTAGE_VERT | CMN_ROM,
AccessFlags::VERTEX_SHADER_READ_TEXTURE},
{IGNORE_MEMUSAGE & IGNORE_RESTYPE,
ACCESS_READ | ACCESS_WRITE | SHADERSTAGE_VERT | CMN_STORAGE,
AccessFlags::VERTEX_SHADER_READ_OTHER},
{IGNORE_MEMUSAGE,
ACCESS_READ | RES_BUFFER | SHADERSTAGE_FRAG | CMN_ROM,
AccessFlags::FRAGMENT_SHADER_READ_UNIFORM_BUFFER},
{CARE_MEMACCESS | CARE_RESTYPE | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_ROM,
AccessFlags::FRAGMENT_SHADER_READ_TEXTURE,
CMN_VB_OR_DS},
{IGNORE_MEMUSAGE,
ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_IB_OR_CA | CMN_INDIRECT_OR_INPUT,
AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT},
{IGNORE_MEMUSAGE,
ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_VB_OR_DS | CMN_INDIRECT_OR_INPUT,
AccessFlags::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT},
{IGNORE_MEMUSAGE & IGNORE_RESTYPE,
ACCESS_READ | ACCESS_WRITE | SHADERSTAGE_FRAG | CMN_STORAGE,
AccessFlags::FRAGMENT_SHADER_READ_OTHER,
CMN_SHADING_RATE},
//{IGNORE_MEMUSAGE,
// ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_IB_OR_CA,
// AccessFlags::COLOR_ATTACHMENT_READ},
{CARE_MEMACCESS | CARE_RESTYPE | CARE_CMNUSAGE | CARE_SHADERSTAGE,
ACCESS_READ | RES_TEXTURE | CMN_VB_OR_DS | CMN_ROM,
AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ},
{IGNORE_MEMUSAGE,
ACCESS_READ | RES_BUFFER | SHADERSTAGE_COMP | CMN_ROM,
AccessFlags::COMPUTE_SHADER_READ_UNIFORM_BUFFER},
{IGNORE_MEMUSAGE,
ACCESS_READ | RES_TEXTURE | SHADERSTAGE_COMP | CMN_ROM,
AccessFlags::COMPUTE_SHADER_READ_TEXTURE,
CMN_VB_OR_DS},
// shading rate has its own flag
{CARE_MEMACCESS | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_READ | ACCESS_WRITE | SHADERSTAGE_COMP | CMN_STORAGE,
AccessFlags::COMPUTE_SHADER_READ_OTHER,
CMN_ROM},
{CARE_MEMACCESS | CARE_CMNUSAGE,
ACCESS_READ | CMN_COPY_SRC,
AccessFlags::TRANSFER_READ},
{CARE_MEMACCESS | CARE_MEMUSAGE,
ACCESS_READ | MEM_HOST,
AccessFlags::HOST_READ},
{CARE_MEMACCESS | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_READ | SHADERSTAGE_FRAG | CMN_SHADING_RATE,
AccessFlags::SHADING_RATE},
//{CARE_CMNUSAGE | CARE_RESTYPE,
// RES_TEXTURE | CMN_NONE,
// AccessFlags::PRESENT},
{CARE_MEMACCESS | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_WRITE | SHADERSTAGE_VERT | CMN_STORAGE,
AccessFlags::VERTEX_SHADER_WRITE},
{CARE_MEMACCESS | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_WRITE | SHADERSTAGE_FRAG | CMN_STORAGE,
AccessFlags::FRAGMENT_SHADER_WRITE},
{IGNORE_MEMUSAGE,
ACCESS_WRITE | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_IB_OR_CA,
AccessFlags::COLOR_ATTACHMENT_WRITE},
{IGNORE_NONE,
ACCESS_WRITE | MEM_DEVICE | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_VB_OR_DS,
AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE},
{CARE_MEMACCESS | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_WRITE | SHADERSTAGE_COMP | CMN_STORAGE,
AccessFlags::COMPUTE_SHADER_WRITE},
{CARE_MEMACCESS | CARE_CMNUSAGE,
ACCESS_WRITE | CMN_COPY_DST,
AccessFlags::TRANSFER_WRITE},
{CARE_MEMACCESS | CARE_MEMUSAGE,
ACCESS_WRITE | MEM_HOST,
AccessFlags::HOST_WRITE},
};
constexpr bool validateAccess(ResourceType type, CommonUsage usage, MemoryAccess access, ShaderStageFlags visibility) {
bool res = true;
if (type == ResourceType::BUFFER) {
uint32_t conflicts[] = {
hasFlag(usage, CommonUsage::ROM) && hasFlag(access, MemoryAccess::WRITE_ONLY), // uniform has write access.
hasAnyFlags(usage, CommonUsage::IB_OR_CA | CommonUsage::VB_OR_DS) && !hasFlag(visibility, ShaderStageFlags::VERTEX), // color/ds/input not in fragment
hasAllFlags(usage, CommonUsage::ROM | CommonUsage::STORAGE), // storage ^ sampled
hasFlag(usage, CommonUsage::COPY_SRC) && hasAllFlags(MemoryAccess::READ_ONLY, access), // transfer src ==> read_only
hasFlag(usage, CommonUsage::COPY_DST) && hasAllFlags(MemoryAccess::WRITE_ONLY, access), // transfer dst ==> write_only
hasAllFlags(usage, CommonUsage::COPY_SRC | CommonUsage::COPY_DST), // both src and dst
hasFlag(usage, CommonUsage::VB_OR_DS) && hasAnyFlags(usage, CommonUsage::IB_OR_CA | CommonUsage::INDIRECT_OR_INPUT),
hasFlag(usage, CommonUsage::IB_OR_CA) && hasAnyFlags(usage, CommonUsage::VB_OR_DS | CommonUsage::INDIRECT_OR_INPUT),
hasFlag(usage, CommonUsage::INDIRECT_OR_INPUT) && hasAnyFlags(usage, CommonUsage::IB_OR_CA | CommonUsage::VB_OR_DS),
// exlusive
};
res = !(*std::max_element(std::begin(conflicts), std::end(conflicts)));
} else if (type == ResourceType::TEXTURE) {
uint32_t conflicts[] = {
// hasAnyFlags(usage, CommonUsage::IB_OR_CA | CommonUsage::VB_OR_DS | CommonUsage::INDIRECT_OR_INPUT) && !hasFlag(visibility, ShaderStageFlags::FRAGMENT), // color/ds/input not in fragment
hasFlag(usage, CommonUsage::INDIRECT_OR_INPUT) && !hasFlag(access, MemoryAccess::READ_ONLY), // input needs read
hasAllFlags(usage, CommonUsage::IB_OR_CA | CommonUsage::STORAGE), // storage ^ sampled
hasFlag(usage, CommonUsage::COPY_SRC) && !hasAllFlags(MemoryAccess::READ_ONLY, access), // transfer src ==> read_only
hasFlag(usage, CommonUsage::COPY_DST) && !hasAllFlags(MemoryAccess::WRITE_ONLY, access),
hasFlag(usage, CommonUsage::INDIRECT_OR_INPUT) && !hasAnyFlags(usage, CommonUsage::IB_OR_CA | CommonUsage::VB_OR_DS), // input needs to specify color or ds // transfer dst ==> write_only
hasAllFlags(usage, CommonUsage::COPY_SRC | CommonUsage::COPY_DST), // both src and dst
};
res = !(*std::max_element(std::begin(conflicts), std::end(conflicts)));
}
return res;
}
constexpr AccessFlags getAccessFlagsImpl(
BufferUsage usage, MemoryUsage memUsage,
MemoryAccess access,
ShaderStageFlags visibility) noexcept {
AccessFlags flags{AccessFlags::NONE};
CommonUsage cmnUsage = bufferUsageToCommonUsage(usage);
if (validateAccess(ResourceType::BUFFER, cmnUsage, access, visibility)) {
uint32_t info = 0xFFFFFFFF;
info &= ((OPERABLE(access) << ACCESS_TYPE_BIT_POS) | IGNORE_MEMACCESS);
info &= ((OPERABLE(memUsage) << MEM_TYPE_BIT_POS) | IGNORE_MEMUSAGE);
info &= ((OPERABLE(ResourceType::TEXTURE) << RESOURCE_TYPE_BIT_POS) | IGNORE_RESTYPE);
info &= ((OPERABLE(visibility) << SHADER_STAGE_BIT_POPS) | IGNORE_SHADERSTAGE);
info &= OPERABLE(cmnUsage) | IGNORE_CMNUSAGE;
for (const auto& elem : ACCESS_MAP) {
auto testFlag = info & elem.mask;
// hasKey
if ((testFlag & elem.key) == elem.key) {
flags |= elem.access;
}
}
} else {
flags = INVALID_ACCESS_FLAGS;
}
return flags;
}
constexpr AccessFlags getAccessFlagsImpl(
TextureUsage usage,
MemoryAccess access,
ShaderStageFlags visibility) noexcept {
AccessFlags flags{AccessFlags::NONE};
CommonUsage cmnUsage = textureUsageToCommonUsage(usage);
if (validateAccess(ResourceType::TEXTURE, cmnUsage, access, visibility)) {
if (usage == gfx::TextureUsageBit::NONE) {
return gfx::AccessFlagBit::PRESENT;
}
uint32_t info = 0xFFFFFFFF;
info &= ((OPERABLE(access) << ACCESS_TYPE_BIT_POS) | IGNORE_MEMACCESS);
info &= ((OPERABLE(MemoryUsage::DEVICE) << MEM_TYPE_BIT_POS) | IGNORE_MEMUSAGE);
info &= ((OPERABLE(ResourceType::TEXTURE) << RESOURCE_TYPE_BIT_POS) | IGNORE_RESTYPE);
info &= ((OPERABLE(visibility) << (SHADER_STAGE_BIT_POPS)) | IGNORE_SHADERSTAGE);
info &= OPERABLE(cmnUsage) | IGNORE_CMNUSAGE;
for (const auto& elem : ACCESS_MAP) {
auto testFlag = info & elem.mask;
// hasKey && no mutex flag
if (((testFlag & elem.key) == elem.key) && ((testFlag & elem.mutex) == 0)) {
flags |= elem.access;
}
}
} else {
flags = INVALID_ACCESS_FLAGS;
}
// CC_ASSERT(flags != INVALID_ACCESS_FLAGS);
return flags;
}
} // namespace
AccessFlags getAccessFlags(
BufferUsage usage, MemoryUsage memUsage,
MemoryAccess access,
ShaderStageFlags visibility) noexcept {
return getAccessFlagsImpl(usage, memUsage, access, visibility);
}
AccessFlags getAccessFlags(
TextureUsage usage,
MemoryAccess access,
ShaderStageFlags visibility) noexcept {
return getAccessFlagsImpl(usage, access, visibility);
}
namespace {
constexpr AccessFlags getDeviceAccessFlagsImpl(
TextureUsage usage,
MemoryAccess access,
ShaderStageFlags visibility) {
// Special Present Usage
if (usage == TextureUsage::NONE) {
return AccessFlags::PRESENT;
}
// not read or write access
if (access == MemoryAccess::NONE) {
return INVALID_ACCESS_FLAGS;
}
// input attachment requires color or depth stencil
if (hasAnyFlags(usage, TextureUsage::INPUT_ATTACHMENT) &&
!hasAnyFlags(usage, TextureUsage::COLOR_ATTACHMENT | TextureUsage::DEPTH_STENCIL_ATTACHMENT)) {
return INVALID_ACCESS_FLAGS;
}
const bool bWrite = hasAnyFlags(access, MemoryAccess::WRITE_ONLY);
const bool bRead = hasAnyFlags(access, MemoryAccess::READ_ONLY);
if (bWrite) { // single write
const auto writeMask =
TextureUsage::TRANSFER_DST |
TextureUsage::STORAGE |
TextureUsage::COLOR_ATTACHMENT |
TextureUsage::DEPTH_STENCIL_ATTACHMENT;
const auto usage1 = usage & writeMask;
// see https://stackoverflow.com/questions/51094594/how-to-check-if-exactly-one-bit-is-set-in-an-int
constexpr auto hasOnebit = [](uint32_t bits) -> bool {
return bits && !(bits & (bits - 1));
};
if (!hasOnebit(static_cast<uint32_t>(usage1))) {
return INVALID_ACCESS_FLAGS;
}
const auto readMask =
TextureUsage::SAMPLED |
TextureUsage::TRANSFER_SRC;
if (hasAnyFlags(usage, readMask)) {
return INVALID_ACCESS_FLAGS;
}
}
auto flags = AccessFlags::NONE;
if (hasAnyFlags(usage, TextureUsage::COLOR_ATTACHMENT)) {
if (hasAnyFlags(visibility, ShaderStageFlags::ALL & ~ShaderStageFlags::FRAGMENT)) {
return INVALID_ACCESS_FLAGS;
}
if (bWrite) {
flags |= AccessFlags::COLOR_ATTACHMENT_WRITE;
}
if (bRead) {
flags |= AccessFlags::COLOR_ATTACHMENT_READ;
}
if (hasAnyFlags(usage, TextureUsage::INPUT_ATTACHMENT)) {
if (!bRead) {
return INVALID_ACCESS_FLAGS;
}
flags |= AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT;
}
if (bWrite) {
return flags;
}
} else if (hasAnyFlags(usage, TextureUsage::DEPTH_STENCIL_ATTACHMENT)) {
if (hasAnyFlags(visibility, ShaderStageFlags::ALL & ~ShaderStageFlags::FRAGMENT)) {
return INVALID_ACCESS_FLAGS;
}
if (bWrite) {
flags |= AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE;
}
if (bRead) {
flags |= AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ;
}
if (hasAnyFlags(usage, TextureUsage::INPUT_ATTACHMENT)) {
if (!bRead) {
return INVALID_ACCESS_FLAGS;
}
flags |= AccessFlags::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT;
}
if (bWrite) {
return flags;
}
} else if (bWrite) {
if (hasAnyFlags(usage, TextureUsage::SAMPLED)) {
return INVALID_ACCESS_FLAGS;
}
const bool bUnorderedAccess = hasAnyFlags(usage, TextureUsage::STORAGE);
const bool bCopyTarget = hasAnyFlags(usage, TextureUsage::TRANSFER_DST);
if (!(bUnorderedAccess ^ bCopyTarget)) {
return INVALID_ACCESS_FLAGS;
}
if (bCopyTarget) {
if (bRead || hasAnyFlags(usage, TextureUsage::TRANSFER_SRC)) {
return INVALID_ACCESS_FLAGS; // both copy source and target
}
flags |= AccessFlags::TRANSFER_WRITE;
} else {
if (hasAnyFlags(visibility, ShaderStageFlags::VERTEX)) {
flags |= AccessFlags::VERTEX_SHADER_WRITE;
if (bRead) {
flags |= AccessFlags::VERTEX_SHADER_READ_TEXTURE;
}
} else if (hasAnyFlags(visibility, ShaderStageFlags::FRAGMENT)) {
flags |= AccessFlags::FRAGMENT_SHADER_WRITE;
if (bRead) {
flags |= AccessFlags::FRAGMENT_SHADER_READ_TEXTURE;
}
} else if (hasAnyFlags(visibility, ShaderStageFlags::COMPUTE)) {
flags |= AccessFlags::COMPUTE_SHADER_WRITE;
if (bRead) {
flags |= AccessFlags::COMPUTE_SHADER_READ_TEXTURE;
}
}
}
return flags;
}
if (bWrite) {
return INVALID_ACCESS_FLAGS;
}
// ReadOnly
if (hasAnyFlags(usage, TextureUsage::TRANSFER_SRC)) {
flags |= AccessFlags::TRANSFER_READ;
}
if (hasAnyFlags(usage, TextureUsage::SAMPLED | TextureUsage::STORAGE)) {
if (hasAnyFlags(visibility, ShaderStageFlags::VERTEX)) {
flags |= AccessFlags::VERTEX_SHADER_READ_TEXTURE;
}
if (hasAnyFlags(visibility, ShaderStageFlags::FRAGMENT)) {
flags |= AccessFlags::FRAGMENT_SHADER_READ_TEXTURE;
}
if (hasAnyFlags(visibility, ShaderStageFlags::COMPUTE)) {
flags |= AccessFlags::COMPUTE_SHADER_READ_TEXTURE;
}
}
return flags;
}
static_assert(
(AccessFlags::VERTEX_SHADER_WRITE | AccessFlags::VERTEX_SHADER_READ_OTHER) ==
getAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::READ_WRITE,
ShaderStageFlags::VERTEX));
static_assert(
(AccessFlags::FRAGMENT_SHADER_WRITE | AccessFlags::FRAGMENT_SHADER_READ_OTHER) ==
getAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::READ_WRITE,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COMPUTE_SHADER_WRITE | AccessFlags::COMPUTE_SHADER_READ_OTHER) ==
getAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::READ_WRITE,
ShaderStageFlags::COMPUTE));
static_assert(
INVALID_ACCESS_FLAGS ==
getAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT | TextureUsage::STORAGE,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
INVALID_ACCESS_FLAGS ==
getAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT | TextureUsage::SAMPLED | TextureUsage::STORAGE,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::TRANSFER_WRITE | AccessFlags::COLOR_ATTACHMENT_WRITE) ==
getAccessFlagsImpl(
TextureUsage::TRANSFER_DST | TextureUsage::COLOR_ATTACHMENT,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::ALL));
////////////////////////////////////
// VERTEX_SHADER_WRITE
static_assert(
AccessFlags::VERTEX_SHADER_WRITE ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::VERTEX));
static_assert(
(AccessFlags::VERTEX_SHADER_WRITE | AccessFlags::VERTEX_SHADER_READ_TEXTURE) ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::READ_WRITE,
ShaderStageFlags::VERTEX));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE | TextureUsage::SAMPLED, // both storage write and sampling
MemoryAccess::READ_WRITE,
ShaderStageFlags::VERTEX));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::SAMPLED, // Sampled cannot be write
MemoryAccess::READ_WRITE,
ShaderStageFlags::VERTEX));
// FRAGMENT_SHADER_WRITE
static_assert(
AccessFlags::FRAGMENT_SHADER_WRITE ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::FRAGMENT_SHADER_WRITE | AccessFlags::FRAGMENT_SHADER_READ_TEXTURE) ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::READ_WRITE,
ShaderStageFlags::FRAGMENT));
// COLOR_ATTACHMENT_WRITE
static_assert(
AccessFlags::COLOR_ATTACHMENT_WRITE ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::VERTEX)); // not fragment stage
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::SAMPLED, // both color attachment and sampled texture
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COLOR_ATTACHMENT_WRITE | AccessFlags::COLOR_ATTACHMENT_READ) ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT,
MemoryAccess::READ_WRITE,
ShaderStageFlags::FRAGMENT));
static_assert(
AccessFlags::COLOR_ATTACHMENT_READ ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COLOR_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT) ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COLOR_ATTACHMENT_WRITE | AccessFlags::COLOR_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT) ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT,
MemoryAccess::READ_WRITE,
ShaderStageFlags::FRAGMENT));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT,
MemoryAccess::WRITE_ONLY, // INPUT_ATTACHMENT needs read access
ShaderStageFlags::FRAGMENT));
// DEPTH_STENCIL_ATTACHMENT_WRITE
static_assert(
AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::VERTEX)); // not fragment stage
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT | TextureUsage::SAMPLED, // both color attachment and sampled texture
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE | AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ) ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT,
MemoryAccess::READ_WRITE,
ShaderStageFlags::FRAGMENT));
static_assert(
AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT) ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE | AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT) ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT,
MemoryAccess::READ_WRITE,
ShaderStageFlags::FRAGMENT));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::DEPTH_STENCIL_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT,
MemoryAccess::WRITE_ONLY, // INPUT_ATTACHMENT needs read access
ShaderStageFlags::FRAGMENT));
// COMPUTE_SHADER_WRITE
static_assert(
AccessFlags::COMPUTE_SHADER_WRITE ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::COMPUTE));
static_assert(
(AccessFlags::COMPUTE_SHADER_WRITE | AccessFlags::COMPUTE_SHADER_READ_TEXTURE) ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE,
MemoryAccess::READ_WRITE,
ShaderStageFlags::COMPUTE));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE | TextureUsage::SAMPLED, // cannot be sampled
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::COMPUTE));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::STORAGE | TextureUsage::SAMPLED, // cannot be sampled
MemoryAccess::READ_WRITE,
ShaderStageFlags::COMPUTE));
// TRANSFER_WRITE
static_assert(
AccessFlags::TRANSFER_WRITE ==
getDeviceAccessFlagsImpl(
TextureUsage::TRANSFER_DST,
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::ALL)); // ShaderStageFlags not used
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::TRANSFER_DST,
MemoryAccess::READ_WRITE,
ShaderStageFlags::ALL)); // ShaderStageFlags not used
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::TRANSFER_DST | TextureUsage::TRANSFER_SRC, // both source and target
MemoryAccess::READ_WRITE, // both read and write
ShaderStageFlags::ALL));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::TRANSFER_DST | TextureUsage::TRANSFER_SRC, // both source and target
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::ALL));
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::TRANSFER_DST | TextureUsage::COLOR_ATTACHMENT, // cannot be sampled
MemoryAccess::WRITE_ONLY,
ShaderStageFlags::ALL));
// Read
// COLOR_ATTACHMENT_READ
static_assert(
INVALID_ACCESS_FLAGS ==
getDeviceAccessFlagsImpl(
TextureUsage::INPUT_ATTACHMENT, // INPUT_ATTACHMENT needs COLOR_ATTACHMENT or DEPTH_STENCIL_ATTACHMENT
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COLOR_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | AccessFlags::FRAGMENT_SHADER_READ_TEXTURE) ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT | TextureUsage::SAMPLED,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COLOR_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | AccessFlags::FRAGMENT_SHADER_READ_TEXTURE) ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT | TextureUsage::STORAGE,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COLOR_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | AccessFlags::FRAGMENT_SHADER_READ_TEXTURE) ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT | TextureUsage::SAMPLED | TextureUsage::STORAGE,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
static_assert(
(AccessFlags::COLOR_ATTACHMENT_READ | AccessFlags::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | AccessFlags::TRANSFER_READ) ==
getDeviceAccessFlagsImpl(
TextureUsage::COLOR_ATTACHMENT | TextureUsage::INPUT_ATTACHMENT | TextureUsage::TRANSFER_SRC,
MemoryAccess::READ_ONLY,
ShaderStageFlags::FRAGMENT));
} // namespace
AccessFlags getDeviceAccessFlags(
TextureUsage usage,
MemoryAccess access,
ShaderStageFlags visibility) {
return getDeviceAccessFlagsImpl(usage, access, visibility);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,51 @@
/****************************************************************************
Copyright (c) 2022-2023 Xiamen Yaji Software Co., Ltd.
https://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 "GFXDef-common.h"
namespace cc {
namespace gfx {
AccessFlags getAccessFlags(
BufferUsage usage, MemoryUsage memUsage,
MemoryAccess access,
ShaderStageFlags visibility) noexcept;
AccessFlags getAccessFlags(
TextureUsage usage,
MemoryAccess access,
ShaderStageFlags visibility) noexcept;
constexpr AccessFlags INVALID_ACCESS_FLAGS = static_cast<AccessFlags>(0xFFFFFFFF);
AccessFlags getDeviceAccessFlags(
TextureUsage usage,
MemoryAccess access,
ShaderStageFlags visibility);
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,106 @@
/****************************************************************************
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 "GFXBuffer.h"
#include "GFXDevice.h"
namespace cc {
namespace gfx {
Buffer::Buffer()
: GFXObject(ObjectType::BUFFER) {
}
Buffer::~Buffer() = default;
ccstd::hash_t Buffer::computeHash(const BufferInfo &info) {
return Hasher<BufferInfo>()(info);
}
void Buffer::initialize(const BufferInfo &info) {
_usage = info.usage;
_memUsage = info.memUsage;
_size = info.size;
_flags = info.flags;
_stride = std::max(info.stride, 1U);
_count = _size / _stride;
doInit(info);
if (hasFlag(info.flags, BufferFlagBit::ENABLE_STAGING_WRITE) && getStagingAddress() == nullptr) {
_data = std::make_unique<uint8_t[]>(_size);
}
}
void Buffer::initialize(const BufferViewInfo &info) {
_usage = info.buffer->getUsage();
_memUsage = info.buffer->getMemUsage();
_flags = info.buffer->getFlags();
_offset = info.offset;
_size = _stride = info.range;
_count = 1U;
_isBufferView = true;
doInit(info);
}
void Buffer::destroy() {
doDestroy();
_offset = _size = _stride = _count = 0U;
}
void Buffer::resize(uint32_t size) {
if (size != _size) {
uint32_t count = size / _stride;
doResize(size, count);
_size = size;
_count = count;
}
}
void Buffer::write(const uint8_t *value, uint32_t offset, uint32_t size) const {
CC_ASSERT(hasFlag(_flags, BufferFlagBit::ENABLE_STAGING_WRITE));
uint8_t *dst = getStagingAddress();
if (dst == nullptr || offset + size > _size) {
return;
}
memcpy(dst + offset, value, size);
}
void Buffer::update() {
flush(getStagingAddress());
}
uint8_t *Buffer::getBufferStagingAddress(Buffer *buffer) {
return buffer->getStagingAddress();
}
void Buffer::flushBuffer(Buffer *buffer, const uint8_t *data) {
buffer->flush(data);
}
} // namespace gfx
} // namespace cc

View 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.
****************************************************************************/
#pragma once
#include "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL Buffer : public GFXObject, public RefCounted {
public:
Buffer();
~Buffer() override;
static ccstd::hash_t computeHash(const BufferInfo &info);
void initialize(const BufferInfo &info);
void initialize(const BufferViewInfo &info);
void resize(uint32_t size);
void destroy();
template <typename T>
void write(const T &value, uint32_t offset) const {
write(reinterpret_cast<const uint8_t *>(&value), offset, sizeof(T));
}
void write(const uint8_t *value, uint32_t offset, uint32_t size) const;
virtual void update(const void *buffer, uint32_t size) = 0;
inline void update(const void *buffer) { update(buffer, _size); }
void update();
inline BufferUsage getUsage() const { return _usage; }
inline MemoryUsage getMemUsage() const { return _memUsage; }
inline uint32_t getStride() const { return _stride; }
inline uint32_t getCount() const { return _count; }
inline uint32_t getSize() const { return _size; }
inline BufferFlags getFlags() const { return _flags; }
inline bool isBufferView() const { return _isBufferView; }
protected:
virtual void doInit(const BufferInfo &info) = 0;
virtual void doInit(const BufferViewInfo &info) = 0;
virtual void doResize(uint32_t size, uint32_t count) = 0;
virtual void doDestroy() = 0;
static uint8_t *getBufferStagingAddress(Buffer *buffer);
static void flushBuffer(Buffer *buffer, const uint8_t *data);
virtual void flush(const uint8_t *data) { update(reinterpret_cast<const void *>(data), _size); }
virtual uint8_t *getStagingAddress() const { return _data.get(); }
BufferUsage _usage = BufferUsageBit::NONE;
MemoryUsage _memUsage = MemoryUsageBit::NONE;
uint32_t _stride = 0U;
uint32_t _count = 0U;
uint32_t _size = 0U;
uint32_t _offset = 0U;
BufferFlags _flags = BufferFlagBit::NONE;
bool _isBufferView = false;
uint8_t _rsv[3] = {0};
std::unique_ptr<uint8_t[]> _data;
};
} // namespace gfx
} // namespace cc

View 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.
****************************************************************************/
#include "GFXCommandBuffer.h"
#include "GFXObject.h"
namespace cc {
namespace gfx {
CommandBuffer::CommandBuffer()
: GFXObject(ObjectType::COMMAND_BUFFER) {
}
CommandBuffer::~CommandBuffer() = default;
void CommandBuffer::initialize(const CommandBufferInfo &info) {
_type = info.type;
_queue = info.queue;
doInit(info);
}
void CommandBuffer::destroy() {
doDestroy();
_type = CommandBufferType::PRIMARY;
_queue = nullptr;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,194 @@
/****************************************************************************
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 "GFXBuffer.h"
#include "GFXInputAssembler.h"
#include "GFXObject.h"
#include "base/RefCounted.h"
#include "base/Utils.h"
#include "base/std/container/vector.h"
namespace cc {
namespace gfx {
class CC_DLL CommandBuffer : public GFXObject, public RefCounted {
public:
CommandBuffer();
~CommandBuffer() override;
void initialize(const CommandBufferInfo &info);
void destroy();
virtual void begin(RenderPass *renderPass, uint32_t subpass, Framebuffer *frameBuffer) = 0;
virtual void end() = 0;
virtual void beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil, CommandBuffer *const *secondaryCBs, uint32_t secondaryCBCount) = 0;
virtual void endRenderPass() = 0;
virtual void insertMarker(const MarkerInfo &marker) = 0;
virtual void beginMarker(const MarkerInfo &marker) = 0;
virtual void endMarker() = 0;
virtual void bindPipelineState(PipelineState *pso) = 0;
virtual void bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet, uint32_t dynamicOffsetCount, const uint32_t *dynamicOffsets) = 0;
virtual void bindInputAssembler(InputAssembler *ia) = 0;
virtual void setViewport(const Viewport &vp) = 0;
virtual void setScissor(const Rect &rect) = 0;
virtual void setLineWidth(float width) = 0;
virtual void setDepthBias(float constant, float clamp, float slope) = 0;
virtual void setBlendConstants(const Color &constants) = 0;
virtual void setDepthBound(float minBounds, float maxBounds) = 0;
virtual void setStencilWriteMask(StencilFace face, uint32_t mask) = 0;
virtual void setStencilCompareMask(StencilFace face, uint32_t ref, uint32_t mask) = 0;
virtual void nextSubpass() = 0;
virtual void draw(const DrawInfo &info) = 0;
virtual void updateBuffer(Buffer *buff, const void *data, uint32_t size) = 0;
virtual void copyBuffersToTexture(const uint8_t *const *buffers, Texture *texture, const BufferTextureCopy *regions, uint32_t count) = 0;
virtual void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlit *regions, uint32_t count, Filter filter) = 0;
virtual void copyTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) = 0;
virtual void resolveTexture(Texture *srcTexture, Texture *dstTexture, const TextureCopy *regions, uint32_t count) = 0;
virtual void execute(CommandBuffer *const *cmdBuffs, uint32_t count) = 0;
virtual void dispatch(const DispatchInfo &info) = 0;
virtual void beginQuery(QueryPool *queryPool, uint32_t id) = 0;
virtual void endQuery(QueryPool *queryPool, uint32_t id) = 0;
virtual void resetQueryPool(QueryPool *queryPool) = 0;
virtual void completeQueryPool(QueryPool *queryPool) {}
using CustomCommand = std::function<void(void *)>;
virtual void customCommand(CustomCommand &&cmd) {}
// barrier: excutionBarrier
// bufferBarriers: array of BufferBarrier*, descriptions of access of buffers
// buffers: array of MTL/VK/GLES buffers
// bufferBarrierCount: number of barrier, should be equal to number of buffers
// textureBarriers: array of TextureBarrier*, descriptions of access of textures
// textures: array of MTL/VK/GLES textures
// textureBarrierCount: number of barrier, should be equal to number of textures
virtual void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrier *const *bufferBarriers, const Buffer *const *buffers, uint32_t bufferBarrierCount, const TextureBarrier *const *textureBarriers, const Texture *const *textures, uint32_t textureBarrierCount) = 0;
inline void begin();
inline void begin(RenderPass *renderPass);
inline void begin(RenderPass *renderPass, uint32_t subpass);
inline void updateBuffer(Buffer *buff, const void *data);
inline void execute(const CommandBufferList &cmdBuffs, uint32_t count);
inline void bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet);
inline void bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet, const ccstd::vector<uint32_t> &dynamicOffsets);
inline void beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const ColorList &colors, float depth, uint32_t stencil, const CommandBufferList &secondaryCBs);
inline void beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const ColorList &colors, float depth, uint32_t stencil);
inline void beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil);
inline void draw(InputAssembler *ia);
inline void copyBuffersToTexture(const BufferDataList &buffers, Texture *texture, const BufferTextureCopyList &regions);
inline void blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlitList &regions, Filter filter);
inline void pipelineBarrier(const GeneralBarrier *barrier);
inline void pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrierList &bufferBarriers, const BufferList &buffers, const TextureBarrierList &textureBarriers, const TextureList &textures);
inline Queue *getQueue() const { return _queue; }
inline CommandBufferType getType() const { return _type; }
virtual uint32_t getNumDrawCalls() const { return _numDrawCalls; }
virtual uint32_t getNumInstances() const { return _numInstances; }
virtual uint32_t getNumTris() const { return _numTriangles; }
protected:
virtual void doInit(const CommandBufferInfo &info) = 0;
virtual void doDestroy() = 0;
Queue *_queue = nullptr;
CommandBufferType _type = CommandBufferType::PRIMARY;
uint32_t _numDrawCalls = 0;
uint32_t _numInstances = 0;
uint32_t _numTriangles = 0;
};
//////////////////////////////////////////////////////////////////////////
void CommandBuffer::begin() {
begin(nullptr, 0, nullptr);
}
void CommandBuffer::begin(RenderPass *renderPass) {
begin(renderPass, 0, nullptr);
}
void CommandBuffer::begin(RenderPass *renderPass, uint32_t subpass) {
begin(renderPass, subpass, nullptr);
}
void CommandBuffer::updateBuffer(Buffer *buff, const void *data) {
updateBuffer(buff, data, buff->getSize());
}
void CommandBuffer::execute(const CommandBufferList &cmdBuffs, uint32_t count) {
execute(cmdBuffs.data(), count);
}
void CommandBuffer::bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet) {
bindDescriptorSet(set, descriptorSet, 0, nullptr);
}
void CommandBuffer::bindDescriptorSet(uint32_t set, DescriptorSet *descriptorSet, const ccstd::vector<uint32_t> &dynamicOffsets) {
bindDescriptorSet(set, descriptorSet, utils::toUint(dynamicOffsets.size()), dynamicOffsets.data());
}
void CommandBuffer::beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const ColorList &colors, float depth, uint32_t stencil, const CommandBufferList &secondaryCBs) {
beginRenderPass(renderPass, fbo, renderArea, colors.data(), depth, stencil, secondaryCBs.data(), utils::toUint(secondaryCBs.size()));
}
void CommandBuffer::beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const ColorList &colors, float depth, uint32_t stencil) {
beginRenderPass(renderPass, fbo, renderArea, colors.data(), depth, stencil, nullptr, 0);
}
void CommandBuffer::beginRenderPass(RenderPass *renderPass, Framebuffer *fbo, const Rect &renderArea, const Color *colors, float depth, uint32_t stencil) {
beginRenderPass(renderPass, fbo, renderArea, colors, depth, stencil, nullptr, 0);
}
void CommandBuffer::draw(InputAssembler *ia) {
draw(ia->getDrawInfo());
}
void CommandBuffer::copyBuffersToTexture(const BufferDataList &buffers, Texture *texture, const BufferTextureCopyList &regions) {
copyBuffersToTexture(buffers.data(), texture, regions.data(), utils::toUint(regions.size()));
}
void CommandBuffer::blitTexture(Texture *srcTexture, Texture *dstTexture, const TextureBlitList &regions, Filter filter) {
blitTexture(srcTexture, dstTexture, regions.data(), utils::toUint(regions.size()), filter);
}
void CommandBuffer::pipelineBarrier(const GeneralBarrier *barrier) {
pipelineBarrier(barrier, nullptr, nullptr, 0, nullptr, nullptr, 0U);
}
void CommandBuffer::pipelineBarrier(const GeneralBarrier *barrier, const BufferBarrierList &bufferBarriers, const BufferList &buffers, const TextureBarrierList &textureBarriers, const TextureList &textures) {
pipelineBarrier(barrier, bufferBarriers.data(), buffers.data(), utils::toUint(bufferBarriers.size()), textureBarriers.data(), textures.data(), utils::toUint(textureBarriers.size()));
}
} // namespace gfx
} // namespace cc

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,664 @@
/****************************************************************************
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 "base/Utils.h"
#include "base/std/container/array.h"
#include "base/std/hash/hash.h"
#include "GFXDef.h"
#include "GFXRenderPass.h"
#include "GFXTexture.h"
namespace cc {
namespace gfx {
// T must have no implicit padding
template <typename T>
ccstd::hash_t quickHashTrivialStruct(const T *info, size_t count = 1) {
static_assert(std::is_trivially_copyable<T>::value && sizeof(T) % 8 == 0, "T must be 8 bytes aligned and trivially copyable");
return ccstd::hash_range(reinterpret_cast<const uint64_t *>(info), reinterpret_cast<const uint64_t *>(info + count));
}
template <>
ccstd::hash_t Hasher<ColorAttachment>::operator()(const ColorAttachment &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const ColorAttachment &lhs, const ColorAttachment &rhs) {
return !memcmp(&lhs, &rhs, sizeof(ColorAttachment));
}
template <>
ccstd::hash_t Hasher<DepthStencilAttachment>::operator()(const DepthStencilAttachment &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const DepthStencilAttachment &lhs, const DepthStencilAttachment &rhs) {
return !memcmp(&lhs, &rhs, sizeof(DepthStencilAttachment));
}
template <>
ccstd::hash_t Hasher<SubpassDependency>::operator()(const SubpassDependency &info) const {
ccstd::hash_t seed = 8;
ccstd::hash_combine(seed, info.dstSubpass);
ccstd::hash_combine(seed, info.srcSubpass);
ccstd::hash_combine(seed, info.generalBarrier);
ccstd::hash_combine(seed, info.prevAccesses);
ccstd::hash_combine(seed, info.nextAccesses);
return seed;
}
bool operator==(const SubpassDependency &lhs, const SubpassDependency &rhs) {
return lhs.srcSubpass == rhs.srcSubpass &&
lhs.dstSubpass == rhs.dstSubpass &&
lhs.generalBarrier == rhs.generalBarrier &&
lhs.prevAccesses == rhs.prevAccesses &&
lhs.nextAccesses == rhs.nextAccesses;
}
template <>
ccstd::hash_t Hasher<SubpassInfo>::operator()(const SubpassInfo &info) const {
ccstd::hash_t seed = 8;
ccstd::hash_combine(seed, info.inputs);
ccstd::hash_combine(seed, info.colors);
ccstd::hash_combine(seed, info.resolves);
ccstd::hash_combine(seed, info.preserves);
ccstd::hash_combine(seed, info.depthStencil);
ccstd::hash_combine(seed, info.depthStencilResolve);
ccstd::hash_combine(seed, info.depthResolveMode);
ccstd::hash_combine(seed, info.stencilResolveMode);
return seed;
}
bool operator==(const SubpassInfo &lhs, const SubpassInfo &rhs) {
return lhs.inputs == rhs.inputs &&
lhs.colors == rhs.colors &&
lhs.resolves == rhs.resolves &&
lhs.preserves == rhs.preserves &&
lhs.depthStencil == rhs.depthStencil &&
lhs.depthStencilResolve == rhs.depthStencilResolve &&
lhs.depthResolveMode == rhs.depthResolveMode &&
lhs.stencilResolveMode == rhs.stencilResolveMode;
}
template <>
ccstd::hash_t Hasher<RenderPassInfo>::operator()(const RenderPassInfo &info) const {
ccstd::hash_t seed = 4;
ccstd::hash_combine(seed, info.colorAttachments);
ccstd::hash_combine(seed, info.depthStencilAttachment);
ccstd::hash_combine(seed, info.depthStencilResolveAttachment);
ccstd::hash_combine(seed, info.subpasses);
ccstd::hash_combine(seed, info.dependencies);
return seed;
}
bool operator==(const RenderPassInfo &lhs, const RenderPassInfo &rhs) {
return lhs.colorAttachments == rhs.colorAttachments &&
lhs.depthStencilAttachment == rhs.depthStencilAttachment &&
lhs.depthStencilResolveAttachment == rhs.depthStencilResolveAttachment &&
lhs.subpasses == rhs.subpasses &&
lhs.dependencies == rhs.dependencies;
}
template <>
ccstd::hash_t Hasher<FramebufferInfo>::operator()(const FramebufferInfo &info) const {
// render pass is mostly irrelevant
ccstd::hash_t seed = static_cast<ccstd::hash_t>(info.colorTextures.size()) +
static_cast<ccstd::hash_t>(info.depthStencilTexture != nullptr) +
static_cast<ccstd::hash_t>(info.depthStencilResolveTexture != nullptr);
if (info.depthStencilTexture) {
ccstd::hash_combine(seed, info.depthStencilTexture->getObjectID());
ccstd::hash_combine(seed, info.depthStencilTexture->getHash());
}
if (info.depthStencilResolveTexture) {
ccstd::hash_combine(seed, info.depthStencilResolveTexture->getObjectID());
ccstd::hash_combine(seed, info.depthStencilResolveTexture->getHash());
}
for (auto *colorTexture : info.colorTextures) {
ccstd::hash_combine(seed, colorTexture->getObjectID());
ccstd::hash_combine(seed, colorTexture->getHash());
}
ccstd::hash_combine(seed, info.renderPass->getHash());
return seed;
}
bool operator==(const FramebufferInfo &lhs, const FramebufferInfo &rhs) {
// render pass is mostly irrelevant
bool res = false;
res = lhs.colorTextures == rhs.colorTextures;
if (res) {
res = lhs.depthStencilTexture == rhs.depthStencilTexture;
}
if (res) {
res = lhs.depthStencilResolveTexture == rhs.depthStencilResolveTexture;
}
if (res) {
for (size_t i = 0; i < lhs.colorTextures.size(); ++i) {
res = lhs.colorTextures[i]->getRaw() == rhs.colorTextures[i]->getRaw() &&
lhs.colorTextures[i]->getHash() == rhs.colorTextures[i]->getHash();
if (!res) {
break;
}
}
res = lhs.renderPass->getHash() == rhs.renderPass->getHash();
if (res) {
res = lhs.depthStencilTexture->getRaw() == rhs.depthStencilTexture->getRaw() &&
lhs.depthStencilTexture->getHash() == rhs.depthStencilTexture->getHash();
}
}
return res;
}
template <>
ccstd::hash_t Hasher<TextureInfo>::operator()(const TextureInfo &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const TextureInfo &lhs, const TextureInfo &rhs) {
return !memcmp(&lhs, &rhs, sizeof(TextureInfo));
}
template <>
ccstd::hash_t Hasher<TextureViewInfo>::operator()(const TextureViewInfo &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const TextureViewInfo &lhs, const TextureViewInfo &rhs) {
return !memcmp(&lhs, &rhs, sizeof(TextureViewInfo));
}
template <>
ccstd::hash_t Hasher<BufferInfo>::operator()(const BufferInfo &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const BufferInfo &lhs, const BufferInfo &rhs) {
return !memcmp(&lhs, &rhs, sizeof(BufferInfo));
}
template <>
ccstd::hash_t Hasher<SamplerInfo>::operator()(const SamplerInfo &info) const {
// return quickHashTrivialStruct(&info);
// the hash may be used to reconstruct the original struct
auto hash = static_cast<uint32_t>(info.minFilter);
hash |= static_cast<uint32_t>(info.magFilter) << 2;
hash |= static_cast<uint32_t>(info.mipFilter) << 4;
hash |= static_cast<uint32_t>(info.addressU) << 6;
hash |= static_cast<uint32_t>(info.addressV) << 8;
hash |= static_cast<uint32_t>(info.addressW) << 10;
hash |= static_cast<uint32_t>(info.maxAnisotropy) << 12;
hash |= static_cast<uint32_t>(info.cmpFunc) << 16;
return static_cast<ccstd::hash_t>(hash);
}
bool operator==(const SamplerInfo &lhs, const SamplerInfo &rhs) {
return !memcmp(&lhs, &rhs, sizeof(SamplerInfo));
}
template <>
ccstd::hash_t Hasher<GeneralBarrierInfo>::operator()(const GeneralBarrierInfo &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const GeneralBarrierInfo &lhs, const GeneralBarrierInfo &rhs) {
return !memcmp(&lhs, &rhs, sizeof(GeneralBarrierInfo));
}
template <>
ccstd::hash_t Hasher<TextureBarrierInfo>::operator()(const TextureBarrierInfo &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const TextureBarrierInfo &lhs, const TextureBarrierInfo &rhs) {
return !memcmp(&lhs, &rhs, sizeof(TextureBarrierInfo));
}
template <>
ccstd::hash_t Hasher<BufferBarrierInfo>::operator()(const BufferBarrierInfo &info) const {
return quickHashTrivialStruct(&info);
}
bool operator==(const BufferBarrierInfo &lhs, const BufferBarrierInfo &rhs) {
return !memcmp(&lhs, &rhs, sizeof(BufferBarrierInfo));
}
///////////////////////////////////////////////////////////////////////////////
bool operator==(const Viewport &lhs, const Viewport &rhs) {
return !memcmp(&lhs, &rhs, sizeof(Viewport));
}
bool operator==(const Rect &lhs, const Rect &rhs) {
return !memcmp(&lhs, &rhs, sizeof(Rect));
}
bool operator==(const Color &lhs, const Color &rhs) {
return !memcmp(&lhs, &rhs, sizeof(Color));
}
bool operator==(const Offset &lhs, const Offset &rhs) {
return !memcmp(&lhs, &rhs, sizeof(Offset));
}
bool operator==(const Extent &lhs, const Extent &rhs) {
return !memcmp(&lhs, &rhs, sizeof(Extent));
}
bool operator==(const Size &lhs, const Size &rhs) {
return !memcmp(&lhs, &rhs, sizeof(Size));
}
const FormatInfo GFX_FORMAT_INFOS[] = {
{"UNKNOWN", 0, 0, FormatType::NONE, false, false, false, false},
{"A8", 1, 1, FormatType::UNORM, true, false, false, false},
{"L8", 1, 1, FormatType::UNORM, false, false, false, false},
{"LA8", 1, 2, FormatType::UNORM, false, false, false, false},
{"R8", 1, 1, FormatType::UNORM, false, false, false, false},
{"R8SN", 1, 1, FormatType::SNORM, false, false, false, false},
{"R8UI", 1, 1, FormatType::UINT, false, false, false, false},
{"R8I", 1, 1, FormatType::INT, false, false, false, false},
{"R16F", 2, 1, FormatType::FLOAT, false, false, false, false},
{"R16UI", 2, 1, FormatType::UINT, false, false, false, false},
{"R16I", 2, 1, FormatType::INT, false, false, false, false},
{"R32F", 4, 1, FormatType::FLOAT, false, false, false, false},
{"R32UI", 4, 1, FormatType::UINT, false, false, false, false},
{"R32I", 4, 1, FormatType::INT, false, false, false, false},
{"RG8", 2, 2, FormatType::UNORM, false, false, false, false},
{"RG8SN", 2, 2, FormatType::SNORM, false, false, false, false},
{"RG8UI", 2, 2, FormatType::UINT, false, false, false, false},
{"RG8I", 2, 2, FormatType::INT, false, false, false, false},
{"RG16F", 4, 2, FormatType::FLOAT, false, false, false, false},
{"RG16UI", 4, 2, FormatType::UINT, false, false, false, false},
{"RG16I", 4, 2, FormatType::INT, false, false, false, false},
{"RG32F", 8, 2, FormatType::FLOAT, false, false, false, false},
{"RG32UI", 8, 2, FormatType::UINT, false, false, false, false},
{"RG32I", 8, 2, FormatType::INT, false, false, false, false},
{"RGB8", 3, 3, FormatType::UNORM, false, false, false, false},
{"SRGB8", 3, 3, FormatType::UNORM, false, false, false, false},
{"RGB8SN", 3, 3, FormatType::SNORM, false, false, false, false},
{"RGB8UI", 3, 3, FormatType::UINT, false, false, false, false},
{"RGB8I", 3, 3, FormatType::INT, false, false, false, false},
{"RGB16F", 6, 3, FormatType::FLOAT, false, false, false, false},
{"RGB16UI", 6, 3, FormatType::UINT, false, false, false, false},
{"RGB16I", 6, 3, FormatType::INT, false, false, false, false},
{"RGB32F", 12, 3, FormatType::FLOAT, false, false, false, false},
{"RGB32UI", 12, 3, FormatType::UINT, false, false, false, false},
{"RGB32I", 12, 3, FormatType::INT, false, false, false, false},
{"RGBA8", 4, 4, FormatType::UNORM, true, false, false, false},
{"BGRA8", 4, 4, FormatType::UNORM, true, false, false, false},
{"SRGB8_A8", 4, 4, FormatType::UNORM, true, false, false, false},
{"RGBA8SN", 4, 4, FormatType::SNORM, true, false, false, false},
{"RGBA8UI", 4, 4, FormatType::UINT, true, false, false, false},
{"RGBA8I", 4, 4, FormatType::INT, true, false, false, false},
{"RGBA16F", 8, 4, FormatType::FLOAT, true, false, false, false},
{"RGBA16UI", 8, 4, FormatType::UINT, true, false, false, false},
{"RGBA16I", 8, 4, FormatType::INT, true, false, false, false},
{"RGBA32F", 16, 4, FormatType::FLOAT, true, false, false, false},
{"RGBA32UI", 16, 4, FormatType::UINT, true, false, false, false},
{"RGBA32I", 16, 4, FormatType::INT, true, false, false, false},
{"R5G6B5", 2, 3, FormatType::UNORM, false, false, false, false},
{"R11G11B10F", 4, 3, FormatType::FLOAT, false, false, false, false},
{"RGB5A1", 2, 4, FormatType::UNORM, true, false, false, false},
{"RGBA4", 2, 4, FormatType::UNORM, true, false, false, false},
{"RGB10A2", 2, 4, FormatType::UNORM, true, false, false, false},
{"RGB10A2UI", 2, 4, FormatType::UINT, true, false, false, false},
{"RGB9E5", 2, 4, FormatType::FLOAT, true, false, false, false},
{"DEPTH", 4, 1, FormatType::FLOAT, false, true, false, false},
{"DEPTH_STENCIL", 5, 2, FormatType::FLOAT, false, true, true, false},
{"BC1", 1, 3, FormatType::UNORM, false, false, false, true},
{"BC1_ALPHA", 1, 4, FormatType::UNORM, true, false, false, true},
{"BC1_SRGB", 1, 3, FormatType::UNORM, false, false, false, true},
{"BC1_SRGB_ALPHA", 1, 4, FormatType::UNORM, true, false, false, true},
{"BC2", 1, 4, FormatType::UNORM, true, false, false, true},
{"BC2_SRGB", 1, 4, FormatType::UNORM, true, false, false, true},
{"BC3", 1, 4, FormatType::UNORM, true, false, false, true},
{"BC3_SRGB", 1, 4, FormatType::UNORM, true, false, false, true},
{"BC4", 1, 1, FormatType::UNORM, false, false, false, true},
{"BC4_SNORM", 1, 1, FormatType::SNORM, false, false, false, true},
{"BC5", 1, 2, FormatType::UNORM, false, false, false, true},
{"BC5_SNORM", 1, 2, FormatType::SNORM, false, false, false, true},
{"BC6H_UF16", 1, 3, FormatType::UFLOAT, false, false, false, true},
{"BC6H_SF16", 1, 3, FormatType::FLOAT, false, false, false, true},
{"BC7", 1, 4, FormatType::UNORM, true, false, false, true},
{"BC7_SRGB", 1, 4, FormatType::UNORM, true, false, false, true},
{"ETC_RGB8", 1, 3, FormatType::UNORM, false, false, false, true},
{"ETC2_RGB8", 1, 3, FormatType::UNORM, false, false, false, true},
{"ETC2_SRGB8", 1, 3, FormatType::UNORM, false, false, false, true},
{"ETC2_RGB8_A1", 1, 4, FormatType::UNORM, true, false, false, true},
{"ETC2_SRGB8_A1", 1, 4, FormatType::UNORM, true, false, false, true},
{"EAC_R11", 1, 1, FormatType::UNORM, false, false, false, true},
{"EAC_R11SN", 1, 1, FormatType::SNORM, false, false, false, true},
{"EAC_RG11", 2, 2, FormatType::UNORM, false, false, false, true},
{"EAC_RG11SN", 2, 2, FormatType::SNORM, false, false, false, true},
{"PVRTC_RGB2", 2, 3, FormatType::UNORM, false, false, false, true},
{"PVRTC_RGBA2", 2, 4, FormatType::UNORM, true, false, false, true},
{"PVRTC_RGB4", 2, 3, FormatType::UNORM, false, false, false, true},
{"PVRTC_RGBA4", 2, 4, FormatType::UNORM, true, false, false, true},
{"PVRTC2_2BPP", 2, 4, FormatType::UNORM, true, false, false, true},
{"PVRTC2_4BPP", 2, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_4X4", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_5X4", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_5X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_6X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_6X6", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_8X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_8X6", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_8X8", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_10X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_10X6", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_10X8", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_10X10", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_12X10", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_RGBA_12X12", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_4X4", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_5X4", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_5X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_6X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_6X6", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_8X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_8X6", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_8X8", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_10X5", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_10X6", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_10X8", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_10X10", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_12X10", 1, 4, FormatType::UNORM, true, false, false, true},
{"ASTC_SRGBA_12X12", 1, 4, FormatType::UNORM, true, false, false, true},
};
bool isCombinedImageSampler(Type type) { return type >= Type::SAMPLER1D && type <= Type::SAMPLER_CUBE; }
bool isSampledImage(Type type) { return type >= Type::TEXTURE1D && type <= Type::TEXTURE_CUBE; }
bool isStorageImage(Type type) { return type >= Type::IMAGE1D && type <= Type::IMAGE_CUBE; }
uint32_t ceilDiv(uint32_t x, uint32_t y) { return (x - 1) / y + 1; }
uint32_t formatSize(Format format, uint32_t width, uint32_t height, uint32_t depth) {
if (!GFX_FORMAT_INFOS[static_cast<uint32_t>(format)].isCompressed) {
return (width * height * depth * GFX_FORMAT_INFOS[static_cast<uint32_t>(format)].size);
}
switch (format) {
case Format::BC1:
case Format::BC1_ALPHA:
case Format::BC1_SRGB:
case Format::BC1_SRGB_ALPHA:
return ceilDiv(width, 4) * ceilDiv(height, 4) * 8 * depth;
case Format::BC2:
case Format::BC2_SRGB:
case Format::BC3:
case Format::BC3_SRGB:
case Format::BC4:
case Format::BC4_SNORM:
case Format::BC6H_SF16:
case Format::BC6H_UF16:
case Format::BC7:
case Format::BC7_SRGB:
return ceilDiv(width, 4) * ceilDiv(height, 4) * 16 * depth;
case Format::BC5:
case Format::BC5_SNORM:
return ceilDiv(width, 4) * ceilDiv(height, 4) * 32 * depth;
case Format::ETC_RGB8:
case Format::ETC2_RGB8:
case Format::ETC2_SRGB8:
case Format::ETC2_RGB8_A1:
case Format::EAC_R11:
case Format::EAC_R11SN:
return ceilDiv(width, 4) * ceilDiv(height, 4) * 8 * depth;
case Format::ETC2_RGBA8:
case Format::ETC2_SRGB8_A1:
case Format::EAC_RG11:
case Format::EAC_RG11SN:
return ceilDiv(width, 4) * ceilDiv(height, 4) * 16 * depth;
case Format::PVRTC_RGB2:
case Format::PVRTC_RGBA2:
case Format::PVRTC2_2BPP:
return ceilDiv(width, 8) * ceilDiv(height, 4) * 8 * depth;
case Format::PVRTC_RGB4:
case Format::PVRTC_RGBA4:
case Format::PVRTC2_4BPP:
return ceilDiv(width, 4) * ceilDiv(height, 4) * 8 * depth;
case Format::ASTC_RGBA_4X4:
case Format::ASTC_SRGBA_4X4:
return ceilDiv(width, 4) * ceilDiv(height, 4) * 16 * depth;
case Format::ASTC_RGBA_5X4:
case Format::ASTC_SRGBA_5X4:
return ceilDiv(width, 5) * ceilDiv(height, 4) * 16 * depth;
case Format::ASTC_RGBA_5X5:
case Format::ASTC_SRGBA_5X5:
return ceilDiv(width, 5) * ceilDiv(height, 5) * 16 * depth;
case Format::ASTC_RGBA_6X5:
case Format::ASTC_SRGBA_6X5:
return ceilDiv(width, 6) * ceilDiv(height, 5) * 16 * depth;
case Format::ASTC_RGBA_6X6:
case Format::ASTC_SRGBA_6X6:
return ceilDiv(width, 6) * ceilDiv(height, 6) * 16 * depth;
case Format::ASTC_RGBA_8X5:
case Format::ASTC_SRGBA_8X5:
return ceilDiv(width, 8) * ceilDiv(height, 5) * 16 * depth;
case Format::ASTC_RGBA_8X6:
case Format::ASTC_SRGBA_8X6:
return ceilDiv(width, 8) * ceilDiv(height, 6) * 16 * depth;
case Format::ASTC_RGBA_8X8:
case Format::ASTC_SRGBA_8X8:
return ceilDiv(width, 8) * ceilDiv(height, 8) * 16 * depth;
case Format::ASTC_RGBA_10X5:
case Format::ASTC_SRGBA_10X5:
return ceilDiv(width, 10) * ceilDiv(height, 5) * 16 * depth;
case Format::ASTC_RGBA_10X6:
case Format::ASTC_SRGBA_10X6:
return ceilDiv(width, 10) * ceilDiv(height, 6) * 16 * depth;
case Format::ASTC_RGBA_10X8:
case Format::ASTC_SRGBA_10X8:
return ceilDiv(width, 10) * ceilDiv(height, 8) * 16 * depth;
case Format::ASTC_RGBA_10X10:
case Format::ASTC_SRGBA_10X10:
return ceilDiv(width, 10) * ceilDiv(height, 10) * 16 * depth;
case Format::ASTC_RGBA_12X10:
case Format::ASTC_SRGBA_12X10:
return ceilDiv(width, 12) * ceilDiv(height, 10) * 16 * depth;
case Format::ASTC_RGBA_12X12:
case Format::ASTC_SRGBA_12X12:
return ceilDiv(width, 12) * ceilDiv(height, 12) * 16 * depth;
default:
return 0;
}
}
std::pair<uint32_t, uint32_t> formatAlignment(Format format) {
switch (format) {
case Format::BC1:
case Format::BC1_ALPHA:
case Format::BC1_SRGB:
case Format::BC1_SRGB_ALPHA:
case Format::BC2:
case Format::BC2_SRGB:
case Format::BC3:
case Format::BC3_SRGB:
case Format::BC4:
case Format::BC4_SNORM:
case Format::BC6H_SF16:
case Format::BC6H_UF16:
case Format::BC7:
case Format::BC7_SRGB:
case Format::BC5:
case Format::BC5_SNORM:
case Format::ETC_RGB8:
case Format::ETC2_RGB8:
case Format::ETC2_SRGB8:
case Format::ETC2_RGB8_A1:
case Format::EAC_R11:
case Format::EAC_R11SN:
case Format::ETC2_RGBA8:
case Format::ETC2_SRGB8_A1:
case Format::EAC_RG11:
case Format::EAC_RG11SN:
return std::make_pair(4, 4);
case Format::PVRTC_RGB2:
case Format::PVRTC_RGBA2:
case Format::PVRTC2_2BPP:
return std::make_pair(8, 4);
case Format::PVRTC_RGB4:
case Format::PVRTC_RGBA4:
case Format::PVRTC2_4BPP:
return std::make_pair(4, 4);
case Format::ASTC_RGBA_4X4:
case Format::ASTC_SRGBA_4X4:
return std::make_pair(4, 4);
case Format::ASTC_RGBA_5X4:
case Format::ASTC_SRGBA_5X4:
return std::make_pair(5, 4);
case Format::ASTC_RGBA_5X5:
case Format::ASTC_SRGBA_5X5:
return std::make_pair(5, 5);
case Format::ASTC_RGBA_6X5:
case Format::ASTC_SRGBA_6X5:
return std::make_pair(6, 5);
case Format::ASTC_RGBA_6X6:
case Format::ASTC_SRGBA_6X6:
return std::make_pair(6, 6);
case Format::ASTC_RGBA_8X5:
case Format::ASTC_SRGBA_8X5:
return std::make_pair(8, 5);
case Format::ASTC_RGBA_8X6:
case Format::ASTC_SRGBA_8X6:
return std::make_pair(8, 6);
case Format::ASTC_RGBA_8X8:
case Format::ASTC_SRGBA_8X8:
return std::make_pair(8, 8);
case Format::ASTC_RGBA_10X5:
case Format::ASTC_SRGBA_10X5:
return std::make_pair(10, 5);
case Format::ASTC_RGBA_10X6:
case Format::ASTC_SRGBA_10X6:
return std::make_pair(10, 6);
case Format::ASTC_RGBA_10X8:
case Format::ASTC_SRGBA_10X8:
return std::make_pair(10, 8);
case Format::ASTC_RGBA_10X10:
case Format::ASTC_SRGBA_10X10:
return std::make_pair(10, 10);
case Format::ASTC_RGBA_12X10:
case Format::ASTC_SRGBA_12X10:
return std::make_pair(12, 10);
case Format::ASTC_RGBA_12X12:
case Format::ASTC_SRGBA_12X12:
return std::make_pair(12, 12);
default:
return std::make_pair(1, 1);
}
}
static constexpr ccstd::array<uint32_t, static_cast<size_t>(Type::COUNT)> GFX_TYPE_SIZES = {
0, // UNKNOWN
4, // BOOL
8, // BOOL2
12, // BOOL3
16, // BOOL4
4, // INT
8, // INT2
12, // INT3
16, // INT4
4, // UINT
8, // UINT2
12, // UINT3
16, // UINT4
4, // FLOAT
8, // FLOAT2
12, // FLOAT3
16, // FLOAT4
16, // MAT2
24, // MAT2X3
32, // MAT2X4
24, // MAT3X2
36, // MAT3
48, // MAT3X4
32, // MAT4X2
48, // MAT4X3
64, // MAT4
4, // SAMPLER1D
4, // SAMPLER1D_ARRAY
4, // SAMPLER2D
4, // SAMPLER2D_ARRAY
4, // SAMPLER3D
4, // SAMPLER_CUBE
};
/**
* @en Get the memory size of the specified type.
* @zh 得到 GFX 数据类型的大小。
* @param type The target type.
*/
uint32_t getTypeSize(Type type) {
if (type < Type::COUNT) {
return GFX_TYPE_SIZES[toNumber(type)];
}
return 0;
}
uint32_t formatSurfaceSize(Format format, uint32_t width, uint32_t height, uint32_t depth, uint32_t mips) {
uint32_t size = 0;
for (uint32_t i = 0; i < mips; ++i) {
size += formatSize(format, width, height, depth);
width = std::max(width >> 1, 1U);
height = std::max(height >> 1, 1U);
}
return size;
}
uint32_t gcd(uint32_t a, uint32_t b) {
while (b) {
uint32_t t = a % b;
a = b;
b = t;
}
return a;
}
uint32_t lcm(uint32_t a, uint32_t b) {
return a * b / gcd(a, b);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,150 @@
/****************************************************************************
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 <functional>
#include "GFXDef-common.h"
#include "base/std/hash/hash.h"
namespace cc {
namespace gfx {
template <typename T, typename Enable = std::enable_if_t<std::is_class<T>::value>>
struct Hasher final {
// NOTE: ccstd::hash_t is a typedef of uint32_t now, sizeof(ccstd::hash_t) == sizeof(size_t) on 32 bits architecture device,
// sizeof(ccstd::hash_t) < sizeof(size_t) on 64 bits architecture device.
// STL containers like ccstd::unordered_map<K, V, Hasher> expects the custom Hasher function to return size_t.
// So it's safe to return ccstd::hash_t for operator() function now.
// If we need to define ccstd::hash_t to uint64_t someday, we must take care of the return value of operator(),
// it should be size_t and we need to convert hash value from uint64_t to uint32_t for 32 bit architecture device.
ccstd::hash_t operator()(const T &info) const;
};
// make this ccstd::hash compatible
template <typename T, typename Enable = std::enable_if_t<std::is_class<T>::value>>
ccstd::hash_t hash_value(const T &info) { return Hasher<T>()(info); } // NOLINT(readability-identifier-naming)
#define DEFINE_CMP_OP(type) \
bool operator==(const type &lhs, const type &rhs); \
inline bool operator!=(const type &lhs, const type &rhs) { return !(lhs == rhs); }
DEFINE_CMP_OP(DepthStencilAttachment)
DEFINE_CMP_OP(SubpassInfo)
DEFINE_CMP_OP(SubpassDependency)
DEFINE_CMP_OP(RenderPassInfo)
DEFINE_CMP_OP(FramebufferInfo)
DEFINE_CMP_OP(Viewport)
DEFINE_CMP_OP(Rect)
DEFINE_CMP_OP(Color)
DEFINE_CMP_OP(Offset)
DEFINE_CMP_OP(Extent)
DEFINE_CMP_OP(Size)
DEFINE_CMP_OP(TextureInfo)
DEFINE_CMP_OP(TextureViewInfo)
DEFINE_CMP_OP(BufferInfo)
DEFINE_CMP_OP(SamplerInfo)
DEFINE_CMP_OP(GeneralBarrierInfo)
DEFINE_CMP_OP(TextureBarrierInfo)
DEFINE_CMP_OP(BufferBarrierInfo)
#undef DEFINE_CMP_OP
class Executable {
public:
virtual ~Executable() = default;
virtual void execute() = 0;
};
template <typename ExecuteMethodType>
class CallbackExecutable final : public Executable {
public:
using ExecuteMethod = std::remove_reference_t<ExecuteMethodType>;
explicit CallbackExecutable(ExecuteMethod &execute) : Executable(), _execute(execute) {}
explicit CallbackExecutable(ExecuteMethod &&execute) : Executable(), _execute(execute) {}
void execute() override { _execute(); }
private:
ExecuteMethod _execute;
};
struct SwapchainTextureInfo final {
Swapchain *swapchain{nullptr};
Format format{Format::UNKNOWN};
uint32_t width{0};
uint32_t height{0};
};
constexpr TextureUsage TEXTURE_USAGE_TRANSIENT = static_cast<TextureUsage>(
static_cast<uint32_t>(TextureUsageBit::COLOR_ATTACHMENT) |
static_cast<uint32_t>(TextureUsageBit::DEPTH_STENCIL_ATTACHMENT) |
static_cast<uint32_t>(TextureUsageBit::INPUT_ATTACHMENT));
constexpr DescriptorType DESCRIPTOR_BUFFER_TYPE = static_cast<DescriptorType>(
static_cast<uint32_t>(DescriptorType::STORAGE_BUFFER) |
static_cast<uint32_t>(DescriptorType::DYNAMIC_STORAGE_BUFFER) |
static_cast<uint32_t>(DescriptorType::UNIFORM_BUFFER) |
static_cast<uint32_t>(DescriptorType::DYNAMIC_UNIFORM_BUFFER));
constexpr DescriptorType DESCRIPTOR_TEXTURE_TYPE = static_cast<DescriptorType>(
static_cast<uint32_t>(DescriptorType::SAMPLER_TEXTURE) |
static_cast<uint32_t>(DescriptorType::SAMPLER) |
static_cast<uint32_t>(DescriptorType::TEXTURE) |
static_cast<uint32_t>(DescriptorType::STORAGE_IMAGE) |
static_cast<uint32_t>(DescriptorType::INPUT_ATTACHMENT));
constexpr DescriptorType DESCRIPTOR_SAMPLER_TYPE = static_cast<DescriptorType>(
static_cast<uint32_t>(DescriptorType::SAMPLER_TEXTURE) |
static_cast<uint32_t>(DescriptorType::SAMPLER) |
static_cast<uint32_t>(DescriptorType::TEXTURE) |
static_cast<uint32_t>(DescriptorType::STORAGE_IMAGE) |
static_cast<uint32_t>(DescriptorType::INPUT_ATTACHMENT));
constexpr DescriptorType DESCRIPTOR_DYNAMIC_TYPE = static_cast<DescriptorType>(
static_cast<uint32_t>(DescriptorType::DYNAMIC_STORAGE_BUFFER) |
static_cast<uint32_t>(DescriptorType::DYNAMIC_UNIFORM_BUFFER));
extern const FormatInfo GFX_FORMAT_INFOS[];
std::pair<uint32_t, uint32_t> formatAlignment(Format format);
uint32_t formatSize(Format format, uint32_t width, uint32_t height, uint32_t depth);
uint32_t formatSurfaceSize(Format format, uint32_t width, uint32_t height, uint32_t depth, uint32_t mips);
/**
* @en Get the memory size of the specified type.
* @zh 得到 GFX 数据类型的大小。
* @param type The target type.
*/
uint32_t getTypeSize(gfx::Type type);
uint32_t gcd(uint32_t a, uint32_t b);
uint32_t lcm(uint32_t a, uint32_t b);
} // namespace gfx
} // namespace cc

View 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 "GFXDescriptorSet.h"
#include "GFXBuffer.h"
#include "GFXDescriptorSetLayout.h"
#include "GFXObject.h"
#include "GFXTexture.h"
#include "states/GFXSampler.h"
namespace cc {
namespace gfx {
DescriptorSet::DescriptorSet()
: GFXObject(ObjectType::DESCRIPTOR_SET) {
}
DescriptorSet::~DescriptorSet() = default;
void DescriptorSet::initialize(const DescriptorSetInfo &info) {
CC_ASSERT(info.layout);
_layout = info.layout;
uint32_t descriptorCount = _layout->getDescriptorCount();
_buffers.resize(descriptorCount);
_textures.resize(descriptorCount);
_samplers.resize(descriptorCount);
doInit(info);
}
void DescriptorSet::destroy() {
doDestroy();
_layout = nullptr;
// have to clear these or else it might not be properly updated when reused
_buffers.clear();
_textures.clear();
_samplers.clear();
}
void DescriptorSet::bindBuffer(uint32_t binding, Buffer *buffer, uint32_t index) {
bindBuffer(binding, buffer, index, AccessFlagBit::NONE);
}
void DescriptorSet::bindTexture(uint32_t binding, Texture *texture, uint32_t index) {
bindTexture(binding, texture, index, AccessFlagBit::NONE);
}
void DescriptorSet::bindTexture(uint32_t binding, Texture *texture, uint32_t index, AccessFlags flags) {
const uint32_t descriptorIndex = _layout->getDescriptorIndices()[binding] + index;
const uint32_t newId = getObjectID(texture);
if (_textures[descriptorIndex].id != newId) {
_textures[descriptorIndex].ptr = texture;
_textures[descriptorIndex].id = newId;
_textures[descriptorIndex].flags = flags;
_isDirty = true;
}
}
void DescriptorSet::bindBuffer(uint32_t binding, Buffer *buffer, uint32_t index, AccessFlags flags) {
const uint32_t descriptorIndex = _layout->getDescriptorIndices()[binding] + index;
const uint32_t newId = getObjectID(buffer);
if (_buffers[descriptorIndex].id != newId) {
_buffers[descriptorIndex].ptr = buffer;
_buffers[descriptorIndex].id = newId;
_buffers[descriptorIndex].flags = flags;
_isDirty = true;
}
}
void DescriptorSet::bindSampler(uint32_t binding, Sampler *sampler, uint32_t index) {
const uint32_t descriptorIndex = _layout->getDescriptorIndices()[binding] + index;
const uint32_t newId = getObjectID(sampler);
if (_samplers[descriptorIndex].id != newId) {
_samplers[descriptorIndex].ptr = sampler;
_samplers[descriptorIndex].id = newId;
_isDirty = true;
}
}
bool DescriptorSet::bindBufferJSB(uint32_t binding, Buffer *buffer, uint32_t index) {
bindBuffer(binding, buffer, index);
return _isDirty;
}
bool DescriptorSet::bindTextureJSB(uint32_t binding, Texture *texture, uint32_t index, AccessFlags flags) {
bindTexture(binding, texture, index, flags);
return _isDirty;
}
bool DescriptorSet::bindSamplerJSB(uint32_t binding, Sampler *sampler, uint32_t index) {
bindSampler(binding, sampler, index);
return _isDirty;
}
Buffer *DescriptorSet::getBuffer(uint32_t binding, uint32_t index) const {
const ccstd::vector<uint32_t> &descriptorIndices = _layout->getDescriptorIndices();
if (binding >= descriptorIndices.size()) return nullptr;
const uint32_t descriptorIndex = descriptorIndices[binding] + index;
if (descriptorIndex >= _buffers.size()) return nullptr;
return _buffers[descriptorIndex].ptr;
}
Texture *DescriptorSet::getTexture(uint32_t binding, uint32_t index) const {
const ccstd::vector<uint32_t> &descriptorIndices = _layout->getDescriptorIndices();
if (binding >= descriptorIndices.size()) return nullptr;
const uint32_t descriptorIndex = descriptorIndices[binding] + index;
if (descriptorIndex >= _textures.size()) return nullptr;
return _textures[descriptorIndex].ptr;
}
Sampler *DescriptorSet::getSampler(uint32_t binding, uint32_t index) const {
const ccstd::vector<uint32_t> &descriptorIndices = _layout->getDescriptorIndices();
if (binding >= descriptorIndices.size()) return nullptr;
const uint32_t descriptorIndex = descriptorIndices[binding] + index;
if (descriptorIndex >= _samplers.size()) return nullptr;
return _samplers[descriptorIndex].ptr;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,89 @@
/****************************************************************************
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 "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL DescriptorSet : public GFXObject, public RefCounted {
public:
DescriptorSet();
~DescriptorSet() override;
void initialize(const DescriptorSetInfo &info);
void destroy();
virtual void update() = 0;
virtual void forceUpdate() = 0;
virtual void bindBuffer(uint32_t binding, Buffer *buffer, uint32_t index, AccessFlags flags);
virtual void bindSampler(uint32_t binding, Sampler *sampler, uint32_t index);
virtual void bindTexture(uint32_t binding, Texture *texture, uint32_t index, AccessFlags flags);
void bindBuffer(uint32_t binding, Buffer *buffer, uint32_t index);
void bindTexture(uint32_t binding, Texture *texture, uint32_t index);
// Functions invoked by JSB adapter
bool bindBufferJSB(uint32_t binding, Buffer *buffer, uint32_t index);
bool bindTextureJSB(uint32_t binding, Texture *texture, uint32_t index, AccessFlags flags);
bool bindSamplerJSB(uint32_t binding, Sampler *sampler, uint32_t index);
Buffer *getBuffer(uint32_t binding, uint32_t index) const;
Texture *getTexture(uint32_t binding, uint32_t index) const;
Sampler *getSampler(uint32_t binding, uint32_t index) const;
inline const DescriptorSetLayout *getLayout() const { return _layout; }
inline void bindBuffer(uint32_t binding, Buffer *buffer) { bindBuffer(binding, buffer, 0U); }
inline void bindTexture(uint32_t binding, Texture *texture) { bindTexture(binding, texture, 0U); }
inline void bindSampler(uint32_t binding, Sampler *sampler) { bindSampler(binding, sampler, 0U); }
inline Buffer *getBuffer(uint32_t binding) const { return getBuffer(binding, 0U); }
inline Texture *getTexture(uint32_t binding) const { return getTexture(binding, 0U); }
inline Sampler *getSampler(uint32_t binding) const { return getSampler(binding, 0U); }
protected:
virtual void doInit(const DescriptorSetInfo &info) = 0;
virtual void doDestroy() = 0;
template <typename T>
struct ObjectWithId {
T *ptr = nullptr;
uint32_t id = INVALID_OBJECT_ID;
AccessFlags flags = AccessFlagBit::NONE;
};
const DescriptorSetLayout *_layout = nullptr;
ccstd::vector<ObjectWithId<Buffer>> _buffers;
ccstd::vector<ObjectWithId<Texture>> _textures;
ccstd::vector<ObjectWithId<Sampler>> _samplers;
bool _isDirty = false;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,81 @@
/****************************************************************************
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 "GFXObject.h"
#include "base/Utils.h"
#include "GFXDescriptorSetLayout.h"
namespace cc {
namespace gfx {
DescriptorSetLayout::DescriptorSetLayout()
: GFXObject(ObjectType::DESCRIPTOR_SET_LAYOUT) {
}
DescriptorSetLayout::~DescriptorSetLayout() = default;
void DescriptorSetLayout::initialize(const DescriptorSetLayoutInfo &info) {
_bindings = info.bindings;
auto bindingCount = utils::toUint(_bindings.size());
_descriptorCount = 0U;
if (bindingCount) {
uint32_t maxBinding = 0U;
ccstd::vector<uint32_t> flattenedIndices(bindingCount);
for (uint32_t i = 0U; i < bindingCount; i++) {
const DescriptorSetLayoutBinding &binding = _bindings[i];
if (binding.binding > maxBinding) maxBinding = binding.binding;
flattenedIndices[i] = _descriptorCount;
_descriptorCount += binding.count;
}
_bindingIndices.resize(maxBinding + 1, INVALID_BINDING);
_descriptorIndices.resize(maxBinding + 1, INVALID_BINDING);
for (uint32_t i = 0U; i < bindingCount; i++) {
const DescriptorSetLayoutBinding &binding = _bindings[i];
_bindingIndices[binding.binding] = i;
_descriptorIndices[binding.binding] = flattenedIndices[i];
if (hasFlag(DESCRIPTOR_DYNAMIC_TYPE, binding.descriptorType)) {
for (uint32_t j = 0U; j < binding.count; ++j) {
_dynamicBindings.push_back(binding.binding);
}
}
}
}
doInit(info);
}
void DescriptorSetLayout::destroy() {
doDestroy();
_bindings.clear();
_descriptorCount = 0U;
_bindingIndices.clear();
_descriptorIndices.clear();
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,59 @@
/****************************************************************************
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 "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL DescriptorSetLayout : public GFXObject, public RefCounted {
public:
DescriptorSetLayout();
~DescriptorSetLayout() override;
void initialize(const DescriptorSetLayoutInfo &info);
void destroy();
inline const DescriptorSetLayoutBindingList &getBindings() const { return _bindings; }
inline const ccstd::vector<uint32_t> &getDynamicBindings() const { return _dynamicBindings; }
inline const ccstd::vector<uint32_t> &getBindingIndices() const { return _bindingIndices; }
inline const ccstd::vector<uint32_t> &getDescriptorIndices() const { return _descriptorIndices; }
inline uint32_t getDescriptorCount() const { return _descriptorCount; }
protected:
virtual void doInit(const DescriptorSetLayoutInfo &info) = 0;
virtual void doDestroy() = 0;
DescriptorSetLayoutBindingList _bindings;
uint32_t _descriptorCount = 0U;
ccstd::vector<uint32_t> _bindingIndices;
ccstd::vector<uint32_t> _descriptorIndices;
ccstd::vector<uint32_t> _dynamicBindings;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,200 @@
/****************************************************************************
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 "GFXDevice.h"
#include "GFXObject.h"
#include "base/memory/Memory.h"
#include "platform/BasePlatform.h"
#include "platform/interfaces/modules/ISystemWindow.h"
#include "platform/interfaces/modules/ISystemWindowManager.h"
namespace cc {
namespace gfx {
Device *Device::instance = nullptr;
bool Device::isSupportDetachDeviceThread = true;
Device *Device::getInstance() {
return Device::instance;
}
Device::Device() {
Device::instance = this;
// Device instance is created and hold by TS. Native should hold it too
// to make sure it exists after JavaScript virtual machine is destroyed.
// Then will destroy the Device instance in native.
addRef();
_features.fill(false);
_formatFeatures.fill(FormatFeature::NONE);
}
Device::~Device() {
Device::instance = nullptr;
CC_SAFE_RELEASE(_cmdBuff);
CC_SAFE_RELEASE(_queue);
}
bool Device::initialize(const DeviceInfo &info) {
_bindingMappingInfo = info.bindingMappingInfo;
#if CC_CPU_ARCH == CC_CPU_ARCH_32
static_assert(sizeof(void *) == 4, "pointer size assumption broken");
#else
static_assert(sizeof(void *) == 8, "pointer size assumption broken");
#endif
bool result = doInit(info);
CC_SAFE_ADD_REF(_cmdBuff);
CC_SAFE_ADD_REF(_queue);
return result;
}
void Device::destroy() {
for (auto pair : _samplers) {
CC_SAFE_DELETE(pair.second);
}
_samplers.clear();
for (auto pair : _generalBarriers) {
CC_SAFE_DELETE(pair.second);
}
_generalBarriers.clear();
for (auto pair : _textureBarriers) {
CC_SAFE_DELETE(pair.second);
}
_textureBarriers.clear();
for (auto pair : _bufferBarriers) {
CC_SAFE_DELETE(pair.second);
}
_bufferBarriers.clear();
doDestroy();
CC_SAFE_DELETE(_onAcquire);
}
Sampler *Device::getSampler(const SamplerInfo &info) {
if (!_samplers.count(info)) {
_samplers[info] = createSampler(info);
}
return _samplers[info];
}
GeneralBarrier *Device::getGeneralBarrier(const GeneralBarrierInfo &info) {
if (!_generalBarriers.count(info)) {
_generalBarriers[info] = createGeneralBarrier(info);
}
return _generalBarriers[info];
}
TextureBarrier *Device::getTextureBarrier(const TextureBarrierInfo &info) {
if (!_textureBarriers.count(info)) {
_textureBarriers[info] = createTextureBarrier(info);
}
return _textureBarriers[info];
}
BufferBarrier *Device::getBufferBarrier(const BufferBarrierInfo &info) {
if (!_bufferBarriers.count(info)) {
_bufferBarriers[info] = createBufferBarrier(info);
}
return _bufferBarriers[info];
}
DefaultResource::DefaultResource(Device *device) {
uint32_t bufferSize = 64;
ccstd::vector<uint8_t> buffer(bufferSize, 255);
const uint8_t *bufferData = buffer.data();
if (device->getCapabilities().maxTextureSize >= 2) {
_texture2D = device->createTexture({TextureType::TEX2D, TextureUsageBit::STORAGE | TextureUsageBit::SAMPLED | TextureUsageBit::TRANSFER_DST,
Format::RGBA8, 2, 2, TextureFlagBit::NONE});
BufferTextureCopy region = {0, 0, 0, {0, 0, 0}, {2, 2, 1}, {0, 0, 1}};
device->copyBuffersToTexture(&bufferData, _texture2D, &region, 1);
}
if (device->getCapabilities().maxTextureSize >= 2) {
_textureCube = device->createTexture({TextureType::CUBE, TextureUsageBit::STORAGE | TextureUsageBit::SAMPLED | TextureUsageBit::TRANSFER_DST,
Format::RGBA8, 2, 2, TextureFlagBit::NONE, 6});
BufferTextureCopy region = {0, 0, 0, {0, 0, 0}, {2, 2, 1}, {0, 0, 1}};
device->copyBuffersToTexture(&bufferData, _textureCube, &region, 1);
region.texSubres.baseArrayLayer = 1;
device->copyBuffersToTexture(&bufferData, _textureCube, &region, 1);
region.texSubres.baseArrayLayer = 2;
device->copyBuffersToTexture(&bufferData, _textureCube, &region, 1);
region.texSubres.baseArrayLayer = 3;
device->copyBuffersToTexture(&bufferData, _textureCube, &region, 1);
region.texSubres.baseArrayLayer = 4;
device->copyBuffersToTexture(&bufferData, _textureCube, &region, 1);
region.texSubres.baseArrayLayer = 5;
device->copyBuffersToTexture(&bufferData, _textureCube, &region, 1);
}
if (device->getCapabilities().max3DTextureSize >= 2) {
_texture3D = device->createTexture({TextureType::TEX3D, TextureUsageBit::STORAGE | TextureUsageBit::SAMPLED | TextureUsageBit::TRANSFER_DST,
Format::RGBA8, 2, 2, TextureFlagBit::NONE, 1, 1, SampleCount::X1, 2});
BufferTextureCopy region = {0, 0, 0, {0, 0, 0}, {2, 2, 2}, {0, 0, 1}};
device->copyBuffersToTexture(&bufferData, _texture3D, &region, 1);
}
if (device->getCapabilities().maxArrayTextureLayers >= 2) {
_texture2DArray = device->createTexture({TextureType::TEX2D_ARRAY, TextureUsageBit::STORAGE | TextureUsageBit::SAMPLED | TextureUsageBit::TRANSFER_DST,
Format::RGBA8, 2, 2, TextureFlagBit::NONE, 2});
BufferTextureCopy region = {0, 0, 0, {0, 0, 0}, {2, 2, 1}, {0, 0, 1}};
device->copyBuffersToTexture(&bufferData, _texture2DArray, &region, 1);
region.texSubres.baseArrayLayer = 1;
device->copyBuffersToTexture(&bufferData, _texture2DArray, &region, 1);
}
{
BufferInfo bufferInfo = {};
bufferInfo.usage = BufferUsageBit::STORAGE | BufferUsageBit::TRANSFER_DST | BufferUsageBit::TRANSFER_SRC | BufferUsageBit::VERTEX | BufferUsageBit::INDEX | BufferUsageBit::INDIRECT;
bufferInfo.memUsage = MemoryUsageBit::DEVICE | MemoryUsageBit::HOST;
bufferInfo.size = 5 * sizeof(uint32_t); // for indirect command buffer
bufferInfo.stride = bufferInfo.size;
_buffer = device->createBuffer(bufferInfo);
}
}
Texture *DefaultResource::getTexture(TextureType type) const {
switch (type) {
case TextureType::TEX2D:
return _texture2D;
case TextureType::CUBE:
return _textureCube;
case TextureType::TEX3D:
return _texture3D;
case TextureType::TEX2D_ARRAY:
return _texture2DArray;
default:
CC_ABORT();
return nullptr;
}
}
Buffer *DefaultResource::getBuffer() const {
return _buffer;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,339 @@
/****************************************************************************
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 "GFXBuffer.h"
#include "GFXCommandBuffer.h"
#include "GFXDescriptorSet.h"
#include "GFXDescriptorSetLayout.h"
#include "GFXFramebuffer.h"
#include "GFXInputAssembler.h"
#include "GFXObject.h"
#include "GFXPipelineLayout.h"
#include "GFXPipelineState.h"
#include "GFXQueryPool.h"
#include "GFXQueue.h"
#include "GFXRenderPass.h"
#include "GFXShader.h"
#include "GFXSwapchain.h"
#include "GFXTexture.h"
#include "base/RefCounted.h"
#include "base/std/container/array.h"
#include "states/GFXBufferBarrier.h"
#include "states/GFXGeneralBarrier.h"
#include "states/GFXSampler.h"
#include "states/GFXTextureBarrier.h"
namespace cc {
namespace gfx {
class CC_DLL Device : public RefCounted {
public:
static Device *getInstance();
~Device() override;
bool initialize(const DeviceInfo &info);
void destroy();
// aim to ensure waiting for work on gpu done when cpu encodes ahead of gpu certain frame(s).
virtual void frameSync() = 0;
virtual void acquire(Swapchain *const *swapchains, uint32_t count) = 0;
virtual void present() = 0;
virtual void flushCommands(CommandBuffer *const *cmdBuffs, uint32_t count) {}
virtual MemoryStatus &getMemoryStatus() { return _memoryStatus; }
virtual uint32_t getNumDrawCalls() const { return _numDrawCalls; }
virtual uint32_t getNumInstances() const { return _numInstances; }
virtual uint32_t getNumTris() const { return _numTriangles; }
inline CommandBuffer *createCommandBuffer(const CommandBufferInfo &info);
inline Queue *createQueue(const QueueInfo &info);
inline QueryPool *createQueryPool(const QueryPoolInfo &info);
inline Swapchain *createSwapchain(const SwapchainInfo &info);
inline const ccstd::vector<Swapchain *> &getSwapchains() const { return _swapchains; }
inline Buffer *createBuffer(const BufferInfo &info);
inline Buffer *createBuffer(const BufferViewInfo &info);
inline Texture *createTexture(const TextureInfo &info);
inline Texture *createTexture(const TextureViewInfo &info);
inline Shader *createShader(const ShaderInfo &info);
inline InputAssembler *createInputAssembler(const InputAssemblerInfo &info);
inline RenderPass *createRenderPass(const RenderPassInfo &info);
inline Framebuffer *createFramebuffer(const FramebufferInfo &info);
inline DescriptorSet *createDescriptorSet(const DescriptorSetInfo &info);
inline DescriptorSetLayout *createDescriptorSetLayout(const DescriptorSetLayoutInfo &info);
inline PipelineLayout *createPipelineLayout(const PipelineLayoutInfo &info);
inline PipelineState *createPipelineState(const PipelineStateInfo &info);
virtual Sampler *getSampler(const SamplerInfo &info);
virtual GeneralBarrier *getGeneralBarrier(const GeneralBarrierInfo &info);
virtual TextureBarrier *getTextureBarrier(const TextureBarrierInfo &info);
virtual BufferBarrier *getBufferBarrier(const BufferBarrierInfo &info);
virtual void copyBuffersToTexture(const uint8_t *const *buffers, Texture *dst, const BufferTextureCopy *regions, uint32_t count) = 0;
virtual void copyTextureToBuffers(Texture *src, uint8_t *const *buffers, const BufferTextureCopy *region, uint32_t count) = 0;
virtual void getQueryPoolResults(QueryPool *queryPool) = 0;
inline void copyTextureToBuffers(Texture *src, BufferSrcList &buffers, const BufferTextureCopyList &regions);
inline void copyBuffersToTexture(const BufferDataList &buffers, Texture *dst, const BufferTextureCopyList &regions);
inline void flushCommands(const ccstd::vector<CommandBuffer *> &cmdBuffs);
inline void acquire(const ccstd::vector<Swapchain *> &swapchains);
inline Queue *getQueue() const { return _queue; }
inline QueryPool *getQueryPool() const { return _queryPool; }
inline CommandBuffer *getCommandBuffer() const { return _cmdBuff; }
inline const DeviceCaps &getCapabilities() const { return _caps; }
inline API getGfxAPI() const { return _api; }
inline const ccstd::string &getDeviceName() const { return _deviceName; }
inline const ccstd::string &getRenderer() const { return _renderer; }
inline const ccstd::string &getVendor() const { return _vendor; }
inline bool hasFeature(Feature feature) const { return _features[toNumber(feature)]; }
inline FormatFeature getFormatFeatures(Format format) const { return _formatFeatures[toNumber(format)]; }
inline const BindingMappingInfo &bindingMappingInfo() const { return _bindingMappingInfo; }
// for external update operations which has to be performed on the device thread.
// AR camera texture update, etc.
template <typename ExecuteMethod>
void registerOnAcquireCallback(ExecuteMethod &&execute);
virtual void enableAutoBarrier(bool en) { _options.enableBarrierDeduce = en; }
virtual SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const {
std::ignore = format;
std::ignore = usage;
std::ignore = flags;
return SampleCount::X1;
};
protected:
static Device *instance;
static bool isSupportDetachDeviceThread;
friend class DeviceAgent;
friend class DeviceValidator;
friend class DeviceManager;
Device();
virtual bool doInit(const DeviceInfo &info) = 0;
virtual void doDestroy() = 0;
virtual CommandBuffer *createCommandBuffer(const CommandBufferInfo &info, bool hasAgent) = 0;
virtual Queue *createQueue() = 0;
virtual QueryPool *createQueryPool() = 0;
virtual Swapchain *createSwapchain() = 0;
virtual Buffer *createBuffer() = 0;
virtual Texture *createTexture() = 0;
virtual Shader *createShader() = 0;
virtual InputAssembler *createInputAssembler() = 0;
virtual RenderPass *createRenderPass() = 0;
virtual Framebuffer *createFramebuffer() = 0;
virtual DescriptorSet *createDescriptorSet() = 0;
virtual DescriptorSetLayout *createDescriptorSetLayout() = 0;
virtual PipelineLayout *createPipelineLayout() = 0;
virtual PipelineState *createPipelineState() = 0;
virtual Sampler *createSampler(const SamplerInfo &info) { return ccnew Sampler(info); }
virtual GeneralBarrier *createGeneralBarrier(const GeneralBarrierInfo &info) { return ccnew GeneralBarrier(info); }
virtual TextureBarrier *createTextureBarrier(const TextureBarrierInfo &info) { return ccnew TextureBarrier(info); }
virtual BufferBarrier *createBufferBarrier(const BufferBarrierInfo &info) { return ccnew BufferBarrier(info); }
// For context switching between threads
virtual void bindContext(bool bound) {}
ccstd::string _deviceName;
ccstd::string _renderer;
ccstd::string _vendor;
ccstd::string _version;
API _api{API::UNKNOWN};
DeviceCaps _caps;
BindingMappingInfo _bindingMappingInfo;
DeviceOptions _options;
bool _multithreadedCommandRecording{true};
ccstd::array<bool, static_cast<size_t>(Feature::COUNT)> _features;
ccstd::array<FormatFeature, static_cast<size_t>(Format::COUNT)> _formatFeatures;
Queue *_queue{nullptr};
QueryPool *_queryPool{nullptr};
CommandBuffer *_cmdBuff{nullptr};
Executable *_onAcquire{nullptr};
uint32_t _numDrawCalls{0U};
uint32_t _numInstances{0U};
uint32_t _numTriangles{0U};
MemoryStatus _memoryStatus;
ccstd::unordered_map<SamplerInfo, Sampler *, Hasher<SamplerInfo>> _samplers;
ccstd::unordered_map<GeneralBarrierInfo, GeneralBarrier *, Hasher<GeneralBarrierInfo>> _generalBarriers;
ccstd::unordered_map<TextureBarrierInfo, TextureBarrier *, Hasher<TextureBarrierInfo>> _textureBarriers;
ccstd::unordered_map<BufferBarrierInfo, BufferBarrier *, Hasher<BufferBarrierInfo>> _bufferBarriers;
private:
ccstd::vector<Swapchain *> _swapchains; // weak reference
};
class DefaultResource {
public:
explicit DefaultResource(Device *device);
~DefaultResource() = default;
Texture *getTexture(TextureType type) const;
Buffer *getBuffer() const;
private:
IntrusivePtr<Texture> _texture2D;
IntrusivePtr<Texture> _texture2DArray;
IntrusivePtr<Texture> _textureCube;
IntrusivePtr<Texture> _texture3D;
IntrusivePtr<Buffer> _buffer;
};
//////////////////////////////////////////////////////////////////////////
CommandBuffer *Device::createCommandBuffer(const CommandBufferInfo &info) {
CommandBuffer *res = createCommandBuffer(info, false);
res->initialize(info);
return res;
}
Queue *Device::createQueue(const QueueInfo &info) {
Queue *res = createQueue();
res->initialize(info);
return res;
}
QueryPool *Device::createQueryPool(const QueryPoolInfo &info) {
QueryPool *res = createQueryPool();
res->initialize(info);
return res;
}
Swapchain *Device::createSwapchain(const SwapchainInfo &info) {
Swapchain *res = createSwapchain();
res->initialize(info);
_swapchains.push_back(res);
return res;
}
Buffer *Device::createBuffer(const BufferInfo &info) {
Buffer *res = createBuffer();
res->initialize(info);
return res;
}
Buffer *Device::createBuffer(const BufferViewInfo &info) {
Buffer *res = createBuffer();
res->initialize(info);
return res;
}
Texture *Device::createTexture(const TextureInfo &info) {
Texture *res = createTexture();
res->initialize(info);
return res;
}
Texture *Device::createTexture(const TextureViewInfo &info) {
Texture *res = createTexture();
res->initialize(info);
return res;
}
Shader *Device::createShader(const ShaderInfo &info) {
Shader *res = createShader();
res->initialize(info);
return res;
}
InputAssembler *Device::createInputAssembler(const InputAssemblerInfo &info) {
InputAssembler *res = createInputAssembler();
res->initialize(info);
return res;
}
RenderPass *Device::createRenderPass(const RenderPassInfo &info) {
RenderPass *res = createRenderPass();
res->initialize(info);
return res;
}
Framebuffer *Device::createFramebuffer(const FramebufferInfo &info) {
Framebuffer *res = createFramebuffer();
res->initialize(info);
return res;
}
DescriptorSet *Device::createDescriptorSet(const DescriptorSetInfo &info) {
DescriptorSet *res = createDescriptorSet();
res->initialize(info);
return res;
}
DescriptorSetLayout *Device::createDescriptorSetLayout(const DescriptorSetLayoutInfo &info) {
DescriptorSetLayout *res = createDescriptorSetLayout();
res->initialize(info);
return res;
}
PipelineLayout *Device::createPipelineLayout(const PipelineLayoutInfo &info) {
PipelineLayout *res = createPipelineLayout();
res->initialize(info);
return res;
}
PipelineState *Device::createPipelineState(const PipelineStateInfo &info) {
PipelineState *res = createPipelineState();
res->initialize(info);
return res;
}
void Device::copyBuffersToTexture(const BufferDataList &buffers, Texture *dst, const BufferTextureCopyList &regions) {
copyBuffersToTexture(buffers.data(), dst, regions.data(), utils::toUint(regions.size()));
}
void Device::copyTextureToBuffers(Texture *src, BufferSrcList &buffers, const BufferTextureCopyList &regions) {
copyTextureToBuffers(src, buffers.data(), regions.data(), utils::toUint(regions.size()));
}
void Device::flushCommands(const ccstd::vector<CommandBuffer *> &cmdBuffs) {
flushCommands(cmdBuffs.data(), utils::toUint(cmdBuffs.size()));
}
void Device::acquire(const ccstd::vector<Swapchain *> &swapchains) {
acquire(swapchains.data(), utils::toUint(swapchains.size()));
}
template <typename ExecuteMethod>
void Device::registerOnAcquireCallback(ExecuteMethod &&execute) {
_onAcquire = ccnew CallbackExecutable<ExecuteMethod>(std::forward<ExecuteMethod>(execute));
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,71 @@
/****************************************************************************
Copyright (c) 2020-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 <atomic>
#include "base/Macros.h"
#include "base/Ptr.h"
namespace cc {
namespace gfx {
struct DefaultDeleter {
template <typename T>
void operator()(T *ptr) const {
delete ptr;
}
};
template <typename Deleter = DefaultDeleter>
class GFXDeviceObject {
public:
virtual ~GFXDeviceObject() noexcept = default;
void addRef() const noexcept {
++_referenceCount;
}
void release() const noexcept {
// atomic::operator _Ty uses load(memory_order_seq_cst), all threads observe all modifications in the same order.
auto count = static_cast<int32_t>(--_referenceCount);
CC_ASSERT_GE(count, 0);
if (count == 0) {
Deleter()(this);
}
}
uint32_t getRefCount() const noexcept {
return static_cast<uint32_t>(_referenceCount);
}
protected:
GFXDeviceObject() noexcept = default;
mutable std::atomic_uint32_t _referenceCount{0};
};
template <typename T>
using ConstPtr = IntrusivePtr<const T>;
} // namespace gfx
} // namespace cc

View 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 "GFXFramebuffer.h"
#include "GFXRenderPass.h"
#include "GFXTexture.h"
#include "base/Utils.h"
namespace cc {
namespace gfx {
Framebuffer::Framebuffer()
: GFXObject(ObjectType::FRAMEBUFFER) {
}
Framebuffer::~Framebuffer() = default;
ccstd::hash_t Framebuffer::computeHash(const FramebufferInfo &info) {
return Hasher<FramebufferInfo>()(info);
}
void Framebuffer::initialize(const FramebufferInfo &info) {
_renderPass = info.renderPass;
_colorTextures = info.colorTextures;
_depthStencilTexture = info.depthStencilTexture;
_depthStencilResolveTexture = info.depthStencilResolveTexture;
doInit(info);
}
void Framebuffer::destroy() {
doDestroy();
_renderPass = nullptr;
_colorTextures.clear();
_depthStencilTexture = nullptr;
_depthStencilResolveTexture = nullptr;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,64 @@
/****************************************************************************
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 "GFXObject.h"
#include "base/Ptr.h"
#include "base/RefCounted.h"
#include "base/RefVector.h"
namespace cc {
namespace gfx {
class CC_DLL Framebuffer : public GFXObject, public RefCounted {
public:
Framebuffer();
~Framebuffer() override;
static ccstd::hash_t computeHash(const FramebufferInfo &info);
void initialize(const FramebufferInfo &info);
void destroy();
inline RenderPass *getRenderPass() const { return _renderPass; }
inline const TextureList &getColorTextures() const { return _colorTextures; }
inline Texture *getDepthStencilTexture() const { return _depthStencilTexture; }
inline Texture *getDepthStencilResolveTexture() const { return _depthStencilResolveTexture; }
protected:
virtual void doInit(const FramebufferInfo &info) = 0;
virtual void doDestroy() = 0;
// weak reference
RenderPass *_renderPass{nullptr};
// weak reference
TextureList _colorTextures;
// weak reference
Texture *_depthStencilTexture{nullptr};
Texture *_depthStencilResolveTexture{nullptr};
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,86 @@
/****************************************************************************
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 "base/std/hash/hash.h"
#include "GFXBuffer.h"
#include "GFXInputAssembler.h"
#include "GFXObject.h"
namespace cc {
namespace gfx {
InputAssembler::InputAssembler()
: GFXObject(ObjectType::INPUT_ASSEMBLER) {
}
InputAssembler::~InputAssembler() = default;
ccstd::hash_t InputAssembler::computeAttributesHash() const {
ccstd::hash_t seed = static_cast<uint32_t>(_attributes.size()) * 6;
for (const auto &attribute : _attributes) {
ccstd::hash_combine(seed, attribute.name);
ccstd::hash_combine(seed, attribute.format);
ccstd::hash_combine(seed, attribute.isNormalized);
ccstd::hash_combine(seed, attribute.stream);
ccstd::hash_combine(seed, attribute.isInstanced);
ccstd::hash_combine(seed, attribute.location);
}
return seed;
}
void InputAssembler::initialize(const InputAssemblerInfo &info) {
_attributes = info.attributes;
_vertexBuffers = info.vertexBuffers;
_indexBuffer = info.indexBuffer;
_indirectBuffer = info.indirectBuffer;
_attributesHash = computeAttributesHash();
if (_indexBuffer) {
_drawInfo.indexCount = _indexBuffer->getCount();
_drawInfo.firstIndex = 0;
} else if (!_vertexBuffers.empty()) {
_drawInfo.vertexCount = _vertexBuffers[0]->getCount();
_drawInfo.firstVertex = 0;
_drawInfo.vertexOffset = 0;
}
doInit(info);
}
void InputAssembler::destroy() {
doDestroy();
_attributes.clear();
_attributesHash = 0U;
_vertexBuffers.clear();
_indexBuffer = nullptr;
_indirectBuffer = nullptr;
_drawInfo = DrawInfo();
}
} // namespace gfx
} // namespace cc

View 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.
****************************************************************************/
#pragma once
#include "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL InputAssembler : public GFXObject, public RefCounted {
public:
InputAssembler();
~InputAssembler() override;
void initialize(const InputAssemblerInfo &info);
void destroy();
inline const AttributeList &getAttributes() const { return _attributes; }
inline const BufferList &getVertexBuffers() const { return _vertexBuffers; }
inline Buffer *getIndexBuffer() const { return _indexBuffer; }
inline Buffer *getIndirectBuffer() const { return _indirectBuffer; }
inline ccstd::hash_t getAttributesHash() const { return _attributesHash; }
inline const DrawInfo &getDrawInfo() const { return _drawInfo; }
inline void setDrawInfo(const DrawInfo &info) { _drawInfo = info; }
inline void setVertexCount(uint32_t count) { _drawInfo.vertexCount = count; }
inline void setFirstVertex(uint32_t first) { _drawInfo.firstVertex = first; }
inline void setIndexCount(uint32_t count) { _drawInfo.indexCount = count; }
inline void setFirstIndex(uint32_t first) { _drawInfo.firstIndex = first; }
inline void setVertexOffset(int32_t offset) { _drawInfo.vertexOffset = offset; }
inline void setInstanceCount(uint32_t count) { _drawInfo.instanceCount = count; }
inline void setFirstInstance(uint32_t first) { _drawInfo.firstInstance = first; }
inline uint32_t getVertexCount() const { return _drawInfo.vertexCount; }
inline uint32_t getFirstVertex() const { return _drawInfo.firstVertex; }
inline uint32_t getIndexCount() const { return _drawInfo.indexCount; }
inline uint32_t getFirstIndex() const { return _drawInfo.firstIndex; }
inline uint32_t getVertexOffset() const { return _drawInfo.vertexOffset; }
inline uint32_t getInstanceCount() const { return _drawInfo.instanceCount; }
inline uint32_t getFirstInstance() const { return _drawInfo.firstInstance; }
protected:
virtual void doInit(const InputAssemblerInfo &info) = 0;
virtual void doDestroy() = 0;
ccstd::hash_t computeAttributesHash() const;
AttributeList _attributes;
ccstd::hash_t _attributesHash = 0;
BufferList _vertexBuffers;
Buffer *_indexBuffer{nullptr};
Buffer *_indirectBuffer{nullptr};
DrawInfo _drawInfo;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,35 @@
/****************************************************************************
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 "GFXObject.h"
namespace cc {
namespace gfx {
GFXObject::GFXObject(ObjectType type)
: _objectType(type),
_objectID(generateObjectID<GFXObject>()) {}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,59 @@
/****************************************************************************
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 "GFXDef.h"
namespace cc {
namespace gfx {
class GFXObject {
public:
explicit GFXObject(ObjectType type);
virtual ~GFXObject() = default;
inline ObjectType getObjectType() const { return _objectType; }
inline uint32_t getObjectID() const { return _objectID; }
inline uint32_t getTypedID() const { return _typedID; }
inline static uint32_t getObjectID(const GFXObject *obj) {
return obj == nullptr ? INVALID_OBJECT_ID : obj->getObjectID();
}
protected:
template <typename T>
static uint32_t generateObjectID() noexcept {
static uint32_t generator = 1 << 16;
return ++generator;
}
static constexpr uint32_t INVALID_OBJECT_ID = 0;
ObjectType _objectType = ObjectType::UNKNOWN;
uint32_t _objectID = 0U;
uint32_t _typedID = 0U; // inited by sub-classes
};
} // namespace gfx
} // namespace cc

View 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 "GFXPipelineLayout.h"
#include "GFXObject.h"
namespace cc {
namespace gfx {
PipelineLayout::PipelineLayout()
: GFXObject(ObjectType::PIPELINE_LAYOUT) {
}
PipelineLayout::~PipelineLayout() = default;
void PipelineLayout::initialize(const PipelineLayoutInfo &info) {
_setLayouts = info.setLayouts;
doInit(info);
}
void PipelineLayout::destroy() {
doDestroy();
_setLayouts.clear();
}
} // namespace gfx
} // namespace cc

View 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 "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL PipelineLayout : public GFXObject, public RefCounted {
public:
PipelineLayout();
~PipelineLayout() override;
void initialize(const PipelineLayoutInfo &info);
void destroy();
inline const DescriptorSetLayoutList &getSetLayouts() const { return _setLayouts; }
protected:
virtual void doInit(const PipelineLayoutInfo &info) = 0;
virtual void doDestroy() = 0;
DescriptorSetLayoutList _setLayouts;
};
} // namespace gfx
} // namespace cc

View 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 "GFXPipelineState.h"
#include "GFXObject.h"
namespace cc {
namespace gfx {
PipelineState::PipelineState()
: GFXObject(ObjectType::PIPELINE_STATE) {
}
PipelineState::~PipelineState() = default;
void PipelineState::initialize(const PipelineStateInfo &info) {
_primitive = info.primitive;
_shader = info.shader;
_inputState = info.inputState;
_rasterizerState = info.rasterizerState;
_depthStencilState = info.depthStencilState;
_bindPoint = info.bindPoint;
_blendState = info.blendState;
_dynamicStates = info.dynamicStates;
_renderPass = info.renderPass;
_subpass = info.subpass;
_pipelineLayout = info.pipelineLayout;
doInit(info);
}
void PipelineState::destroy() {
doDestroy();
_shader = nullptr;
_renderPass = nullptr;
_pipelineLayout = nullptr;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,70 @@
/****************************************************************************
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 "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL PipelineState : public GFXObject, public RefCounted {
public:
PipelineState();
~PipelineState() override;
void initialize(const PipelineStateInfo &info);
void destroy();
inline Shader *getShader() const { return _shader; }
inline PipelineBindPoint getBindPoint() const { return _bindPoint; }
inline PrimitiveMode getPrimitive() const { return _primitive; }
inline DynamicStateFlags getDynamicStates() const { return _dynamicStates; }
inline const InputState &getInputState() const { return _inputState; }
inline const RasterizerState &getRasterizerState() const { return _rasterizerState; }
inline const DepthStencilState &getDepthStencilState() const { return _depthStencilState; }
inline const BlendState &getBlendState() const { return _blendState; }
inline const RenderPass *getRenderPass() const { return _renderPass; }
inline const PipelineLayout *getPipelineLayout() const { return _pipelineLayout; }
protected:
virtual void doInit(const PipelineStateInfo &info) = 0;
virtual void doDestroy() = 0;
Shader *_shader = nullptr;
PipelineBindPoint _bindPoint = PipelineBindPoint::GRAPHICS;
PrimitiveMode _primitive = PrimitiveMode::TRIANGLE_LIST;
DynamicStateFlags _dynamicStates = DynamicStateFlags::NONE;
InputState _inputState;
RasterizerState _rasterizerState;
DepthStencilState _depthStencilState;
BlendState _blendState;
RenderPass *_renderPass = nullptr;
uint32_t _subpass = 0U;
PipelineLayout *_pipelineLayout = nullptr;
};
} // namespace gfx
} // namespace cc

View 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.
****************************************************************************/
#include "GFXQueryPool.h"
namespace cc {
namespace gfx {
QueryPool::QueryPool()
: GFXObject(ObjectType::QUERY_POOL) {
}
QueryPool::~QueryPool() = default;
void QueryPool::initialize(const QueryPoolInfo &info) {
_type = info.type;
_maxQueryObjects = info.maxQueryObjects;
_forceWait = info.forceWait;
doInit(info);
}
void QueryPool::destroy() {
doDestroy();
_type = QueryType::OCCLUSION;
_maxQueryObjects = 0;
}
} // namespace gfx
} // namespace cc

View 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.
****************************************************************************/
#pragma once
#include <cstdint>
#include <mutex>
#include "GFXObject.h"
#include "base/std/container/unordered_map.h"
namespace cc {
namespace gfx {
/**
* QueryPool usage:
* Update
* Render
* getQueryPoolResults
* resetQueryPool
* for each renderObject
* beginQuery
* drawObject
* endQuery
* completeQueryPool
*/
class CC_DLL QueryPool : public GFXObject {
public:
QueryPool();
~QueryPool() override;
void initialize(const QueryPoolInfo &info);
void destroy();
inline bool hasResult(uint32_t id) { return _results.count(id) != 0; }
inline uint64_t getResult(uint32_t id) { return _results[id]; }
inline QueryType getType() const { return _type; }
inline uint32_t getMaxQueryObjects() const { return _maxQueryObjects; }
inline bool getForceWait() const { return _forceWait; }
protected:
virtual void doInit(const QueryPoolInfo &info) = 0;
virtual void doDestroy() = 0;
QueryType _type{QueryType::OCCLUSION};
uint32_t _maxQueryObjects{0};
bool _forceWait{true};
std::mutex _mutex;
ccstd::unordered_map<uint32_t, uint64_t> _results;
};
} // namespace gfx
} // namespace cc

View 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 "GFXQueue.h"
#include "GFXObject.h"
namespace cc {
namespace gfx {
Queue::Queue()
: GFXObject(ObjectType::QUEUE) {
}
Queue::~Queue() = default;
void Queue::initialize(const QueueInfo &info) {
_type = info.type;
doInit(info);
}
void Queue::destroy() {
doDestroy();
_type = QueueType::GRAPHICS;
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,56 @@
/****************************************************************************
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 "GFXObject.h"
#include "base/RefCounted.h"
#include "base/Utils.h"
namespace cc {
namespace gfx {
class CC_DLL Queue : public GFXObject, public RefCounted {
public:
Queue();
~Queue() override;
void initialize(const QueueInfo &info);
void destroy();
virtual void submit(CommandBuffer *const *cmdBuffs, uint32_t count) = 0;
inline void submit(const CommandBufferList &cmdBuffs) { submit(cmdBuffs.data(), utils::toUint(cmdBuffs.size())); }
inline QueueType getType() const { return _type; }
protected:
virtual void doInit(const QueueInfo &info) = 0;
virtual void doDestroy() = 0;
QueueType _type = QueueType::GRAPHICS;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,78 @@
/****************************************************************************
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 "base/std/hash/hash.h"
#include "GFXObject.h"
#include "GFXRenderPass.h"
#include "base/Utils.h"
#include "gfx-base/GFXDef-common.h"
namespace cc {
namespace gfx {
RenderPass::RenderPass()
: GFXObject(ObjectType::RENDER_PASS) {
}
RenderPass::~RenderPass() = default;
// Based on render pass compatibility
ccstd::hash_t RenderPass::computeHash() {
ccstd::hash_t seed = static_cast<uint32_t>(_colorAttachments.size()) * 2 + 3;
for (const ColorAttachment &ca : _colorAttachments) {
ccstd::hash_combine(seed, ca);
}
ccstd::hash_combine(seed, _depthStencilAttachment);
ccstd::hash_combine(seed, _depthStencilResolveAttachment);
ccstd::hash_combine(seed, _subpasses);
return seed;
}
ccstd::hash_t RenderPass::computeHash(const RenderPassInfo &info) {
return Hasher<RenderPassInfo>()(info);
}
void RenderPass::initialize(const RenderPassInfo &info) {
_colorAttachments = info.colorAttachments;
_depthStencilAttachment = info.depthStencilAttachment;
_depthStencilResolveAttachment = info.depthStencilResolveAttachment;
_subpasses = info.subpasses;
_dependencies = info.dependencies;
_hash = computeHash();
doInit(info);
}
void RenderPass::destroy() {
doDestroy();
_colorAttachments.clear();
_subpasses.clear();
_hash = 0U;
}
} // namespace gfx
} // namespace cc

View 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 "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL RenderPass : public GFXObject, public RefCounted {
public:
RenderPass();
~RenderPass() override;
static ccstd::hash_t computeHash(const RenderPassInfo &info);
void initialize(const RenderPassInfo &info);
void destroy();
inline const ColorAttachmentList &getColorAttachments() const { return _colorAttachments; }
inline const DepthStencilAttachment &getDepthStencilAttachment() const { return _depthStencilAttachment; }
inline const DepthStencilAttachment &getDepthStencilResolveAttachment() const { return _depthStencilResolveAttachment; }
inline const SubpassInfoList &getSubpasses() const { return _subpasses; }
inline const SubpassDependencyList &getDependencies() const { return _dependencies; }
inline ccstd::hash_t getHash() const { return _hash; }
protected:
ccstd::hash_t computeHash();
virtual void doInit(const RenderPassInfo &info) = 0;
virtual void doDestroy() = 0;
ColorAttachmentList _colorAttachments;
DepthStencilAttachment _depthStencilAttachment;
DepthStencilAttachment _depthStencilResolveAttachment;
SubpassInfoList _subpasses;
SubpassDependencyList _dependencies;
ccstd::hash_t _hash = 0;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,68 @@
/****************************************************************************
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 "GFXShader.h"
#include "GFXDevice.h"
#include "GFXObject.h"
namespace cc {
namespace gfx {
Shader::Shader()
: GFXObject(ObjectType::SHADER) {
}
Shader::~Shader() = default;
void Shader::initialize(const ShaderInfo &info) {
_name = info.name;
_stages = info.stages;
_attributes = info.attributes;
_blocks = info.blocks;
_buffers = info.buffers;
_samplerTextures = info.samplerTextures;
_samplers = info.samplers;
_textures = info.textures;
_images = info.images;
_subpassInputs = info.subpassInputs;
_hash = info.hash;
doInit(info);
}
void Shader::destroy() {
doDestroy();
_stages.clear();
_attributes.clear();
_blocks.clear();
_buffers.clear();
_samplerTextures.clear();
_samplers.clear();
_textures.clear();
_images.clear();
_subpassInputs.clear();
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,70 @@
/****************************************************************************
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 "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL Shader : public GFXObject, public RefCounted {
public:
Shader();
~Shader() override;
void initialize(const ShaderInfo &info);
void destroy();
inline const ccstd::string &getName() const { return _name; }
inline const ShaderStageList &getStages() const { return _stages; }
inline const AttributeList &getAttributes() const { return _attributes; }
inline const UniformBlockList &getBlocks() const { return _blocks; }
inline const UniformStorageBufferList &getBuffers() const { return _buffers; }
inline const UniformSamplerTextureList &getSamplerTextures() const { return _samplerTextures; }
inline const UniformSamplerList &getSamplers() const { return _samplers; }
inline const UniformTextureList &getTextures() const { return _textures; }
inline const UniformStorageImageList &getImages() const { return _images; }
inline const UniformInputAttachmentList &getSubpassInputs() const { return _subpassInputs; }
protected:
virtual void doInit(const ShaderInfo &info) = 0;
virtual void doDestroy() = 0;
ccstd::string _name;
ShaderStageList _stages;
AttributeList _attributes;
UniformBlockList _blocks;
UniformStorageBufferList _buffers;
UniformSamplerTextureList _samplerTextures;
UniformSamplerList _samplers;
UniformTextureList _textures;
UniformStorageImageList _images;
UniformInputAttachmentList _subpassInputs;
ccstd::hash_t _hash = 0;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,60 @@
/****************************************************************************
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 "GFXSwapchain.h"
namespace cc {
namespace gfx {
Swapchain::Swapchain()
: GFXObject(ObjectType::SWAPCHAIN) {
}
Swapchain::~Swapchain() = default;
void Swapchain::initialize(const SwapchainInfo &info) {
#if !defined(CC_SERVER_MODE)
CC_ASSERT(info.windowHandle);
#endif
_windowId = info.windowId;
_windowHandle = info.windowHandle;
_vsyncMode = info.vsyncMode;
doInit(info);
}
void Swapchain::destroy() {
doDestroy();
_windowHandle = nullptr;
_windowId = 0;
}
void Swapchain::resize(uint32_t width, uint32_t height, SurfaceTransform transform) {
doResize(width, height, transform);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,111 @@
/****************************************************************************
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 "GFXTexture.h"
#include "base/Ptr.h"
#include "gfx-base/GFXDef-common.h"
namespace cc {
namespace gfx {
class CC_DLL Swapchain : public GFXObject {
public:
Swapchain();
~Swapchain() override;
void initialize(const SwapchainInfo &info);
void destroy();
/**
* Resize the swapchain with the given metric.
* Note that you should invoke this function iff when there is actual
* size or orientation changes, with the up-to-date information about
* the underlying surface.
*
* @param width The width of the surface in oriented screen space
* @param height The height of the surface in oriented screen space
* @param transform The orientation of the surface
*/
void resize(uint32_t width, uint32_t height, SurfaceTransform transform);
inline void destroySurface();
inline void createSurface(void *windowHandle);
inline uint32_t getWindowId() const { return _windowId; }
inline void *getWindowHandle() const { return _windowHandle; }
inline VsyncMode getVSyncMode() const { return _vsyncMode; }
inline Texture *getColorTexture() const { return _colorTexture; }
inline Texture *getDepthStencilTexture() const { return _depthStencilTexture; }
inline SurfaceTransform getSurfaceTransform() const { return _transform; }
inline uint32_t getWidth() const { return _colorTexture->getWidth(); }
inline uint32_t getHeight() const { return _colorTexture->getHeight(); }
inline uint32_t getGeneration() const { return _generation; }
protected:
virtual void doInit(const SwapchainInfo &info) = 0;
virtual void doDestroy() = 0;
virtual void doResize(uint32_t width, uint32_t height, SurfaceTransform transform) = 0;
virtual void doDestroySurface() = 0;
virtual void doCreateSurface(void *windowHandle) = 0;
static inline void initTexture(const SwapchainTextureInfo &info, Texture *texture);
static inline void updateTextureInfo(const SwapchainTextureInfo &info, Texture *texture);
uint32_t _windowId{0};
void *_windowHandle{nullptr};
VsyncMode _vsyncMode{VsyncMode::RELAXED};
SurfaceTransform _transform{SurfaceTransform::IDENTITY};
bool _preRotationEnabled{false};
uint32_t _generation{0};
IntrusivePtr<Texture> _colorTexture;
IntrusivePtr<Texture> _depthStencilTexture;
};
///////////////////////////////////////////////////////////
void Swapchain::destroySurface() {
doDestroySurface();
_windowHandle = nullptr;
}
void Swapchain::createSurface(void *windowHandle) {
_windowHandle = windowHandle;
doCreateSurface(windowHandle);
}
void Swapchain::initTexture(const SwapchainTextureInfo &info, Texture *texture) {
Texture::initialize(info, texture);
}
void Swapchain::updateTextureInfo(const SwapchainTextureInfo &info, Texture *texture) {
Texture::updateTextureInfo(info, texture);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,152 @@
/****************************************************************************
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 "base/Utils.h"
#include "GFXSwapchain.h"
#include "GFXTexture.h"
#include "base/std/hash/hash.h"
namespace cc {
namespace gfx {
Texture::Texture()
: GFXObject(ObjectType::TEXTURE) {
}
Texture::~Texture() = default;
ccstd::hash_t Texture::computeHash(const TextureInfo &info) {
return Hasher<TextureInfo>()(info);
}
ccstd::hash_t Texture::computeHash(const TextureViewInfo &info) {
return Hasher<TextureViewInfo>()(info);
}
ccstd::hash_t Texture::computeHash(const Texture *texture) {
ccstd::hash_t hash = texture->isTextureView() ? computeHash(texture->getViewInfo()) : computeHash(texture->getInfo());
if (texture->_swapchain) {
ccstd::hash_combine(hash, texture->_swapchain->getObjectID());
ccstd::hash_combine(hash, texture->_swapchain->getGeneration());
}
return hash;
}
void Texture::initialize(const TextureInfo &info) {
_info = info;
_size = formatSize(_info.format, _info.width, _info.height, _info.depth);
_hash = computeHash(info);
_viewInfo.texture = this;
_viewInfo.format = _info.format;
_viewInfo.type = _info.type;
_viewInfo.baseLayer = 0;
_viewInfo.layerCount = _info.layerCount;
_viewInfo.baseLevel = 0;
_viewInfo.levelCount = _info.levelCount;
doInit(info);
}
void Texture::initialize(const TextureViewInfo &info) {
_info = info.texture->getInfo();
_viewInfo = info;
_isTextureView = true;
_size = formatSize(_info.format, _info.width, _info.height, _info.depth);
_hash = computeHash(info);
doInit(info);
}
uint32_t getLevelCount(uint32_t width, uint32_t height) {
return static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
}
void Texture::resize(uint32_t width, uint32_t height) {
if (_info.width != width || _info.height != height) {
if (_info.levelCount == getLevelCount(_info.width, _info.height)) {
_info.levelCount = getLevelCount(width, height);
} else if (_info.levelCount > 1) {
_info.levelCount = std::min(_info.levelCount, getLevelCount(width, height));
}
uint32_t size = formatSize(_info.format, width, height, _info.depth);
doResize(width, height, size);
_info.width = width;
_info.height = height;
_size = size;
_hash = computeHash(this);
}
}
void Texture::destroy() {
doDestroy();
_info = TextureInfo();
_viewInfo = TextureViewInfo();
_isTextureView = false;
_hash = _size = 0;
}
///////////////////////////// Swapchain Specific /////////////////////////////
void Texture::initialize(const SwapchainTextureInfo &info, Texture *out) {
updateTextureInfo(info, out);
out->doInit(info);
}
void Texture::updateTextureInfo(const SwapchainTextureInfo &info, Texture *out) {
out->_info.type = TextureType::TEX2D;
out->_info.format = info.format;
out->_info.width = info.width;
out->_info.height = info.height;
out->_info.layerCount = 1;
out->_info.levelCount = 1;
out->_info.depth = 1;
out->_info.samples = SampleCount::X1;
out->_info.flags = TextureFlagBit::NONE;
out->_info.usage = TextureUsageBit::SAMPLED | (GFX_FORMAT_INFOS[toNumber(info.format)].hasDepth
? TextureUsageBit::DEPTH_STENCIL_ATTACHMENT
: TextureUsageBit::COLOR_ATTACHMENT);
out->_swapchain = info.swapchain;
out->_size = formatSize(info.format, info.width, info.height, 1);
out->_hash = computeHash(out);
out->_viewInfo.texture = out;
out->_viewInfo.format = out->_info.format;
out->_viewInfo.type = out->_info.type;
out->_viewInfo.baseLayer = 0;
out->_viewInfo.layerCount = out->_info.layerCount;
out->_viewInfo.baseLevel = 0;
out->_viewInfo.levelCount = out->_info.levelCount;
out->_viewInfo.basePlane = 0;
out->_viewInfo.planeCount = info.format == gfx::Format::DEPTH_STENCIL ? 2 : 1;
}
} // namespace gfx
} // namespace cc

View 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.
****************************************************************************/
#pragma once
#include "GFXObject.h"
#include "base/RefCounted.h"
namespace cc {
namespace gfx {
class CC_DLL Texture : public GFXObject, public RefCounted {
public:
Texture();
~Texture() override;
static ccstd::hash_t computeHash(const TextureInfo &info);
static ccstd::hash_t computeHash(const TextureViewInfo &info);
void initialize(const TextureInfo &info);
void initialize(const TextureViewInfo &info);
void resize(uint32_t width, uint32_t height);
void destroy();
inline const TextureInfo &getInfo() const { return _info; }
inline const TextureViewInfo &getViewInfo() const { return _viewInfo; }
inline bool isTextureView() const { return _isTextureView; }
inline uint32_t getSize() const { return _size; }
inline ccstd::hash_t getHash() const { return _hash; }
// convenient getter for common usages
inline Format getFormat() const { return _isTextureView ? _viewInfo.format : _info.format; }
inline uint32_t getWidth() const { return _info.width; }
inline uint32_t getHeight() const { return _info.height; }
virtual const Texture *getRaw() const { return this; }
virtual uint32_t getGLTextureHandle() const noexcept { return 0; }
protected:
friend class Swapchain;
virtual void doInit(const TextureInfo &info) = 0;
virtual void doInit(const TextureViewInfo &info) = 0;
virtual void doDestroy() = 0;
virtual void doResize(uint32_t width, uint32_t height, uint32_t size) = 0;
static ccstd::hash_t computeHash(const Texture *texture);
static void initialize(const SwapchainTextureInfo &info, Texture *out);
static void updateTextureInfo(const SwapchainTextureInfo &info, Texture *out);
virtual void doInit(const SwapchainTextureInfo &info) = 0;
TextureInfo _info;
TextureViewInfo _viewInfo;
Swapchain *_swapchain{nullptr};
bool _isTextureView{false};
uint32_t _size{0U};
ccstd::hash_t _hash{0U};
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,34 @@
/****************************************************************************
Copyright (c) 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 "GFXUtil.h"
#include "platform/FileUtils.h"
namespace cc::gfx {
ccstd::string getPipelineCacheFolder() {
return FileUtils::getInstance()->getWritablePath();
}
} // namespace cc::gfx

View File

@@ -0,0 +1,34 @@
/****************************************************************************
Copyright (c) 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/std/container/string.h"
namespace cc::gfx {
// FileUtils `enum class Status conflicts` with `#define Status int` in Xlib.h
ccstd::string getPipelineCacheFolder();
} // namespace cc::gfx

View File

@@ -0,0 +1,254 @@
/****************************************************************************
Copyright (c) 2020-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 "SPIRVUtils.h"
#include "base/Log.h"
#include "base/Utils.h"
#include "glslang/Public/ShaderLang.h"
#include "glslang/SPIRV/GlslangToSpv.h"
#include "glslang/StandAlone/ResourceLimits.h"
#include "spirv/spirv.h"
#define CC_GLSLANG_VERSION_GREATOR_OR_EQUAL_TO(major, minor, patch) \
(((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \
(((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \
((patch) <= GLSLANG_VERSION_PATCH)))))
namespace cc {
namespace gfx {
namespace {
EShLanguage getShaderStage(ShaderStageFlagBit type) {
switch (type) {
case ShaderStageFlagBit::VERTEX: return EShLangVertex;
case ShaderStageFlagBit::CONTROL: return EShLangTessControl;
case ShaderStageFlagBit::EVALUATION: return EShLangTessEvaluation;
case ShaderStageFlagBit::GEOMETRY: return EShLangGeometry;
case ShaderStageFlagBit::FRAGMENT: return EShLangFragment;
case ShaderStageFlagBit::COMPUTE: return EShLangCompute;
default: {
CC_ABORT();
return EShLangVertex;
}
}
}
#include <glslang/build_info.h>
glslang::EShTargetClientVersion getClientVersion(int vulkanMinorVersion) {
switch (vulkanMinorVersion) {
case 0: return glslang::EShTargetVulkan_1_0;
case 1: return glslang::EShTargetVulkan_1_1;
case 2: return glslang::EShTargetVulkan_1_2;
#if CC_GLSLANG_VERSION_GREATOR_OR_EQUAL_TO(11, 10, 0)
case 3: return glslang::EShTargetVulkan_1_3;
#else
case 3: return glslang::EShTargetVulkan_1_2;
#endif
default: {
CC_ABORT();
return glslang::EShTargetVulkan_1_0;
}
}
}
glslang::EShTargetLanguageVersion getTargetVersion(int vulkanMinorVersion) {
switch (vulkanMinorVersion) {
case 0: return glslang::EShTargetSpv_1_0;
case 1: return glslang::EShTargetSpv_1_3;
case 2: return glslang::EShTargetSpv_1_5;
#if CC_GLSLANG_VERSION_GREATOR_OR_EQUAL_TO(11, 10, 0)
case 3: return glslang::EShTargetSpv_1_6;
#else
case 3: return glslang::EShTargetSpv_1_5;
#endif
default: {
CC_ABORT();
return glslang::EShTargetSpv_1_0;
}
}
}
// https://www.khronos.org/registry/spir-v/specs/1.0/SPIRV.pdf
struct Id {
uint32_t opcode{0};
uint32_t typeId{0};
uint32_t storageClass{0};
uint32_t *pLocation{nullptr};
};
} // namespace
SPIRVUtils SPIRVUtils::instance;
void SPIRVUtils::initialize(int vulkanMinorVersion) {
glslang::InitializeProcess();
_clientInputSemanticsVersion = 100 + vulkanMinorVersion * 10;
_clientVersion = getClientVersion(vulkanMinorVersion);
_targetVersion = getTargetVersion(vulkanMinorVersion);
}
void SPIRVUtils::destroy() {
glslang::FinalizeProcess();
_output.clear();
}
void SPIRVUtils::compileGLSL(ShaderStageFlagBit type, const ccstd::string &source) {
EShLanguage stage = getShaderStage(type);
const char *string = source.c_str();
_shader = std::make_unique<glslang::TShader>(stage);
_shader->setStrings(&string, 1);
_shader->setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, _clientInputSemanticsVersion);
_shader->setEnvClient(glslang::EShClientVulkan, _clientVersion);
_shader->setEnvTarget(glslang::EShTargetSpv, _targetVersion);
auto messages = static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
if (!_shader->parse(&glslang::DefaultTBuiltInResource, _clientInputSemanticsVersion, false, messages)) {
CC_LOG_ERROR("GLSL Parsing Failed:\n%s\n%s", _shader->getInfoLog(), _shader->getInfoDebugLog());
}
_program = std::make_unique<glslang::TProgram>();
_program->addShader(_shader.get());
if (!_program->link(messages)) {
CC_LOG_ERROR("GLSL Linking Failed:\n%s\n%s", _program->getInfoLog(), _program->getInfoDebugLog());
}
_output.clear();
spv::SpvBuildLogger logger;
glslang::SpvOptions spvOptions;
spvOptions.disableOptimizer = false; // Do not disable optimizer in debug mode. It will cause the shader to fail to compile.
spvOptions.optimizeSize = true;
#if CC_DEBUG > 0
// spvOptions.validate = true;
#else
spvOptions.stripDebugInfo = true;
#endif
glslang::GlslangToSpv(*_program->getIntermediate(stage), _output, &logger, &spvOptions);
}
void SPIRVUtils::compressInputLocations(gfx::AttributeList &attributes) {
static ccstd::vector<Id> ids;
static ccstd::vector<uint32_t> activeLocations;
static ccstd::vector<uint32_t> newLocations;
uint32_t *code = _output.data();
uint32_t codeSize = utils::toUint(_output.size());
CC_ASSERT(code[0] == SpvMagicNumber);
uint32_t idBound = code[3];
ids.assign(idBound, {});
uint32_t *insn = code + 5;
while (insn != code + codeSize) {
auto opcode = static_cast<uint16_t>(insn[0]);
auto wordCount = static_cast<uint16_t>(insn[0] >> 16);
switch (opcode) {
case SpvOpDecorate: {
CC_ASSERT_GE(wordCount, 3);
uint32_t id = insn[1];
CC_ASSERT_LT(id, idBound);
switch (insn[2]) {
case SpvDecorationLocation:
CC_ASSERT_EQ(wordCount, 4);
ids[id].pLocation = &insn[3];
break;
}
} break;
case SpvOpVariable: {
CC_ASSERT_GE(wordCount, 4);
uint32_t id = insn[2];
CC_ASSERT_LT(id, idBound);
CC_ASSERT(ids[id].opcode == 0);
ids[id].opcode = opcode;
ids[id].typeId = insn[1];
ids[id].storageClass = insn[3];
} break;
}
CC_ASSERT(insn + wordCount <= code + codeSize);
insn += wordCount;
}
_program->buildReflection();
activeLocations.clear();
int activeCount = _program->getNumPipeInputs();
for (int i = 0; i < activeCount; ++i) {
activeLocations.push_back(_program->getPipeInput(i).getType()->getQualifier().layoutLocation);
}
uint32_t location = 0;
uint32_t unusedLocation = activeCount;
newLocations.assign(attributes.size(), UINT_MAX);
for (auto &id : ids) {
if (id.opcode == SpvOpVariable && id.storageClass == SpvStorageClassInput && id.pLocation) {
uint32_t oldLocation = *id.pLocation;
// update locations in SPIRV
if (std::find(activeLocations.begin(), activeLocations.end(), *id.pLocation) != activeLocations.end()) {
*id.pLocation = location++;
} else {
*id.pLocation = unusedLocation++;
}
// save record
bool found{false};
for (size_t i = 0; i < attributes.size(); ++i) {
if (attributes[i].location == oldLocation) {
newLocations[i] = *id.pLocation;
found = true;
break;
}
}
// Missing attribute declarations?
CC_ASSERT(found);
}
}
// update gfx references
for (size_t i = 0; i < attributes.size(); ++i) {
attributes[i].location = newLocations[i];
}
attributes.erase(std::remove_if(attributes.begin(), attributes.end(), [](const auto &attr) {
return attr.location == UINT_MAX;
}),
attributes.end());
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,67 @@
/****************************************************************************
Copyright (c) 2020-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 <memory>
#include "gfx-base/GFXDef.h"
#include "glslang/Public/ShaderLang.h"
namespace cc {
namespace gfx {
class SPIRVUtils {
public:
static SPIRVUtils *getInstance() { return &instance; }
void initialize(int vulkanMinorVersion);
void destroy();
void compileGLSL(ShaderStageFlagBit type, const ccstd::string &source);
void compressInputLocations(gfx::AttributeList &attributes);
inline uint32_t *getOutputData() {
_shader.reset();
_program.reset();
return _output.data();
}
inline size_t getOutputSize() {
return _output.size() * sizeof(uint32_t);
}
private:
int _clientInputSemanticsVersion{0};
glslang::EShTargetClientVersion _clientVersion{glslang::EShTargetClientVersion::EShTargetVulkan_1_0};
glslang::EShTargetLanguageVersion _targetVersion{glslang::EShTargetLanguageVersion::EShTargetSpv_1_0};
std::unique_ptr<glslang::TShader> _shader{nullptr};
std::unique_ptr<glslang::TProgram> _program{nullptr};
ccstd::vector<uint32_t> _output;
static SPIRVUtils instance;
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,45 @@
/****************************************************************************
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 "GFXBufferBarrier.h"
#include "../GFXQueue.h"
#include "base/Utils.h"
#include "base/std/hash/hash.h"
#include "gfx-base/GFXDef-common.h"
namespace cc {
namespace gfx {
BufferBarrier::BufferBarrier(const BufferBarrierInfo &info)
: GFXObject(ObjectType::BUFFER_BARRIER) {
_info = info;
_hash = computeHash(info);
}
ccstd::hash_t BufferBarrier::computeHash(const BufferBarrierInfo &info) {
return Hasher<BufferBarrierInfo>()(info);
}
} // namespace gfx
} // namespace cc

View 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 "../GFXObject.h"
#include "gfx-base/GFXDef-common.h"
namespace cc {
namespace gfx {
class CC_DLL BufferBarrier : public GFXObject {
public:
explicit BufferBarrier(const BufferBarrierInfo &info);
static ccstd::hash_t computeHash(const BufferBarrierInfo &info);
inline const BufferBarrierInfo &getInfo() const { return _info; }
inline const ccstd::hash_t &getHash() const { return _hash; }
protected:
BufferBarrierInfo _info;
ccstd::hash_t _hash{0U};
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,44 @@
/****************************************************************************
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 "base/std/hash/hash.h"
#include "GFXGeneralBarrier.h"
#include "base/Utils.h"
namespace cc {
namespace gfx {
GeneralBarrier::GeneralBarrier(const GeneralBarrierInfo &info)
: GFXObject(ObjectType::GLOBAL_BARRIER) {
_info = info;
_hash = computeHash(info);
}
ccstd::hash_t GeneralBarrier::computeHash(const GeneralBarrierInfo &info) {
return Hasher<GeneralBarrierInfo>()(info);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,47 @@
/****************************************************************************
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 "../GFXObject.h"
namespace cc {
namespace gfx {
class CC_DLL GeneralBarrier : public GFXObject {
public:
explicit GeneralBarrier(const GeneralBarrierInfo &info);
static ccstd::hash_t computeHash(const GeneralBarrierInfo &info);
inline const GeneralBarrierInfo &getInfo() const { return _info; }
inline const ccstd::hash_t &getHash() const { return _hash; }
protected:
GeneralBarrierInfo _info;
ccstd::hash_t _hash{0U};
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,54 @@
/****************************************************************************
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 "GFXSampler.h"
namespace cc {
namespace gfx {
Sampler::Sampler(const SamplerInfo &info)
: GFXObject(ObjectType::SAMPLER) {
_info = info;
_hash = computeHash(info);
}
ccstd::hash_t Sampler::computeHash(const SamplerInfo &info) {
return Hasher<SamplerInfo>()(info);
}
SamplerInfo Sampler::unpackFromHash(ccstd::hash_t hash) {
SamplerInfo info;
info.minFilter = static_cast<Filter>((hash & ((1 << 2) - 1)) >> 0);
info.magFilter = static_cast<Filter>((hash & ((1 << 2) - 1)) >> 2);
info.mipFilter = static_cast<Filter>((hash & ((1 << 2) - 1)) >> 4);
info.addressU = static_cast<Address>((hash & ((1 << 2) - 1)) >> 6);
info.addressV = static_cast<Address>((hash & ((1 << 2) - 1)) >> 8);
info.addressW = static_cast<Address>((hash & ((1 << 2) - 1)) >> 10);
info.maxAnisotropy = (hash & ((1 << 4) - 1)) >> 12;
info.cmpFunc = static_cast<ComparisonFunc>((hash & ((1 << 3) - 1)) >> 16);
return info;
}
} // namespace gfx
} // namespace cc

View 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 "../GFXObject.h"
#include "base/std/hash/hash.h"
#include "gfx-base/GFXDef-common.h"
namespace cc {
namespace gfx {
class CC_DLL Sampler : public GFXObject {
public:
explicit Sampler(const SamplerInfo &info);
static ccstd::hash_t computeHash(const SamplerInfo &info);
static SamplerInfo unpackFromHash(ccstd::hash_t hash);
inline const SamplerInfo &getInfo() const { return _info; }
inline const ccstd::hash_t &getHash() const { return _hash; }
protected:
SamplerInfo _info;
ccstd::hash_t _hash{0U};
};
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,44 @@
/****************************************************************************
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 "GFXTextureBarrier.h"
#include "../GFXQueue.h"
#include "base/Utils.h"
#include "base/std/hash/hash.h"
namespace cc {
namespace gfx {
TextureBarrier::TextureBarrier(const TextureBarrierInfo &info)
: GFXObject(ObjectType::TEXTURE_BARRIER) {
_info = info;
_hash = computeHash(info);
}
ccstd::hash_t TextureBarrier::computeHash(const TextureBarrierInfo &info) {
return Hasher<TextureBarrierInfo>()(info);
}
} // namespace gfx
} // namespace cc

View File

@@ -0,0 +1,47 @@
/****************************************************************************
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 "../GFXObject.h"
namespace cc {
namespace gfx {
class CC_DLL TextureBarrier : public GFXObject {
public:
explicit TextureBarrier(const TextureBarrierInfo &info);
static ccstd::hash_t computeHash(const TextureBarrierInfo &info);
inline const TextureBarrierInfo &getInfo() const { return _info; }
inline const ccstd::hash_t &getHash() const { return _hash; }
protected:
TextureBarrierInfo _info;
ccstd::hash_t _hash{0U};
};
} // namespace gfx
} // namespace cc