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

@@ -55,6 +55,49 @@ FramebufferAttachmentType ResolveDepthAttachmentType(Format format) {
: FramebufferAttachmentType::Depth;
}
uint32_t ResolveBufferElementStride(OpenGLBuffer* buffer, const ResourceViewDesc& desc) {
if (desc.dimension == ResourceViewDimension::RawBuffer) {
return 4u;
}
if (desc.structureByteStride > 0) {
return desc.structureByteStride;
}
return buffer != nullptr ? buffer->GetStride() : 0u;
}
uint64_t ResolveBufferByteOffset(OpenGLBuffer* buffer, const ResourceViewDesc& desc) {
const uint32_t elementStride = ResolveBufferElementStride(buffer, desc);
if (elementStride == 0) {
return desc.bufferLocation;
}
return desc.bufferLocation + static_cast<uint64_t>(desc.firstElement) * elementStride;
}
uint32_t ResolveBufferElementCount(OpenGLBuffer* buffer, const ResourceViewDesc& desc) {
if (desc.elementCount > 0) {
return desc.elementCount;
}
if (buffer == nullptr) {
return 0;
}
const uint32_t elementStride = ResolveBufferElementStride(buffer, desc);
if (elementStride == 0) {
return 0;
}
const uint64_t byteOffset = ResolveBufferByteOffset(buffer, desc);
if (byteOffset >= buffer->GetSize()) {
return 0;
}
return static_cast<uint32_t>((buffer->GetSize() - byteOffset) / elementStride);
}
} // namespace
OpenGLResourceView::OpenGLResourceView()
@@ -113,7 +156,8 @@ void* OpenGLResourceView::GetNativeHandle() {
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_framebufferID));
case ResourceViewType::ShaderResource:
case ResourceViewType::UnorderedAccess:
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_texture ? m_texture->GetID() : 0));
return reinterpret_cast<void*>(static_cast<uintptr_t>(
m_texture != nullptr ? m_texture->GetID() : (m_buffer != nullptr ? m_buffer->GetID() : 0)));
case ResourceViewType::ConstantBuffer:
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_buffer ? m_buffer->GetID() : 0));
default:
@@ -130,9 +174,11 @@ bool OpenGLResourceView::IsValid() const {
case ResourceViewType::DepthStencil:
return m_framebufferID != 0;
case ResourceViewType::ShaderResource:
return m_texture != nullptr && m_texture->GetID() != 0;
return (m_texture != nullptr && m_texture->GetID() != 0) ||
(m_buffer != nullptr && m_buffer->GetID() != 0 && m_bufferSize > 0);
case ResourceViewType::UnorderedAccess:
return m_texture != nullptr && m_textureUnit >= 0;
return (m_texture != nullptr && m_textureUnit >= 0) ||
(m_buffer != nullptr && m_buffer->GetID() != 0 && m_bufferSize > 0);
case ResourceViewType::ConstantBuffer:
return m_buffer != nullptr && m_bindingPoint >= 0;
default:
@@ -230,6 +276,62 @@ bool OpenGLResourceView::InitializeAsUnorderedAccess(
return true;
}
bool OpenGLResourceView::InitializeAsShaderResource(
OpenGLBuffer* buffer,
const ResourceViewDesc& desc) {
if (!buffer || !IsBufferResourceViewDimension(desc.dimension)) {
return false;
}
const uint32_t elementStride = ResolveBufferElementStride(buffer, desc);
if (elementStride == 0) {
return false;
}
const uint32_t elementCount = ResolveBufferElementCount(buffer, desc);
if (elementCount == 0) {
return false;
}
m_viewType = ResourceViewType::ShaderResource;
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : Format::Unknown;
m_dimension =
desc.dimension != ResourceViewDimension::Unknown ? desc.dimension : ResourceViewDimension::Buffer;
m_buffer = buffer;
m_bufferOffset = ResolveBufferByteOffset(buffer, desc);
m_bufferStride = elementStride;
m_bufferSize = elementCount * elementStride;
return true;
}
bool OpenGLResourceView::InitializeAsUnorderedAccess(
OpenGLBuffer* buffer,
const ResourceViewDesc& desc) {
if (!buffer || !IsBufferResourceViewDimension(desc.dimension)) {
return false;
}
const uint32_t elementStride = ResolveBufferElementStride(buffer, desc);
if (elementStride == 0) {
return false;
}
const uint32_t elementCount = ResolveBufferElementCount(buffer, desc);
if (elementCount == 0) {
return false;
}
m_viewType = ResourceViewType::UnorderedAccess;
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : Format::Unknown;
m_dimension =
desc.dimension != ResourceViewDimension::Unknown ? desc.dimension : ResourceViewDimension::Buffer;
m_buffer = buffer;
m_bufferOffset = ResolveBufferByteOffset(buffer, desc);
m_bufferStride = elementStride;
m_bufferSize = elementCount * elementStride;
return true;
}
bool OpenGLResourceView::InitializeAsConstantBuffer(
OpenGLBuffer* buffer,
const ResourceViewDesc& desc,