Commit 5c41bb97 authored by Laszlo Agocs's avatar Laszlo Agocs

Rework a bit how we handle cubemap faces as render targets

parent 2bcdac4c
......@@ -242,6 +242,7 @@ struct Q_RHI_EXPORT QRhiTextureRenderTargetDescription
QRhiTexture *texture = nullptr;
QRhiRenderBuffer *renderBuffer = nullptr;
int layer = 0; // face (0..5) for cubemaps
int level = 0;
};
QRhiTextureRenderTargetDescription()
......
......@@ -998,7 +998,7 @@ void QRhiD3D11::finishActiveReadbacks()
f();
}
static inline QD3D11BasicRenderTargetData *basicRtData(QRhiRenderTarget *rt)
static inline QD3D11RenderTargetData *rtData(QRhiRenderTarget *rt)
{
switch (rt->type()) {
case QRhiRenderTarget::RtRef:
......@@ -1031,7 +1031,7 @@ void QRhiD3D11::beginPass(QRhiCommandBuffer *cb,
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
bool needsColorClear = true;
QD3D11BasicRenderTargetData *rtD = basicRtData(rt);
QD3D11RenderTargetData *rtD = rtData(rt);
if (rt->type() == QRhiRenderTarget::RtTexture) {
QD3D11TextureRenderTarget *rtTex = QRHI_RES(QD3D11TextureRenderTarget, rt);
needsColorClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents);
......@@ -1241,13 +1241,13 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD)
nullsrvs[i] = nullptr;
context->VSSetShaderResources(0, nullsrvs.count(), nullsrvs.constData());
context->PSSetShaderResources(0, nullsrvs.count(), nullsrvs.constData());
QD3D11BasicRenderTargetData *rtD = basicRtData(rt);
QD3D11RenderTargetData *rtD = rtData(rt);
context->OMSetRenderTargets(rtD->colorAttCount, rtD->colorAttCount ? rtD->rtv : nullptr, rtD->dsv);
}
break;
case QD3D11CommandBuffer::Command::Clear:
{
QD3D11BasicRenderTargetData *rtD = basicRtData(cmd.args.clear.rt);
QD3D11RenderTargetData *rtD = rtData(cmd.args.clear.rt);
if (cmd.args.clear.mask & QD3D11CommandBuffer::Command::Color) {
for (int i = 0; i < rtD->colorAttCount; ++i)
context->ClearRenderTargetView(rtD->rtv[i], cmd.args.clear.c);
......@@ -1779,7 +1779,7 @@ QD3D11TextureRenderTarget::QD3D11TextureRenderTarget(QRhiImplementation *rhi,
: QRhiTextureRenderTarget(rhi, desc, flags),
d(rhi)
{
for (int i = 0; i < QD3D11BasicRenderTargetData::MAX_COLOR_ATTACHMENTS; ++i) {
for (int i = 0; i < QD3D11RenderTargetData::MAX_COLOR_ATTACHMENTS; ++i) {
ownsRtv[i] = false;
rtv[i] = nullptr;
}
......@@ -1796,7 +1796,7 @@ void QD3D11TextureRenderTarget::release()
dsv = nullptr;
}
for (int i = 0; i < QD3D11BasicRenderTargetData::MAX_COLOR_ATTACHMENTS; ++i) {
for (int i = 0; i < QD3D11RenderTargetData::MAX_COLOR_ATTACHMENTS; ++i) {
if (rtv[i]) {
if (ownsRtv[i])
rtv[i]->Release();
......@@ -1833,11 +1833,16 @@ bool QD3D11TextureRenderTarget::build()
rtvDesc.Format = toD3DTextureFormat(texD->format(), texD->flags());
if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
rtvDesc.Texture2DArray.MipSlice = m_desc.colorAttachments[i].level;
rtvDesc.Texture2DArray.FirstArraySlice = m_desc.colorAttachments[i].layer;
rtvDesc.Texture2DArray.ArraySize = 1;
} else {
rtvDesc.ViewDimension = texD->sampleDesc.Count > 1 ? D3D11_RTV_DIMENSION_TEXTURE2DMS
: D3D11_RTV_DIMENSION_TEXTURE2D;
if (texD->sampleDesc.Count > 1) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
} else {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtvDesc.Texture2D.MipSlice = m_desc.colorAttachments[i].level;
}
}
HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[i]);
if (FAILED(hr)) {
......@@ -1885,7 +1890,7 @@ bool QD3D11TextureRenderTarget::build()
d.dsAttCount = 0;
}
for (int i = 0; i < QD3D11BasicRenderTargetData::MAX_COLOR_ATTACHMENTS; ++i)
for (int i = 0; i < QD3D11RenderTargetData::MAX_COLOR_ATTACHMENTS; ++i)
d.rtv[i] = i < d.colorAttCount ? rtv[i] : nullptr;
d.dsv = dsv;
......
......@@ -114,9 +114,9 @@ struct QD3D11RenderPassDescriptor : public QRhiRenderPassDescriptor
void release() override;
};
struct QD3D11BasicRenderTargetData
struct QD3D11RenderTargetData
{
QD3D11BasicRenderTargetData(QRhiImplementation *)
QD3D11RenderTargetData(QRhiImplementation *)
{
for (int i = 0; i < MAX_COLOR_ATTACHMENTS; ++i)
rtv[i] = nullptr;
......@@ -139,7 +139,7 @@ struct QD3D11ReferenceRenderTarget : public QRhiReferenceRenderTarget
Type type() const override;
QSize sizeInPixels() const override;
QD3D11BasicRenderTargetData d;
QD3D11RenderTargetData d;
};
struct QD3D11TextureRenderTarget : public QRhiTextureRenderTarget
......@@ -153,9 +153,9 @@ struct QD3D11TextureRenderTarget : public QRhiTextureRenderTarget
QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
bool build() override;
QD3D11BasicRenderTargetData d;
bool ownsRtv[QD3D11BasicRenderTargetData::MAX_COLOR_ATTACHMENTS];
ID3D11RenderTargetView *rtv[QD3D11BasicRenderTargetData::MAX_COLOR_ATTACHMENTS];
QD3D11RenderTargetData d;
bool ownsRtv[QD3D11RenderTargetData::MAX_COLOR_ATTACHMENTS];
ID3D11RenderTargetView *rtv[QD3D11RenderTargetData::MAX_COLOR_ATTACHMENTS];
bool ownsDsv = false;
ID3D11DepthStencilView *dsv = nullptr;
friend class QRhiD3D11;
......
......@@ -1783,8 +1783,9 @@ bool QGles2TextureRenderTarget::build()
rhiD->f->glGenFramebuffers(1, &framebuffer);
rhiD->f->glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
QRhiTexture *texture = m_desc.colorAttachments.first().texture;
QRhiRenderBuffer *renderBuffer = m_desc.colorAttachments.first().renderBuffer;
const QRhiTextureRenderTargetDescription::ColorAttachment &colorAtt(m_desc.colorAttachments.constFirst());
QRhiTexture *texture = colorAtt.texture;
QRhiRenderBuffer *renderBuffer = colorAtt.renderBuffer;
Q_ASSERT(texture || renderBuffer);
d.rp = QRHI_RES(QGles2RenderPassDescriptor, m_renderPassDesc);
......@@ -1793,7 +1794,9 @@ bool QGles2TextureRenderTarget::build()
if (texture) {
QGles2Texture *texD = QRHI_RES(QGles2Texture, texture);
Q_ASSERT(texD->texture && texD->specified);
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texD->target, texD->texture, 0);
const GLenum targetBase = texD->flags().testFlag(QRhiTexture::CubeMap) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target;
const GLenum target = targetBase + colorAtt.layer;
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, texD->texture, colorAtt.level);
d.pixelSize = texD->pixelSize();
} else {
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, renderBuffer);
......
......@@ -144,7 +144,12 @@ struct QMetalRenderTargetData
int colorAttCount = 0;
int dsAttCount = 0;
struct {
id<MTLTexture> colorTex[QMetalRenderPassDescriptor::MAX_COLOR_ATTACHMENTS];
struct ColorAtt {
id<MTLTexture> tex = nil;
int layer = 0;
int level = 0;
};
ColorAtt colorAtt[QMetalRenderPassDescriptor::MAX_COLOR_ATTACHMENTS];
id<MTLTexture> dsTex = nil;
id<MTLTexture> resolveTex = nil;
bool hasStencil = false;
......@@ -561,7 +566,7 @@ QRhi::FrameOpResult QRhiMetal::beginFrame(QRhiSwapChain *swapChain)
scTex = swapChainD->d->msaaTex[currentFrameSlot];
}
swapChainD->rtWrapper.d->fb.colorTex[0] = scTex;
swapChainD->rtWrapper.d->fb.colorAtt[0] = { scTex, 0, 0 };
swapChainD->rtWrapper.d->fb.dsTex = swapChainD->ds ? swapChainD->ds->d->tex : nil;
swapChainD->rtWrapper.d->fb.resolveTex = resolveTex;
swapChainD->rtWrapper.d->fb.hasStencil = swapChainD->ds ? true : false;
......@@ -849,8 +854,11 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
break;
}
for (int i = 0; i < rtD->colorAttCount; ++i)
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorTex[i];
for (int i = 0; i < rtD->colorAttCount; ++i) {
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex;
cbD->d->currentPassRpDesc.colorAttachments[i].slice = rtD->fb.colorAtt[i].layer;
cbD->d->currentPassRpDesc.colorAttachments[i].level = rtD->fb.colorAtt[i].level;
}
// MSAA swapchains pass the multisample texture in colorTex and the
// non-multisample texture (from the drawable) in resolveTex.
......@@ -1334,7 +1342,7 @@ bool QMetalTextureRenderTarget::build()
QRhiTexture *texture = m_desc.colorAttachments[i].texture;
Q_ASSERT(texture);
QMetalTexture *texD = QRHI_RES(QMetalTexture, texture);
d->fb.colorTex[i] = texD->d->tex;
d->fb.colorAtt[i] = { texD->d->tex, m_desc.colorAttachments[i].layer, m_desc.colorAttachments[i].level };
if (i == 0)
d->pixelSize = texD->pixelSize();
}
......
......@@ -2434,8 +2434,8 @@ void QRhiVulkan::executeDeferredReleases(bool forced)
break;
case QRhiVulkan::DeferredReleaseEntry::TextureRenderTarget:
df->vkDestroyFramebuffer(dev, e.textureRenderTarget.fb, nullptr);
for (int face = 0; face < 6; ++face)
df->vkDestroyImageView(dev, e.textureRenderTarget.cubeFaceView[face], nullptr);
for (int att = 0; att < QVkRenderTargetData::MAX_COLOR_ATTACHMENTS; ++att)
df->vkDestroyImageView(dev, e.textureRenderTarget.rtv[att], nullptr);
break;
case QRhiVulkan::DeferredReleaseEntry::RenderPass:
df->vkDestroyRenderPass(dev, e.renderPass.rp, nullptr);
......@@ -3451,7 +3451,7 @@ bool QVkTexture::build()
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.levelCount = mipLevelCount;
viewInfo.subresourceRange.layerCount = isCube ? 6 : 1;
err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &imageView);
......@@ -3569,8 +3569,8 @@ QVkTextureRenderTarget::QVkTextureRenderTarget(QRhiImplementation *rhi,
Flags flags)
: QRhiTextureRenderTarget(rhi, desc, flags)
{
for (int i = 0; i < 6; ++i)
cubeFaceView[i] = VK_NULL_HANDLE;
for (int att = 0; att < QVkRenderTargetData::MAX_COLOR_ATTACHMENTS; ++att)
rtv[att] = VK_NULL_HANDLE;
}
void QVkTextureRenderTarget::release()
......@@ -3585,9 +3585,9 @@ void QVkTextureRenderTarget::release()
e.textureRenderTarget.fb = d.fb;
d.fb = VK_NULL_HANDLE;
for (int i = 0; i < 6; ++i) {
e.textureRenderTarget.cubeFaceView[i] = cubeFaceView[i];
cubeFaceView[i] = VK_NULL_HANDLE;
for (int att = 0; att < QVkRenderTargetData::MAX_COLOR_ATTACHMENTS; ++att) {
e.textureRenderTarget.rtv[att] = rtv[att];
rtv[att] = VK_NULL_HANDLE;
}
QRHI_RES_RHI(QRhiVulkan);
......@@ -3633,34 +3633,27 @@ bool QVkTextureRenderTarget::build()
Q_ASSERT(texD || rbD);
if (texD) {
Q_ASSERT(texD->flags().testFlag(QRhiTexture::RenderTarget));
VkImageView view = texD->imageView;
if (texD->flags().testFlag(QRhiTexture::CubeMap)) {
const int face = m_desc.colorAttachments[i].layer;
Q_ASSERT(face >= 0 && face < 6);
if (!cubeFaceView[face]) {
VkImageViewCreateInfo viewInfo;
memset(&viewInfo, 0, sizeof(viewInfo));
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = texD->image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = texD->vkformat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = face;
viewInfo.subresourceRange.layerCount = 1;
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &cubeFaceView[face]);
if (err != VK_SUCCESS) {
qWarning("Failed to create cubemap face image view: %d", err);
return false;
}
}
view = cubeFaceView[face];
VkImageViewCreateInfo viewInfo;
memset(&viewInfo, 0, sizeof(viewInfo));
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = texD->image;
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = texD->vkformat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.subresourceRange.baseMipLevel = m_desc.colorAttachments[i].level;
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = m_desc.colorAttachments[i].layer;
viewInfo.subresourceRange.layerCount = 1;
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &rtv[i]);
if (err != VK_SUCCESS) {
qWarning("Failed to create cubemap face image view: %d", err);
return false;
}
views.append(view);
views.append(rtv[i]);
if (i == 0)
d.pixelSize = texD->pixelSize();
} else if (rbD) {
......
......@@ -149,6 +149,7 @@ struct QVkRenderTargetData
int colorAttCount = 0;
int dsAttCount = 0;
int msaaAttCount = 0;
static const int MAX_COLOR_ATTACHMENTS = 8;
};
struct QVkReferenceRenderTarget : public QRhiReferenceRenderTarget
......@@ -173,7 +174,7 @@ struct QVkTextureRenderTarget : public QRhiTextureRenderTarget
bool build() override;
QVkRenderTargetData d;
VkImageView cubeFaceView[6];
VkImageView rtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS];
int lastActiveFrameSlot = -1;
friend class QRhiVulkan;
};
......@@ -549,7 +550,7 @@ public:
} sampler;
struct {
VkFramebuffer fb;
VkImageView cubeFaceView[6];
VkImageView rtv[QVkRenderTargetData::MAX_COLOR_ATTACHMENTS];
} textureRenderTarget;
struct {
VkRenderPass rp;
......
mtl: rhi without a window, offscreen frame
mtl: readback (tex, backbuffer)
mtl: compressed textures
mtl: targeting cubemap faces
mtl: srgb (tex, swapchain buf)
mtl: resolveimage (color)
mtl: color renderbuffer
......@@ -59,6 +58,8 @@ dxc for d3d as an alternative to fxc?
hlsl -> dxc -> spirv -> spirv-cross hmmm...
+++ done
targeting mip level in texrt
mtl: targeting cubemap faces
mtl: cubemaps
mtl: msaa tex+rt
clear window vs surface/layer size mess
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment