Add RHI buffer SRV and UAV view support
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user