1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[dxvk] Respect bufferImageGranularity for non-linear images

May fix aliasing issues on GPUs where the bufferImageGranularity limit
is greater than the alignment requirement of non-linear resources.
This commit is contained in:
Philip Rebohle 2018-03-20 20:24:11 +01:00
parent fd4e55007f
commit 42d49d7603
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 27 additions and 1 deletions

View File

@ -30,12 +30,23 @@ namespace dxvk {
&info, nullptr, &m_image) != VK_SUCCESS) &info, nullptr, &m_image) != VK_SUCCESS)
throw DxvkError("DxvkImage::DxvkImage: Failed to create image"); throw DxvkError("DxvkImage::DxvkImage: Failed to create image");
// Get memory requirements for the image. We may enforce strict
// alignment on non-linear images in order not to violate the
// bufferImageGranularity limit, which may be greater than the
// required resource memory alignment on some GPUs.
VkMemoryRequirements memReq; VkMemoryRequirements memReq;
m_vkd->vkGetImageMemoryRequirements( m_vkd->vkGetImageMemoryRequirements(
m_vkd->device(), m_image, &memReq); m_vkd->device(), m_image, &memReq);
if (info.tiling != VK_IMAGE_TILING_LINEAR) {
memReq.size = align(memReq.size, memAlloc.bufferImageGranularity());
memReq.alignment = align(memReq.alignment , memAlloc.bufferImageGranularity());
}
m_memory = memAlloc.alloc(memReq, memFlags); m_memory = memAlloc.alloc(memReq, memFlags);
// Try to bind the allocated memory slice to the image
if (m_vkd->vkBindImageMemory(m_vkd->device(), if (m_vkd->vkBindImageMemory(m_vkd->device(),
m_image, m_memory.memory(), m_memory.offset()) != VK_SUCCESS) m_image, m_memory.memory(), m_memory.offset()) != VK_SUCCESS)
throw DxvkError("DxvkImage::DxvkImage: Failed to bind device memory"); throw DxvkError("DxvkImage::DxvkImage: Failed to bind device memory");

View File

@ -246,7 +246,9 @@ namespace dxvk {
DxvkMemoryAllocator::DxvkMemoryAllocator( DxvkMemoryAllocator::DxvkMemoryAllocator(
const Rc<DxvkAdapter>& adapter, const Rc<DxvkAdapter>& adapter,
const Rc<vk::DeviceFn>& vkd) const Rc<vk::DeviceFn>& vkd)
: m_vkd(vkd), m_memProps(adapter->memoryProperties()) { : m_vkd (vkd),
m_devProps(adapter->deviceProperties()),
m_memProps(adapter->memoryProperties()) {
for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++)
m_heaps[i] = new DxvkMemoryHeap(m_vkd, i, m_memProps.memoryTypes[i]); m_heaps[i] = new DxvkMemoryHeap(m_vkd, i, m_memProps.memoryTypes[i]);
} }

View File

@ -214,6 +214,18 @@ namespace dxvk {
const Rc<vk::DeviceFn>& vkd); const Rc<vk::DeviceFn>& vkd);
~DxvkMemoryAllocator(); ~DxvkMemoryAllocator();
/**
* \brief Buffer-image granularity
*
* The granularity between linear and non-linear
* resources in adjacent memory locations. See
* section 11.6 of the Vulkan spec for details.
* \returns Buffer-image granularity
*/
VkDeviceSize bufferImageGranularity() const {
return m_devProps.limits.bufferImageGranularity;
}
/** /**
* \brief Allocates device memory * \brief Allocates device memory
* *
@ -228,6 +240,7 @@ namespace dxvk {
private: private:
const Rc<vk::DeviceFn> m_vkd; const Rc<vk::DeviceFn> m_vkd;
const VkPhysicalDeviceProperties m_devProps;
const VkPhysicalDeviceMemoryProperties m_memProps; const VkPhysicalDeviceMemoryProperties m_memProps;
std::array<Rc<DxvkMemoryHeap>, VK_MAX_MEMORY_TYPES> m_heaps; std::array<Rc<DxvkMemoryHeap>, VK_MAX_MEMORY_TYPES> m_heaps;