mirror of
https://github.com/yquake2/ref_vk.git
synced 2024-12-02 00:11:50 +00:00
Use first found optimal flags in select memory
Should fix #34, when NVIDIA card provides memory type with several addional flags more than code has asked but retuns error on allocate. Code has be changed to use first memory type with minimal prefered properties. E.g. if code needs VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, a first block should be used instead a fourth as before: ``` Memory blocks: 1: VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 2: VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT VK_MEMORY_PROPERTY_HOST_COHERENT_BIT 3: VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT VK_MEMORY_PROPERTY_HOST_COHERENT_BIT VK_MEMORY_PROPERTY_HOST_CACHED_BIT 4: VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ```
This commit is contained in:
parent
335b8855e2
commit
def5407ae0
2 changed files with 54 additions and 24 deletions
|
@ -6,10 +6,11 @@ This is the vkQuake2 vulkan renderer library ported to Yamagi Quake II.
|
||||||
## Compilation
|
## Compilation
|
||||||
|
|
||||||
You'll need:
|
You'll need:
|
||||||
* clang or gcc
|
* clang or gcc,
|
||||||
* GNU Make
|
* GNU Make,
|
||||||
* SDL2 with `sdl2-config`.
|
* SDL2 with `sdl2-config`,
|
||||||
* vulkan-headers.
|
* vulkan-headers,
|
||||||
|
* vulkan-validationlayers if you like to debug issues.
|
||||||
|
|
||||||
Type `make` to compile the library. If the compilation is successfull,
|
Type `make` to compile the library. If the compilation is successfull,
|
||||||
the library can be found under *release/ref_vk.dll* (Windows) or
|
the library can be found under *release/ref_vk.dll* (Windows) or
|
||||||
|
|
|
@ -46,6 +46,11 @@ static inline uint32_t count_bits_set(uint32_t v)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check:
|
||||||
|
* https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceMemoryProperties.html
|
||||||
|
* for more information.
|
||||||
|
*/
|
||||||
static uint32_t
|
static uint32_t
|
||||||
get_memory_type(uint32_t mem_req_type_bits,
|
get_memory_type(uint32_t mem_req_type_bits,
|
||||||
VkMemoryPropertyFlags mem_prop,
|
VkMemoryPropertyFlags mem_prop,
|
||||||
|
@ -53,7 +58,7 @@ get_memory_type(uint32_t mem_req_type_bits,
|
||||||
VkMemoryPropertyFlags mem_skip)
|
VkMemoryPropertyFlags mem_skip)
|
||||||
{
|
{
|
||||||
uint32_t mem_type_index = VK_MAX_MEMORY_TYPES;
|
uint32_t mem_type_index = VK_MAX_MEMORY_TYPES;
|
||||||
int max_cost = 0;
|
int max_cost = -1;
|
||||||
|
|
||||||
// update prefered with required
|
// update prefered with required
|
||||||
mem_pref |= mem_prop;
|
mem_pref |= mem_prop;
|
||||||
|
@ -65,18 +70,23 @@ get_memory_type(uint32_t mem_req_type_bits,
|
||||||
|
|
||||||
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)) {
|
||||||
|
VkMemoryPropertyFlags propertyFlags;
|
||||||
|
|
||||||
|
// cache flags
|
||||||
|
propertyFlags = vk_device.mem_properties.memoryTypes[i].propertyFlags;
|
||||||
// This memory type contains mem_prop and no mem_skip
|
// This memory type contains mem_prop and no mem_skip
|
||||||
if(
|
if(
|
||||||
(vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_prop) == mem_prop &&
|
(propertyFlags & mem_prop) == mem_prop &&
|
||||||
!(vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_skip)
|
!(propertyFlags & mem_skip)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Calculate cost as number of bits from preferredFlags present in this memory type.
|
int curr_cost;
|
||||||
int curr_cost = count_bits_set(
|
|
||||||
vk_device.mem_properties.memoryTypes[i].propertyFlags & mem_pref);
|
|
||||||
|
|
||||||
// Remember memory type with lowest cost.
|
// Calculate cost as number of bits from preferredFlags
|
||||||
if(curr_cost >= max_cost)
|
// not present in this memory type.
|
||||||
|
curr_cost = count_bits_set(propertyFlags & mem_pref);
|
||||||
|
// Remember memory type with upper cost as has more prefered bits.
|
||||||
|
if(curr_cost > max_cost)
|
||||||
{
|
{
|
||||||
mem_type_index = i;
|
mem_type_index = i;
|
||||||
max_cost = curr_cost;
|
max_cost = curr_cost;
|
||||||
|
@ -122,6 +132,12 @@ vulkan_memory_init(void)
|
||||||
static void
|
static void
|
||||||
memory_type_print(VkMemoryPropertyFlags mem_prop)
|
memory_type_print(VkMemoryPropertyFlags mem_prop)
|
||||||
{
|
{
|
||||||
|
if (!mem_prop)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, " VK_MEMORY_PROPERTY_NONE");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#define MPSTR(r, prop) \
|
#define MPSTR(r, prop) \
|
||||||
if((prop & VK_MEMORY_PROPERTY_ ##r) != 0) \
|
if((prop & VK_MEMORY_PROPERTY_ ##r) != 0) \
|
||||||
{ R_Printf(PRINT_ALL, " %s", "VK_MEMORY_PROPERTY_"#r); }; \
|
{ R_Printf(PRINT_ALL, " %s", "VK_MEMORY_PROPERTY_"#r); }; \
|
||||||
|
@ -391,7 +407,7 @@ memory_create(VkDeviceSize size,
|
||||||
{
|
{
|
||||||
// check size of block,
|
// check size of block,
|
||||||
// new block should be at least same size as current
|
// new block should be at least same size as current
|
||||||
// and beger than double minimal offset
|
// and bigger than double minimal offset
|
||||||
// and marked as not for mmap
|
// and marked as not for mmap
|
||||||
if (used_memory[pos].size > (size * 2) &&
|
if (used_memory[pos].size > (size * 2) &&
|
||||||
(used_memory[pos].size > (used_memory[pos].alignment * 2)) &&
|
(used_memory[pos].size > (used_memory[pos].alignment * 2)) &&
|
||||||
|
@ -448,8 +464,19 @@ memory_create_by_property(VkMemoryRequirements* mem_reqs,
|
||||||
VkDeviceMemory *memory,
|
VkDeviceMemory *memory,
|
||||||
VkDeviceSize *offset)
|
VkDeviceSize *offset)
|
||||||
{
|
{
|
||||||
uint32_t memory_index;
|
|
||||||
VkMemoryPropertyFlags host_visible;
|
VkMemoryPropertyFlags host_visible;
|
||||||
|
uint32_t memory_index;
|
||||||
|
|
||||||
|
if (r_validation->value)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "Asked about memory properties with:\n");
|
||||||
|
memory_type_print(mem_properties);
|
||||||
|
R_Printf(PRINT_ALL, "\nAsked about memory preferences with:\n");
|
||||||
|
memory_type_print(mem_preferences);
|
||||||
|
R_Printf(PRINT_ALL, "\nAsked about memory skip with:\n");
|
||||||
|
memory_type_print(mem_skip);
|
||||||
|
R_Printf(PRINT_ALL, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
|
memory_index = get_memory_type(mem_reqs->memoryTypeBits,
|
||||||
mem_properties, mem_preferences, mem_skip);
|
mem_properties, mem_preferences, mem_skip);
|
||||||
|
@ -460,6 +487,18 @@ memory_create_by_property(VkMemoryRequirements* mem_reqs,
|
||||||
__func__, __LINE__);
|
__func__, __LINE__);
|
||||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||||
}
|
}
|
||||||
|
else if (r_validation->value)
|
||||||
|
{
|
||||||
|
R_Printf(PRINT_ALL, "%s:%d: Selected %d memory properties with:\n",
|
||||||
|
__func__, __LINE__, memory_index);
|
||||||
|
memory_type_print(
|
||||||
|
vk_device.mem_properties.memoryTypes[memory_index].propertyFlags);
|
||||||
|
R_Printf(PRINT_ALL, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get selected memory properties */
|
||||||
|
mem_properties = vk_device.mem_properties.memoryTypes[memory_index].propertyFlags &
|
||||||
|
(mem_properties | mem_preferences);
|
||||||
|
|
||||||
host_visible = mem_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
host_visible = mem_properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||||
|
|
||||||
|
@ -499,11 +538,6 @@ buffer_create(BufferResource_t *buf,
|
||||||
if(result != VK_SUCCESS) {
|
if(result != VK_SUCCESS) {
|
||||||
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
||||||
__func__, __LINE__, QVk_GetError(result));
|
__func__, __LINE__, QVk_GetError(result));
|
||||||
R_Printf(PRINT_ALL, "Memory properties with:\n");
|
|
||||||
memory_type_print(mem_properties);
|
|
||||||
R_Printf(PRINT_ALL, "Memory preferences with:\n");
|
|
||||||
memory_type_print(mem_preferences);
|
|
||||||
R_Printf(PRINT_ALL, "\n");
|
|
||||||
goto fail_mem_alloc;
|
goto fail_mem_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,11 +590,6 @@ image_create(ImageResource_t *img,
|
||||||
if(result != VK_SUCCESS) {
|
if(result != VK_SUCCESS) {
|
||||||
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
R_Printf(PRINT_ALL, "%s:%d: VkResult verification: %s\n",
|
||||||
__func__, __LINE__, QVk_GetError(result));
|
__func__, __LINE__, QVk_GetError(result));
|
||||||
R_Printf(PRINT_ALL, "Memory properties with:\n");
|
|
||||||
memory_type_print(mem_properties);
|
|
||||||
R_Printf(PRINT_ALL, "Memory preferences with:\n");
|
|
||||||
memory_type_print(mem_preferences);
|
|
||||||
R_Printf(PRINT_ALL, "\n");
|
|
||||||
goto fail_mem_alloc;
|
goto fail_mem_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue