Skip to content

Commit

Permalink
compute storage for web
Browse files Browse the repository at this point in the history
  • Loading branch information
hana-alice committed Oct 10, 2023
1 parent f36d85a commit b60172d
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 27 deletions.
5 changes: 4 additions & 1 deletion cocos/rendering/custom/web-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ export class WebComputePassBuilder extends WebSetter implements ComputePassBuild
this._addComputeResource(name, accessType, slotName);
}
addStorageImage (name: string, accessType: AccessType, slotName: string): void {
throw new Error('Method not implemented.');
this._addComputeResource(name, accessType, slotName);
}
addMaterialTexture (resourceName: string, flags?: ShaderStageFlagBit | undefined): void {
throw new Error('Method not implemented.');
Expand Down Expand Up @@ -1493,6 +1493,9 @@ export class WebPipeline implements BasicPipeline {
}
updateRenderWindow (name: string, renderWindow: RenderWindow): void {
const resId = this.resourceGraph.vertex(name);
const desc = this.resourceGraph.getDesc(resId);
desc.width = renderWindow.width;
desc.height = renderWindow.height;
const currFbo = this.resourceGraph._vertices[resId]._object;
if (currFbo !== renderWindow.framebuffer) {
this.resourceGraph._vertices[resId]._object = renderWindow.framebuffer;
Expand Down
13 changes: 10 additions & 3 deletions cocos/rendering/custom/web-program-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,20 @@ function overwriteShaderSourceBinding (shaderInfo: ShaderInfo, source: string):
code = code.replace(samplerIter[0], replaceStr);
samplerIter = samplerExp.exec(code);
}
const blockExp = /layout\s*\(([^\)])+\)\s*(readonly)?\s*\b(uniform|buffer)\b\s+(\b\w+\b)\s*[{;]/g;
const blockExp = /layout\s*\(([^\)]+)\)\s*(readonly|writeonly)?\s*\b((uniform\s+|buffer|image2D){1,2})\b\s+(\b\w+\b)\s*[{;]/g;
let blockIter = blockExp.exec(code);
while (blockIter) {
const name = blockIter[4];
const name = blockIter[5];
const { set, binding } = findBinding(shaderInfo, name);
const accessStr = blockIter[2] ? blockIter[2] : '';
const replaceStr = `layout(set = ${set}, binding = ${binding}) ${accessStr} ${blockIter[3]} ${blockIter[4]} {`;
let endStr = ' {';
if (blockIter[3].includes('image')) {
endStr = `;`;
}
let desc = blockIter[1];
desc = desc.replace(/set\s*=\s*\d+/g, `set = ${set}`);
desc = desc.replace(/binding\s*=\s*\d+/g, `binding = ${binding}`);
const replaceStr = `layout(${desc}) ${accessStr} ${blockIter[3]} ${blockIter[5]}` + endStr;
code = code.replace(blockIter[0], replaceStr);
blockIter = blockExp.exec(code);
}
Expand Down
10 changes: 5 additions & 5 deletions native/cocos/renderer/gfx-base/GFXBarrier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ constexpr AccessElem ACCESS_MAP[] = {
AccessFlags::VERTEX_SHADER_READ_TEXTURE},

{IGNORE_MEMUSAGE & IGNORE_RESTYPE,
ACCESS_READ | SHADERSTAGE_VERT | CMN_STORAGE,
ACCESS_READ | ACCESS_WRITE | SHADERSTAGE_VERT | CMN_STORAGE,
AccessFlags::VERTEX_SHADER_READ_OTHER},

{IGNORE_MEMUSAGE,
Expand All @@ -251,7 +251,7 @@ constexpr AccessElem ACCESS_MAP[] = {
{CARE_MEMACCESS | CARE_RESTYPE | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_ROM,
AccessFlags::FRAGMENT_SHADER_READ_TEXTURE,
CMN_STORAGE | CMN_VB_OR_DS},
CMN_VB_OR_DS},

{IGNORE_MEMUSAGE,
ACCESS_READ | RES_TEXTURE | SHADERSTAGE_FRAG | CMN_IB_OR_CA | CMN_INDIRECT_OR_INPUT,
Expand All @@ -262,7 +262,7 @@ constexpr AccessElem ACCESS_MAP[] = {
AccessFlags::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT},

{IGNORE_MEMUSAGE & IGNORE_RESTYPE,
ACCESS_READ | SHADERSTAGE_FRAG | CMN_STORAGE,
ACCESS_READ | ACCESS_WRITE | SHADERSTAGE_FRAG | CMN_STORAGE,
AccessFlags::FRAGMENT_SHADER_READ_OTHER,
CMN_SHADING_RATE},

Expand All @@ -285,9 +285,9 @@ constexpr AccessElem ACCESS_MAP[] = {

// shading rate has its own flag
{CARE_MEMACCESS | CARE_SHADERSTAGE | CARE_CMNUSAGE,
ACCESS_READ | SHADERSTAGE_COMP | CMN_STORAGE,
ACCESS_READ | ACCESS_WRITE | SHADERSTAGE_COMP | CMN_STORAGE,
AccessFlags::COMPUTE_SHADER_READ_OTHER,
RES_TEXTURE | CMN_ROM},
CMN_ROM},

{CARE_MEMACCESS | CARE_CMNUSAGE,
ACCESS_READ | CMN_COPY_SRC,
Expand Down
7 changes: 5 additions & 2 deletions native/cocos/renderer/gfx-vulkan/VKGPUObjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -1062,8 +1062,11 @@ class CCVKGPUDescriptorHub final {
if (hasFlag(texture->gpuTexture->flags, TextureFlagBit::GENERAL_LAYOUT)) {
descriptor->imageLayout = VK_IMAGE_LAYOUT_GENERAL;
} else {
if (hasAllFlags(flags, AccessFlagBit::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | AccessFlagBit::COLOR_ATTACHMENT_WRITE) ||
hasAllFlags(flags, AccessFlagBit::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT | AccessFlagBit::DEPTH_STENCIL_ATTACHMENT_WRITE)) {
bool inoutAttachment = hasAllFlags(flags, AccessFlagBit::FRAGMENT_SHADER_READ_COLOR_INPUT_ATTACHMENT | AccessFlagBit::COLOR_ATTACHMENT_WRITE) ||
hasAllFlags(flags, AccessFlagBit::FRAGMENT_SHADER_READ_DEPTH_STENCIL_INPUT_ATTACHMENT | AccessFlagBit::DEPTH_STENCIL_ATTACHMENT_WRITE);
bool storageWrite = hasAnyFlags(flags, AccessFlagBit::VERTEX_SHADER_WRITE | AccessFlagBit::FRAGMENT_SHADER_WRITE | AccessFlagBit::COMPUTE_SHADER_WRITE);

if (inoutAttachment || storageWrite) {
descriptor->imageLayout = VK_IMAGE_LAYOUT_GENERAL;
} else if (hasFlag(texture->gpuTexture->usage, TextureUsage::DEPTH_STENCIL_ATTACHMENT)) {
descriptor->imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
Expand Down
12 changes: 8 additions & 4 deletions native/cocos/renderer/gfx-wgpu/WGPUDescriptorSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ void CCWGPUDescriptorSet::update() {
auto &bindGroupEntry = _gpuBindGroupObj->bindGroupEntries.emplace_back();
bindGroupEntry.binding = binding.binding;
bindGroupEntry.textureView = static_cast<WGPUTextureView>(ccTexture->getPlaneView(0));
dsLayout->updateTextureLayout(i, ccTexture);
dsLayout->updateSampledTextureLayout(i, ccTexture);
_gpuDescriptorObj->gpuDescriptors[i].texture = ccTexture;

auto &sBindGroupEntry = _gpuBindGroupObj->bindGroupEntries.emplace_back();
Expand All @@ -204,14 +204,18 @@ void CCWGPUDescriptorSet::update() {
_gpuDescriptorObj->gpuDescriptors[i].sampler = ccSampler;
} else if (DescriptorType::STORAGE_IMAGE == bindings[i].descriptorType || DescriptorType::TEXTURE == bindings[i].descriptorType) {
auto *ccTexture = _textures[resourceIndex].ptr ? static_cast<CCWGPUTexture *>(_textures[resourceIndex].ptr) : CCWGPUTexture::defaultCommonTexture();
auto &bindGroupEntry = _gpuBindGroupObj->bindGroupEntries[resourceIndex];
auto &bindGroupEntry = _gpuBindGroupObj->bindGroupEntries.emplace_back();
bindGroupEntry.binding = binding.binding;
bindGroupEntry.textureView = static_cast<WGPUTextureView>(ccTexture->getPlaneView(0));
dsLayout->updateTextureLayout(i, ccTexture);
if (DescriptorType::STORAGE_IMAGE == bindings[i].descriptorType) {
dsLayout->updateStorageTextureLayout(i, ccTexture);
} else {
dsLayout->updateSampledTextureLayout(i, ccTexture);
}
_gpuDescriptorObj->gpuDescriptors[i].texture = ccTexture;
} else if (DescriptorType::SAMPLER == bindings[i].descriptorType) {
auto *ccSampler = _samplers[resourceIndex].ptr ? static_cast<CCWGPUSampler *>(_samplers[resourceIndex].ptr) : CCWGPUSampler::defaultFilterableSampler();
auto &bindGroupEntry = _gpuBindGroupObj->bindGroupEntries[resourceIndex];
auto &bindGroupEntry = _gpuBindGroupObj->bindGroupEntries.emplace_back();
bindGroupEntry.binding = binding.binding;
bindGroupEntry.sampler = ccSampler->gpuSampler();
dsLayout->updateSamplerLayout(i, ccSampler);
Expand Down
22 changes: 13 additions & 9 deletions native/cocos/renderer/gfx-wgpu/WGPUDescriptorSetLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,29 +131,33 @@ WGPUTextureSampleType sampletypeTraits(const CCWGPUTexture *texture, uint32_t pl
}
} // namespace

void CCWGPUDescriptorSetLayout::updateTextureLayout(uint8_t index, const CCWGPUTexture *texture, uint32_t plane) {
void CCWGPUDescriptorSetLayout::updateSampledTextureLayout(uint8_t index, const CCWGPUTexture *texture, uint32_t plane) {
WGPUBindGroupLayoutEntry textureEntry{};
textureEntry.binding = _bindings[index].binding;
textureEntry.visibility = toWGPUShaderStageFlag(_bindings[index].stageFlags);

CC_ASSERT(texture);

if (texture->getInfo().usage == TextureUsageBit::STORAGE) {
WGPUStorageTextureBindingLayout storageTextureLayout{};
storageTextureLayout.access = WGPUStorageTextureAccess::WGPUStorageTextureAccess_WriteOnly;
storageTextureLayout.format = formatTraits(texture, plane);
TextureType type = texture->isTextureView() ? texture->getViewInfo().type : texture->getInfo().type;
storageTextureLayout.viewDimension = toWGPUTextureViewDimension(type);
textureEntry.storageTexture = storageTextureLayout;
} else {
WGPUTextureBindingLayout textureLayout{};
textureLayout.sampleType = sampletypeTraits(texture, plane); // textureSampleTypeTrait(texture->getFormat());
const CCWGPUTexture *ccTex = static_cast<const CCWGPUTexture *>(texture->isTextureView() ? texture->getViewInfo().texture : texture);
TextureType type = ccTex->getViewInfo().type;
textureLayout.viewDimension = toWGPUTextureViewDimension(type);
textureLayout.multisampled = ccTex->getInfo().samples != SampleCount::X1;
textureEntry.texture = textureLayout;
_gpuLayoutEntryObj->bindGroupLayoutEntries[textureEntry.binding] = textureEntry;
}
void CCWGPUDescriptorSetLayout::updateStorageTextureLayout(uint8_t index, const CCWGPUTexture *texture, uint32_t plane) {
WGPUBindGroupLayoutEntry textureEntry{};
textureEntry.binding = _bindings[index].binding;
textureEntry.visibility = toWGPUShaderStageFlag(_bindings[index].stageFlags);
CC_ASSERT(texture);
WGPUStorageTextureBindingLayout storageTextureLayout{};
storageTextureLayout.access = WGPUStorageTextureAccess::WGPUStorageTextureAccess_WriteOnly;
storageTextureLayout.format = formatTraits(texture, plane);
TextureType type = texture->isTextureView() ? texture->getViewInfo().type : texture->getInfo().type;
storageTextureLayout.viewDimension = toWGPUTextureViewDimension(type);
textureEntry.storageTexture = storageTextureLayout;
_gpuLayoutEntryObj->bindGroupLayoutEntries[textureEntry.binding] = textureEntry;
}

Expand Down
3 changes: 2 additions & 1 deletion native/cocos/renderer/gfx-wgpu/WGPUDescriptorSetLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class CCWGPUDescriptorSetLayout final : public DescriptorSetLayout {
inline CCWGPUBindGroupLayoutObject *gpuLayoutEntryObject() { return _gpuLayoutEntryObj; }

void updateBufferLayout(uint8_t index, const CCWGPUBuffer *buffer, AccessFlags flags);
void updateTextureLayout(uint8_t index, const CCWGPUTexture *texture, uint32_t plane = 0);
void updateSampledTextureLayout(uint8_t index, const CCWGPUTexture *texture, uint32_t plane = 0);
void updateStorageTextureLayout(uint8_t index, const CCWGPUTexture *texture, uint32_t plane = 0);
void updateSamplerLayout(uint8_t index, const CCWGPUSampler *sampler);

inline void setBindings(const DescriptorSetLayoutBindingList &list) { _bindings.assign(list.begin(), list.end()); }
Expand Down
15 changes: 13 additions & 2 deletions native/cocos/renderer/pipeline/custom/NativeExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,10 +537,20 @@ gfx::DescriptorSet* initDescriptorSet(

auto iter = resourceIndex.find(d.descriptorID);
if (iter != resourceIndex.end()) {
gfx::AccessFlags access = gfx::AccessFlagBit::NONE;
if (accessNode != nullptr) {
const auto& resID = iter->second;
// whole access only now.
auto parentID = parent(resID, resg);
parentID = parentID == ResourceGraph::null_vertex() ? resID : parentID;
const auto& resName = get(ResourceGraph::NameTag{}, resg, parentID);
access = accessNode->resourceStatus.at(resName).accessFlag;
}

// render graph textures
auto* texture = resg.getTexture(iter->second);
CC_ENSURES(texture);
newSet->bindTexture(bindID, texture);
newSet->bindTexture(bindID, texture, 0, access);
}
bindID += d.count;
}
Expand Down Expand Up @@ -940,11 +950,12 @@ struct RenderGraphUploadVisitor : boost::dfs_visitor<> {
auto& set = iter->second;
const auto& user = get(RenderGraph::DataTag{}, ctx.g, vertID);
auto& node = ctx.context.layoutGraphResources.at(layoutID);
const auto& accessNode = ctx.fgd.getAccessNode(vertID);
auto* perPassSet = initDescriptorSet(
ctx.resourceGraph,
ctx.device, ctx.cmdBuff,
*ctx.context.defaultResource, ctx.lg,
resourceIndex, set, user, node);
resourceIndex, set, user, node, &accessNode);
CC_ENSURES(perPassSet);
ctx.renderGraphDescriptorSet[vertID] = perPassSet;
} else if (holds<QueueTag>(vertID, ctx.g)) {
Expand Down

0 comments on commit b60172d

Please sign in to comment.