Add RHI buffer SRV and UAV view support

This commit is contained in:
2026-04-08 18:05:00 +08:00
parent 162f1cc12e
commit 4728b09ae8
28 changed files with 988 additions and 43 deletions

View File

@@ -34,6 +34,10 @@ uint32_t ResolveBindingPoint(
}
}
bool UsesBufferBinding(ResourceViewDimension dimension) {
return IsBufferResourceViewDimension(dimension);
}
} // namespace
OpenGLDescriptorSet::OpenGLDescriptorSet()
@@ -81,11 +85,20 @@ bool OpenGLDescriptorSet::Initialize(OpenGLTextureUnitAllocator* allocator, uint
m_bindings[i].binding = layout.bindings[i].binding;
m_bindings[i].type = static_cast<DescriptorType>(layout.bindings[i].type);
m_bindings[i].count = layout.bindings[i].count;
m_bindings[i].resourceDimension = layout.bindings[i].resourceDimension;
m_bindings[i].textureUnits.resize(layout.bindings[i].count);
m_bindings[i].textureIds.resize(layout.bindings[i].count, 0);
m_bindings[i].textureTargets.resize(layout.bindings[i].count, GL_TEXTURE_2D);
m_bindings[i].bufferIds.resize(layout.bindings[i].count, 0);
m_bindings[i].bufferOffsets.resize(layout.bindings[i].count, 0);
m_bindings[i].bufferSizes.resize(layout.bindings[i].count, 0);
m_bindings[i].samplerIds.resize(layout.bindings[i].count, 0);
if (UsesBufferBinding(m_bindings[i].resourceDimension)) {
m_bindings[i].textureUnits.clear();
continue;
}
if (m_bindings[i].type != DescriptorType::SRV &&
m_bindings[i].type != DescriptorType::Sampler &&
m_bindings[i].type != DescriptorType::UAV) {
@@ -156,11 +169,32 @@ void OpenGLDescriptorSet::Update(uint32_t offset, RHIResourceView* view) {
}
DescriptorBinding* binding = FindBinding(offset);
if (binding == nullptr || binding->textureIds.empty()) {
if (binding == nullptr) {
return;
}
OpenGLResourceView* glView = static_cast<OpenGLResourceView*>(view);
const bool expectsBuffer = UsesBufferBinding(binding->resourceDimension);
const bool viewIsBuffer = IsBufferResourceViewDimension(glView->GetDimension());
if (expectsBuffer != viewIsBuffer) {
return;
}
if (expectsBuffer) {
if (binding->bufferIds.empty()) {
return;
}
binding->bufferIds[0] = glView->GetBuffer();
binding->bufferOffsets[0] = glView->GetBufferOffset();
binding->bufferSizes[0] = glView->GetBufferSize();
return;
}
if (binding->textureIds.empty()) {
return;
}
binding->textureIds[0] = glView->GetTexture();
if (const OpenGLTexture* texture = glView->GetTextureResource()) {
binding->textureTargets[0] = static_cast<uint32_t>(ToOpenGL(texture->GetOpenGLType()));
@@ -199,6 +233,31 @@ void OpenGLDescriptorSet::Bind() {
for (size_t i = 0; i < m_bindings.size(); ++i) {
const auto& binding = m_bindings[i];
if (UsesBufferBinding(binding.resourceDimension)) {
for (size_t j = 0; j < binding.bufferIds.size(); ++j) {
const GLuint bufferId = binding.bufferIds[j];
if (bufferId == 0) {
continue;
}
const GLuint rangeSize = j < binding.bufferSizes.size() ? binding.bufferSizes[j] : 0u;
if (rangeSize > 0) {
glBindBufferRange(
GL_SHADER_STORAGE_BUFFER,
binding.binding + static_cast<uint32_t>(j),
bufferId,
static_cast<GLintptr>(binding.bufferOffsets[j]),
static_cast<GLsizeiptr>(rangeSize));
} else {
glBindBufferBase(
GL_SHADER_STORAGE_BUFFER,
binding.binding + static_cast<uint32_t>(j),
bufferId);
}
}
continue;
}
for (size_t j = 0; j < binding.textureUnits.size(); ++j) {
uint32_t unit = binding.textureUnits[j];
uint32_t textureId = binding.textureIds[j];
@@ -246,6 +305,29 @@ void OpenGLDescriptorSet::BindWithPipelineLayout(const OpenGLPipelineLayout* pip
continue;
}
if (UsesBufferBinding(binding.resourceDimension)) {
for (size_t i = 0; i < binding.bufferIds.size(); ++i) {
const GLuint bufferId = binding.bufferIds[i];
if (bufferId == 0) {
continue;
}
const uint32_t bindingPoint = baseBindingPoint + static_cast<uint32_t>(i);
const GLuint rangeSize = i < binding.bufferSizes.size() ? binding.bufferSizes[i] : 0u;
if (rangeSize > 0) {
glBindBufferRange(
GL_SHADER_STORAGE_BUFFER,
bindingPoint,
bufferId,
static_cast<GLintptr>(binding.bufferOffsets[i]),
static_cast<GLsizeiptr>(rangeSize));
} else {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, bindingPoint, bufferId);
}
}
continue;
}
for (size_t i = 0; i < binding.textureIds.size(); ++i) {
const uint32_t bindingPoint = baseBindingPoint + static_cast<uint32_t>(i);
const uint32_t textureId = binding.textureIds[i];
@@ -282,6 +364,13 @@ void OpenGLDescriptorSet::Unbind() {
}
}
if (UsesBufferBinding(binding.resourceDimension)) {
for (size_t j = 0; j < binding.bufferIds.size(); ++j) {
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, binding.binding + static_cast<uint32_t>(j), 0);
}
continue;
}
for (size_t j = 0; j < binding.textureUnits.size(); ++j) {
uint32_t unit = binding.textureUnits[j];