mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 23:52:20 +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,
|
||||
UINT MapFlags,
|
||||
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||
const Rc<DxvkImage> mappedImage = pResource->GetImage();
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
|
||||
|
||||
auto mapMode = pResource->GetMapMode();
|
||||
|
||||
if (pMappedResource)
|
||||
@ -449,9 +446,10 @@ namespace dxvk {
|
||||
uint64_t sequenceNumber = pResource->GetSequenceNumber(Subresource);
|
||||
|
||||
auto formatInfo = lookupFormatInfo(packedFormat);
|
||||
void* mapPtr;
|
||||
|
||||
if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
|
||||
Rc<DxvkImage> mappedImage = pResource->GetImage();
|
||||
|
||||
// Wait for the resource to become available. We do not
|
||||
// support image renaming, so stall on DISCARD instead.
|
||||
if (MapType == D3D11_MAP_WRITE_DISCARD)
|
||||
@ -461,11 +459,9 @@ namespace dxvk {
|
||||
if (!WaitForResource(*mappedImage, sequenceNumber, MapType, MapFlags))
|
||||
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 {
|
||||
Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
|
||||
|
||||
constexpr uint32_t DoInvalidate = (1u << 0);
|
||||
constexpr uint32_t DoPreserve = (1u << 1);
|
||||
constexpr uint32_t DoWait = (1u << 2);
|
||||
@ -536,17 +532,17 @@ namespace dxvk {
|
||||
auto dstSlice = pResource->DiscardSlice(Subresource);
|
||||
|
||||
auto srcPtr = srcSlice->mapPtr();
|
||||
mapPtr = dstSlice->mapPtr();
|
||||
auto dstPtr = dstSlice->mapPtr();
|
||||
|
||||
EmitCs([
|
||||
cImageBuffer = mappedBuffer,
|
||||
cImageBuffer = std::move(mappedBuffer),
|
||||
cImageBufferSlice = std::move(dstSlice)
|
||||
] (DxvkContext* ctx) mutable {
|
||||
ctx->invalidateBuffer(cImageBuffer, std::move(cImageBufferSlice));
|
||||
});
|
||||
|
||||
if (doFlags & DoPreserve)
|
||||
std::memcpy(mapPtr, srcPtr, bufferSize);
|
||||
std::memcpy(dstPtr, srcPtr, bufferSize);
|
||||
|
||||
ThrottleDiscard(bufferSize);
|
||||
} else {
|
||||
@ -560,8 +556,6 @@ namespace dxvk {
|
||||
if (!WaitForResource(*mappedBuffer, sequenceNumber, MapType, MapFlags))
|
||||
return DXGI_ERROR_WAS_STILL_DRAWING;
|
||||
}
|
||||
|
||||
mapPtr = pResource->GetMappedSlice(Subresource)->mapPtr();
|
||||
}
|
||||
}
|
||||
|
||||
@ -570,7 +564,7 @@ namespace dxvk {
|
||||
|
||||
if (pMappedResource) {
|
||||
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->DepthPitch = layout.DepthPitch;
|
||||
}
|
||||
|
@ -2435,11 +2435,7 @@ namespace dxvk {
|
||||
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = pTexture->GetSubresourceLayout(aspect, Subresource);
|
||||
|
||||
// Compute actual map pointer, accounting for the region offset
|
||||
VkDeviceSize mapOffset = pTexture->ComputeMappedOffset(Subresource, i, offset);
|
||||
|
||||
void* mapPtr = pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER
|
||||
? pTexture->GetMappedBuffer(Subresource)->mapPtr(mapOffset)
|
||||
: image->mapPtr(mapOffset);
|
||||
void* mapPtr = pTexture->GetMapPtr(Subresource, pTexture->ComputeMappedOffset(Subresource, i, offset));
|
||||
|
||||
if constexpr (std::is_const<Void>::value) {
|
||||
// WriteToSubresource
|
||||
|
@ -244,6 +244,9 @@ namespace dxvk {
|
||||
else
|
||||
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)
|
||||
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
|
||||
*
|
||||
@ -503,7 +528,9 @@ namespace dxvk {
|
||||
Rc<DxvkImage> m_image;
|
||||
std::vector<MappedBuffer> m_buffers;
|
||||
std::vector<MappedInfo> m_mapInfo;
|
||||
|
||||
|
||||
void* m_mapPtr = nullptr;
|
||||
|
||||
MappedBuffer CreateMappedBuffer(
|
||||
UINT MipLevel) const;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user