mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-08 01:54:15 +01:00
[d3d11] Add GetMapPtr method to D3D11CommonTexture
Fixes a bug in Read/WriteSubresource where discards result in the wrong pointer being passed to the app.
This commit is contained in:
parent
81bdf191cb
commit
1832332d6d
@ -417,9 +417,6 @@ namespace dxvk {
|
|||||||
D3D11_MAP MapType,
|
D3D11_MAP MapType,
|
||||||
UINT MapFlags,
|
UINT MapFlags,
|
||||||
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||||
const Rc<DxvkImage> mappedImage = pResource->GetImage();
|
|
||||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
|
|
||||||
|
|
||||||
auto mapMode = pResource->GetMapMode();
|
auto mapMode = pResource->GetMapMode();
|
||||||
|
|
||||||
if (pMappedResource)
|
if (pMappedResource)
|
||||||
@ -449,9 +446,10 @@ namespace dxvk {
|
|||||||
uint64_t sequenceNumber = pResource->GetSequenceNumber(Subresource);
|
uint64_t sequenceNumber = pResource->GetSequenceNumber(Subresource);
|
||||||
|
|
||||||
auto formatInfo = lookupFormatInfo(packedFormat);
|
auto formatInfo = lookupFormatInfo(packedFormat);
|
||||||
void* mapPtr;
|
|
||||||
|
|
||||||
if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
|
if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
|
||||||
|
Rc<DxvkImage> mappedImage = pResource->GetImage();
|
||||||
|
|
||||||
// Wait for the resource to become available. We do not
|
// Wait for the resource to become available. We do not
|
||||||
// support image renaming, so stall on DISCARD instead.
|
// support image renaming, so stall on DISCARD instead.
|
||||||
if (MapType == D3D11_MAP_WRITE_DISCARD)
|
if (MapType == D3D11_MAP_WRITE_DISCARD)
|
||||||
@ -461,11 +459,9 @@ namespace dxvk {
|
|||||||
if (!WaitForResource(*mappedImage, sequenceNumber, MapType, MapFlags))
|
if (!WaitForResource(*mappedImage, sequenceNumber, MapType, MapFlags))
|
||||||
return DXGI_ERROR_WAS_STILL_DRAWING;
|
return DXGI_ERROR_WAS_STILL_DRAWING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query the subresource's memory layout and hope that
|
|
||||||
// the application respects the returned pitch values.
|
|
||||||
mapPtr = mappedImage->mapPtr(0);
|
|
||||||
} else {
|
} else {
|
||||||
|
Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
|
||||||
|
|
||||||
constexpr uint32_t DoInvalidate = (1u << 0);
|
constexpr uint32_t DoInvalidate = (1u << 0);
|
||||||
constexpr uint32_t DoPreserve = (1u << 1);
|
constexpr uint32_t DoPreserve = (1u << 1);
|
||||||
constexpr uint32_t DoWait = (1u << 2);
|
constexpr uint32_t DoWait = (1u << 2);
|
||||||
@ -536,17 +532,17 @@ namespace dxvk {
|
|||||||
auto dstSlice = pResource->DiscardSlice(Subresource);
|
auto dstSlice = pResource->DiscardSlice(Subresource);
|
||||||
|
|
||||||
auto srcPtr = srcSlice->mapPtr();
|
auto srcPtr = srcSlice->mapPtr();
|
||||||
mapPtr = dstSlice->mapPtr();
|
auto dstPtr = dstSlice->mapPtr();
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cImageBuffer = mappedBuffer,
|
cImageBuffer = std::move(mappedBuffer),
|
||||||
cImageBufferSlice = std::move(dstSlice)
|
cImageBufferSlice = std::move(dstSlice)
|
||||||
] (DxvkContext* ctx) mutable {
|
] (DxvkContext* ctx) mutable {
|
||||||
ctx->invalidateBuffer(cImageBuffer, std::move(cImageBufferSlice));
|
ctx->invalidateBuffer(cImageBuffer, std::move(cImageBufferSlice));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (doFlags & DoPreserve)
|
if (doFlags & DoPreserve)
|
||||||
std::memcpy(mapPtr, srcPtr, bufferSize);
|
std::memcpy(dstPtr, srcPtr, bufferSize);
|
||||||
|
|
||||||
ThrottleDiscard(bufferSize);
|
ThrottleDiscard(bufferSize);
|
||||||
} else {
|
} else {
|
||||||
@ -560,8 +556,6 @@ namespace dxvk {
|
|||||||
if (!WaitForResource(*mappedBuffer, sequenceNumber, MapType, MapFlags))
|
if (!WaitForResource(*mappedBuffer, sequenceNumber, MapType, MapFlags))
|
||||||
return DXGI_ERROR_WAS_STILL_DRAWING;
|
return DXGI_ERROR_WAS_STILL_DRAWING;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapPtr = pResource->GetMappedSlice(Subresource)->mapPtr();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +564,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (pMappedResource) {
|
if (pMappedResource) {
|
||||||
auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
|
auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
|
||||||
pMappedResource->pData = reinterpret_cast<char*>(mapPtr) + layout.Offset;
|
pMappedResource->pData = pResource->GetMapPtr(Subresource, layout.Offset);
|
||||||
pMappedResource->RowPitch = layout.RowPitch;
|
pMappedResource->RowPitch = layout.RowPitch;
|
||||||
pMappedResource->DepthPitch = layout.DepthPitch;
|
pMappedResource->DepthPitch = layout.DepthPitch;
|
||||||
}
|
}
|
||||||
|
@ -2435,11 +2435,7 @@ namespace dxvk {
|
|||||||
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = pTexture->GetSubresourceLayout(aspect, Subresource);
|
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = pTexture->GetSubresourceLayout(aspect, Subresource);
|
||||||
|
|
||||||
// Compute actual map pointer, accounting for the region offset
|
// Compute actual map pointer, accounting for the region offset
|
||||||
VkDeviceSize mapOffset = pTexture->ComputeMappedOffset(Subresource, i, offset);
|
void* mapPtr = pTexture->GetMapPtr(Subresource, pTexture->ComputeMappedOffset(Subresource, i, offset));
|
||||||
|
|
||||||
void* mapPtr = pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER
|
|
||||||
? pTexture->GetMappedBuffer(Subresource)->mapPtr(mapOffset)
|
|
||||||
: image->mapPtr(mapOffset);
|
|
||||||
|
|
||||||
if constexpr (std::is_const<Void>::value) {
|
if constexpr (std::is_const<Void>::value) {
|
||||||
// WriteToSubresource
|
// WriteToSubresource
|
||||||
|
@ -244,6 +244,9 @@ namespace dxvk {
|
|||||||
else
|
else
|
||||||
m_image = m_device->GetDXVKDevice()->importImage(imageInfo, vkImage, memoryProperties);
|
m_image = m_device->GetDXVKDevice()->importImage(imageInfo, vkImage, memoryProperties);
|
||||||
|
|
||||||
|
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
|
||||||
|
m_mapPtr = m_image->mapPtr(0);
|
||||||
|
|
||||||
if (imageInfo.sharing.mode == DxvkSharedHandleMode::Export)
|
if (imageInfo.sharing.mode == DxvkSharedHandleMode::Export)
|
||||||
ExportImageInfo();
|
ExportImageInfo();
|
||||||
}
|
}
|
||||||
|
@ -303,6 +303,31 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Queries map pointer of the raw image
|
||||||
|
*
|
||||||
|
* If the image is mapped directly, the returned pointer will
|
||||||
|
* point directly to the image, otherwise it will point to a
|
||||||
|
* buffer that contains image data.
|
||||||
|
* \param [in] Subresource Subresource index
|
||||||
|
* \param [in] Offset Offset derived from the subresource layout
|
||||||
|
*/
|
||||||
|
void* GetMapPtr(uint32_t Subresource, size_t Offset) const {
|
||||||
|
switch (m_mapMode) {
|
||||||
|
case D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT:
|
||||||
|
return reinterpret_cast<char*>(m_mapPtr) + Offset;
|
||||||
|
|
||||||
|
case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER:
|
||||||
|
case D3D11_COMMON_TEXTURE_MAP_MODE_STAGING:
|
||||||
|
return reinterpret_cast<char*>(m_buffers[Subresource].slice->mapPtr()) + Offset;
|
||||||
|
|
||||||
|
case D3D11_COMMON_TEXTURE_MAP_MODE_NONE:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Adds a dirty region
|
* \brief Adds a dirty region
|
||||||
*
|
*
|
||||||
@ -504,6 +529,8 @@ namespace dxvk {
|
|||||||
std::vector<MappedBuffer> m_buffers;
|
std::vector<MappedBuffer> m_buffers;
|
||||||
std::vector<MappedInfo> m_mapInfo;
|
std::vector<MappedInfo> m_mapInfo;
|
||||||
|
|
||||||
|
void* m_mapPtr = nullptr;
|
||||||
|
|
||||||
MappedBuffer CreateMappedBuffer(
|
MappedBuffer CreateMappedBuffer(
|
||||||
UINT MipLevel) const;
|
UINT MipLevel) const;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user