mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 22:24:15 +01:00
[d3d11] Implemented buffer mapping on deferred contexts
Allows the MultiThreadedRendering demo from the Microsoft SDK to run.
This commit is contained in:
parent
0eaa3fea3b
commit
f1c3b59e87
@ -48,10 +48,10 @@ namespace dxvk {
|
|||||||
void STDMETHODCALLTYPE GetDesc(
|
void STDMETHODCALLTYPE GetDesc(
|
||||||
D3D11_BUFFER_DESC *pDesc) final;
|
D3D11_BUFFER_DESC *pDesc) final;
|
||||||
|
|
||||||
/**
|
Rc<DxvkBuffer> GetBuffer() const {
|
||||||
* \brief Retrieves buffer slice
|
return m_buffer;
|
||||||
* \returns Buffer slice containing the entire buffer
|
}
|
||||||
*/
|
|
||||||
DxvkBufferSlice GetBufferSlice() const {
|
DxvkBufferSlice GetBufferSlice() const {
|
||||||
return DxvkBufferSlice(m_buffer, 0, m_buffer->info().size);
|
return DxvkBufferSlice(m_buffer, 0, m_buffer->info().size);
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ namespace dxvk {
|
|||||||
else
|
else
|
||||||
ClearState();
|
ClearState();
|
||||||
|
|
||||||
|
m_mappedResources.clear();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,15 +67,130 @@ namespace dxvk {
|
|||||||
D3D11_MAP MapType,
|
D3D11_MAP MapType,
|
||||||
UINT MapFlags,
|
UINT MapFlags,
|
||||||
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||||
Logger::err("D3D11DeferredContext::Map: Not implemented");
|
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
||||||
return E_NOTIMPL;
|
pResource->GetType(&resourceDim);
|
||||||
|
|
||||||
|
if (MapType != D3D11_MAP_WRITE_DISCARD
|
||||||
|
&& MapType != D3D11_MAP_WRITE_NO_OVERWRITE)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
|
return MapBuffer(
|
||||||
|
static_cast<D3D11Buffer*>(pResource),
|
||||||
|
MapType, MapFlags, pMappedResource);
|
||||||
|
} else {
|
||||||
|
return MapImage(
|
||||||
|
GetCommonTexture(pResource),
|
||||||
|
Subresource, MapType, MapFlags,
|
||||||
|
pMappedResource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void STDMETHODCALLTYPE D3D11DeferredContext::Unmap(
|
void STDMETHODCALLTYPE D3D11DeferredContext::Unmap(
|
||||||
ID3D11Resource* pResource,
|
ID3D11Resource* pResource,
|
||||||
UINT Subresource) {
|
UINT Subresource) {
|
||||||
Logger::err("D3D11DeferredContext::Unmap: Not implemented");
|
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
||||||
|
pResource->GetType(&resourceDim);
|
||||||
|
|
||||||
|
if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
|
||||||
|
UnmapBuffer(static_cast<D3D11Buffer*>(pResource));
|
||||||
|
} else {
|
||||||
|
UnmapImage(
|
||||||
|
GetCommonTexture(pResource),
|
||||||
|
Subresource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT D3D11DeferredContext::MapBuffer(
|
||||||
|
D3D11Buffer* pResource,
|
||||||
|
D3D11_MAP MapType,
|
||||||
|
UINT MapFlags,
|
||||||
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||||
|
Rc<DxvkBuffer> buffer = pResource->GetBuffer();
|
||||||
|
|
||||||
|
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
||||||
|
Logger::err("D3D11: Cannot map a device-local buffer");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pMappedResource == nullptr)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
auto entry = FindMapEntry(pResource, 0);
|
||||||
|
|
||||||
|
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
||||||
|
if (entry != m_mappedResources.end())
|
||||||
|
m_mappedResources.erase(entry);
|
||||||
|
|
||||||
|
D3D11DeferredContextMapEntry mapEntry;
|
||||||
|
mapEntry.pResource = pResource;
|
||||||
|
mapEntry.Subresource = 0;
|
||||||
|
mapEntry.MapType = D3D11_MAP_WRITE_DISCARD;
|
||||||
|
mapEntry.RowPitch = pResource->GetSize();
|
||||||
|
mapEntry.DepthPitch = pResource->GetSize();
|
||||||
|
mapEntry.DataSlice = AllocUpdateBufferSlice(pResource->GetSize());
|
||||||
|
m_mappedResources.push_back(mapEntry);
|
||||||
|
|
||||||
|
pMappedResource->pData = mapEntry.DataSlice.ptr();
|
||||||
|
pMappedResource->RowPitch = mapEntry.RowPitch;
|
||||||
|
pMappedResource->DepthPitch = mapEntry.DepthPitch;
|
||||||
|
return S_OK;
|
||||||
|
} else {
|
||||||
|
// The resource must be mapped with D3D11_MAP_WRITE_DISCARD
|
||||||
|
// before it can be mapped with D3D11_MAP_WRITE_NO_OVERWRITE.
|
||||||
|
if (entry == m_mappedResources.end())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
// Return same memory region as earlier
|
||||||
|
entry->MapType = D3D11_MAP_WRITE_NO_OVERWRITE;
|
||||||
|
|
||||||
|
pMappedResource->pData = entry->DataSlice.ptr();
|
||||||
|
pMappedResource->RowPitch = entry->RowPitch;
|
||||||
|
pMappedResource->DepthPitch = entry->DepthPitch;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT D3D11DeferredContext::MapImage(
|
||||||
|
D3D11CommonTexture* pResource,
|
||||||
|
UINT Subresource,
|
||||||
|
D3D11_MAP MapType,
|
||||||
|
UINT MapFlags,
|
||||||
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||||
|
Logger::err("D3D11DeferredContext::MapImage: Not implemented");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11DeferredContext::UnmapBuffer(
|
||||||
|
D3D11Buffer* pResource) {
|
||||||
|
auto entry = FindMapEntry(pResource, 0);
|
||||||
|
|
||||||
|
if (entry == m_mappedResources.end()) {
|
||||||
|
Logger::err("D3D11DeferredContext::Unmap: Buffer not mapped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->MapType == D3D11_MAP_WRITE_DISCARD) {
|
||||||
|
EmitCs([
|
||||||
|
cDstBuffer = pResource->GetBuffer(),
|
||||||
|
cDataSlice = entry->DataSlice
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
DxvkPhysicalBufferSlice slice = cDstBuffer->allocPhysicalSlice();
|
||||||
|
std::memcpy(slice.mapPtr(0), cDataSlice.ptr(), cDataSlice.length());
|
||||||
|
ctx->invalidateBuffer(cDstBuffer, slice);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3D11DeferredContext::UnmapImage(
|
||||||
|
D3D11CommonTexture* pResource,
|
||||||
|
UINT Subresource) {
|
||||||
|
Logger::err("D3D11DeferredContext::UnmapImage: Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "d3d11_buffer.h"
|
||||||
#include "d3d11_cmdlist.h"
|
#include "d3d11_cmdlist.h"
|
||||||
#include "d3d11_context.h"
|
#include "d3d11_context.h"
|
||||||
|
#include "d3d11_texture.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
struct D3D11DeferredContextMapEntry {
|
||||||
|
Com<ID3D11Resource> pResource;
|
||||||
|
UINT Subresource;
|
||||||
|
D3D11_MAP MapType;
|
||||||
|
UINT RowPitch;
|
||||||
|
UINT DepthPitch;
|
||||||
|
DxvkDataSlice DataSlice;
|
||||||
|
};
|
||||||
|
|
||||||
class D3D11DeferredContext : public D3D11DeviceContext {
|
class D3D11DeferredContext : public D3D11DeviceContext {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -43,12 +54,46 @@ namespace dxvk {
|
|||||||
|
|
||||||
const UINT m_contextFlags;
|
const UINT m_contextFlags;
|
||||||
|
|
||||||
|
// Command list that we're recording
|
||||||
Com<D3D11CommandList> m_commandList;
|
Com<D3D11CommandList> m_commandList;
|
||||||
|
|
||||||
|
// Info about currently mapped (sub)resources. Using a vector
|
||||||
|
// here is reasonable since there will usually only be a small
|
||||||
|
// number of mapped resources per command list.
|
||||||
|
std::vector<D3D11DeferredContextMapEntry> m_mappedResources;
|
||||||
|
|
||||||
|
HRESULT MapBuffer(
|
||||||
|
D3D11Buffer* pResource,
|
||||||
|
D3D11_MAP MapType,
|
||||||
|
UINT MapFlags,
|
||||||
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource);
|
||||||
|
|
||||||
|
HRESULT MapImage(
|
||||||
|
D3D11CommonTexture* pResource,
|
||||||
|
UINT Subresource,
|
||||||
|
D3D11_MAP MapType,
|
||||||
|
UINT MapFlags,
|
||||||
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource);
|
||||||
|
|
||||||
|
void UnmapBuffer(
|
||||||
|
D3D11Buffer* pResource);
|
||||||
|
|
||||||
|
void UnmapImage(
|
||||||
|
D3D11CommonTexture* pResource,
|
||||||
|
UINT Subresource);
|
||||||
|
|
||||||
Com<D3D11CommandList> CreateCommandList();
|
Com<D3D11CommandList> CreateCommandList();
|
||||||
|
|
||||||
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
|
void EmitCsChunk(Rc<DxvkCsChunk>&& chunk) final;
|
||||||
|
|
||||||
|
auto FindMapEntry(ID3D11Resource* pResource, UINT Subresource) {
|
||||||
|
return std::find_if(m_mappedResources.begin(), m_mappedResources.end(),
|
||||||
|
[pResource, Subresource] (const D3D11DeferredContextMapEntry& entry) {
|
||||||
|
return entry.pResource == pResource
|
||||||
|
&& entry.Subresource == Subresource;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -128,7 +128,7 @@ namespace dxvk {
|
|||||||
D3D11_MAP MapType,
|
D3D11_MAP MapType,
|
||||||
UINT MapFlags,
|
UINT MapFlags,
|
||||||
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||||
Rc<DxvkBuffer> buffer = pResource->GetBufferSlice().buffer();
|
Rc<DxvkBuffer> buffer = pResource->GetBuffer();
|
||||||
|
|
||||||
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
||||||
Logger::err("D3D11: Cannot map a device-local buffer");
|
Logger::err("D3D11: Cannot map a device-local buffer");
|
||||||
|
Loading…
Reference in New Issue
Block a user