mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-30 02:52:10 +01:00
[d3d9] Fix crash when auto generating mip maps for unmappable textures
This commit is contained in:
parent
3c38bdbd0e
commit
a8b578b2a2
@ -180,7 +180,11 @@ namespace dxvk {
|
||||
return memory.Ptr();
|
||||
}
|
||||
|
||||
void D3D9CommonTexture::CreateBufferSubresource(UINT Subresource) {
|
||||
void D3D9CommonTexture::CreateBufferSubresource(UINT Subresource, bool Initialize) {
|
||||
if (likely(m_buffers[Subresource] != nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DxvkBufferCreateInfo info;
|
||||
info.size = GetMipSize(Subresource);
|
||||
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
@ -201,6 +205,16 @@ namespace dxvk {
|
||||
|
||||
m_buffers[Subresource] = m_device->GetDXVKDevice()->createBuffer(info, memType);
|
||||
m_mappedSlices[Subresource] = m_buffers[Subresource]->getSliceHandle();
|
||||
|
||||
if (Initialize) {
|
||||
if (m_data[Subresource]) {
|
||||
m_data[Subresource].Map();
|
||||
memcpy(m_mappedSlices[Subresource].mapPtr, m_data[Subresource].Ptr(), info.size);
|
||||
} else {
|
||||
memset(m_mappedSlices[Subresource].mapPtr, 0, info.size);
|
||||
}
|
||||
}
|
||||
m_data[Subresource] = {};
|
||||
}
|
||||
|
||||
|
||||
@ -642,21 +656,7 @@ namespace dxvk {
|
||||
}
|
||||
}
|
||||
|
||||
const Rc<DxvkBuffer>& D3D9CommonTexture::GetBuffer(UINT Subresource, bool Initialize) {
|
||||
if (unlikely(m_buffers[Subresource] == nullptr)) {
|
||||
CreateBufferSubresource(Subresource);
|
||||
|
||||
if (Initialize) {
|
||||
if (m_data[Subresource]) {
|
||||
m_data[Subresource].Map();
|
||||
memcpy(m_mappedSlices[Subresource].mapPtr, m_data[Subresource].Ptr(), GetMipSize(Subresource));
|
||||
} else {
|
||||
memset(m_mappedSlices[Subresource].mapPtr, 0, GetMipSize(Subresource));
|
||||
}
|
||||
}
|
||||
m_data[Subresource] = {};
|
||||
}
|
||||
|
||||
const Rc<DxvkBuffer>& D3D9CommonTexture::GetBuffer(UINT Subresource) {
|
||||
return m_buffers[Subresource];
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ namespace dxvk {
|
||||
*/
|
||||
void* GetData(UINT Subresource);
|
||||
|
||||
const Rc<DxvkBuffer>& GetBuffer(UINT Subresource, bool Initialize);
|
||||
const Rc<DxvkBuffer>& GetBuffer(UINT Subresource);
|
||||
|
||||
|
||||
DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) {
|
||||
@ -466,6 +466,14 @@ namespace dxvk {
|
||||
*/
|
||||
VkDeviceSize GetMipSize(UINT Subresource) const;
|
||||
|
||||
/**
|
||||
* \brief Creates a buffer
|
||||
* Creates mapping and staging buffers for a given subresource
|
||||
* allocates new buffers if necessary
|
||||
* \returns Whether an allocation happened
|
||||
*/
|
||||
void CreateBufferSubresource(UINT Subresource, bool Initialize);
|
||||
|
||||
private:
|
||||
|
||||
D3D9DeviceEx* m_device;
|
||||
@ -542,14 +550,6 @@ namespace dxvk {
|
||||
D3DRESOURCETYPE Dimension,
|
||||
UINT Layer);
|
||||
|
||||
/**
|
||||
* \brief Creates a buffer
|
||||
* Creates mapping and staging buffers for a given subresource
|
||||
* allocates new buffers if necessary
|
||||
* \returns Whether an allocation happened
|
||||
*/
|
||||
void CreateBufferSubresource(UINT Subresource);
|
||||
|
||||
/**
|
||||
* \brief Creates buffers
|
||||
* Creates mapping and staging buffers for all subresources
|
||||
@ -559,7 +559,7 @@ namespace dxvk {
|
||||
// D3D9Initializer will handle clearing the buffers
|
||||
const uint32_t count = CountSubresources();
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
CreateBufferSubresource(i);
|
||||
CreateBufferSubresource(i, false);
|
||||
}
|
||||
|
||||
void AllocData();
|
||||
|
@ -889,7 +889,8 @@ namespace dxvk {
|
||||
VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel());
|
||||
VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(src->GetMipLevel());
|
||||
|
||||
Rc<DxvkBuffer> dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height);
|
||||
dstTexInfo->CreateBufferSubresource(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height);
|
||||
Rc<DxvkBuffer> dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource());
|
||||
|
||||
Rc<DxvkImage> srcImage = srcTexInfo->GetImage();
|
||||
const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format);
|
||||
@ -4260,12 +4261,17 @@ namespace dxvk {
|
||||
bool needsReadback = pResource->NeedsReadback(Subresource) || renderable;
|
||||
pResource->SetNeedsReadback(Subresource, false);
|
||||
|
||||
if (unlikely(pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED || needsReadback)) {
|
||||
// Create mapping buffer if it doesn't exist yet. (POOL_DEFAULT)
|
||||
pResource->CreateBufferSubresource(Subresource, !needsReadback);
|
||||
}
|
||||
|
||||
void* mapPtr;
|
||||
|
||||
if ((Flags & D3DLOCK_DISCARD) && needsReadback) {
|
||||
// We do not have to preserve the contents of the
|
||||
// buffer if the entire image gets discarded.
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource, false);
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource);
|
||||
DxvkBufferSliceHandle physSlice = pResource->DiscardMapSlice(Subresource);
|
||||
mapPtr = physSlice.mapPtr;
|
||||
|
||||
@ -4276,16 +4282,11 @@ namespace dxvk {
|
||||
ctx->invalidateBuffer(cImageBuffer, cBufferSlice);
|
||||
});
|
||||
} else {
|
||||
if (unlikely(pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED)) {
|
||||
// Create mapping buffer if it doesn't exist yet. (POOL_DEFAULT)
|
||||
pResource->GetBuffer(Subresource, !needsReadback);
|
||||
}
|
||||
|
||||
// Don't use MapTexture here to keep the mapped list small while the resource is still locked.
|
||||
mapPtr = pResource->GetData(Subresource);
|
||||
|
||||
if (needsReadback) {
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource, false);
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource);
|
||||
if (unlikely(needsReadback) && pResource->GetImage() != nullptr) {
|
||||
Rc<DxvkImage> resourceImage = pResource->GetImage();
|
||||
|
||||
@ -4523,7 +4524,8 @@ namespace dxvk {
|
||||
auto convertFormat = pDestTexture->GetFormatMapping().ConversionFormatInfo;
|
||||
|
||||
if (unlikely(pSrcTexture->NeedsReadback(SrcSubresource))) {
|
||||
const Rc<DxvkBuffer>& buffer = pSrcTexture->GetBuffer(SrcSubresource, false);
|
||||
pSrcTexture->CreateBufferSubresource(SrcSubresource, true);
|
||||
const Rc<DxvkBuffer>& buffer = pSrcTexture->GetBuffer(SrcSubresource);
|
||||
WaitForResource(buffer, pSrcTexture->GetMappingBufferSequenceNumber(SrcSubresource), 0);
|
||||
pSrcTexture->SetNeedsReadback(SrcSubresource, false);
|
||||
}
|
||||
|
@ -180,7 +180,8 @@ namespace dxvk {
|
||||
VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel());
|
||||
VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(0);
|
||||
|
||||
Rc<DxvkBuffer> dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height);
|
||||
dstTexInfo->CreateBufferSubresource(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height);
|
||||
Rc<DxvkBuffer> dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource());
|
||||
Rc<DxvkImage> srcImage = srcTexInfo->GetImage();
|
||||
|
||||
if (srcImage->info().sampleCount != VK_SAMPLE_COUNT_1_BIT) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user