mirror of
https://github.com/yquake2/ref_vk.git
synced 2024-11-12 23:54:28 +00:00
Merge pull request #25 from yquake2/vma_heuristic
Support memory preferences cost logic
This commit is contained in:
commit
592f847fca
1 changed files with 50 additions and 13 deletions
|
@ -22,16 +22,59 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static uint32_t
|
/*
|
||||||
get_memory_type(uint32_t mem_req_type_bits, VkMemoryPropertyFlags mem_prop)
|
Returns number of bits set to 1 in (v).
|
||||||
|
|
||||||
|
On specific platforms and compilers you can use instrinsics like:
|
||||||
|
|
||||||
|
Visual Studio:
|
||||||
|
return __popcnt(v);
|
||||||
|
GCC, Clang:
|
||||||
|
return static_cast<uint32_t>(__builtin_popcount(v));
|
||||||
|
*/
|
||||||
|
static inline uint32_t count_bits_set(uint32_t v)
|
||||||
{
|
{
|
||||||
|
#ifdef __builtin_popcount
|
||||||
|
return __builtin_popcount(v);
|
||||||
|
#else
|
||||||
|
uint32_t c = v - ((v >> 1) & 0x55555555);
|
||||||
|
c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
|
||||||
|
c = ((c >> 4) + c) & 0x0F0F0F0F;
|
||||||
|
c = ((c >> 8) + c) & 0x00FF00FF;
|
||||||
|
c = ((c >> 16) + c) & 0x0000FFFF;
|
||||||
|
return c;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
get_memory_type(uint32_t mem_req_type_bits,
|
||||||
|
VkMemoryPropertyFlags mem_prop,
|
||||||
|
VkMemoryPropertyFlags mem_pref)
|
||||||
|
{
|
||||||
|
uint32_t mem_type_index = VK_MAX_MEMORY_TYPES;
|
||||||
|
int max_cost = 0;
|
||||||
|
|
||||||
|
// update prefered with requiredVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||||
|
mem_pref |= mem_prop;
|
||||||
for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
|
for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
|
||||||
if(mem_req_type_bits & (1 << i)) {
|
if(mem_req_type_bits & (1 << i)) {
|
||||||
|
// This memory type contains mem_prop.
|
||||||
if((vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_prop) == mem_prop)
|
if((vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_prop) == mem_prop)
|
||||||
return i;
|
{
|
||||||
|
// Calculate cost as number of bits from preferredFlags present in this memory type.
|
||||||
|
int curr_cost = count_bits_set(
|
||||||
|
vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_pref);
|
||||||
|
|
||||||
|
// Remember memory type with lowest cost.
|
||||||
|
if(curr_cost >= max_cost)
|
||||||
|
{
|
||||||
|
mem_type_index = i;
|
||||||
|
max_cost = curr_cost;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return mem_type_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct MemoryResource_s {
|
typedef struct MemoryResource_s {
|
||||||
|
@ -391,15 +434,9 @@ memory_create_by_property(VkMemoryRequirements* mem_reqs,
|
||||||
VkMemoryPropertyFlags host_visible;
|
VkMemoryPropertyFlags host_visible;
|
||||||
|
|
||||||
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
|
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
|
||||||
mem_properties | mem_preferences);
|
mem_properties, mem_preferences);
|
||||||
// prefered memory allocation
|
|
||||||
if (memory_index == -1)
|
if (memory_index == VK_MAX_MEMORY_TYPES)
|
||||||
{
|
|
||||||
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
|
|
||||||
mem_properties);
|
|
||||||
}
|
|
||||||
// strictly required
|
|
||||||
if (memory_index == -1)
|
|
||||||
{
|
{
|
||||||
R_Printf(PRINT_ALL, "%s:%d: Have not found required memory type.\n",
|
R_Printf(PRINT_ALL, "%s:%d: Have not found required memory type.\n",
|
||||||
__func__, __LINE__);
|
__func__, __LINE__);
|
||||||
|
|
Loading…
Reference in a new issue