Fix OpenGL render target binding composition
This commit is contained in:
@@ -14,6 +14,7 @@ class OpenGLVertexArray;
|
||||
class OpenGLShader;
|
||||
class OpenGLTexture;
|
||||
class OpenGLPipelineState;
|
||||
class OpenGLFramebuffer;
|
||||
|
||||
enum class PrimitiveType {
|
||||
Points,
|
||||
@@ -193,6 +194,7 @@ public:
|
||||
void DrawIndexed(uint32_t indexCount, uint32_t instanceCount, uint32_t startIndex, int32_t baseVertex, uint32_t startInstance) override;
|
||||
|
||||
private:
|
||||
void ReleaseComposedFramebuffer();
|
||||
void EnsureInternalVertexArrayBound();
|
||||
void DisableConfiguredVertexAttributes();
|
||||
|
||||
@@ -203,6 +205,7 @@ private:
|
||||
OpenGLPipelineState* m_currentPipelineState;
|
||||
std::vector<unsigned int> m_enabledVertexAttributes;
|
||||
OpenGLShader* m_currentShader;
|
||||
OpenGLFramebuffer* m_composedFramebuffer;
|
||||
};
|
||||
|
||||
} // namespace RHI
|
||||
|
||||
@@ -18,8 +18,9 @@ enum class FramebufferAttachmentType {
|
||||
|
||||
struct FramebufferAttachment {
|
||||
unsigned int texture = 0;
|
||||
unsigned int target = 0;
|
||||
int mipLevel = 0;
|
||||
int layer = 0;
|
||||
int layer = -1;
|
||||
FramebufferAttachmentType type = FramebufferAttachmentType::Color;
|
||||
uint32_t format = 0;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLFramebuffer.h"
|
||||
#include "XCEngine/RHI/RHIResourceView.h"
|
||||
#include "XCEngine/RHI/RHITypes.h"
|
||||
|
||||
@@ -63,6 +64,8 @@ public:
|
||||
uint64_t GetBufferOffset() const { return m_bufferOffset; }
|
||||
uint32_t GetBufferSize() const { return m_bufferSize; }
|
||||
uint32_t GetBufferStride() const { return m_bufferStride; }
|
||||
const FramebufferAttachment& GetFramebufferAttachment() const { return m_framebufferAttachment; }
|
||||
const OpenGLTexture* GetTextureResource() const { return m_texture; }
|
||||
|
||||
private:
|
||||
ResourceViewType m_viewType;
|
||||
@@ -76,6 +79,7 @@ private:
|
||||
OpenGLFramebuffer* m_framebuffer;
|
||||
OpenGLTextureUnitAllocator* m_textureUnitAllocator;
|
||||
OpenGLUniformBufferManager* m_uniformBufferManager;
|
||||
FramebufferAttachment m_framebufferAttachment;
|
||||
uint64_t m_bufferOffset;
|
||||
uint32_t m_bufferSize;
|
||||
uint32_t m_bufferStride;
|
||||
|
||||
@@ -65,7 +65,8 @@ OpenGLCommandList::OpenGLCommandList()
|
||||
, m_currentProgram(0)
|
||||
, m_internalVAO(0)
|
||||
, m_currentPipelineState(nullptr)
|
||||
, m_currentShader(nullptr) {
|
||||
, m_currentShader(nullptr)
|
||||
, m_composedFramebuffer(nullptr) {
|
||||
}
|
||||
|
||||
OpenGLCommandList::~OpenGLCommandList() {
|
||||
@@ -457,6 +458,7 @@ void OpenGLCommandList::PopDebugGroup() {
|
||||
}
|
||||
|
||||
void OpenGLCommandList::Shutdown() {
|
||||
ReleaseComposedFramebuffer();
|
||||
DisableConfiguredVertexAttributes();
|
||||
if (m_internalVAO != 0) {
|
||||
glDeleteVertexArrays(1, &m_internalVAO);
|
||||
@@ -467,12 +469,21 @@ void OpenGLCommandList::Shutdown() {
|
||||
}
|
||||
|
||||
void OpenGLCommandList::Reset() {
|
||||
ReleaseComposedFramebuffer();
|
||||
m_currentPipelineState = nullptr;
|
||||
}
|
||||
|
||||
void OpenGLCommandList::Close() {
|
||||
}
|
||||
|
||||
void OpenGLCommandList::ReleaseComposedFramebuffer() {
|
||||
if (m_composedFramebuffer != nullptr) {
|
||||
m_composedFramebuffer->Shutdown();
|
||||
delete m_composedFramebuffer;
|
||||
m_composedFramebuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLCommandList::SetShader(RHIShader* shader) {
|
||||
m_currentShader = static_cast<OpenGLShader*>(shader);
|
||||
if (m_currentShader) {
|
||||
@@ -593,29 +604,63 @@ void OpenGLCommandList::SetScissorRects(uint32_t count, const Rect* rects) {
|
||||
|
||||
void OpenGLCommandList::SetRenderTargets(uint32_t count, RHIResourceView** renderTargets, RHIResourceView* depthStencil) {
|
||||
if (count > 0 && renderTargets != nullptr) {
|
||||
std::vector<GLuint> fbos(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (renderTargets[i]) {
|
||||
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(renderTargets[i]);
|
||||
fbos[i] = view->GetFramebuffer();
|
||||
}
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[0]);
|
||||
|
||||
std::vector<GLenum> drawBuffers(count);
|
||||
const bool requiresComposedFramebuffer = count > 1 || depthStencil != nullptr;
|
||||
std::vector<GLenum> drawBuffers(count, GL_NONE);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (renderTargets[i] != nullptr) {
|
||||
drawBuffers[i] = ToOpenGLColorAttachment(i);
|
||||
}
|
||||
glDrawBuffers(count, drawBuffers.data());
|
||||
}
|
||||
|
||||
if (requiresComposedFramebuffer) {
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
auto* view = static_cast<OpenGLResourceView*>(renderTargets[i]);
|
||||
const OpenGLTexture* texture = view != nullptr ? view->GetTextureResource() : nullptr;
|
||||
if (texture != nullptr) {
|
||||
width = texture->GetWidth();
|
||||
height = texture->GetHeight();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((width == 0 || height == 0) && depthStencil != nullptr) {
|
||||
auto* dsv = static_cast<OpenGLResourceView*>(depthStencil);
|
||||
const OpenGLTexture* depthTexture = dsv != nullptr ? dsv->GetTextureResource() : nullptr;
|
||||
if (depthTexture != nullptr) {
|
||||
width = depthTexture->GetWidth();
|
||||
height = depthTexture->GetHeight();
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseComposedFramebuffer();
|
||||
m_composedFramebuffer = new OpenGLFramebuffer();
|
||||
if (!m_composedFramebuffer->Initialize(nullptr, width, height, count, renderTargets, depthStencil)) {
|
||||
ReleaseComposedFramebuffer();
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glDrawBuffers(0, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_composedFramebuffer->GetFramebuffer());
|
||||
} else {
|
||||
ReleaseComposedFramebuffer();
|
||||
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(renderTargets[0]);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, view != nullptr ? view->GetFramebuffer() : 0);
|
||||
}
|
||||
|
||||
glDrawBuffers(count, drawBuffers.data());
|
||||
} else if (depthStencil) {
|
||||
ReleaseComposedFramebuffer();
|
||||
OpenGLResourceView* dsv = static_cast<OpenGLResourceView*>(depthStencil);
|
||||
if (dsv && dsv->IsValid()) {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dsv->GetFramebuffer());
|
||||
}
|
||||
glDrawBuffers(0, nullptr);
|
||||
} else {
|
||||
ReleaseComposedFramebuffer();
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,42 @@ OpenGLFormat ToOpenGLTextureFormat(Format format) {
|
||||
}
|
||||
}
|
||||
|
||||
GLenum ResolveFramebufferTextureTarget(OpenGLTextureType textureType, const ResourceViewDesc& desc) {
|
||||
switch (textureType) {
|
||||
case OpenGLTextureType::Texture1D:
|
||||
return GL_TEXTURE_1D;
|
||||
case OpenGLTextureType::Texture2D:
|
||||
return GL_TEXTURE_2D;
|
||||
case OpenGLTextureType::TextureCube: {
|
||||
const uint32_t face = desc.firstArraySlice < 6 ? desc.firstArraySlice : 0;
|
||||
return GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
|
||||
}
|
||||
case OpenGLTextureType::Texture2DArray:
|
||||
case OpenGLTextureType::Texture3D:
|
||||
case OpenGLTextureType::TextureCubeArray:
|
||||
return 0;
|
||||
default:
|
||||
return GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
|
||||
int ResolveFramebufferAttachmentLayer(OpenGLTextureType textureType, const ResourceViewDesc& desc) {
|
||||
switch (textureType) {
|
||||
case OpenGLTextureType::Texture2DArray:
|
||||
case OpenGLTextureType::Texture3D:
|
||||
case OpenGLTextureType::TextureCubeArray:
|
||||
return static_cast<int>(desc.firstArraySlice);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
FramebufferAttachmentType ResolveDepthAttachmentType(Format format) {
|
||||
return format == Format::D24_UNorm_S8_UInt
|
||||
? FramebufferAttachmentType::DepthStencil
|
||||
: FramebufferAttachmentType::Depth;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OpenGLDevice::OpenGLDevice()
|
||||
@@ -634,9 +670,11 @@ RHIResourceView* OpenGLDevice::CreateRenderTargetView(RHITexture* texture, const
|
||||
|
||||
FramebufferAttachment colorAttachment = {};
|
||||
colorAttachment.texture = glTexture->GetID();
|
||||
colorAttachment.target = ResolveFramebufferTextureTarget(glTexture->GetOpenGLType(), desc);
|
||||
colorAttachment.mipLevel = static_cast<int>(desc.mipLevel);
|
||||
colorAttachment.layer = ResolveFramebufferAttachmentLayer(glTexture->GetOpenGLType(), desc);
|
||||
colorAttachment.type = FramebufferAttachmentType::Color;
|
||||
colorAttachment.format = desc.format;
|
||||
colorAttachment.format = desc.format != 0 ? desc.format : static_cast<uint32_t>(texture->GetFormat());
|
||||
fbDesc.colorAttachments.push_back(colorAttachment);
|
||||
|
||||
auto* framebuffer = new OpenGLFramebuffer();
|
||||
@@ -668,9 +706,11 @@ RHIResourceView* OpenGLDevice::CreateDepthStencilView(RHITexture* texture, const
|
||||
|
||||
FramebufferAttachment depthAttachment = {};
|
||||
depthAttachment.texture = glTexture->GetID();
|
||||
depthAttachment.target = ResolveFramebufferTextureTarget(glTexture->GetOpenGLType(), desc);
|
||||
depthAttachment.mipLevel = static_cast<int>(desc.mipLevel);
|
||||
depthAttachment.type = FramebufferAttachmentType::DepthStencil;
|
||||
depthAttachment.format = desc.format;
|
||||
depthAttachment.layer = ResolveFramebufferAttachmentLayer(glTexture->GetOpenGLType(), desc);
|
||||
depthAttachment.format = desc.format != 0 ? desc.format : static_cast<uint32_t>(texture->GetFormat());
|
||||
depthAttachment.type = ResolveDepthAttachmentType(static_cast<Format>(depthAttachment.format));
|
||||
fbDesc.depthAttachment = depthAttachment;
|
||||
|
||||
auto* framebuffer = new OpenGLFramebuffer();
|
||||
|
||||
@@ -6,6 +6,38 @@
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsTexture2DAttachmentTarget(GLenum target) {
|
||||
return target == GL_TEXTURE_2D ||
|
||||
(target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
|
||||
}
|
||||
|
||||
void AttachFramebufferTexture(GLenum attachmentPoint, const FramebufferAttachment& attachment) {
|
||||
if (attachment.texture == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attachment.layer >= 0) {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachmentPoint, attachment.texture, attachment.mipLevel, attachment.layer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attachment.target == GL_TEXTURE_1D) {
|
||||
glFramebufferTexture1D(GL_FRAMEBUFFER, attachmentPoint, GL_TEXTURE_1D, attachment.texture, attachment.mipLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsTexture2DAttachmentTarget(attachment.target)) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentPoint, attachment.target, attachment.texture, attachment.mipLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, attachmentPoint, attachment.texture, attachment.mipLevel);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OpenGLFramebuffer::OpenGLFramebuffer()
|
||||
: m_framebuffer(0)
|
||||
, m_width(0)
|
||||
@@ -32,45 +64,23 @@ bool OpenGLFramebuffer::Initialize(const FramebufferDesc& desc) {
|
||||
for (size_t i = 0; i < desc.colorAttachments.size() && i < 16; ++i) {
|
||||
const auto& attachment = desc.colorAttachments[i];
|
||||
GLenum glAttachment = ToOpenGLColorAttachment(static_cast<uint32_t>(i));
|
||||
|
||||
switch (attachment.type) {
|
||||
case FramebufferAttachmentType::Color:
|
||||
if (attachment.layer == 0 && attachment.mipLevel == 0) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, glAttachment, GL_TEXTURE_2D, attachment.texture, 0);
|
||||
} else if (attachment.layer > 0) {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, glAttachment, attachment.texture, attachment.mipLevel, attachment.layer);
|
||||
} else {
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, glAttachment, attachment.texture, attachment.mipLevel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
AttachFramebufferTexture(glAttachment, attachment);
|
||||
drawBuffers[drawBufferCount++] = glAttachment;
|
||||
}
|
||||
|
||||
if (desc.depthAttachment.texture != 0) {
|
||||
GLenum depthAttachment = ToOpenGLDepthAttachment();
|
||||
if (desc.stencilAttachment.texture != 0) {
|
||||
if (desc.depthAttachment.type == FramebufferAttachmentType::DepthStencil || desc.stencilAttachment.texture != 0) {
|
||||
depthAttachment = ToOpenGLDepthStencilAttachment();
|
||||
}
|
||||
|
||||
if (desc.depthAttachment.layer == 0 && desc.depthAttachment.mipLevel == 0) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, depthAttachment, GL_TEXTURE_2D, desc.depthAttachment.texture, 0);
|
||||
} else if (desc.depthAttachment.layer > 0) {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, depthAttachment, desc.depthAttachment.texture, desc.depthAttachment.mipLevel, desc.depthAttachment.layer);
|
||||
} else {
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, depthAttachment, desc.depthAttachment.texture, desc.depthAttachment.mipLevel);
|
||||
}
|
||||
AttachFramebufferTexture(depthAttachment, desc.depthAttachment);
|
||||
}
|
||||
|
||||
if (desc.stencilAttachment.texture != 0 && desc.stencilAttachment.texture != desc.depthAttachment.texture) {
|
||||
if (desc.stencilAttachment.texture != 0 &&
|
||||
(desc.stencilAttachment.texture != desc.depthAttachment.texture ||
|
||||
desc.depthAttachment.type != FramebufferAttachmentType::DepthStencil)) {
|
||||
GLenum stencilAttachment = ToOpenGLStencilAttachment();
|
||||
if (desc.stencilAttachment.layer == 0 && desc.stencilAttachment.mipLevel == 0) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, stencilAttachment, GL_TEXTURE_2D, desc.stencilAttachment.texture, 0);
|
||||
} else if (desc.stencilAttachment.layer > 0) {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, stencilAttachment, desc.stencilAttachment.texture, desc.stencilAttachment.mipLevel, desc.stencilAttachment.layer);
|
||||
} else {
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, stencilAttachment, desc.stencilAttachment.texture, desc.stencilAttachment.mipLevel);
|
||||
}
|
||||
AttachFramebufferTexture(stencilAttachment, desc.stencilAttachment);
|
||||
}
|
||||
|
||||
if (drawBufferCount > 0) {
|
||||
@@ -118,9 +128,9 @@ bool OpenGLFramebuffer::Initialize(class RHIRenderPass* renderPass, uint32_t wid
|
||||
if (colorAttachments[i]) {
|
||||
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(colorAttachments[i]);
|
||||
GLenum glAttachment = ToOpenGLColorAttachment(i);
|
||||
unsigned int texture = view->GetTexture();
|
||||
if (texture) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, glAttachment, GL_TEXTURE_2D, texture, 0);
|
||||
const auto& attachment = view->GetFramebufferAttachment();
|
||||
if (attachment.texture != 0) {
|
||||
AttachFramebufferTexture(glAttachment, attachment);
|
||||
}
|
||||
drawBuffers[drawBufferCount++] = glAttachment;
|
||||
}
|
||||
@@ -128,9 +138,13 @@ bool OpenGLFramebuffer::Initialize(class RHIRenderPass* renderPass, uint32_t wid
|
||||
|
||||
if (depthStencilAttachment) {
|
||||
OpenGLResourceView* view = static_cast<OpenGLResourceView*>(depthStencilAttachment);
|
||||
unsigned int texture = view->GetTexture();
|
||||
if (texture) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, ToOpenGLDepthStencilAttachment(), GL_TEXTURE_2D, texture, 0);
|
||||
const auto& attachment = view->GetFramebufferAttachment();
|
||||
if (attachment.texture != 0) {
|
||||
const GLenum depthAttachment =
|
||||
attachment.type == FramebufferAttachmentType::DepthStencil
|
||||
? ToOpenGLDepthStencilAttachment()
|
||||
: ToOpenGLDepthAttachment();
|
||||
AttachFramebufferTexture(depthAttachment, attachment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,53 @@
|
||||
namespace XCEngine {
|
||||
namespace RHI {
|
||||
|
||||
namespace {
|
||||
|
||||
GLenum ResolveFramebufferTextureTarget(OpenGLTextureType textureType, const ResourceViewDesc& desc) {
|
||||
switch (textureType) {
|
||||
case OpenGLTextureType::Texture1D:
|
||||
return GL_TEXTURE_1D;
|
||||
case OpenGLTextureType::Texture2D:
|
||||
return GL_TEXTURE_2D;
|
||||
case OpenGLTextureType::TextureCube: {
|
||||
const uint32_t face = desc.firstArraySlice < 6 ? desc.firstArraySlice : 0;
|
||||
return GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
|
||||
}
|
||||
case OpenGLTextureType::Texture2DArray:
|
||||
case OpenGLTextureType::Texture3D:
|
||||
case OpenGLTextureType::TextureCubeArray:
|
||||
return 0;
|
||||
default:
|
||||
return GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
|
||||
int ResolveFramebufferAttachmentLayer(OpenGLTextureType textureType, const ResourceViewDesc& desc) {
|
||||
switch (textureType) {
|
||||
case OpenGLTextureType::Texture2DArray:
|
||||
case OpenGLTextureType::Texture3D:
|
||||
case OpenGLTextureType::TextureCubeArray:
|
||||
return static_cast<int>(desc.firstArraySlice);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Format ResolveViewFormat(OpenGLTexture* texture, const ResourceViewDesc& desc) {
|
||||
if (desc.format != 0) {
|
||||
return static_cast<Format>(desc.format);
|
||||
}
|
||||
return texture ? texture->GetFormat() : Format::Unknown;
|
||||
}
|
||||
|
||||
FramebufferAttachmentType ResolveDepthAttachmentType(Format format) {
|
||||
return format == Format::D24_UNorm_S8_UInt
|
||||
? FramebufferAttachmentType::DepthStencil
|
||||
: FramebufferAttachmentType::Depth;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OpenGLResourceView::OpenGLResourceView()
|
||||
: m_viewType(ResourceViewType::RenderTarget)
|
||||
, m_format(Format::Unknown)
|
||||
@@ -47,6 +94,7 @@ void OpenGLResourceView::Shutdown() {
|
||||
m_framebuffer = nullptr;
|
||||
m_textureUnitAllocator = nullptr;
|
||||
m_uniformBufferManager = nullptr;
|
||||
m_framebufferAttachment = {};
|
||||
m_framebufferID = 0;
|
||||
m_texture = nullptr;
|
||||
m_buffer = nullptr;
|
||||
@@ -101,11 +149,17 @@ bool OpenGLResourceView::InitializeAsRenderTarget(
|
||||
}
|
||||
|
||||
m_viewType = ResourceViewType::RenderTarget;
|
||||
m_format = static_cast<Format>(desc.format);
|
||||
m_format = ResolveViewFormat(texture, desc);
|
||||
m_dimension = desc.dimension;
|
||||
m_texture = texture;
|
||||
m_framebuffer = framebuffer;
|
||||
m_framebufferID = framebuffer->GetFramebuffer();
|
||||
m_framebufferAttachment.texture = texture->GetID();
|
||||
m_framebufferAttachment.target = ResolveFramebufferTextureTarget(texture->GetOpenGLType(), desc);
|
||||
m_framebufferAttachment.mipLevel = static_cast<int>(desc.mipLevel);
|
||||
m_framebufferAttachment.layer = ResolveFramebufferAttachmentLayer(texture->GetOpenGLType(), desc);
|
||||
m_framebufferAttachment.type = FramebufferAttachmentType::Color;
|
||||
m_framebufferAttachment.format = static_cast<uint32_t>(m_format);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -118,11 +172,17 @@ bool OpenGLResourceView::InitializeAsDepthStencil(
|
||||
}
|
||||
|
||||
m_viewType = ResourceViewType::DepthStencil;
|
||||
m_format = static_cast<Format>(desc.format);
|
||||
m_format = ResolveViewFormat(texture, desc);
|
||||
m_dimension = desc.dimension;
|
||||
m_texture = texture;
|
||||
m_framebuffer = framebuffer;
|
||||
m_framebufferID = framebuffer->GetFramebuffer();
|
||||
m_framebufferAttachment.texture = texture->GetID();
|
||||
m_framebufferAttachment.target = ResolveFramebufferTextureTarget(texture->GetOpenGLType(), desc);
|
||||
m_framebufferAttachment.mipLevel = static_cast<int>(desc.mipLevel);
|
||||
m_framebufferAttachment.layer = ResolveFramebufferAttachmentLayer(texture->GetOpenGLType(), desc);
|
||||
m_framebufferAttachment.type = ResolveDepthAttachmentType(m_format);
|
||||
m_framebufferAttachment.format = static_cast<uint32_t>(m_format);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,7 +195,7 @@ bool OpenGLResourceView::InitializeAsShaderResource(
|
||||
}
|
||||
|
||||
m_viewType = ResourceViewType::ShaderResource;
|
||||
m_format = static_cast<Format>(desc.format);
|
||||
m_format = ResolveViewFormat(texture, desc);
|
||||
m_dimension = desc.dimension;
|
||||
m_texture = texture;
|
||||
m_textureUnit = -1;
|
||||
@@ -157,7 +217,7 @@ bool OpenGLResourceView::InitializeAsUnorderedAccess(
|
||||
}
|
||||
|
||||
m_viewType = ResourceViewType::UnorderedAccess;
|
||||
m_format = static_cast<Format>(desc.format);
|
||||
m_format = ResolveViewFormat(texture, desc);
|
||||
m_dimension = desc.dimension;
|
||||
m_texture = texture;
|
||||
m_textureUnit = unit;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "XCEngine/RHI/RHIRenderPass.h"
|
||||
#include "XCEngine/RHI/RHIFramebuffer.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
|
||||
#include "XCEngine/RHI/OpenGL/OpenGLResourceView.h"
|
||||
#include <glad/glad.h>
|
||||
|
||||
using namespace XCEngine::RHI;
|
||||
@@ -363,6 +364,145 @@ TEST_P(RHITestFixture, CommandList_SetRenderTargets_WithRealViews) {
|
||||
delete texture;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, CommandList_SetRenderTargets_BindsColorAndDepthAttachmentsOnOpenGL) {
|
||||
if (GetBackendType() != RHIType::OpenGL) {
|
||||
GTEST_SKIP() << "OpenGL-specific framebuffer attachment verification";
|
||||
}
|
||||
|
||||
TextureDesc colorDesc = {};
|
||||
colorDesc.width = 128;
|
||||
colorDesc.height = 128;
|
||||
colorDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||
colorDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||
|
||||
TextureDesc depthDesc = {};
|
||||
depthDesc.width = 128;
|
||||
depthDesc.height = 128;
|
||||
depthDesc.format = static_cast<uint32_t>(Format::D24_UNorm_S8_UInt);
|
||||
depthDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||
|
||||
RHITexture* colorTexture = GetDevice()->CreateTexture(colorDesc);
|
||||
RHITexture* depthTexture = GetDevice()->CreateTexture(depthDesc);
|
||||
ASSERT_NE(colorTexture, nullptr);
|
||||
ASSERT_NE(depthTexture, nullptr);
|
||||
|
||||
ResourceViewDesc colorViewDesc = {};
|
||||
colorViewDesc.format = colorDesc.format;
|
||||
RHIResourceView* rtv = GetDevice()->CreateRenderTargetView(colorTexture, colorViewDesc);
|
||||
|
||||
ResourceViewDesc depthViewDesc = {};
|
||||
depthViewDesc.format = depthDesc.format;
|
||||
RHIResourceView* dsv = GetDevice()->CreateDepthStencilView(depthTexture, depthViewDesc);
|
||||
ASSERT_NE(rtv, nullptr);
|
||||
ASSERT_NE(dsv, nullptr);
|
||||
|
||||
CommandListDesc cmdDesc = {};
|
||||
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||
ASSERT_NE(cmdList, nullptr);
|
||||
|
||||
cmdList->Reset();
|
||||
cmdList->SetRenderTargets(1, &rtv, dsv);
|
||||
|
||||
GLint framebuffer = 0;
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &framebuffer);
|
||||
EXPECT_NE(framebuffer, 0);
|
||||
EXPECT_EQ(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
GLint colorAttachment = 0;
|
||||
glGetFramebufferAttachmentParameteriv(
|
||||
GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
|
||||
&colorAttachment);
|
||||
EXPECT_EQ(static_cast<GLuint>(colorAttachment), static_cast<OpenGLResourceView*>(rtv)->GetTexture());
|
||||
|
||||
GLint depthAttachment = 0;
|
||||
glGetFramebufferAttachmentParameteriv(
|
||||
GL_DRAW_FRAMEBUFFER,
|
||||
GL_DEPTH_ATTACHMENT,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
|
||||
&depthAttachment);
|
||||
EXPECT_EQ(static_cast<GLuint>(depthAttachment), static_cast<OpenGLResourceView*>(dsv)->GetTexture());
|
||||
|
||||
cmdList->Close();
|
||||
|
||||
cmdList->Shutdown();
|
||||
delete cmdList;
|
||||
delete dsv;
|
||||
delete rtv;
|
||||
depthTexture->Shutdown();
|
||||
delete depthTexture;
|
||||
colorTexture->Shutdown();
|
||||
delete colorTexture;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, CommandList_SetRenderTargets_BindsMultipleColorAttachmentsOnOpenGL) {
|
||||
if (GetBackendType() != RHIType::OpenGL) {
|
||||
GTEST_SKIP() << "OpenGL-specific multiple render target verification";
|
||||
}
|
||||
|
||||
TextureDesc texDesc = {};
|
||||
texDesc.width = 128;
|
||||
texDesc.height = 128;
|
||||
texDesc.format = static_cast<uint32_t>(Format::R8G8B8A8_UNorm);
|
||||
texDesc.textureType = static_cast<uint32_t>(TextureType::Texture2D);
|
||||
|
||||
RHITexture* texture0 = GetDevice()->CreateTexture(texDesc);
|
||||
RHITexture* texture1 = GetDevice()->CreateTexture(texDesc);
|
||||
ASSERT_NE(texture0, nullptr);
|
||||
ASSERT_NE(texture1, nullptr);
|
||||
|
||||
ResourceViewDesc viewDesc = {};
|
||||
viewDesc.format = texDesc.format;
|
||||
RHIResourceView* rtv0 = GetDevice()->CreateRenderTargetView(texture0, viewDesc);
|
||||
RHIResourceView* rtv1 = GetDevice()->CreateRenderTargetView(texture1, viewDesc);
|
||||
ASSERT_NE(rtv0, nullptr);
|
||||
ASSERT_NE(rtv1, nullptr);
|
||||
|
||||
RHIResourceView* rtvs[] = { rtv0, rtv1 };
|
||||
|
||||
CommandListDesc cmdDesc = {};
|
||||
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||
ASSERT_NE(cmdList, nullptr);
|
||||
|
||||
cmdList->Reset();
|
||||
cmdList->SetRenderTargets(2, rtvs, nullptr);
|
||||
|
||||
GLint framebuffer = 0;
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &framebuffer);
|
||||
EXPECT_NE(framebuffer, 0);
|
||||
EXPECT_EQ(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE);
|
||||
|
||||
GLint colorAttachment0 = 0;
|
||||
glGetFramebufferAttachmentParameteriv(
|
||||
GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
|
||||
&colorAttachment0);
|
||||
EXPECT_EQ(static_cast<GLuint>(colorAttachment0), static_cast<OpenGLResourceView*>(rtv0)->GetTexture());
|
||||
|
||||
GLint colorAttachment1 = 0;
|
||||
glGetFramebufferAttachmentParameteriv(
|
||||
GL_DRAW_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT1,
|
||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
|
||||
&colorAttachment1);
|
||||
EXPECT_EQ(static_cast<GLuint>(colorAttachment1), static_cast<OpenGLResourceView*>(rtv1)->GetTexture());
|
||||
|
||||
cmdList->Close();
|
||||
|
||||
cmdList->Shutdown();
|
||||
delete cmdList;
|
||||
delete rtv1;
|
||||
delete rtv0;
|
||||
texture1->Shutdown();
|
||||
delete texture1;
|
||||
texture0->Shutdown();
|
||||
delete texture0;
|
||||
}
|
||||
|
||||
TEST_P(RHITestFixture, CommandList_CopyResource_WithRealResources) {
|
||||
TextureDesc texDesc = {};
|
||||
texDesc.width = 256;
|
||||
|
||||
Reference in New Issue
Block a user