2018-01-23 09:23:31 +01:00
|
|
|
#include "d3d11_context_def.h"
|
2018-10-09 16:29:50 +02:00
|
|
|
#include "d3d11_device.h"
|
2018-01-23 09:23:31 +01:00
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
D3D11DeferredContext::D3D11DeferredContext(
|
2018-04-28 14:17:52 +02:00
|
|
|
D3D11Device* pParent,
|
|
|
|
const Rc<DxvkDevice>& Device,
|
|
|
|
UINT ContextFlags)
|
2022-08-03 22:19:16 +02:00
|
|
|
: D3D11CommonContext<D3D11DeferredContext>(pParent, Device, ContextFlags, GetCsChunkFlags(pParent)),
|
2018-01-23 12:03:26 +01:00
|
|
|
m_commandList (CreateCommandList()) {
|
2022-08-04 14:21:27 +02:00
|
|
|
ResetContextState();
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-06-08 12:29:24 +02:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DeferredContext::GetData(
|
|
|
|
ID3D11Asynchronous* pAsync,
|
|
|
|
void* pData,
|
|
|
|
UINT DataSize,
|
|
|
|
UINT GetDataFlags) {
|
2019-12-04 20:15:28 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11: GetData called on a deferred context");
|
|
|
|
|
2018-06-08 12:29:24 +02:00
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-11-02 13:06:44 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::Begin(
|
|
|
|
ID3D11Asynchronous* pAsync) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (unlikely(!pAsync))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Com<D3D11Query, false> query(static_cast<D3D11Query*>(pAsync));
|
|
|
|
|
|
|
|
if (unlikely(!query->IsScoped()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
auto entry = std::find(
|
|
|
|
m_queriesBegun.begin(),
|
|
|
|
m_queriesBegun.end(), query);
|
|
|
|
|
|
|
|
if (unlikely(entry != m_queriesBegun.end()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
EmitCs([cQuery = query]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
cQuery->Begin(ctx);
|
|
|
|
});
|
|
|
|
|
|
|
|
m_queriesBegun.push_back(std::move(query));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::End(
|
|
|
|
ID3D11Asynchronous* pAsync) {
|
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
|
|
|
if (unlikely(!pAsync))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Com<D3D11Query, false> query(static_cast<D3D11Query*>(pAsync));
|
|
|
|
|
|
|
|
if (query->IsScoped()) {
|
|
|
|
auto entry = std::find(
|
|
|
|
m_queriesBegun.begin(),
|
|
|
|
m_queriesBegun.end(), query);
|
|
|
|
|
2020-01-22 04:17:13 +01:00
|
|
|
if (likely(entry != m_queriesBegun.end())) {
|
|
|
|
m_queriesBegun.erase(entry);
|
|
|
|
} else {
|
|
|
|
EmitCs([cQuery = query]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
cQuery->Begin(ctx);
|
|
|
|
});
|
|
|
|
}
|
2019-11-02 13:06:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
m_commandList->AddQuery(query.ptr());
|
|
|
|
|
|
|
|
EmitCs([cQuery = std::move(query)]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
cQuery->End(ctx);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-23 09:23:31 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::Flush() {
|
2019-12-04 20:15:28 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11: Flush called on a deferred context");
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
2019-09-16 13:12:13 +02:00
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::Flush1(
|
|
|
|
D3D11_CONTEXT_TYPE ContextType,
|
|
|
|
HANDLE hEvent) {
|
2019-12-04 20:15:28 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11: Flush1 called on a deferred context");
|
2019-09-16 13:12:13 +02:00
|
|
|
}
|
2018-01-23 09:23:31 +01:00
|
|
|
|
|
|
|
|
2019-09-16 13:17:00 +02:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DeferredContext::Signal(
|
|
|
|
ID3D11Fence* pFence,
|
|
|
|
UINT64 Value) {
|
2019-12-04 20:15:28 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11: Signal called on a deferred context");
|
|
|
|
|
2019-09-16 13:17:00 +02:00
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DeferredContext::Wait(
|
|
|
|
ID3D11Fence* pFence,
|
|
|
|
UINT64 Value) {
|
2019-12-04 20:15:28 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11: Wait called on a deferred context");
|
|
|
|
|
2019-09-16 13:17:00 +02:00
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-23 09:23:31 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::ExecuteCommandList(
|
|
|
|
ID3D11CommandList* pCommandList,
|
2018-03-06 20:34:34 +03:00
|
|
|
BOOL RestoreContextState) {
|
2018-11-29 20:59:40 +01:00
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
2022-08-04 14:21:27 +02:00
|
|
|
// Clear state so that the command list can't observe any
|
|
|
|
// current context state. The command list itself will clean
|
|
|
|
// up after execution to ensure that no state changes done
|
|
|
|
// by the command list are visible to the immediate context.
|
|
|
|
ResetCommandListState();
|
|
|
|
|
|
|
|
// Flush any outstanding commands so that
|
|
|
|
// we don't mess up the execution order
|
2018-03-12 23:36:55 +01:00
|
|
|
FlushCsChunk();
|
|
|
|
|
2022-08-04 14:21:27 +02:00
|
|
|
// Record any chunks from the given command list into the
|
|
|
|
// current command list and deal with context state
|
|
|
|
auto commandList = static_cast<D3D11CommandList*>(pCommandList);
|
2023-01-17 12:33:19 +01:00
|
|
|
m_chunkId = m_commandList->AddCommandList(commandList);
|
2018-03-03 20:59:17 +01:00
|
|
|
|
2023-01-17 12:33:19 +01:00
|
|
|
// Restore deferred context state
|
2018-03-03 20:59:17 +01:00
|
|
|
if (RestoreContextState)
|
2022-08-04 14:07:48 +02:00
|
|
|
RestoreCommandListState();
|
2018-03-03 20:59:17 +01:00
|
|
|
else
|
2022-08-04 14:21:27 +02:00
|
|
|
ResetContextState();
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DeferredContext::FinishCommandList(
|
2018-03-06 20:34:34 +03:00
|
|
|
BOOL RestoreDeferredContextState,
|
2018-01-23 09:23:31 +01:00
|
|
|
ID3D11CommandList **ppCommandList) {
|
2018-11-29 20:59:40 +01:00
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
2022-08-04 14:21:27 +02:00
|
|
|
// End all queries that were left active by the app
|
2019-11-02 13:06:44 +01:00
|
|
|
FinalizeQueries();
|
2022-08-04 14:21:27 +02:00
|
|
|
|
|
|
|
// Clean up command list state so that the any state changed
|
2023-01-17 12:33:19 +01:00
|
|
|
// by this command list does not affect the calling context.
|
|
|
|
// This also ensures that the command list is never empty.
|
2022-08-04 14:21:27 +02:00
|
|
|
ResetCommandListState();
|
|
|
|
|
|
|
|
// Make sure all commands are visible to the command list
|
2018-03-12 23:36:55 +01:00
|
|
|
FlushCsChunk();
|
|
|
|
|
2022-08-04 14:21:27 +02:00
|
|
|
if (ppCommandList)
|
2018-03-03 22:28:30 +01:00
|
|
|
*ppCommandList = m_commandList.ref();
|
2022-08-04 14:21:27 +02:00
|
|
|
|
|
|
|
// Create a clean command list, and if requested, restore all
|
|
|
|
// previously set context state. Otherwise, reset the context.
|
|
|
|
// Any use of ExecuteCommandList will reset command list state
|
|
|
|
// before the command list is actually executed.
|
2018-03-03 20:59:17 +01:00
|
|
|
m_commandList = CreateCommandList();
|
2023-01-17 12:33:19 +01:00
|
|
|
m_chunkId = 0;
|
2018-03-03 20:59:17 +01:00
|
|
|
|
2018-03-10 14:41:06 +01:00
|
|
|
if (RestoreDeferredContextState)
|
2022-08-04 14:07:48 +02:00
|
|
|
RestoreCommandListState();
|
2018-03-10 14:41:06 +01:00
|
|
|
else
|
2022-08-04 14:21:27 +02:00
|
|
|
ResetContextState();
|
2018-03-03 20:59:17 +01:00
|
|
|
|
2018-03-19 03:19:13 +01:00
|
|
|
m_mappedResources.clear();
|
2022-02-06 18:19:37 +01:00
|
|
|
ResetStagingBuffer();
|
2018-03-03 20:59:17 +01:00
|
|
|
return S_OK;
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DeferredContext::Map(
|
|
|
|
ID3D11Resource* pResource,
|
|
|
|
UINT Subresource,
|
|
|
|
D3D11_MAP MapType,
|
|
|
|
UINT MapFlags,
|
|
|
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
2018-11-29 20:59:40 +01:00
|
|
|
D3D10DeviceLock lock = LockContext();
|
|
|
|
|
2019-06-03 15:30:04 +02:00
|
|
|
if (unlikely(!pResource || !pMappedResource))
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2024-11-01 23:05:46 +01:00
|
|
|
if (likely(MapType == D3D11_MAP_WRITE_DISCARD)) {
|
2022-02-10 14:23:53 +01:00
|
|
|
D3D11_RESOURCE_DIMENSION resourceDim;
|
|
|
|
pResource->GetType(&resourceDim);
|
|
|
|
|
2024-11-01 23:05:46 +01:00
|
|
|
return likely(resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER)
|
|
|
|
? MapBuffer(pResource, pMappedResource)
|
|
|
|
: MapImage(pResource, Subresource, pMappedResource);
|
|
|
|
} else if (likely(MapType == D3D11_MAP_WRITE_NO_OVERWRITE)) {
|
2018-03-25 13:24:03 +02:00
|
|
|
// The resource must be mapped with D3D11_MAP_WRITE_DISCARD
|
|
|
|
// before it can be mapped with D3D11_MAP_WRITE_NO_OVERWRITE.
|
|
|
|
auto entry = FindMapEntry(pResource, Subresource);
|
|
|
|
|
2022-02-10 14:23:53 +01:00
|
|
|
if (unlikely(!entry)) {
|
2024-10-30 00:28:07 +01:00
|
|
|
pMappedResource->pData = nullptr;
|
2024-11-01 23:05:46 +01:00
|
|
|
|
|
|
|
// NO_OVERWRITE is only supported on buffers
|
|
|
|
D3D11_RESOURCE_DIMENSION resourceDim;
|
|
|
|
pResource->GetType(&resourceDim);
|
|
|
|
|
|
|
|
return resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER
|
|
|
|
? D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD
|
|
|
|
: E_INVALIDARG;
|
2019-06-03 15:30:04 +02:00
|
|
|
}
|
2018-03-25 13:24:03 +02:00
|
|
|
|
|
|
|
// Return same memory region as earlier
|
2022-02-10 14:23:53 +01:00
|
|
|
*pMappedResource = entry->MapInfo;
|
2018-03-25 13:24:03 +02:00
|
|
|
return S_OK;
|
2018-03-19 03:19:13 +01:00
|
|
|
} else {
|
2018-03-25 13:24:03 +02:00
|
|
|
// Not allowed on deferred contexts
|
2024-10-30 00:28:07 +01:00
|
|
|
pMappedResource->pData = nullptr;
|
2018-03-25 13:24:03 +02:00
|
|
|
return E_INVALIDARG;
|
2018-03-19 03:19:13 +01:00
|
|
|
}
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::Unmap(
|
|
|
|
ID3D11Resource* pResource,
|
|
|
|
UINT Subresource) {
|
2019-08-10 11:11:44 +02:00
|
|
|
// No-op, updates are committed in Map
|
2018-03-19 03:19:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-03 16:41:44 +02:00
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::SwapDeviceContextState(
|
|
|
|
ID3DDeviceContextState* pState,
|
|
|
|
ID3DDeviceContextState** ppPreviousState) {
|
2019-12-04 20:15:28 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11: SwapDeviceContextState called on a deferred context");
|
2019-05-03 16:41:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-19 03:19:13 +01:00
|
|
|
HRESULT D3D11DeferredContext::MapBuffer(
|
2018-03-25 13:24:03 +02:00
|
|
|
ID3D11Resource* pResource,
|
2022-02-10 14:23:53 +01:00
|
|
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
2018-05-22 00:11:32 +02:00
|
|
|
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
|
2024-09-26 14:54:35 +02:00
|
|
|
|
2019-02-04 10:25:49 +01:00
|
|
|
if (unlikely(pBuffer->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_NONE)) {
|
2018-03-19 03:19:13 +01:00
|
|
|
Logger::err("D3D11: Cannot map a device-local buffer");
|
2024-11-01 23:05:46 +01:00
|
|
|
pMappedResource->pData = nullptr;
|
2018-03-19 03:19:13 +01:00
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
2024-09-26 14:54:35 +02:00
|
|
|
|
|
|
|
auto bufferSlice = pBuffer->AllocSlice(&m_allocationCache);
|
2024-11-01 23:05:46 +01:00
|
|
|
pMappedResource->pData = bufferSlice->mapPtr();
|
2022-02-10 14:23:53 +01:00
|
|
|
pMappedResource->RowPitch = pBuffer->Desc()->ByteWidth;
|
|
|
|
pMappedResource->DepthPitch = pBuffer->Desc()->ByteWidth;
|
2024-09-26 14:54:35 +02:00
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cDstBuffer = pBuffer->GetBuffer(),
|
|
|
|
cDstSlice = std::move(bufferSlice)
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->invalidateBuffer(cDstBuffer, Rc<DxvkResourceAllocation>(cDstSlice));
|
|
|
|
});
|
|
|
|
|
2024-11-01 23:05:46 +01:00
|
|
|
AddMapEntry(pResource, 0, D3D11_RESOURCE_DIMENSION_BUFFER, *pMappedResource);
|
2018-03-25 13:24:03 +02:00
|
|
|
return S_OK;
|
2018-03-19 03:19:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT D3D11DeferredContext::MapImage(
|
2018-03-25 13:24:03 +02:00
|
|
|
ID3D11Resource* pResource,
|
|
|
|
UINT Subresource,
|
2022-02-10 14:23:53 +01:00
|
|
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
2021-06-24 03:27:42 +02:00
|
|
|
D3D11CommonTexture* pTexture = GetCommonTexture(pResource);
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2019-06-03 15:30:04 +02:00
|
|
|
if (unlikely(pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) {
|
2018-03-25 13:24:03 +02:00
|
|
|
Logger::err("D3D11: Cannot map a device-local image");
|
2024-11-01 23:05:46 +01:00
|
|
|
pMappedResource->pData = nullptr;
|
2018-03-25 13:24:03 +02:00
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
2019-05-20 19:26:15 +02:00
|
|
|
|
2024-11-01 23:05:46 +01:00
|
|
|
if (unlikely(Subresource >= pTexture->CountSubresources())) {
|
|
|
|
pMappedResource->pData = nullptr;
|
2019-05-20 19:26:15 +02:00
|
|
|
return E_INVALIDARG;
|
2024-11-01 23:05:46 +01:00
|
|
|
}
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2021-06-24 03:27:42 +02:00
|
|
|
VkFormat packedFormat = pTexture->GetPackedFormat();
|
2022-07-15 17:23:54 +02:00
|
|
|
auto formatInfo = lookupFormatInfo(packedFormat);
|
2021-05-27 20:24:36 +02:00
|
|
|
auto layout = pTexture->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
|
2019-08-10 11:11:44 +02:00
|
|
|
|
2024-10-31 21:15:52 +01:00
|
|
|
if (pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
|
|
|
|
auto storage = pTexture->AllocStorage();
|
|
|
|
auto mapPtr = storage->mapPtr();
|
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cImage = pTexture->GetImage(),
|
|
|
|
cStorage = std::move(storage)
|
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->invalidateImage(cImage, Rc<DxvkResourceAllocation>(cStorage));
|
|
|
|
ctx->initImage(cImage, cImage->getAvailableSubresources(), VK_IMAGE_LAYOUT_PREINITIALIZED);
|
|
|
|
});
|
|
|
|
|
|
|
|
pMappedResource->RowPitch = layout.RowPitch;
|
|
|
|
pMappedResource->DepthPitch = layout.DepthPitch;
|
|
|
|
pMappedResource->pData = mapPtr;
|
|
|
|
return S_OK;
|
|
|
|
} else {
|
|
|
|
auto dataSlice = AllocStagingBuffer(layout.Size);
|
|
|
|
|
|
|
|
pMappedResource->RowPitch = layout.RowPitch;
|
|
|
|
pMappedResource->DepthPitch = layout.DepthPitch;
|
|
|
|
pMappedResource->pData = dataSlice.mapPtr(0);
|
|
|
|
|
|
|
|
auto subresource = pTexture->GetSubresourceFromIndex(formatInfo->aspectMask, Subresource);
|
|
|
|
auto mipExtent = pTexture->MipLevelExtent(subresource.mipLevel);
|
|
|
|
|
|
|
|
UpdateImage(pTexture, &subresource,
|
|
|
|
VkOffset3D { 0, 0, 0 }, mipExtent,
|
|
|
|
std::move(dataSlice));
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-02-06 18:20:31 +01:00
|
|
|
void D3D11DeferredContext::UpdateMappedBuffer(
|
|
|
|
D3D11Buffer* pDstBuffer,
|
|
|
|
UINT Offset,
|
|
|
|
UINT Length,
|
|
|
|
const void* pSrcData,
|
|
|
|
UINT CopyFlags) {
|
|
|
|
void* mapPtr = nullptr;
|
|
|
|
|
|
|
|
if (unlikely(CopyFlags == D3D11_COPY_NO_OVERWRITE)) {
|
|
|
|
auto entry = FindMapEntry(pDstBuffer, 0);
|
|
|
|
|
2022-02-10 14:23:53 +01:00
|
|
|
if (entry)
|
|
|
|
mapPtr = entry->MapInfo.pData;
|
2022-02-06 18:20:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (likely(!mapPtr)) {
|
|
|
|
// The caller validates the map mode, so we can
|
|
|
|
// safely ignore the MapBuffer return value here
|
2022-02-10 14:23:53 +01:00
|
|
|
D3D11_MAPPED_SUBRESOURCE mapInfo;
|
|
|
|
MapBuffer(pDstBuffer, &mapInfo);
|
|
|
|
AddMapEntry(pDstBuffer, 0, D3D11_RESOURCE_DIMENSION_BUFFER, mapInfo);
|
|
|
|
mapPtr = mapInfo.pData;
|
2022-02-06 18:20:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::memcpy(reinterpret_cast<char*>(mapPtr) + Offset, pSrcData, Length);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-11-02 13:06:44 +01:00
|
|
|
void D3D11DeferredContext::FinalizeQueries() {
|
|
|
|
for (auto& query : m_queriesBegun) {
|
|
|
|
m_commandList->AddQuery(query.ptr());
|
|
|
|
|
|
|
|
EmitCs([cQuery = std::move(query)]
|
|
|
|
(DxvkContext* ctx) {
|
|
|
|
cQuery->End(ctx);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
m_queriesBegun.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-23 12:03:26 +01:00
|
|
|
Com<D3D11CommandList> D3D11DeferredContext::CreateCommandList() {
|
2022-08-03 22:19:16 +02:00
|
|
|
return new D3D11CommandList(m_parent, m_flags);
|
2018-01-23 12:03:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-19 13:21:08 +02:00
|
|
|
void D3D11DeferredContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
|
2023-01-17 12:33:19 +01:00
|
|
|
m_chunkId = m_commandList->AddChunk(std::move(chunk));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t D3D11DeferredContext::GetCurrentChunkId() const {
|
|
|
|
return m_csChunk->empty() ? m_chunkId : m_chunkId + 1;
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
|
|
|
|
2018-11-20 10:44:04 +01:00
|
|
|
|
2022-02-09 02:54:32 +01:00
|
|
|
void D3D11DeferredContext::TrackTextureSequenceNumber(
|
|
|
|
D3D11CommonTexture* pResource,
|
|
|
|
UINT Subresource) {
|
2022-02-09 04:36:50 +01:00
|
|
|
m_commandList->TrackResourceUsage(
|
|
|
|
pResource->GetInterface(),
|
|
|
|
pResource->GetDimension(),
|
2023-01-17 12:33:19 +01:00
|
|
|
Subresource, GetCurrentChunkId());
|
2022-02-09 02:54:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeferredContext::TrackBufferSequenceNumber(
|
|
|
|
D3D11Buffer* pResource) {
|
2023-01-17 12:33:19 +01:00
|
|
|
m_commandList->TrackResourceUsage(pResource,
|
|
|
|
D3D11_RESOURCE_DIMENSION_BUFFER, 0,
|
|
|
|
GetCurrentChunkId());
|
2022-02-09 02:54:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-02-10 14:23:53 +01:00
|
|
|
D3D11DeferredContextMapEntry* D3D11DeferredContext::FindMapEntry(
|
|
|
|
ID3D11Resource* pResource,
|
|
|
|
UINT Subresource) {
|
|
|
|
// Recently mapped resources as well as entries with
|
|
|
|
// up-to-date map infos will be located at the end
|
|
|
|
// of the resource array, so scan in reverse order.
|
|
|
|
size_t size = m_mappedResources.size();
|
|
|
|
|
|
|
|
for (size_t i = 1; i <= size; i++) {
|
|
|
|
auto entry = &m_mappedResources[size - i];
|
|
|
|
|
|
|
|
if (entry->Resource.Get() == pResource
|
|
|
|
&& entry->Resource.GetSubresource() == Subresource)
|
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void D3D11DeferredContext::AddMapEntry(
|
|
|
|
ID3D11Resource* pResource,
|
|
|
|
UINT Subresource,
|
|
|
|
D3D11_RESOURCE_DIMENSION ResourceType,
|
|
|
|
const D3D11_MAPPED_SUBRESOURCE& MapInfo) {
|
|
|
|
m_mappedResources.emplace_back(pResource,
|
|
|
|
Subresource, ResourceType, MapInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-11-20 10:44:04 +01:00
|
|
|
DxvkCsChunkFlags D3D11DeferredContext::GetCsChunkFlags(
|
|
|
|
D3D11Device* pDevice) {
|
2018-11-20 10:51:09 +01:00
|
|
|
return pDevice->GetOptions()->dcSingleUseMode
|
2018-11-20 10:44:04 +01:00
|
|
|
? DxvkCsChunkFlags(DxvkCsChunkFlag::SingleUse)
|
|
|
|
: DxvkCsChunkFlags();
|
|
|
|
}
|
|
|
|
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|