summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhid3d11.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-05-19 19:30:53 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-05-31 17:16:57 +0200
commit51c22a1f51e2f91289c938be7754f957c9bfa47e (patch)
tree58eea1c4aeb83f4ee2ede516f321624ab5558181 /src/gui/rhi/qrhid3d11.cpp
parent5eab5d62530f351307a01ca57af964e5c506079c (diff)
rhi: Add support for 3D textures
Supported on OpenGL (and ES) 3.0+ and everywhere else. Can also be a render target, targeting a single slice at a time. Can be mipmapped, cannot be multisample. Reading back a given slice from a 3D texture is left as a future exercise, for now it is documented to be not supported. Upload is going to be limited to one slice in one upload entry, just like we specify one face or one miplevel for cubemap and mipmapped textures. This also involves some welcome hardening of how texture subresources are described internally: as we no longer can count on a layer index between 0..5 (as is the case with cubemaps), simply arrays with MAX_LAYER==6 are no longer sufficient. Switch to sufficiently dynamic data structures where applicable. On Vulkan rendering to a slice needs Vulkan 1.1 (and 1.1 enabled on the VkInstance). Task-number: QTBUG-89703 Change-Id: Ide6c20124ec9201d94ffc339dd479cd1ece777b0 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhid3d11.cpp')
-rw-r--r--src/gui/rhi/qrhid3d11.cpp178
1 files changed, 125 insertions, 53 deletions
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 8d15f2622f..d16332e5b9 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -546,6 +546,10 @@ bool QRhiD3D11::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::RenderBufferImport:
return false;
+ case QRhi::ThreeDimensionalTextures:
+ return true;
+ case QRhi::RenderTo3DTextureSlice:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -633,10 +637,11 @@ QRhiRenderBuffer *QRhiD3D11::createRenderBuffer(QRhiRenderBuffer::Type type, con
return new QD3D11RenderBuffer(this, type, pixelSize, sampleCount, flags, backingFormatHint);
}
-QRhiTexture *QRhiD3D11::createTexture(QRhiTexture::Format format, const QSize &pixelSize,
+QRhiTexture *QRhiD3D11::createTexture(QRhiTexture::Format format,
+ const QSize &pixelSize, int depth,
int sampleCount, QRhiTexture::Flags flags)
{
- return new QD3D11Texture(this, format, pixelSize, sampleCount, flags);
+ return new QD3D11Texture(this, format, pixelSize, depth, sampleCount, flags);
}
QRhiSampler *QRhiD3D11::createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
@@ -1351,17 +1356,18 @@ QRhi::FrameOpResult QRhiD3D11::finish()
void QRhiD3D11::enqueueSubresUpload(QD3D11Texture *texD, QD3D11CommandBuffer *cbD,
int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc)
{
- UINT subres = D3D11CalcSubresource(UINT(level), UINT(layer), texD->mipLevelCount);
- const QPoint dp = subresDesc.destinationTopLeft();
+ const bool is3D = texD->m_flags.testFlag(QRhiTexture::ThreeDimensional);
+ UINT subres = D3D11CalcSubresource(UINT(level), is3D ? 0u : UINT(layer), texD->mipLevelCount);
D3D11_BOX box;
- box.front = 0;
+ box.front = is3D ? UINT(layer) : 0u;
// back, right, bottom are exclusive
- box.back = 1;
+ box.back = box.front + 1;
QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::UpdateSubRes;
- cmd.args.updateSubRes.dst = texD->tex;
+ cmd.args.updateSubRes.dst = texD->textureResource();
cmd.args.updateSubRes.dstSubRes = subres;
+ const QPoint dp = subresDesc.destinationTopLeft();
if (!subresDesc.image().isNull()) {
QImage img = subresDesc.image();
QSize size = img.size();
@@ -1488,6 +1494,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copySubRes.dstSubRes = 0;
cmd.args.copySubRes.dstX = 0;
cmd.args.copySubRes.dstY = 0;
+ cmd.args.copySubRes.dstZ = 0;
cmd.args.copySubRes.src = bufD->buffer;
cmd.args.copySubRes.srcSubRes = 0;
cmd.args.copySubRes.hasSrcBox = true;
@@ -1508,8 +1515,8 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
QD3D11Texture *texD = QRHI_RES(QD3D11Texture, u.dst);
- for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
- for (int level = 0; level < QRhi::MAX_LEVELS; ++level) {
+ for (int layer = 0, maxLayer = u.subresDesc.count(); layer < maxLayer; ++layer) {
+ for (int level = 0; level < QRhi::MAX_MIP_LEVELS; ++level) {
for (const QRhiTextureSubresourceUploadDescription &subresDesc : qAsConst(u.subresDesc[layer][level]))
enqueueSubresUpload(texD, cbD, layer, level, subresDesc);
}
@@ -1518,8 +1525,10 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
Q_ASSERT(u.src && u.dst);
QD3D11Texture *srcD = QRHI_RES(QD3D11Texture, u.src);
QD3D11Texture *dstD = QRHI_RES(QD3D11Texture, u.dst);
- UINT srcSubRes = D3D11CalcSubresource(UINT(u.desc.sourceLevel()), UINT(u.desc.sourceLayer()), srcD->mipLevelCount);
- UINT dstSubRes = D3D11CalcSubresource(UINT(u.desc.destinationLevel()), UINT(u.desc.destinationLayer()), dstD->mipLevelCount);
+ const bool srcIs3D = srcD->m_flags.testFlag(QRhiTexture::ThreeDimensional);
+ const bool dstIs3D = dstD->m_flags.testFlag(QRhiTexture::ThreeDimensional);
+ UINT srcSubRes = D3D11CalcSubresource(UINT(u.desc.sourceLevel()), srcIs3D ? 0u : UINT(u.desc.sourceLayer()), srcD->mipLevelCount);
+ UINT dstSubRes = D3D11CalcSubresource(UINT(u.desc.destinationLevel()), dstIs3D ? 0u : UINT(u.desc.destinationLayer()), dstD->mipLevelCount);
const QPoint dp = u.desc.destinationTopLeft();
const QSize mipSize = q->sizeForMipLevel(u.desc.sourceLevel(), srcD->m_pixelSize);
const QSize copySize = u.desc.pixelSize().isEmpty() ? mipSize : u.desc.pixelSize();
@@ -1527,18 +1536,19 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
D3D11_BOX srcBox;
srcBox.left = UINT(sp.x());
srcBox.top = UINT(sp.y());
- srcBox.front = 0;
+ srcBox.front = srcIs3D ? UINT(u.desc.sourceLayer()) : 0u;
// back, right, bottom are exclusive
srcBox.right = srcBox.left + UINT(copySize.width());
srcBox.bottom = srcBox.top + UINT(copySize.height());
- srcBox.back = 1;
+ srcBox.back = srcBox.front + 1;
QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::CopySubRes;
- cmd.args.copySubRes.dst = dstD->tex;
+ cmd.args.copySubRes.dst = dstD->textureResource();
cmd.args.copySubRes.dstSubRes = dstSubRes;
cmd.args.copySubRes.dstX = UINT(dp.x());
cmd.args.copySubRes.dstY = UINT(dp.y());
- cmd.args.copySubRes.src = srcD->tex;
+ cmd.args.copySubRes.dstZ = dstIs3D ? UINT(u.desc.destinationLayer()) : 0u;
+ cmd.args.copySubRes.src = srcD->textureResource();
cmd.args.copySubRes.srcSubRes = srcSubRes;
cmd.args.copySubRes.hasSrcBox = true;
cmd.args.copySubRes.srcBox = srcBox;
@@ -1560,7 +1570,13 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
qWarning("Multisample texture cannot be read back");
continue;
}
- src = texD->tex;
+ // No support for reading back 3D, not because it is not
+ // possible technically, but we need to draw the line somewhere.
+ if (texD->m_flags.testFlag(QRhiTexture::ThreeDimensional)) {
+ qWarning("3D texture cannot be read back");
+ continue;
+ }
+ src = texD->textureResource();
dxgiFormat = texD->dxgiFormat;
pixelSize = q->sizeForMipLevel(u.rb.level(), texD->m_pixelSize);
format = texD->m_format;
@@ -1616,6 +1632,7 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cmd.args.copySubRes.dstSubRes = 0;
cmd.args.copySubRes.dstX = 0;
cmd.args.copySubRes.dstY = 0;
+ cmd.args.copySubRes.dstZ = 0;
cmd.args.copySubRes.src = src;
cmd.args.copySubRes.srcSubRes = subres;
cmd.args.copySubRes.hasSrcBox = false;
@@ -1791,12 +1808,12 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
Q_ASSERT(srcTexD || srcRbD);
QD3D11CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
- cmd.args.resolveSubRes.dst = dstTexD->tex;
+ cmd.args.resolveSubRes.dst = dstTexD->textureResource();
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(UINT(colorAtt.resolveLevel()),
UINT(colorAtt.resolveLayer()),
dstTexD->mipLevelCount);
if (srcTexD) {
- cmd.args.resolveSubRes.src = srcTexD->tex;
+ cmd.args.resolveSubRes.src = srcTexD->textureResource();
if (srcTexD->dxgiFormat != dstTexD->dxgiFormat) {
qWarning("Resolve source (%d) and destination (%d) formats do not match",
int(srcTexD->dxgiFormat), int(dstTexD->dxgiFormat));
@@ -2582,7 +2599,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD, QD3D11SwapChain *
break;
case QD3D11CommandBuffer::Command::CopySubRes:
context->CopySubresourceRegion(cmd.args.copySubRes.dst, cmd.args.copySubRes.dstSubRes,
- cmd.args.copySubRes.dstX, cmd.args.copySubRes.dstY, 0,
+ cmd.args.copySubRes.dstX, cmd.args.copySubRes.dstY, cmd.args.copySubRes.dstZ,
cmd.args.copySubRes.src, cmd.args.copySubRes.srcSubRes,
cmd.args.copySubRes.hasSrcBox ? &cmd.args.copySubRes.srcBox : nullptr);
break;
@@ -2885,11 +2902,11 @@ QRhiTexture::Format QD3D11RenderBuffer::backingFormat() const
return m_type == Color ? QRhiTexture::RGBA8 : QRhiTexture::UnknownFormat;
}
-QD3D11Texture::QD3D11Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize,
+QD3D11Texture::QD3D11Texture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth,
int sampleCount, Flags flags)
- : QRhiTexture(rhi, format, pixelSize, sampleCount, flags)
+ : QRhiTexture(rhi, format, pixelSize, depth, sampleCount, flags)
{
- for (int i = 0; i < QRhi::MAX_LEVELS; ++i)
+ for (int i = 0; i < QRhi::MAX_MIP_LEVELS; ++i)
perLevelViews[i] = nullptr;
}
@@ -2900,7 +2917,7 @@ QD3D11Texture::~QD3D11Texture()
void QD3D11Texture::destroy()
{
- if (!tex)
+ if (!tex && !tex3D)
return;
if (srv) {
@@ -2908,17 +2925,22 @@ void QD3D11Texture::destroy()
srv = nullptr;
}
- for (int i = 0; i < QRhi::MAX_LEVELS; ++i) {
+ for (int i = 0; i < QRhi::MAX_MIP_LEVELS; ++i) {
if (perLevelViews[i]) {
perLevelViews[i]->Release();
perLevelViews[i] = nullptr;
}
}
- if (owns)
- tex->Release();
+ if (owns) {
+ if (tex)
+ tex->Release();
+ if (tex3D)
+ tex3D->Release();
+ }
tex = nullptr;
+ tex3D = nullptr;
QRHI_RES_RHI(QRhiD3D11);
QRHI_PROF;
@@ -2962,12 +2984,13 @@ static inline DXGI_FORMAT toD3DDepthTextureDSVFormat(QRhiTexture::Format format)
bool QD3D11Texture::prepareCreate(QSize *adjustedSize)
{
- if (tex)
+ if (tex || tex3D)
destroy();
const QSize size = m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize;
const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool is3D = m_flags.testFlag(ThreeDimensional);
const bool hasMipMaps = m_flags.testFlag(MipMapped);
QRHI_RES_RHI(QRhiD3D11);
@@ -2979,6 +3002,10 @@ bool QD3D11Texture::prepareCreate(QSize *adjustedSize)
qWarning("Cubemap texture cannot be multisample");
return false;
}
+ if (is3D) {
+ qWarning("3D texture cannot be multisample");
+ return false;
+ }
if (hasMipMaps) {
qWarning("Multisample texture cannot have mipmaps");
return false;
@@ -2988,6 +3015,15 @@ bool QD3D11Texture::prepareCreate(QSize *adjustedSize)
qWarning("Depth texture cannot have mipmaps");
return false;
}
+ if (isCube && is3D) {
+ qWarning("Texture cannot be both cube and 3D");
+ return false;
+ }
+ m_depth = qMax(1, m_depth);
+ if (m_depth > 1 && !is3D) {
+ qWarning("Texture cannot have a depth of %d when it is not 3D", m_depth);
+ return false;
+ }
if (adjustedSize)
*adjustedSize = size;
@@ -3000,6 +3036,7 @@ bool QD3D11Texture::finishCreate()
QRHI_RES_RHI(QRhiD3D11);
const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool is3D = m_flags.testFlag(ThreeDimensional);
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
memset(&srvDesc, 0, sizeof(srvDesc));
@@ -3010,13 +3047,16 @@ bool QD3D11Texture::finishCreate()
} else {
if (sampleDesc.Count > 1) {
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ } else if (is3D) {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
+ srvDesc.Texture3D.MipLevels = mipLevelCount;
} else {
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = mipLevelCount;
}
}
- HRESULT hr = rhiD->dev->CreateShaderResourceView(tex, &srvDesc, &srv);
+ HRESULT hr = rhiD->dev->CreateShaderResourceView(textureResource(), &srvDesc, &srv);
if (FAILED(hr)) {
qWarning("Failed to create srv: %s", qPrintable(comErrorMessage(hr)));
return false;
@@ -3034,6 +3074,7 @@ bool QD3D11Texture::create()
const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool is3D = m_flags.testFlag(ThreeDimensional);
uint bindFlags = D3D11_BIND_SHADER_RESOURCE;
uint miscFlags = isCube ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0;
@@ -3054,31 +3095,51 @@ bool QD3D11Texture::create()
if (m_flags.testFlag(UsedWithLoadStore))
bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
- D3D11_TEXTURE2D_DESC desc;
- memset(&desc, 0, sizeof(desc));
- desc.Width = UINT(size.width());
- desc.Height = UINT(size.height());
- desc.MipLevels = mipLevelCount;
- desc.ArraySize = isCube ? 6 : 1;
- desc.Format = dxgiFormat;
- desc.SampleDesc = sampleDesc;
- desc.Usage = D3D11_USAGE_DEFAULT;
- desc.BindFlags = bindFlags;
- desc.MiscFlags = miscFlags;
-
QRHI_RES_RHI(QRhiD3D11);
- HRESULT hr = rhiD->dev->CreateTexture2D(&desc, nullptr, &tex);
- if (FAILED(hr)) {
- qWarning("Failed to create texture: %s", qPrintable(comErrorMessage(hr)));
- return false;
+ if (!is3D) {
+ D3D11_TEXTURE2D_DESC desc;
+ memset(&desc, 0, sizeof(desc));
+ desc.Width = UINT(size.width());
+ desc.Height = UINT(size.height());
+ desc.MipLevels = mipLevelCount;
+ desc.ArraySize = isCube ? 6 : 1;
+ desc.Format = dxgiFormat;
+ desc.SampleDesc = sampleDesc;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = bindFlags;
+ desc.MiscFlags = miscFlags;
+
+ HRESULT hr = rhiD->dev->CreateTexture2D(&desc, nullptr, &tex);
+ if (FAILED(hr)) {
+ qWarning("Failed to create 2D texture: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ if (!m_objectName.isEmpty())
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
+ } else {
+ D3D11_TEXTURE3D_DESC desc;
+ memset(&desc, 0, sizeof(desc));
+ desc.Width = UINT(size.width());
+ desc.Height = UINT(size.height());
+ desc.Depth = UINT(m_depth);
+ desc.MipLevels = mipLevelCount;
+ desc.Format = dxgiFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = bindFlags;
+ desc.MiscFlags = miscFlags;
+
+ HRESULT hr = rhiD->dev->CreateTexture3D(&desc, nullptr, &tex3D);
+ if (FAILED(hr)) {
+ qWarning("Failed to create 3D texture: %s", qPrintable(comErrorMessage(hr)));
+ return false;
+ }
+ if (!m_objectName.isEmpty())
+ tex3D->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
}
if (!finishCreate())
return false;
- if (!m_objectName.isEmpty())
- tex->SetPrivateData(WKPDID_D3DDebugObjectName, UINT(m_objectName.size()), m_objectName.constData());
-
QRHI_PROF;
QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, int(sampleDesc.Count)));
@@ -3089,14 +3150,16 @@ bool QD3D11Texture::create()
bool QD3D11Texture::createFrom(QRhiTexture::NativeTexture src)
{
- ID3D11Texture2D *srcTex = reinterpret_cast<ID3D11Texture2D *>(src.object);
- if (srcTex == nullptr)
+ if (!src.object)
return false;
if (!prepareCreate())
return false;
- tex = srcTex;
+ if (m_flags.testFlag(ThreeDimensional))
+ tex3D = reinterpret_cast<ID3D11Texture3D *>(src.object);
+ else
+ tex = reinterpret_cast<ID3D11Texture2D *>(src.object);
if (!finishCreate())
return false;
@@ -3112,7 +3175,7 @@ bool QD3D11Texture::createFrom(QRhiTexture::NativeTexture src)
QRhiTexture::NativeTexture QD3D11Texture::nativeTexture()
{
- return {quint64(tex), 0};
+ return { quint64(textureResource()), 0 };
}
ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
@@ -3121,6 +3184,7 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
return perLevelViews[level];
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool is3D = m_flags.testFlag(ThreeDimensional);
D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
memset(&desc, 0, sizeof(desc));
desc.Format = dxgiFormat;
@@ -3129,6 +3193,9 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
desc.Texture2DArray.MipSlice = UINT(level);
desc.Texture2DArray.FirstArraySlice = 0;
desc.Texture2DArray.ArraySize = 6;
+ } else if (is3D) {
+ desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
+ desc.Texture3D.MipSlice = UINT(level);
} else {
desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
desc.Texture2D.MipSlice = UINT(level);
@@ -3136,7 +3203,7 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level)
QRHI_RES_RHI(QRhiD3D11);
ID3D11UnorderedAccessView *uav = nullptr;
- HRESULT hr = rhiD->dev->CreateUnorderedAccessView(tex, &desc, &uav);
+ HRESULT hr = rhiD->dev->CreateUnorderedAccessView(textureResource(), &desc, &uav);
if (FAILED(hr)) {
qWarning("Failed to create UAV: %s", qPrintable(comErrorMessage(hr)));
return nullptr;
@@ -3404,6 +3471,11 @@ bool QD3D11TextureRenderTarget::create()
rtvDesc.Texture2DArray.MipSlice = UINT(colorAtt.level());
rtvDesc.Texture2DArray.FirstArraySlice = UINT(colorAtt.layer());
rtvDesc.Texture2DArray.ArraySize = 1;
+ } else if (texD->flags().testFlag(QRhiTexture::ThreeDimensional)) {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = UINT(colorAtt.level());
+ rtvDesc.Texture3D.FirstWSlice = UINT(colorAtt.layer());
+ rtvDesc.Texture3D.WSize = 1;
} else {
if (texD->sampleDesc.Count > 1) {
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
@@ -3412,7 +3484,7 @@ bool QD3D11TextureRenderTarget::create()
rtvDesc.Texture2D.MipSlice = UINT(colorAtt.level());
}
}
- HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->tex, &rtvDesc, &rtv[attIndex]);
+ HRESULT hr = rhiD->dev->CreateRenderTargetView(texD->textureResource(), &rtvDesc, &rtv[attIndex]);
if (FAILED(hr)) {
qWarning("Failed to create rtv: %s", qPrintable(comErrorMessage(hr)));
return false;