1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 01:24:11 +01:00

[d3d11] Add D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC

This commit is contained in:
Philip Rebohle 2024-11-02 10:22:30 +01:00 committed by Philip Rebohle
parent 1d2d05dde0
commit da406133f1
3 changed files with 71 additions and 28 deletions

View File

@ -465,6 +465,10 @@ namespace dxvk {
if (!WaitForResource(*mappedImage, sequenceNumber, MapType, MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
}
} else if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC) {
// Nothing else to really do here, NotifyMap will ensure that we
// actually get a staging buffer that isn't currently in use.
ThrottleDiscard(layout.Size);
} else {
Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
@ -565,8 +569,8 @@ namespace dxvk {
}
}
// Mark the given subresource as mapped
pResource->SetMapType(Subresource, MapType);
// Mark the subresource as successfully mapped
pResource->NotifyMap(Subresource, MapType);
if (pMappedResource) {
pMappedResource->pData = pResource->GetMapPtr(Subresource, layout.Offset);
@ -582,28 +586,35 @@ namespace dxvk {
void D3D11ImmediateContext::UnmapImage(
D3D11CommonTexture* pResource,
UINT Subresource) {
D3D11_MAP mapType = pResource->GetMapType(Subresource);
pResource->SetMapType(Subresource, D3D11_MAP(~0u));
auto mapType = pResource->GetMapType(Subresource);
auto mapMode = pResource->GetMapMode();
if (mapType == D3D11_MAP(~0u))
if (mapType == D3D11CommonTexture::UnmappedSubresource)
return;
// Decrement mapped image counter only after making sure
// the given subresource is actually mapped right now
m_mappedImageCount -= 1;
if ((mapType != D3D11_MAP_READ) && (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)) {
// If the texture has an image as well as a staging buffer,
// upload the written buffer data to the image
bool needsUpload = mapType != D3D11_MAP_READ
&& (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER || mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC);
if (needsUpload) {
if (pResource->NeedsDirtyRegionTracking()) {
for (uint32_t i = 0; i < pResource->GetDirtyRegionCount(Subresource); i++) {
D3D11_COMMON_TEXTURE_REGION region = pResource->GetDirtyRegion(Subresource, i);
UpdateDirtyImageRegion(pResource, Subresource, &region);
}
pResource->ClearDirtyRegions(Subresource);
} else {
UpdateDirtyImageRegion(pResource, Subresource, nullptr);
}
}
// Unmap the subresource. This will implicitly destroy the
// staging buffer for dynamically mapped images.
pResource->NotifyUnmap(Subresource);
}

View File

@ -200,11 +200,14 @@ namespace dxvk {
}
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER
|| m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_STAGING) {
|| m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_STAGING
|| m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC) {
m_buffers.resize(subresourceCount);
for (uint32_t i = 0; i < subresourceCount; i++)
CreateMappedBuffer(i);
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC) {
for (uint32_t i = 0; i < subresourceCount; i++)
CreateMappedBuffer(i);
}
}
// Skip image creation if possible
@ -778,6 +781,14 @@ namespace dxvk {
entry.buffer = m_device->GetDXVKDevice()->createBuffer(info, memType);
entry.slice = entry.buffer->storage();
}
void D3D11CommonTexture::FreeMappedBuffer(
UINT Subresource) {
auto& entry = m_buffers[Subresource];
entry.buffer = nullptr;
entry.slice = nullptr;
}
VkImageType D3D11CommonTexture::GetImageTypeFromResourceDim(D3D11_RESOURCE_DIMENSION Dimension) {

View File

@ -26,6 +26,7 @@ namespace dxvk {
enum D3D11_COMMON_TEXTURE_MAP_MODE {
D3D11_COMMON_TEXTURE_MAP_MODE_NONE, ///< Not mapped
D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER, ///< Mapped through buffer
D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC, ///< Mapped through temporary buffer
D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT, ///< Directly mapped to host mem
D3D11_COMMON_TEXTURE_MAP_MODE_STAGING, ///< Buffer only, no image
};
@ -83,7 +84,9 @@ namespace dxvk {
class D3D11CommonTexture {
public:
static constexpr D3D11_MAP UnmappedSubresource = D3D11_MAP(-1u);
D3D11CommonTexture(
ID3D11Resource* pInterface,
D3D11Device* pDevice,
@ -205,15 +208,40 @@ namespace dxvk {
/**
* \brief Sets map type for a given subresource
*
*
* Also ensures taht a staging buffer is created
* in case of dynamic mapping.
* \param [in] Subresource The subresource
* \param [in] MapType The map type
*/
void SetMapType(UINT Subresource, D3D11_MAP MapType) {
if (Subresource < m_mapInfo.size())
void NotifyMap(UINT Subresource, D3D11_MAP MapType) {
if (likely(Subresource < m_mapInfo.size())) {
m_mapInfo[Subresource].mapType = MapType;
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC)
CreateMappedBuffer(Subresource);
}
}
/**
* \brief Resets map info for a given subresource
*
* For dynamic mapping, this will also free the
* staging buffer.
* \param [in] Subresource The subresource
*/
void NotifyUnmap(UINT Subresource) {
if (likely(Subresource < m_mapInfo.size())) {
m_mapInfo[Subresource].mapType = UnmappedSubresource;
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC)
FreeMappedBuffer(Subresource);
if (Subresource < m_buffers.size())
m_buffers[Subresource].dirtyRegions.clear();
}
}
/**
* \brief The DXVK image
* \returns The DXVK image
@ -359,6 +387,7 @@ namespace dxvk {
return reinterpret_cast<char*>(m_mapPtr) + Offset;
case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER:
case D3D11_COMMON_TEXTURE_MAP_MODE_DYNAMIC:
case D3D11_COMMON_TEXTURE_MAP_MODE_STAGING:
return reinterpret_cast<char*>(m_buffers[Subresource].slice->mapPtr()) + Offset;
@ -386,17 +415,6 @@ namespace dxvk {
m_buffers[Subresource].dirtyRegions.push_back(region);
}
/**
* \brief Clears dirty regions
*
* Removes all dirty regions from the given subresource.
* \param [in] Subresource Subresource index
*/
void ClearDirtyRegions(UINT Subresource) {
if (Subresource < m_buffers.size())
m_buffers[Subresource].dirtyRegions.clear();
}
/**
* \brief Counts dirty regions
*
@ -553,7 +571,7 @@ namespace dxvk {
struct MappedInfo {
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = { };
D3D11_MAP mapType = D3D11_MAP(~0u);
D3D11_MAP mapType = UnmappedSubresource;
uint64_t seq = 0u;
};
@ -575,6 +593,9 @@ namespace dxvk {
void CreateMappedBuffer(
UINT Subresource);
void FreeMappedBuffer(
UINT Subresource);
BOOL CheckImageSupport(
const DxvkImageCreateInfo* pImageInfo,
VkImageTiling Tiling) const;