mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +01:00
[d3d9] Use memory mapped files for textures
This commit is contained in:
parent
d598fd3156
commit
6ca6554452
@ -40,7 +40,8 @@ namespace dxvk {
|
||||
m_shadow = DetermineShadowState();
|
||||
m_supportsFetch4 = DetermineFetch4Compatibility();
|
||||
|
||||
if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED) {
|
||||
const bool createImage = m_desc.Pool != D3DPOOL_SYSTEMMEM && m_desc.Pool != D3DPOOL_SCRATCH && m_desc.Format != D3D9Format::NULL_FORMAT;
|
||||
if (createImage) {
|
||||
bool plainSurface = m_type == D3DRTYPE_SURFACE &&
|
||||
!(m_desc.Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL));
|
||||
|
||||
@ -73,7 +74,9 @@ namespace dxvk {
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM)
|
||||
if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)
|
||||
AllocData();
|
||||
else if (m_mapMode != D3D9_COMMON_TEXTURE_MAP_MODE_NONE && m_desc.Pool != D3DPOOL_DEFAULT)
|
||||
CreateBuffers();
|
||||
|
||||
m_exposedMipLevels = m_desc.MipLevels;
|
||||
@ -165,11 +168,16 @@ namespace dxvk {
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
void* D3D9CommonTexture::GetData(UINT Subresource) {
|
||||
if (unlikely(m_mappedSlices[Subresource].mapPtr != nullptr || m_mapMode != D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE))
|
||||
return m_mappedSlices[Subresource].mapPtr;
|
||||
|
||||
bool D3D9CommonTexture::CreateBufferSubresource(UINT Subresource) {
|
||||
if (m_buffers[Subresource] != nullptr)
|
||||
return false;
|
||||
D3D9Memory& memory = m_data[Subresource];
|
||||
memory.Map();
|
||||
return memory.Ptr();
|
||||
}
|
||||
|
||||
void D3D9CommonTexture::CreateBufferSubresource(UINT Subresource) {
|
||||
DxvkBufferCreateInfo info;
|
||||
info.size = GetMipSize(Subresource);
|
||||
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
@ -190,8 +198,6 @@ namespace dxvk {
|
||||
|
||||
m_buffers[Subresource] = m_device->GetDXVKDevice()->createBuffer(info, memType);
|
||||
m_mappedSlices[Subresource] = m_buffers[Subresource]->getSliceHandle();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -477,6 +483,20 @@ namespace dxvk {
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
}
|
||||
|
||||
D3D9_COMMON_TEXTURE_MAP_MODE D3D9CommonTexture::DetermineMapMode() const {
|
||||
if (m_desc.Format == D3D9Format::NULL_FORMAT)
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_NONE;
|
||||
|
||||
#ifdef D3D9_ALLOW_UNMAPPING
|
||||
if (m_desc.Pool != D3DPOOL_DEFAULT)
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE;
|
||||
#endif
|
||||
|
||||
if (m_desc.Pool == D3DPOOL_SYSTEMMEM || m_desc.Pool == D3DPOOL_SCRATCH)
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM;
|
||||
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_BACKED;
|
||||
}
|
||||
|
||||
void D3D9CommonTexture::ExportImageInfo() {
|
||||
/* From MSDN:
|
||||
@ -606,5 +626,30 @@ namespace dxvk {
|
||||
m_sampleView.Srgb = CreateView(AllLayers, Lod, VK_IMAGE_USAGE_SAMPLED_BIT, true);
|
||||
}
|
||||
|
||||
void D3D9CommonTexture::AllocData() {
|
||||
// D3D9Initializer will handle clearing the data
|
||||
const uint32_t count = CountSubresources();
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
m_data[i] = m_device->GetAllocator()->Alloc(GetMipSize(i));
|
||||
}
|
||||
}
|
||||
|
||||
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] = {};
|
||||
}
|
||||
|
||||
return m_buffers[Subresource];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "d3d9_format.h"
|
||||
#include "d3d9_util.h"
|
||||
#include "d3d9_caps.h"
|
||||
#include "d3d9_mem.h"
|
||||
|
||||
#include "../dxvk/dxvk_device.h"
|
||||
|
||||
@ -22,6 +23,7 @@ namespace dxvk {
|
||||
D3D9_COMMON_TEXTURE_MAP_MODE_NONE, ///< No mapping available
|
||||
D3D9_COMMON_TEXTURE_MAP_MODE_BACKED, ///< Mapped image through buffer
|
||||
D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM, ///< Only a buffer - no image
|
||||
D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE, ///< Non-Vulkan memory that can be unmapped
|
||||
};
|
||||
|
||||
/**
|
||||
@ -141,9 +143,17 @@ namespace dxvk {
|
||||
return m_resolveImage;
|
||||
}
|
||||
|
||||
const Rc<DxvkBuffer>& GetBuffer(UINT Subresource) {
|
||||
return m_buffers[Subresource];
|
||||
}
|
||||
/**
|
||||
* \brief Returns a pointer to the internal data used for LockRect/LockBox
|
||||
*
|
||||
* This works regardless of the map mode used by this texture
|
||||
* and will map the memory if necessary.
|
||||
* \param [in] Subresource Subresource index
|
||||
* @return Pointer to locking data
|
||||
*/
|
||||
void* GetData(UINT Subresource);
|
||||
|
||||
const Rc<DxvkBuffer>& GetBuffer(UINT Subresource, bool Initialize);
|
||||
|
||||
|
||||
DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) {
|
||||
@ -215,24 +225,16 @@ namespace dxvk {
|
||||
return Face * m_desc.MipLevels + MipLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates buffers
|
||||
* Creates mapping and staging buffers for all subresources
|
||||
* allocates new buffers if necessary
|
||||
*/
|
||||
void CreateBuffers() {
|
||||
const uint32_t count = CountSubresources();
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
CreateBufferSubresource(i);
|
||||
void UnmapData(UINT Subresource) {
|
||||
m_data[Subresource].Unmap();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates a buffer
|
||||
* Creates mapping and staging buffers for a given subresource
|
||||
* allocates new buffers if necessary
|
||||
* \returns Whether an allocation happened
|
||||
*/
|
||||
bool CreateBufferSubresource(UINT Subresource);
|
||||
void UnmapData() {
|
||||
const uint32_t subresources = CountSubresources();
|
||||
for (uint32_t i = 0; i < subresources; i++) {
|
||||
m_data[i].Unmap();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Destroys a buffer
|
||||
@ -456,6 +458,12 @@ namespace dxvk {
|
||||
: 0ull;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mip level
|
||||
* \returns Size of packed mip level in bytes
|
||||
*/
|
||||
VkDeviceSize GetMipSize(UINT Subresource) const;
|
||||
|
||||
private:
|
||||
|
||||
D3D9DeviceEx* m_device;
|
||||
@ -468,7 +476,9 @@ namespace dxvk {
|
||||
D3D9SubresourceArray<
|
||||
Rc<DxvkBuffer>> m_buffers;
|
||||
D3D9SubresourceArray<
|
||||
DxvkBufferSliceHandle> m_mappedSlices;
|
||||
DxvkBufferSliceHandle> m_mappedSlices = { };
|
||||
D3D9SubresourceArray<
|
||||
D3D9Memory> m_data = { };
|
||||
D3D9SubresourceArray<
|
||||
uint64_t> m_seqs = { };
|
||||
|
||||
@ -503,12 +513,6 @@ namespace dxvk {
|
||||
|
||||
std::array<D3DBOX, 6> m_dirtyBoxes;
|
||||
|
||||
/**
|
||||
* \brief Mip level
|
||||
* \returns Size of packed mip level in bytes
|
||||
*/
|
||||
VkDeviceSize GetMipSize(UINT Subresource) const;
|
||||
|
||||
Rc<DxvkImage> CreatePrimaryImage(D3DRESOURCETYPE ResourceType, bool TryOffscreenRT, HANDLE* pSharedHandle) const;
|
||||
|
||||
Rc<DxvkImage> CreateResolveImage() const;
|
||||
@ -525,15 +529,7 @@ namespace dxvk {
|
||||
VkFormat Format,
|
||||
VkImageTiling Tiling) const;
|
||||
|
||||
D3D9_COMMON_TEXTURE_MAP_MODE DetermineMapMode() const {
|
||||
if (m_desc.Format == D3D9Format::NULL_FORMAT)
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_NONE;
|
||||
|
||||
if (m_desc.Pool == D3DPOOL_SYSTEMMEM || m_desc.Pool == D3DPOOL_SCRATCH)
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM;
|
||||
|
||||
return D3D9_COMMON_TEXTURE_MAP_MODE_BACKED;
|
||||
}
|
||||
D3D9_COMMON_TEXTURE_MAP_MODE DetermineMapMode() const;
|
||||
|
||||
VkImageLayout OptimizeLayout(
|
||||
VkImageUsageFlags Usage) const;
|
||||
@ -544,6 +540,28 @@ 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
|
||||
* allocates new buffers if necessary
|
||||
*/
|
||||
void CreateBuffers() {
|
||||
// D3D9Initializer will handle clearing the buffers
|
||||
const uint32_t count = CountSubresources();
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
CreateBufferSubresource(i);
|
||||
}
|
||||
|
||||
void AllocData();
|
||||
|
||||
static constexpr UINT AllLayers = UINT32_MAX;
|
||||
|
||||
};
|
||||
|
@ -876,7 +876,10 @@ namespace dxvk {
|
||||
if (dstTexInfo->Desc()->Pool == D3DPOOL_DEFAULT)
|
||||
return this->StretchRect(pRenderTarget, nullptr, pDestSurface, nullptr, D3DTEXF_NONE);
|
||||
|
||||
Rc<DxvkBuffer> dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource());
|
||||
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);
|
||||
|
||||
Rc<DxvkImage> srcImage = srcTexInfo->GetImage();
|
||||
const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format);
|
||||
@ -887,9 +890,8 @@ namespace dxvk {
|
||||
srcSubresource.mipLevel,
|
||||
srcSubresource.arrayLayer, 1 };
|
||||
|
||||
VkExtent3D srcExtent = srcTexInfo->GetExtentMip(src->GetMipLevel());
|
||||
|
||||
VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(srcExtent, srcFormatInfo->blockSize);
|
||||
VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(srcTexExtent, srcFormatInfo->blockSize);
|
||||
VkDeviceSize pitch = align(texLevelExtentBlockCount.width * uint32_t(srcFormatInfo->elementSize), 4);
|
||||
uint32_t pitchBlocks = uint32_t(pitch / srcFormatInfo->elementSize);
|
||||
VkExtent2D dstExtent = VkExtent2D{ pitchBlocks,
|
||||
@ -899,7 +901,7 @@ namespace dxvk {
|
||||
cBuffer = dstBuffer,
|
||||
cImage = srcImage,
|
||||
cSubresources = srcSubresourceLayers,
|
||||
cLevelExtent = srcExtent,
|
||||
cLevelExtent = srcTexExtent,
|
||||
cDstExtent = dstExtent
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->copyImageToBuffer(cBuffer, 0, 4, 0,
|
||||
@ -4128,10 +4130,6 @@ namespace dxvk {
|
||||
|
||||
auto& desc = *(pResource->Desc());
|
||||
|
||||
bool alloced = pResource->CreateBufferSubresource(Subresource);
|
||||
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource);
|
||||
|
||||
auto& formatMapping = pResource->GetFormatMapping();
|
||||
|
||||
const DxvkFormatInfo* formatInfo = formatMapping.IsValid()
|
||||
@ -4182,12 +4180,14 @@ namespace dxvk {
|
||||
bool needsReadback = pResource->NeedsReachback(Subresource) || renderable;
|
||||
pResource->SetNeedsReadback(Subresource, false);
|
||||
|
||||
DxvkBufferSliceHandle physSlice;
|
||||
void* mapPtr;
|
||||
|
||||
if ((Flags & D3DLOCK_DISCARD) && needsReadback) {
|
||||
// We do not have to preserve the contents of the
|
||||
// buffer if the entire image gets discarded.
|
||||
physSlice = pResource->DiscardMapSlice(Subresource);
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource, false);
|
||||
DxvkBufferSliceHandle physSlice = pResource->DiscardMapSlice(Subresource);
|
||||
mapPtr = physSlice.mapPtr;
|
||||
|
||||
EmitCs([
|
||||
cImageBuffer = std::move(mappedBuffer),
|
||||
@ -4196,10 +4196,15 @@ namespace dxvk {
|
||||
ctx->invalidateBuffer(cImageBuffer, cBufferSlice);
|
||||
});
|
||||
} else {
|
||||
physSlice = pResource->GetMappedSlice(Subresource);
|
||||
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);
|
||||
}
|
||||
|
||||
mapPtr = pResource->GetData(Subresource);
|
||||
|
||||
if (needsReadback) {
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource);
|
||||
const Rc<DxvkBuffer> mappedBuffer = pResource->GetBuffer(Subresource, false);
|
||||
if (unlikely(needsReadback) && pResource->GetImage() != nullptr) {
|
||||
Rc<DxvkImage> resourceImage = pResource->GetImage();
|
||||
|
||||
@ -4274,8 +4279,6 @@ namespace dxvk {
|
||||
|
||||
if (!WaitForResource(mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), Flags))
|
||||
return D3DERR_WASSTILLDRAWING;
|
||||
} else if (alloced) {
|
||||
std::memset(physSlice.mapPtr, 0, physSlice.length);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4332,8 +4335,7 @@ namespace dxvk {
|
||||
(!atiHack) ? formatInfo : nullptr,
|
||||
pBox);
|
||||
|
||||
|
||||
uint8_t* data = reinterpret_cast<uint8_t*>(physSlice.mapPtr);
|
||||
uint8_t* data = reinterpret_cast<uint8_t*>(mapPtr);
|
||||
data += offset;
|
||||
pLockedBox->pBits = data;
|
||||
return D3D_OK;
|
||||
@ -4419,7 +4421,6 @@ namespace dxvk {
|
||||
|
||||
// Now that data has been written into the buffer,
|
||||
// we need to copy its contents into the image
|
||||
const DxvkBufferSliceHandle srcSlice = pSrcTexture->GetMappedSlice(SrcSubresource);
|
||||
|
||||
auto formatInfo = lookupFormatInfo(image->info().format);
|
||||
auto srcSubresource = pSrcTexture->GetSubresourceFromIndex(
|
||||
@ -4462,9 +4463,10 @@ namespace dxvk {
|
||||
+ srcOffsetBlockCount.y * pitch
|
||||
+ srcOffsetBlockCount.x * formatInfo->elementSize;
|
||||
|
||||
const void* mapPtr = pSrcTexture->GetData(SrcSubresource);
|
||||
VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize;
|
||||
D3D9BufferSlice slice = AllocStagingBuffer(dirtySize);
|
||||
const void* srcData = reinterpret_cast<const uint8_t*>(srcSlice.mapPtr) + copySrcOffset;
|
||||
const void* srcData = reinterpret_cast<const uint8_t*>(mapPtr) + copySrcOffset;
|
||||
util::packImageData(
|
||||
slice.mapPtr, srcData, extentBlockCount, formatInfo->elementSize,
|
||||
pitch, pitch * srcTexLevelExtentBlockCount.height);
|
||||
@ -4487,6 +4489,7 @@ namespace dxvk {
|
||||
}
|
||||
else {
|
||||
const DxvkFormatInfo* formatInfo = lookupFormatInfo(pDestTexture->GetFormatMapping().FormatColor);
|
||||
const void* mapPtr = pSrcTexture->GetData(SrcSubresource);
|
||||
|
||||
// Add more blocks for the other planes that we might have.
|
||||
// TODO: PLEASE CLEAN ME
|
||||
@ -4504,11 +4507,11 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
// the converter can not handle the 4 aligned pitch so we always repack into a staging buffer
|
||||
D3D9BufferSlice slice = AllocStagingBuffer(srcSlice.length);
|
||||
D3D9BufferSlice slice = AllocStagingBuffer(pSrcTexture->GetMipSize(SrcSubresource));
|
||||
VkDeviceSize pitch = align(srcTexLevelExtentBlockCount.width * formatInfo->elementSize, 4);
|
||||
|
||||
util::packImageData(
|
||||
slice.mapPtr, srcSlice.mapPtr, srcTexLevelExtentBlockCount, formatInfo->elementSize,
|
||||
slice.mapPtr, mapPtr, srcTexLevelExtentBlockCount, formatInfo->elementSize,
|
||||
pitch, std::min(convertFormat.PlaneCount, 2u) * pitch * srcTexLevelExtentBlockCount.height);
|
||||
|
||||
Flush();
|
||||
@ -5214,7 +5217,7 @@ namespace dxvk {
|
||||
|
||||
void D3D9DeviceEx::UploadManagedTexture(D3D9CommonTexture* pResource) {
|
||||
for (uint32_t subresource = 0; subresource < pResource->CountSubresources(); subresource++) {
|
||||
if (!pResource->NeedsUpload(subresource) || pResource->GetBuffer(subresource) == nullptr)
|
||||
if (!pResource->NeedsUpload(subresource))
|
||||
continue;
|
||||
|
||||
this->FlushImage(pResource, subresource);
|
||||
|
@ -40,13 +40,15 @@ namespace dxvk {
|
||||
|
||||
void D3D9Initializer::InitTexture(
|
||||
D3D9CommonTexture* pTexture,
|
||||
void* pInitialData) {
|
||||
void* pInitialData) {
|
||||
if (pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_NONE)
|
||||
return;
|
||||
|
||||
(pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED)
|
||||
? InitDeviceLocalTexture(pTexture)
|
||||
: InitHostVisibleTexture(pTexture, pInitialData);
|
||||
if (pTexture->GetImage() != nullptr)
|
||||
InitDeviceLocalTexture(pTexture);
|
||||
|
||||
if (pTexture->Desc()->Pool != D3DPOOL_DEFAULT)
|
||||
InitHostVisibleTexture(pTexture, pInitialData);
|
||||
}
|
||||
|
||||
|
||||
@ -115,7 +117,8 @@ namespace dxvk {
|
||||
for (uint32_t a = 0; a < desc->ArraySize; a++) {
|
||||
for (uint32_t m = 0; m < desc->MipLevels; m++) {
|
||||
uint32_t subresource = pTexture->CalcSubresource(a, m);
|
||||
DxvkBufferSliceHandle mapSlice = pTexture->GetBuffer(subresource)->getSliceHandle();
|
||||
void* mapPtr = pTexture->GetData(subresource);
|
||||
uint32_t length = pTexture->GetMipSize(subresource);
|
||||
|
||||
if (pInitialData != nullptr) {
|
||||
VkExtent3D mipExtent = pTexture->GetExtentMip(m);
|
||||
@ -125,7 +128,7 @@ namespace dxvk {
|
||||
uint32_t alignedPitch = align(pitch, 4);
|
||||
|
||||
util::packImageData(
|
||||
mapSlice.mapPtr,
|
||||
mapPtr,
|
||||
pInitialData,
|
||||
pitch,
|
||||
pitch * blockCount.height,
|
||||
@ -138,11 +141,13 @@ namespace dxvk {
|
||||
VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
} else {
|
||||
std::memset(
|
||||
mapSlice.mapPtr, 0,
|
||||
mapSlice.length);
|
||||
mapPtr, 0,
|
||||
length);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)
|
||||
pTexture->UnmapData();
|
||||
}
|
||||
|
||||
|
||||
|
@ -341,7 +341,10 @@ namespace dxvk {
|
||||
if (unlikely(dstTexInfo->Desc()->Pool != D3DPOOL_SYSTEMMEM && dstTexInfo->Desc()->Pool != D3DPOOL_SCRATCH))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
Rc<DxvkBuffer> dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource());
|
||||
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);
|
||||
Rc<DxvkImage> srcImage = srcTexInfo->GetImage();
|
||||
|
||||
if (srcImage->info().sampleCount != VK_SAMPLE_COUNT_1_BIT) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user