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)
|
2018-11-20 10:44:04 +01:00
|
|
|
: D3D11DeviceContext(pParent, Device, GetCsChunkFlags(pParent)),
|
2018-01-23 12:03:26 +01:00
|
|
|
m_contextFlags(ContextFlags),
|
|
|
|
m_commandList (CreateCommandList()) {
|
2018-03-03 20:59:17 +01:00
|
|
|
ClearState();
|
2018-01-23 09:23:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE D3D11DeferredContext::GetType() {
|
|
|
|
return D3D11_DEVICE_CONTEXT_DEFERRED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UINT STDMETHODCALLTYPE D3D11DeferredContext::GetContextFlags() {
|
|
|
|
return m_contextFlags;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
2018-03-12 23:36:55 +01:00
|
|
|
FlushCsChunk();
|
|
|
|
|
2018-03-03 20:59:17 +01:00
|
|
|
static_cast<D3D11CommandList*>(pCommandList)->EmitToCommandList(m_commandList.ptr());
|
|
|
|
|
|
|
|
if (RestoreContextState)
|
|
|
|
RestoreState();
|
|
|
|
else
|
|
|
|
ClearState();
|
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();
|
|
|
|
|
2019-11-02 13:06:44 +01:00
|
|
|
FinalizeQueries();
|
2018-03-12 23:36:55 +01:00
|
|
|
FlushCsChunk();
|
|
|
|
|
2018-03-03 22:28:30 +01:00
|
|
|
if (ppCommandList != nullptr)
|
|
|
|
*ppCommandList = m_commandList.ref();
|
2018-03-03 20:59:17 +01:00
|
|
|
m_commandList = CreateCommandList();
|
|
|
|
|
2018-03-10 14:41:06 +01:00
|
|
|
if (RestoreDeferredContextState)
|
2018-03-03 22:28:30 +01:00
|
|
|
RestoreState();
|
2018-03-10 14:41:06 +01:00
|
|
|
else
|
|
|
|
ClearState();
|
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;
|
|
|
|
|
2018-03-25 13:24:03 +02:00
|
|
|
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
2022-02-10 14:23:53 +01:00
|
|
|
D3D11_RESOURCE_DIMENSION resourceDim;
|
|
|
|
pResource->GetType(&resourceDim);
|
|
|
|
|
|
|
|
D3D11_MAPPED_SUBRESOURCE mapInfo;
|
2018-03-25 13:24:03 +02:00
|
|
|
HRESULT status = resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER
|
2022-02-10 14:23:53 +01:00
|
|
|
? MapBuffer(pResource, &mapInfo)
|
|
|
|
: MapImage (pResource, Subresource, &mapInfo);
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2019-06-03 15:30:04 +02:00
|
|
|
if (unlikely(FAILED(status))) {
|
|
|
|
*pMappedResource = D3D11_MAPPED_SUBRESOURCE();
|
2018-03-25 13:24:03 +02:00
|
|
|
return status;
|
2019-06-03 15:30:04 +02:00
|
|
|
}
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2022-02-10 14:23:53 +01:00
|
|
|
AddMapEntry(pResource, Subresource, resourceDim, mapInfo);
|
|
|
|
*pMappedResource = mapInfo;
|
2018-03-25 13:24:03 +02:00
|
|
|
return S_OK;
|
|
|
|
} else if (MapType == D3D11_MAP_WRITE_NO_OVERWRITE) {
|
|
|
|
// 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)) {
|
2019-06-03 15:30:04 +02:00
|
|
|
*pMappedResource = D3D11_MAPPED_SUBRESOURCE();
|
2018-03-25 13:24:03 +02:00
|
|
|
return 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
|
2019-06-03 15:30:04 +02:00
|
|
|
*pMappedResource = D3D11_MAPPED_SUBRESOURCE();
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-02-06 18:20:31 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource(
|
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
const D3D11_BOX* pDstBox,
|
|
|
|
const void* pSrcData,
|
|
|
|
UINT SrcRowPitch,
|
|
|
|
UINT SrcDepthPitch) {
|
|
|
|
UpdateResource<D3D11DeferredContext>(this, pDstResource,
|
|
|
|
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource1(
|
|
|
|
ID3D11Resource* pDstResource,
|
|
|
|
UINT DstSubresource,
|
|
|
|
const D3D11_BOX* pDstBox,
|
|
|
|
const void* pSrcData,
|
|
|
|
UINT SrcRowPitch,
|
|
|
|
UINT SrcDepthPitch,
|
|
|
|
UINT CopyFlags) {
|
|
|
|
UpdateResource<D3D11DeferredContext>(this, pDstResource,
|
|
|
|
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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);
|
2018-03-19 03:19:13 +01: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");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
|
2022-02-10 14:23:53 +01:00
|
|
|
pMappedResource->RowPitch = pBuffer->Desc()->ByteWidth;
|
|
|
|
pMappedResource->DepthPitch = pBuffer->Desc()->ByteWidth;
|
2018-05-22 00:11:32 +02:00
|
|
|
|
2020-04-18 17:12:20 +02:00
|
|
|
if (likely(m_csFlags.test(DxvkCsChunkFlag::SingleUse))) {
|
2018-05-22 00:11:32 +02:00
|
|
|
// For resources that cannot be written by the GPU,
|
|
|
|
// we may write to the buffer resource directly and
|
2019-01-09 17:56:53 +01:00
|
|
|
// just swap in the buffer slice as needed.
|
2019-10-30 00:44:17 +01:00
|
|
|
auto bufferSlice = pBuffer->AllocSlice();
|
2022-02-10 14:23:53 +01:00
|
|
|
pMappedResource->pData = bufferSlice.mapPtr;
|
2019-08-10 11:11:44 +02:00
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cDstBuffer = pBuffer->GetBuffer(),
|
2019-10-30 00:44:17 +01:00
|
|
|
cPhysSlice = bufferSlice
|
2019-08-10 11:11:44 +02:00
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
ctx->invalidateBuffer(cDstBuffer, cPhysSlice);
|
|
|
|
});
|
2018-05-22 00:11:32 +02:00
|
|
|
} else {
|
|
|
|
// For GPU-writable resources, we need a data slice
|
|
|
|
// to perform the update operation at execution time.
|
2019-10-30 00:44:17 +01:00
|
|
|
auto dataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth);
|
2022-02-10 14:23:53 +01:00
|
|
|
pMappedResource->pData = dataSlice.ptr();
|
2019-08-10 11:11:44 +02:00
|
|
|
|
|
|
|
EmitCs([
|
|
|
|
cDstBuffer = pBuffer->GetBuffer(),
|
2019-10-30 00:44:17 +01:00
|
|
|
cDataSlice = dataSlice
|
2019-08-10 11:11:44 +02:00
|
|
|
] (DxvkContext* ctx) {
|
|
|
|
DxvkBufferSliceHandle slice = cDstBuffer->allocSlice();
|
|
|
|
std::memcpy(slice.mapPtr, cDataSlice.ptr(), cDataSlice.length());
|
|
|
|
ctx->invalidateBuffer(cDstBuffer, slice);
|
|
|
|
});
|
2018-05-22 00:11:32 +02:00
|
|
|
}
|
|
|
|
|
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");
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
2019-05-20 19:26:15 +02:00
|
|
|
|
|
|
|
if (unlikely(Subresource >= pTexture->CountSubresources()))
|
|
|
|
return E_INVALIDARG;
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2021-06-24 03:27:42 +02:00
|
|
|
VkFormat packedFormat = pTexture->GetPackedFormat();
|
2018-04-21 20:34:41 +02:00
|
|
|
|
2022-07-15 17:23:54 +02:00
|
|
|
auto formatInfo = lookupFormatInfo(packedFormat);
|
2019-03-26 18:04:25 +01:00
|
|
|
auto subresource = pTexture->GetSubresourceFromIndex(
|
2018-04-21 20:34:41 +02:00
|
|
|
formatInfo->aspectMask, Subresource);
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2021-06-24 03:27:42 +02:00
|
|
|
VkExtent3D levelExtent = pTexture->MipLevelExtent(subresource.mipLevel);
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2021-05-27 20:24:36 +02:00
|
|
|
auto layout = pTexture->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
|
|
|
|
auto dataSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, levelExtent));
|
2018-03-25 13:24:03 +02:00
|
|
|
|
2022-02-10 14:23:53 +01:00
|
|
|
pMappedResource->RowPitch = layout.RowPitch;
|
|
|
|
pMappedResource->DepthPitch = layout.DepthPitch;
|
|
|
|
pMappedResource->pData = dataSlice.mapPtr(0);
|
2019-08-10 11:11:44 +02:00
|
|
|
|
2021-06-24 03:27:42 +02:00
|
|
|
UpdateImage(pTexture, &subresource,
|
|
|
|
VkOffset3D { 0, 0, 0 }, levelExtent,
|
|
|
|
std::move(dataSlice));
|
2019-08-10 11:11:44 +02:00
|
|
|
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() {
|
2019-10-27 11:00:59 +01:00
|
|
|
return new D3D11CommandList(m_parent, m_contextFlags);
|
2018-01-23 12:03:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-05-19 13:21:08 +02:00
|
|
|
void D3D11DeferredContext::EmitCsChunk(DxvkCsChunkRef&& chunk) {
|
2018-06-04 23:31:49 +02:00
|
|
|
m_commandList->AddChunk(std::move(chunk));
|
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(),
|
|
|
|
Subresource);
|
2022-02-09 02:54:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void D3D11DeferredContext::TrackBufferSequenceNumber(
|
|
|
|
D3D11Buffer* pResource) {
|
2022-02-09 04:36:50 +01:00
|
|
|
m_commandList->TrackResourceUsage(
|
|
|
|
pResource, D3D11_RESOURCE_DIMENSION_BUFFER, 0);
|
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
|
|
|
}
|