Fix OpenGL sampler and copy semantics

This commit is contained in:
2026-03-26 02:14:21 +08:00
parent c47e871c5a
commit 1ef3048da1
6 changed files with 215 additions and 6 deletions

View File

@@ -6,6 +6,7 @@
#include "XCEngine/RHI/OpenGL/OpenGLRenderPass.h"
#include "XCEngine/RHI/OpenGL/OpenGLDescriptorSet.h"
#include "XCEngine/RHI/OpenGL/OpenGLEnums.h"
#include <algorithm>
#include <glad/glad.h>
namespace XCEngine {
@@ -830,10 +831,17 @@ void OpenGLCommandList::CopyResource(RHIResourceView* dst, RHIResourceView* src)
GLuint dstTex = dstView->GetTexture();
GLuint srcTex = srcView->GetTexture();
if (dstTex && srcTex) {
glCopyImageSubData(srcTex, GL_TEXTURE_2D, 0, 0, 0, 0,
dstTex, GL_TEXTURE_2D, 0, 0, 0, 0,
256, 256, 1);
const OpenGLTexture* dstTexture = dstView->GetTextureResource();
const OpenGLTexture* srcTexture = srcView->GetTextureResource();
if (dstTex && srcTex && dstTexture != nullptr && srcTexture != nullptr) {
const GLuint srcTarget = ToOpenGL(srcTexture->GetOpenGLType());
const GLuint dstTarget = ToOpenGL(dstTexture->GetOpenGLType());
const GLsizei copyWidth = static_cast<GLsizei>(std::min(srcTexture->GetWidth(), dstTexture->GetWidth()));
const GLsizei copyHeight = static_cast<GLsizei>(std::min(srcTexture->GetHeight(), dstTexture->GetHeight()));
const GLsizei copyDepth = static_cast<GLsizei>(std::max<uint32_t>(1u, std::min(srcTexture->GetDepth(), dstTexture->GetDepth())));
glCopyImageSubData(srcTex, srcTarget, 0, 0, 0, 0,
dstTex, dstTarget, 0, 0, 0, 0,
copyWidth, copyHeight, copyDepth);
}
}

View File

@@ -9,6 +9,7 @@
#include "XCEngine/RHI/OpenGL/OpenGLTexture.h"
#include "XCEngine/RHI/OpenGL/OpenGLShader.h"
#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h"
#include "XCEngine/RHI/OpenGL/OpenGLEnums.h"
#include "XCEngine/RHI/OpenGL/OpenGLFence.h"
#include "XCEngine/RHI/OpenGL/OpenGLSampler.h"
#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h"
@@ -121,6 +122,75 @@ FramebufferAttachmentType ResolveDepthAttachmentType(Format format) {
: FramebufferAttachmentType::Depth;
}
SamplerWrapMode ToOpenGLSamplerWrapMode(TextureAddressMode mode) {
switch (mode) {
case TextureAddressMode::Wrap:
return SamplerWrapMode::Repeat;
case TextureAddressMode::Mirror:
return SamplerWrapMode::MirroredRepeat;
case TextureAddressMode::Clamp:
return SamplerWrapMode::ClampToEdge;
case TextureAddressMode::Border:
return SamplerWrapMode::ClampToBorder;
case TextureAddressMode::MirrorOnce:
return SamplerWrapMode::ClampToEdge;
default:
return SamplerWrapMode::Repeat;
}
}
OpenGLSamplerDesc ToOpenGLSamplerDesc(const SamplerDesc& desc) {
OpenGLSamplerDesc glDesc = {};
const FilterMode filter = static_cast<FilterMode>(desc.filter);
switch (filter) {
case FilterMode::Point:
glDesc.minFilter = SamplerFilter::Nearest;
glDesc.magFilter = SamplerFilter::Nearest;
break;
case FilterMode::Linear:
glDesc.minFilter = SamplerFilter::Linear;
glDesc.magFilter = SamplerFilter::Linear;
break;
case FilterMode::Anisotropic:
glDesc.minFilter = SamplerFilter::LinearMipmapLinear;
glDesc.magFilter = SamplerFilter::Linear;
glDesc.maxAnisotropy = desc.maxAnisotropy > 0 ? static_cast<float>(desc.maxAnisotropy) : 1.0f;
break;
case FilterMode::ComparisonPoint:
glDesc.minFilter = SamplerFilter::Nearest;
glDesc.magFilter = SamplerFilter::Nearest;
glDesc.compareMode = SamplerCompareMode::CompareToRef;
break;
case FilterMode::ComparisonLinear:
glDesc.minFilter = SamplerFilter::Linear;
glDesc.magFilter = SamplerFilter::Linear;
glDesc.compareMode = SamplerCompareMode::CompareToRef;
break;
case FilterMode::ComparisonAnisotropic:
glDesc.minFilter = SamplerFilter::LinearMipmapLinear;
glDesc.magFilter = SamplerFilter::Linear;
glDesc.compareMode = SamplerCompareMode::CompareToRef;
glDesc.maxAnisotropy = desc.maxAnisotropy > 0 ? static_cast<float>(desc.maxAnisotropy) : 1.0f;
break;
default:
break;
}
glDesc.wrapS = ToOpenGLSamplerWrapMode(static_cast<TextureAddressMode>(desc.addressU));
glDesc.wrapT = ToOpenGLSamplerWrapMode(static_cast<TextureAddressMode>(desc.addressV));
glDesc.wrapR = ToOpenGLSamplerWrapMode(static_cast<TextureAddressMode>(desc.addressW));
glDesc.compareFunc = static_cast<int>(ToOpenGL(static_cast<ComparisonFunc>(desc.comparisonFunc)));
glDesc.mipLodBias = desc.mipLodBias;
glDesc.maxAnisotropy = glDesc.maxAnisotropy < 1.0f ? 1.0f : glDesc.maxAnisotropy;
glDesc.borderColor[0] = desc.borderColorR;
glDesc.borderColor[1] = desc.borderColorG;
glDesc.borderColor[2] = desc.borderColorB;
glDesc.borderColor[3] = desc.borderColorA;
glDesc.minLod = desc.minLod;
glDesc.maxLod = desc.maxLod;
return glDesc;
}
HWND CreateHiddenOpenGLWindow() {
WNDCLASSEXW wc = {};
wc.cbSize = sizeof(WNDCLASSEXW);
@@ -684,8 +754,11 @@ RHIFence* OpenGLDevice::CreateFence(const FenceDesc& desc) {
RHISampler* OpenGLDevice::CreateSampler(const SamplerDesc& desc) {
auto* sampler = new OpenGLSampler();
OpenGLSamplerDesc samplerDesc = {};
sampler->Initialize(samplerDesc);
const OpenGLSamplerDesc samplerDesc = ToOpenGLSamplerDesc(desc);
if (!sampler->Initialize(samplerDesc)) {
delete sampler;
return nullptr;
}
return sampler;
}

View File

@@ -20,9 +20,16 @@ bool OpenGLSampler::Initialize(const OpenGLSamplerDesc& desc) {
glSamplerParameteri(m_sampler, GL_TEXTURE_WRAP_S, ToOpenGL(desc.wrapS));
glSamplerParameteri(m_sampler, GL_TEXTURE_WRAP_T, ToOpenGL(desc.wrapT));
glSamplerParameteri(m_sampler, GL_TEXTURE_WRAP_R, ToOpenGL(desc.wrapR));
glSamplerParameterf(m_sampler, GL_TEXTURE_LOD_BIAS, desc.mipLodBias);
glSamplerParameterf(m_sampler, GL_TEXTURE_MIN_LOD, desc.minLod);
glSamplerParameterf(m_sampler, GL_TEXTURE_MAX_LOD, desc.maxLod);
glSamplerParameterf(m_sampler, GL_TEXTURE_MAX_ANISOTROPY, desc.maxAnisotropy);
glSamplerParameteri(
m_sampler,
GL_TEXTURE_COMPARE_MODE,
desc.compareMode == SamplerCompareMode::CompareToRef ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE);
glSamplerParameteri(m_sampler, GL_TEXTURE_COMPARE_FUNC, desc.compareFunc);
glSamplerParameterfv(m_sampler, GL_TEXTURE_BORDER_COLOR, desc.borderColor);
return true;
}