aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-03-21 11:24:03 +0100
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-03-22 09:51:50 +0000
commite32fb877ec0662dfda41ce490d77d8bf35a377f1 (patch)
tree64a05c1a2a37a0b27f0d92597d45643e75769965
parent83eee56e9c047ff83329fe4a175a4b40fdbcb5d2 (diff)
D3D12: Support offscreen render targets in the engine
Also add a skeleton for the QSGLayer implementation. Change-Id: Id7234fa48b5c243147009a23d0e9689894a18366 Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/d3d12.pri6
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp5
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h1
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp326
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h7
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h62
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp165
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h98
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp12
-rw-r--r--src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h2
10 files changed, 599 insertions, 85 deletions
diff --git a/src/quick/scenegraph/adaptations/d3d12/d3d12.pri b/src/quick/scenegraph/adaptations/d3d12/d3d12.pri
index 8950734c56..1a24f84756 100644
--- a/src/quick/scenegraph/adaptations/d3d12/d3d12.pri
+++ b/src/quick/scenegraph/adaptations/d3d12/d3d12.pri
@@ -10,7 +10,8 @@ SOURCES += \
$$PWD/qsgd3d12texture.cpp \
$$PWD/qsgd3d12imagenode.cpp \
$$PWD/qsgd3d12glyphnode.cpp \
- $$PWD/qsgd3d12glyphcache.cpp
+ $$PWD/qsgd3d12glyphcache.cpp \
+ $$PWD/qsgd3d12layer.cpp
NO_PCH_SOURCES += \
$$PWD/qsgd3d12engine.cpp
@@ -29,7 +30,8 @@ HEADERS += \
$$PWD/qsgd3d12texture_p.h \
$$PWD/qsgd3d12imagenode_p.h \
$$PWD/qsgd3d12glyphnode_p.h \
- $$PWD/qsgd3d12glyphcache_p.h
+ $$PWD/qsgd3d12glyphcache_p.h \
+ $$PWD/qsgd3d12layer_p.h
LIBS += -ldxgi -ld3d12
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp
index f54be683f5..5c0d739c01 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context.cpp
@@ -88,6 +88,11 @@ QSGLayer *QSGD3D12Context::createLayer(QSGRenderContext *rc)
return nullptr;
}
+QSize QSGD3D12Context::minimumFBOSize() const
+{
+ return QSize(16, 16);
+}
+
QSurfaceFormat QSGD3D12Context::defaultSurfaceFormat() const
{
return QSGContext::defaultSurfaceFormat();
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h
index 6a092e8606..2afe22e3af 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12context_p.h
@@ -67,6 +67,7 @@ public:
QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode) override;
QSGNinePatchNode *createNinePatchNode() override;
QSGLayer *createLayer(QSGRenderContext *rc) override;
+ QSize minimumFBOSize() const override;
QSurfaceFormat defaultSurfaceFormat() const override;
};
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp
index f0ac2eee15..c486b0bfdd 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine.cpp
@@ -376,9 +376,9 @@ void QSGD3D12Engine::queueScissor(const QRect &rect)
d->queueScissor(rect);
}
-void QSGD3D12Engine::queueSetRenderTarget()
+void QSGD3D12Engine::queueSetRenderTarget(uint id)
{
- d->queueSetRenderTarget();
+ d->queueSetRenderTarget(id);
}
void QSGD3D12Engine::queueClearRenderTarget(const QColor &color)
@@ -458,6 +458,26 @@ void QSGD3D12Engine::activateTexture(uint id)
d->activateTexture(id);
}
+uint QSGD3D12Engine::genRenderTarget()
+{
+ return d->genRenderTarget();
+}
+
+void QSGD3D12Engine::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples)
+{
+ d->createRenderTarget(id, size, clearColor, samples);
+}
+
+void QSGD3D12Engine::releaseRenderTarget(uint id)
+{
+ d->releaseRenderTarget(id);
+}
+
+void QSGD3D12Engine::activateRenderTargetAsTexture(uint id)
+{
+ d->activateRenderTargetAsTexture(id);
+}
+
static inline quint32 alignedSize(quint32 size, quint32 byteAlign)
{
return (size + byteAlign - 1) & ~(byteAlign - 1);
@@ -564,7 +584,7 @@ void QSGD3D12EnginePrivate::releaseResources()
depthStencil = nullptr;
for (int i = 0; i < SWAP_CHAIN_BUFFER_COUNT; ++i)
- renderTargets[i] = nullptr;
+ backBufferRT[i] = nullptr;
for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
pframeData[i].vertex.buffer = nullptr;
@@ -576,6 +596,7 @@ void QSGD3D12EnginePrivate::releaseResources()
psoCache.clear();
rootSigCache.clear();
textures.clear();
+ renderTargets.clear();
cpuDescHeapManager.releaseResources();
@@ -709,6 +730,8 @@ void QSGD3D12EnginePrivate::initialize(QWindow *w)
if (!mipmapper.initialize(this))
return;
+ currentRenderTarget = 0;
+
initialized = true;
}
@@ -754,6 +777,41 @@ DXGI_SAMPLE_DESC QSGD3D12EnginePrivate::makeSampleDesc(DXGI_FORMAT format, int s
return sampleDesc;
}
+ID3D12Resource *QSGD3D12EnginePrivate::createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size,
+ const QVector4D &clearColor, int samples)
+{
+ D3D12_CLEAR_VALUE clearValue = {};
+ clearValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ clearValue.Color[0] = clearColor.x();
+ clearValue.Color[1] = clearColor.y();
+ clearValue.Color[2] = clearColor.z();
+ clearValue.Color[3] = clearColor.w();
+
+ D3D12_HEAP_PROPERTIES heapProp = {};
+ heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
+
+ D3D12_RESOURCE_DESC rtDesc = {};
+ rtDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ rtDesc.Width = size.width();
+ rtDesc.Height = size.height();
+ rtDesc.DepthOrArraySize = 1;
+ rtDesc.MipLevels = 1;
+ rtDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ rtDesc.SampleDesc = makeSampleDesc(rtDesc.Format, samples);
+ rtDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+
+ ID3D12Resource *resource = nullptr;
+ if (FAILED(device->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &rtDesc,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, &clearValue, IID_PPV_ARGS(&resource)))) {
+ qWarning("Failed to create offscreen render target of size %dx%d", size.width(), size.height());
+ return nullptr;
+ }
+
+ device->CreateRenderTargetView(resource, nullptr, viewHandle);
+
+ return resource;
+}
+
ID3D12Resource *QSGD3D12EnginePrivate::createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, int samples)
{
D3D12_CLEAR_VALUE depthClearValue = {};
@@ -793,17 +851,19 @@ ID3D12Resource *QSGD3D12EnginePrivate::createDepthStencil(D3D12_CPU_DESCRIPTOR_H
void QSGD3D12EnginePrivate::setupRenderTargets()
{
+ // ### multisampling needs an offscreen rt and explicit resolve, add this at some point
+
for (int i = 0; i < SWAP_CHAIN_BUFFER_COUNT; ++i) {
- if (FAILED(swapChain->GetBuffer(i, IID_PPV_ARGS(&renderTargets[i])))) {
+ if (FAILED(swapChain->GetBuffer(i, IID_PPV_ARGS(&backBufferRT[i])))) {
qWarning("Failed to get buffer %d from swap chain", i);
return;
}
- rtv[i] = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
- device->CreateRenderTargetView(renderTargets[i].Get(), nullptr, rtv[i]);
+ backBufferRTV[i] = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+ device->CreateRenderTargetView(backBufferRT[i].Get(), nullptr, backBufferRTV[i]);
}
- dsv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
- ID3D12Resource *ds = createDepthStencil(dsv, window->size(), 0);
+ backBufferDSV = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
+ ID3D12Resource *ds = createDepthStencil(backBufferDSV, window->size(), 0);
if (ds)
depthStencil.Attach(ds);
@@ -820,10 +880,10 @@ void QSGD3D12EnginePrivate::resize()
// Clear these, otherwise resizing will fail.
depthStencil = nullptr;
- cpuDescHeapManager.release(dsv, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
+ cpuDescHeapManager.release(backBufferDSV, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
for (int i = 0; i < SWAP_CHAIN_BUFFER_COUNT; ++i) {
- renderTargets[i] = nullptr;
- cpuDescHeapManager.release(rtv[i], D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+ backBufferRT[i] = nullptr;
+ cpuDescHeapManager.release(backBufferRTV[i], D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
}
HRESULT hr = swapChain->ResizeBuffers(SWAP_CHAIN_BUFFER_COUNT, window->width(), window->height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0);
@@ -923,14 +983,14 @@ ID3D12Resource *QSGD3D12EnginePrivate::createBuffer(int size)
return buf;
}
-ID3D12Resource *QSGD3D12EnginePrivate::backBufferRT() const
+ID3D12Resource *QSGD3D12EnginePrivate::currentBackBufferRT() const
{
- return renderTargets[presentFrameIndex % SWAP_CHAIN_BUFFER_COUNT].Get();
+ return backBufferRT[presentFrameIndex % SWAP_CHAIN_BUFFER_COUNT].Get();
}
-D3D12_CPU_DESCRIPTOR_HANDLE QSGD3D12EnginePrivate::backBufferRTV() const
+D3D12_CPU_DESCRIPTOR_HANDLE QSGD3D12EnginePrivate::currentBackBufferRTV() const
{
- D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtv[0];
+ D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = backBufferRTV[0];
rtvHandle.ptr += (presentFrameIndex % SWAP_CHAIN_BUFFER_COUNT) * cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
return rtvHandle;
}
@@ -1125,7 +1185,7 @@ void QSGD3D12EnginePrivate::beginFrame()
if (!pfd.pendingTextureReleases.isEmpty()) {
for (uint id : qAsConst(pfd.pendingTextureReleases)) {
Texture &t(textures[id - 1]);
- t.entryInUse = false; // createTexture() can now reuse this entry
+ t.flags &= ~RenderTarget::EntryInUse; // createTexture() can now reuse this entry
t.texture = nullptr;
}
pfd.pendingTextureReleases.clear();
@@ -1151,7 +1211,7 @@ void QSGD3D12EnginePrivate::beginDrawCalls(bool needsBackbufferTransition)
tframeData.descHeapSet = false;
if (needsBackbufferTransition)
- transitionResource(backBufferRT(), commandList.Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
+ transitionResource(currentBackBufferRT(), commandList.Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
}
void QSGD3D12EnginePrivate::endFrame()
@@ -1189,7 +1249,7 @@ void QSGD3D12EnginePrivate::endDrawCalls(bool needsBackbufferTransition)
t.lastWaitFenceValue = t.fenceValue;
if (t.fenceValue > topFenceValue)
topFenceValue = t.fenceValue;
- if (t.mipmap)
+ if (t.mipmap())
pfd.pendingTextureMipMap.insert(id);
}
if (topFenceValue) {
@@ -1208,7 +1268,7 @@ void QSGD3D12EnginePrivate::endDrawCalls(bool needsBackbufferTransition)
// Transition the backbuffer for present, if needed.
if (needsBackbufferTransition)
- transitionResource(backBufferRT(), commandList.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
+ transitionResource(currentBackBufferRT(), commandList.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT);
// Go!
HRESULT hr = commandList->Close();
@@ -1497,16 +1557,31 @@ void QSGD3D12EnginePrivate::queueScissor(const QRect &rect)
commandList->RSSetScissorRects(1, &scissorRect);
}
-void QSGD3D12EnginePrivate::queueSetRenderTarget()
+void QSGD3D12EnginePrivate::queueSetRenderTarget(uint id)
{
if (!inFrame) {
qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
return;
}
- D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = backBufferRTV();
- D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsv;
+ D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle;
+ D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle;
+
+ if (!id) {
+ rtvHandle = currentBackBufferRTV();
+ dsvHandle = backBufferDSV;
+ } else {
+ const int idx = id - 1;
+ Q_ASSERT(idx < renderTargets.count());
+ RenderTarget &rt(renderTargets[idx]);
+ rtvHandle = rt.rtv;
+ dsvHandle = rt.dsv;
+ rt.flags |= RenderTarget::NeedsReadBarrier;
+ }
+
commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, &dsvHandle);
+
+ currentRenderTarget = id;
}
void QSGD3D12EnginePrivate::queueClearRenderTarget(const QColor &color)
@@ -1517,7 +1592,7 @@ void QSGD3D12EnginePrivate::queueClearRenderTarget(const QColor &color)
}
const float clearColor[] = { float(color.redF()), float(color.blueF()), float(color.greenF()), float(color.alphaF()) };
- commandList->ClearRenderTargetView(backBufferRTV(), clearColor, 0, nullptr);
+ commandList->ClearRenderTargetView(currentBackBufferRTV(), clearColor, 0, nullptr);
}
void QSGD3D12EnginePrivate::queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which)
@@ -1527,7 +1602,7 @@ void QSGD3D12EnginePrivate::queueClearDepthStencil(float depthValue, quint8 sten
return;
}
- commandList->ClearDepthStencilView(dsv, D3D12_CLEAR_FLAGS(int(which)), depthValue, stencilValue, 0, nullptr);
+ commandList->ClearDepthStencilView(backBufferDSV, D3D12_CLEAR_FLAGS(int(which)), depthValue, stencilValue, 0, nullptr);
}
void QSGD3D12EnginePrivate::queueSetBlendFactor(const QVector4D &factor)
@@ -1640,9 +1715,12 @@ void QSGD3D12EnginePrivate::queueDraw(QSGGeometry::DrawingMode mode, int count,
const uint stride = cpuDescHeapManager.handleSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
D3D12_CPU_DESCRIPTOR_HANDLE dst = pfd.gpuCbvSrvUavHeap->GetCPUDescriptorHandleForHeapStart();
dst.ptr += pfd.cbvSrvUavNextFreeDescriptorIndex * stride;
- for (uint id : qAsConst(tframeData.activeTextures)) {
- const int idx = id - 1;
- device->CopyDescriptorsSimple(1, dst, textures[idx].srv, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+ for (const TransientFrameData::ActiveTexture &t : qAsConst(tframeData.activeTextures)) {
+ Q_ASSERT(t.id);
+ const int idx = t.id - 1;
+ const bool isTex = t.type == TransientFrameData::ActiveTexture::TypeTexture;
+ device->CopyDescriptorsSimple(1, dst, isTex ? textures[idx].srv : renderTargets[idx].srv,
+ D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
dst.ptr += stride;
}
@@ -1669,7 +1747,7 @@ void QSGD3D12EnginePrivate::queueDraw(QSGGeometry::DrawingMode mode, int count,
// start a new one
beginDrawCalls();
// prepare for the upcoming drawcalls
- queueSetRenderTarget();
+ queueSetRenderTarget(currentRenderTarget);
queueViewport(tframeData.viewport);
queueScissor(tframeData.scissor);
queueSetBlendFactor(tframeData.blendFactor);
@@ -1725,28 +1803,41 @@ void QSGD3D12EnginePrivate::waitGPU()
waitForGPU(presentFence);
}
-uint QSGD3D12EnginePrivate::genTexture()
+template<class T> uint newId(T *tbl)
{
uint id = 0;
- for (int i = 0; i < textures.count(); ++i) {
- if (!textures[i].entryInUse) {
+ for (int i = 0; i < tbl->count(); ++i) {
+ if (!(*tbl)[i].entryInUse()) {
id = i + 1;
break;
}
}
if (!id) {
- textures.resize(textures.size() + 1);
- id = textures.count();
+ tbl->resize(tbl->size() + 1);
+ id = tbl->count();
}
- Texture &t(textures[id - 1]);
- t.entryInUse = true;
- t.fenceValue = 0;
+ (*tbl)[id - 1].flags = 0x01; // reset flags and set EntryInUse
return id;
}
+template<class T> void syncEntryFlags(T *e, int flag, bool b)
+{
+ if (b)
+ e->flags |= flag;
+ else
+ e->flags &= ~flag;
+}
+
+uint QSGD3D12EnginePrivate::genTexture()
+{
+ const uint id = newId(&textures);
+ textures[id - 1].fenceValue = 0;
+ return id;
+}
+
static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha, bool mipmap,
QImage::Format *imageFormat, int *bytesPerPixel)
{
@@ -1792,17 +1883,17 @@ static inline DXGI_FORMAT textureFormat(QImage::Format format, bool wantsAlpha,
}
void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Format format,
- QSGD3D12Engine::TextureCreateFlags flags)
+ QSGD3D12Engine::TextureCreateFlags createFlags)
{
Q_ASSERT(id);
const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse);
+ Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
Texture &t(textures[idx]);
- t.alpha = flags & QSGD3D12Engine::CreateWithAlpha;
- t.mipmap = flags & QSGD3D12Engine::CreateWithMipMaps;
+ syncEntryFlags(&t, Texture::Alpha, createFlags & QSGD3D12Engine::CreateWithAlpha);
+ syncEntryFlags(&t, Texture::MipMap, createFlags & QSGD3D12Engine::CreateWithMipMaps);
- const QSize adjustedSize = !t.mipmap ? size : QSGD3D12Engine::mipMapAdjustedSourceSize(size);
+ const QSize adjustedSize = !t.mipmap() ? size : QSGD3D12Engine::mipMapAdjustedSourceSize(size);
D3D12_HEAP_PROPERTIES defaultHeapProp = {};
defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
@@ -1812,11 +1903,11 @@ void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Fo
textureDesc.Width = adjustedSize.width();
textureDesc.Height = adjustedSize.height();
textureDesc.DepthOrArraySize = 1;
- textureDesc.MipLevels = !t.mipmap ? 1 : QSGD3D12Engine::mipMapLevels(adjustedSize);
- textureDesc.Format = textureFormat(format, t.alpha, t.mipmap, nullptr, nullptr);
+ textureDesc.MipLevels = !t.mipmap() ? 1 : QSGD3D12Engine::mipMapLevels(adjustedSize);
+ textureDesc.Format = textureFormat(format, t.alpha(), t.mipmap(), nullptr, nullptr);
textureDesc.SampleDesc.Count = 1;
textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
- if (t.mipmap)
+ if (t.mipmap())
textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
@@ -1836,7 +1927,7 @@ void QSGD3D12EnginePrivate::createTexture(uint id, const QSize &size, QImage::Fo
device->CreateShaderResourceView(t.texture.Get(), &srvDesc, t.srv);
- if (t.mipmap) {
+ if (t.mipmap()) {
// Mipmap generation will need an UAV for each level that needs to be generated.
t.mipUAVs.clear();
for (int level = 1; level < textureDesc.MipLevels; ++level) {
@@ -1858,7 +1949,7 @@ void QSGD3D12EnginePrivate::queueTextureResize(uint id, const QSize &size)
{
Q_ASSERT(id);
const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse);
+ Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
Texture &t(textures[idx]);
if (!t.texture) {
@@ -1866,7 +1957,7 @@ void QSGD3D12EnginePrivate::queueTextureResize(uint id, const QSize &size)
return;
}
- if (t.mipmap) {
+ if (t.mipmap()) {
qWarning("Cannot resize mipmapped texture %u", id);
return;
}
@@ -1935,20 +2026,20 @@ void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector<QImage> &i
return;
const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse);
+ Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
Texture &t(textures[idx]);
Q_ASSERT(t.texture);
// When mipmapping is not in use, image can be smaller than the size passed
// to createTexture() and dstPos can specify a non-zero destination position.
- if (t.mipmap && (images.count() != 1 || dstPos.count() != 1 || !dstPos[0].isNull())) {
+ if (t.mipmap() && (images.count() != 1 || dstPos.count() != 1 || !dstPos[0].isNull())) {
qWarning("Mipmapped textures (%u) do not support partial uploads", id);
return;
}
// Make life simpler by disallowing queuing a new mipmapped upload before the previous one finishes.
- if (t.mipmap && t.fenceValue) {
+ if (t.mipmap() && t.fenceValue) {
qWarning("Attempted to queue mipmapped texture upload (%u) while a previous upload is still in progress", id);
return;
}
@@ -1964,9 +2055,9 @@ void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector<QImage> &i
int totalSize = 0;
for (const QImage &image : images) {
int bytesPerPixel;
- textureFormat(image.format(), t.alpha, t.mipmap, nullptr, &bytesPerPixel);
- const int w = !t.mipmap ? image.width() : adjustedTextureSize.width();
- const int h = !t.mipmap ? image.height() : adjustedTextureSize.height();
+ textureFormat(image.format(), t.alpha(), t.mipmap(), nullptr, &bytesPerPixel);
+ const int w = !t.mipmap() ? image.width() : adjustedTextureSize.width();
+ const int h = !t.mipmap() ? image.height() : adjustedTextureSize.height();
const int stride = alignedSize(w * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
totalSize += alignedSize(h * stride, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT);
}
@@ -1996,13 +2087,13 @@ void QSGD3D12EnginePrivate::queueTextureUpload(uint id, const QVector<QImage> &i
for (int i = 0; i < images.count(); ++i) {
QImage::Format convFormat;
int bytesPerPixel;
- textureFormat(images[i].format(), t.alpha, t.mipmap, &convFormat, &bytesPerPixel);
+ textureFormat(images[i].format(), t.alpha(), t.mipmap(), &convFormat, &bytesPerPixel);
if (Q_UNLIKELY(debug_render() && i == 0))
qDebug("source image format %d, target format %d, bpp %d", images[i].format(), convFormat, bytesPerPixel);
QImage convImage = images[i].format() == convFormat ? images[i] : images[i].convertToFormat(convFormat);
- if (t.mipmap && adjustedTextureSize != convImage.size())
+ if (t.mipmap() && adjustedTextureSize != convImage.size())
convImage = convImage.scaled(adjustedTextureSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
const int stride = alignedSize(convImage.width() * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
@@ -2076,7 +2167,7 @@ void QSGD3D12EnginePrivate::releaseTexture(uint id)
qDebug("releasing texture %d", id);
Texture &t(textures[idx]);
- if (!t.entryInUse)
+ if (!t.entryInUse())
return;
if (t.texture) {
@@ -2097,7 +2188,7 @@ SIZE_T QSGD3D12EnginePrivate::textureSRV(uint id) const
{
Q_ASSERT(id);
const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse);
+ Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
return textures[idx].srv.ptr;
}
@@ -2110,10 +2201,10 @@ void QSGD3D12EnginePrivate::activateTexture(uint id)
Q_ASSERT(id);
const int idx = id - 1;
- Q_ASSERT(idx < textures.count() && textures[idx].entryInUse);
+ Q_ASSERT(idx < textures.count() && textures[idx].entryInUse());
// activeTextures is a vector because the order matters
- tframeData.activeTextures.append(id);
+ tframeData.activeTextures.append(TransientFrameData::ActiveTexture(TransientFrameData::ActiveTexture::TypeTexture, id));
if (textures[idx].fenceValue)
pframeData[currentPFrameIndex].pendingTextureUploads.insert(id);
@@ -2295,4 +2386,121 @@ void QSGD3D12EnginePrivate::deferredDelete(D3D12_CPU_DESCRIPTOR_HANDLE h)
(*dq) << e;
}
+uint QSGD3D12EnginePrivate::genRenderTarget()
+{
+ return newId(&renderTargets);
+}
+
+void QSGD3D12EnginePrivate::createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples)
+{
+ Q_ASSERT(id);
+ const int idx = id - 1;
+ Q_ASSERT(idx < renderTargets.count() && renderTargets[idx].entryInUse());
+ RenderTarget &rt(renderTargets[idx]);
+
+ ID3D12Resource *res = createColorBuffer(rt.rtv, size, clearColor, samples);
+ if (res)
+ rt.color.Attach(res);
+
+ ID3D12Resource *dsres = createDepthStencil(rt.dsv, size, samples);
+ if (dsres)
+ rt.ds.Attach(dsres);
+
+ rt.rtv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+ rt.dsv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
+ rt.srv = cpuDescHeapManager.allocate(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
+
+ device->CreateRenderTargetView(rt.color.Get(), nullptr, rt.rtv);
+ device->CreateDepthStencilView(rt.ds.Get(), nullptr, rt.dsv);
+
+ const bool multisample = rt.color->GetDesc().SampleDesc.Count > 1;
+ syncEntryFlags(&rt, RenderTarget::Multisample, multisample);
+
+ if (!multisample) {
+ device->CreateShaderResourceView(rt.color.Get(), nullptr, rt.srv);
+ } else {
+ D3D12_HEAP_PROPERTIES defaultHeapProp = {};
+ defaultHeapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
+
+ D3D12_RESOURCE_DESC textureDesc = {};
+ textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ textureDesc.Width = size.width();
+ textureDesc.Height = size.height();
+ textureDesc.DepthOrArraySize = 1;
+ textureDesc.MipLevels = 1;
+ textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ textureDesc.SampleDesc.Count = 1;
+ textureDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+
+ HRESULT hr = device->CreateCommittedResource(&defaultHeapProp, D3D12_HEAP_FLAG_NONE, &textureDesc,
+ D3D12_RESOURCE_STATE_COMMON, nullptr, IID_PPV_ARGS(&rt.colorResolve));
+ if (FAILED(hr)) {
+ qWarning("Failed to create resolve buffer: 0x%x", hr);
+ return;
+ }
+
+ device->CreateShaderResourceView(rt.colorResolve.Get(), nullptr, rt.srv);
+ }
+
+}
+
+void QSGD3D12EnginePrivate::releaseRenderTarget(uint id)
+{
+ if (!id)
+ return;
+
+ const int idx = id - 1;
+ Q_ASSERT(idx < renderTargets.count());
+ RenderTarget &rt(renderTargets[idx]);
+ if (!rt.entryInUse())
+ return;
+
+ if (rt.colorResolve) {
+ deferredDelete(rt.colorResolve);
+ rt.colorResolve = nullptr;
+ }
+ if (rt.color) {
+ deferredDelete(rt.color);
+ rt.color = nullptr;
+ deferredDelete(rt.rtv);
+ deferredDelete(rt.srv);
+ }
+ if (rt.ds) {
+ deferredDelete(rt.ds);
+ rt.ds = nullptr;
+ deferredDelete(rt.dsv);
+ }
+
+ rt.flags &= ~RenderTarget::EntryInUse;
+}
+
+void QSGD3D12EnginePrivate::activateRenderTargetAsTexture(uint id)
+{
+ if (!inFrame) {
+ qWarning("%s: Cannot be called outside begin/endFrame", __FUNCTION__);
+ return;
+ }
+
+ Q_ASSERT(id);
+ const int idx = id - 1;
+ Q_ASSERT(idx < renderTargets.count());
+ RenderTarget &rt(renderTargets[idx]);
+ Q_ASSERT(rt.entryInUse() && rt.color);
+
+ if (rt.flags & RenderTarget::NeedsReadBarrier) {
+ if (rt.flags & RenderTarget::Multisample) {
+ transitionResource(rt.color.Get(), commandList.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
+ transitionResource(rt.colorResolve.Get(), commandList.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RESOLVE_DEST);
+ commandList->ResolveSubresource(rt.colorResolve.Get(), 0, rt.color.Get(), 0, DXGI_FORMAT_R8G8B8A8_UNORM);
+ transitionResource(rt.colorResolve.Get(), commandList.Get(), D3D12_RESOURCE_STATE_RESOLVE_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+ transitionResource(rt.color.Get(), commandList.Get(), D3D12_RESOURCE_STATE_RESOLVE_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
+ } else {
+ transitionResource(rt.color.Get(), commandList.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+ }
+ rt.flags &= ~RenderTarget::NeedsReadBarrier;
+ }
+
+ tframeData.activeTextures.append(TransientFrameData::ActiveTexture::ActiveTexture(TransientFrameData::ActiveTexture::TypeRenderTarget, id));
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h
index 7236053cf4..8ef1281554 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p.h
@@ -288,7 +288,7 @@ public:
void queueViewport(const QRect &rect);
void queueScissor(const QRect &rect);
- void queueSetRenderTarget();
+ void queueSetRenderTarget(uint id = 0);
void queueClearRenderTarget(const QColor &color);
void queueClearDepthStencil(float depthValue, quint8 stencilValue, ClearFlags which);
void queueSetBlendFactor(const QVector4D &factor);
@@ -324,6 +324,11 @@ public:
SIZE_T textureSRV(uint id) const;
void activateTexture(uint id);
+ uint genRenderTarget();
+ void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples);
+ void releaseRenderTarget(uint id);
+ void activateRenderTargetAsTexture(uint id);
+
private:
QSGD3D12EnginePrivate *d;
Q_DISABLE_COPY(QSGD3D12Engine)
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h
index 573dbded8e..1003f2dc30 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12engine_p_p.h
@@ -148,7 +148,7 @@ public:
void queueViewport(const QRect &rect);
void queueScissor(const QRect &rect);
- void queueSetRenderTarget();
+ void queueSetRenderTarget(uint id);
void queueClearRenderTarget(const QColor &color);
void queueClearDepthStencil(float depthValue, quint8 stencilValue, QSGD3D12Engine::ClearFlags which);
void queueSetBlendFactor(const QVector4D &factor);
@@ -172,6 +172,11 @@ public:
SIZE_T textureSRV(uint id) const;
void activateTexture(uint id);
+ uint genRenderTarget();
+ void createRenderTarget(uint id, const QSize &size, const QVector4D &clearColor, int samples);
+ void releaseRenderTarget(uint id);
+ void activateRenderTargetAsTexture(uint id);
+
// the device is intentionally hidden here. all resources have to go
// through the engine and, unlike with GL, cannot just be created in random
// places due to the need for proper tracking, managing and releasing.
@@ -184,6 +189,8 @@ private:
void ensureGPUDescriptorHeap(int cbvSrvUavDescriptorCount);
DXGI_SAMPLE_DESC makeSampleDesc(DXGI_FORMAT format, int samples);
+ ID3D12Resource *createColorBuffer(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size,
+ const QVector4D &clearColor, int samples);
ID3D12Resource *createDepthStencil(D3D12_CPU_DESCRIPTOR_HANDLE viewHandle, const QSize &size, int samples);
QSGD3D12CPUWaitableFence *createCPUWaitableFence() const;
@@ -196,8 +203,8 @@ private:
ID3D12Resource *createBuffer(int size);
- ID3D12Resource *backBufferRT() const;
- D3D12_CPU_DESCRIPTOR_HANDLE backBufferRTV() const;
+ ID3D12Resource *currentBackBufferRT() const;
+ D3D12_CPU_DESCRIPTOR_HANDLE currentBackBufferRTV() const;
struct CPUBufferRef {
const quint8 *p = nullptr;
@@ -253,9 +260,9 @@ private:
ComPtr<ID3D12CommandQueue> commandQueue;
ComPtr<ID3D12CommandQueue> copyCommandQueue;
ComPtr<IDXGISwapChain3> swapChain;
- ComPtr<ID3D12Resource> renderTargets[SWAP_CHAIN_BUFFER_COUNT];
- D3D12_CPU_DESCRIPTOR_HANDLE rtv[SWAP_CHAIN_BUFFER_COUNT];
- D3D12_CPU_DESCRIPTOR_HANDLE dsv;
+ ComPtr<ID3D12Resource> backBufferRT[SWAP_CHAIN_BUFFER_COUNT];
+ D3D12_CPU_DESCRIPTOR_HANDLE backBufferRTV[SWAP_CHAIN_BUFFER_COUNT];
+ D3D12_CPU_DESCRIPTOR_HANDLE backBufferDSV;
ComPtr<ID3D12Resource> depthStencil;
ComPtr<ID3D12CommandAllocator> commandAllocator[MAX_FRAMES_IN_FLIGHT];
ComPtr<ID3D12CommandAllocator> copyCommandAllocator;
@@ -284,7 +291,15 @@ private:
QCache<QSGD3D12RootSignature, RootSigCacheEntry> rootSigCache;
struct Texture {
- bool entryInUse = false;
+ enum Flag {
+ EntryInUse = 0x01,
+ Alpha = 0x02,
+ MipMap = 0x04
+ };
+ int flags = 0;
+ bool entryInUse() const { return flags & EntryInUse; }
+ bool alpha() const { return flags & Alpha; }
+ bool mipmap() const { return flags & MipMap; }
ComPtr<ID3D12Resource> texture;
D3D12_CPU_DESCRIPTOR_HANDLE srv;
quint64 fenceValue = 0;
@@ -298,8 +313,6 @@ private:
};
QVector<StagingBuffer> stagingBuffers;
QVector<D3D12_CPU_DESCRIPTOR_HANDLE> mipUAVs;
- bool alpha = true;
- bool mipmap = false;
};
QVector<Texture> textures;
@@ -309,7 +322,17 @@ private:
struct TransientFrameData {
QSGGeometry::DrawingMode drawingMode;
bool indexBufferSet;
- QVector<uint> activeTextures;
+ struct ActiveTexture {
+ enum Type {
+ TypeTexture,
+ TypeRenderTarget
+ };
+ Type type = TypeTexture;
+ uint id = 0;
+ ActiveTexture(Type type, uint id) : type(type), id(id) { }
+ ActiveTexture() { }
+ };
+ QVector<ActiveTexture> activeTextures;
int drawCount;
ID3D12PipelineState *lastPso;
ID3D12RootSignature *lastRootSig;
@@ -334,6 +357,25 @@ private:
};
MipMapGen mipmapper;
+
+ struct RenderTarget {
+ enum Flag {
+ EntryInUse = 0x01,
+ NeedsReadBarrier = 0x02,
+ Multisample = 0x04
+ };
+ int flags = 0;
+ bool entryInUse() const { return flags & EntryInUse; }
+ ComPtr<ID3D12Resource> color;
+ ComPtr<ID3D12Resource> colorResolve;
+ D3D12_CPU_DESCRIPTOR_HANDLE rtv;
+ ComPtr<ID3D12Resource> ds;
+ D3D12_CPU_DESCRIPTOR_HANDLE dsv;
+ D3D12_CPU_DESCRIPTOR_HANDLE srv;
+ };
+
+ QVector<RenderTarget> renderTargets;
+ uint currentRenderTarget;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp
new file mode 100644
index 0000000000..6c137a718e
--- /dev/null
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgd3d12layer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QSGD3D12Layer::QSGD3D12Layer(QSGD3D12RenderContext *rc)
+ : m_rc(rc)
+{
+}
+
+QSGD3D12Layer::~QSGD3D12Layer()
+{
+ cleanup();
+}
+
+int QSGD3D12Layer::textureId() const
+{
+ return 0;
+}
+
+QSize QSGD3D12Layer::textureSize() const
+{
+ return QSize();
+}
+
+bool QSGD3D12Layer::hasAlphaChannel() const
+{
+ return true;
+}
+
+bool QSGD3D12Layer::hasMipmaps() const
+{
+ // ###
+ return false;
+}
+
+QRectF QSGD3D12Layer::normalizedTextureSubRect() const
+{
+ return QRectF(0, 0, 1, 1); // ### mirror h/v
+}
+
+void QSGD3D12Layer::bind()
+{
+
+}
+
+bool QSGD3D12Layer::updateTexture()
+{
+ return false;
+}
+
+void QSGD3D12Layer::setItem(QSGNode *item)
+{
+
+}
+
+void QSGD3D12Layer::setRect(const QRectF &rect)
+{
+
+}
+
+void QSGD3D12Layer::setSize(const QSize &size)
+{
+
+}
+
+void QSGD3D12Layer::scheduleUpdate()
+{
+
+}
+
+QImage QSGD3D12Layer::toImage() const
+{
+ // ### figure out something for item grab support
+ return QImage();
+}
+
+void QSGD3D12Layer::setLive(bool live)
+{
+
+}
+
+void QSGD3D12Layer::setRecursive(bool recursive)
+{
+
+}
+
+void QSGD3D12Layer::setFormat(GLenum format)
+{
+
+}
+
+void QSGD3D12Layer::setHasMipmaps(bool mipmap)
+{
+
+}
+
+void QSGD3D12Layer::setDevicePixelRatio(qreal ratio)
+{
+
+}
+
+void QSGD3D12Layer::setMirrorHorizontal(bool mirror)
+{
+
+}
+
+void QSGD3D12Layer::setMirrorVertical(bool mirror)
+{
+
+}
+
+void QSGD3D12Layer::markDirtyTexture()
+{
+
+}
+
+void QSGD3D12Layer::invalidated()
+{
+ cleanup();
+}
+
+void QSGD3D12Layer::cleanup()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h
new file mode 100644
index 0000000000..cfd15ae761
--- /dev/null
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12layer_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGD3D12LAYER_P_H
+#define QSGD3D12LAYER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qsgadaptationlayer_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGD3D12RenderContext;
+
+class QSGD3D12Layer : public QSGLayer
+{
+public:
+ QSGD3D12Layer(QSGD3D12RenderContext *rc);
+ ~QSGD3D12Layer();
+
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+ QRectF normalizedTextureSubRect() const override;
+ void bind() override;
+
+ bool updateTexture() override;
+
+ void setItem(QSGNode *item) override;
+ void setRect(const QRectF &rect) override;
+ void setSize(const QSize &size) override;
+ void scheduleUpdate() override;
+ QImage toImage() const override;
+ void setLive(bool live) override;
+ void setRecursive(bool recursive) override;
+ void setFormat(GLenum format) override;
+ void setHasMipmaps(bool mipmap) override;
+ void setDevicePixelRatio(qreal ratio) override;
+ void setMirrorHorizontal(bool mirror) override;
+ void setMirrorVertical(bool mirror) override;
+ void markDirtyTexture() override;
+ void invalidated() override;
+
+private:
+ void cleanup();
+
+ QSGD3D12RenderContext *m_rc;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGD3D12LAYER_P_H
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp
index c1164b5add..0250023fdf 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture.cpp
@@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
void QSGD3D12Texture::setImage(const QImage &image, uint flags)
{
- // ### atlas
+ // ### atlas?
const bool alphaRequest = flags & QSGRenderContext::CreateTexture_Alpha;
m_alphaWanted = alphaRequest && image.hasAlphaChannel();
@@ -93,16 +93,6 @@ QRectF QSGD3D12Texture::normalizedTextureSubRect() const
return QRectF(0, 0, 1, 1);
}
-bool QSGD3D12Texture::isAtlasTexture() const
-{
- return false; // ###
-}
-
-QSGTexture *QSGD3D12Texture::removedFromAtlas() const
-{
- return nullptr; // ###
-}
-
void QSGD3D12Texture::bind()
{
// Called when the texture material updates the pipeline state.
diff --git a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h
index 35f65420fa..510bb65139 100644
--- a/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h
+++ b/src/quick/scenegraph/adaptations/d3d12/qsgd3d12texture_p.h
@@ -70,8 +70,6 @@ public:
bool hasAlphaChannel() const override;
bool hasMipmaps() const override;
QRectF normalizedTextureSubRect() const override;
- bool isAtlasTexture() const override;
- QSGTexture *removedFromAtlas() const override;
void bind() override;
SIZE_T srv() const;