Bindless textures

main
noah metz 2024-01-13 16:37:29 -07:00
parent a730ab001b
commit 87141577f9
5 changed files with 151 additions and 103 deletions

@ -10,6 +10,8 @@ OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert))) VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert)))
FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag))) FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag)))
export MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS=1
.PHONY: all .PHONY: all
all: spacegame $(VERT_SPV) $(FRAG_SPV) all: spacegame $(VERT_SPV) $(FRAG_SPV)

@ -1,12 +1,9 @@
#version 450 #version 450
#extension GL_EXT_buffer_reference : require #extension GL_EXT_buffer_reference : require
struct Object {
mat4 model;
};
layout(buffer_reference, buffer_reference_align = 16) buffer ObjectBuffer { layout(buffer_reference, buffer_reference_align = 16) buffer ObjectBuffer {
Object objects[]; mat4 model[];
}; };
layout( push_constant ) uniform constants { layout( push_constant ) uniform constants {
@ -25,6 +22,6 @@ layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor; layout(location = 0) out vec3 fragColor;
void main() { void main() {
gl_Position = scene.proj * scene.view * scene.objects.objects[0].model * vec4(inPosition, 1.0); gl_Position = scene.proj * scene.view * scene.objects.model[0] * vec4(inPosition, 1.0);
fragColor = inColor; fragColor = inColor;
} }

@ -4,7 +4,8 @@ layout(location = 0) in vec3 fragColor;
layout(location = 1) in vec2 fragTex; layout(location = 1) in vec2 fragTex;
layout(location = 0) out vec4 outColor; layout(location = 0) out vec4 outColor;
layout(set = 1, binding = 0) uniform sampler2D texSampler;
void main() { void main() {
outColor = vec4(fragTex, 1.0, 1.0); outColor = texture(texSampler, fragTex);
} }

@ -1,9 +1,15 @@
#version 450 #version 450
#extension GL_EXT_buffer_reference : require
layout(buffer_reference, buffer_reference_align = 16) buffer ObjectBuffer {
mat4 model[];
};
layout( push_constant ) uniform constants { layout( push_constant ) uniform constants {
mat4 view; mat4 view;
mat4 proj; mat4 proj;
} scene_pc; ObjectBuffer objects;
} scene;
layout(set = 0, binding = 0) uniform SceneUniformBuffer { layout(set = 0, binding = 0) uniform SceneUniformBuffer {
mat4 test; mat4 test;
@ -17,7 +23,7 @@ layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTex; layout(location = 1) out vec2 fragTex;
void main() { void main() {
gl_Position = scene_pc.proj * scene_pc.view * vec4(inPosition, 1.0); gl_Position = scene.proj * scene.view * scene.objects.model[1] * vec4(inPosition, 1.0);
fragColor = inColor; fragColor = inColor;
fragTex = inTex; fragTex = inTex;
} }

@ -109,8 +109,7 @@ typedef struct MeshStruct {
typedef struct GraphicsPipelineInfoStruct { typedef struct GraphicsPipelineInfoStruct {
VkDescriptorSetLayout scene_layout; VkDescriptorSetLayout scene_layout;
VkDescriptorSetLayoutBinding* descriptor_bindings; VkDescriptorSetLayoutCreateInfo descriptor_info;
uint32_t descriptor_bindings_count;
uint32_t input_bindings_count; uint32_t input_bindings_count;
VkVertexInputBindingDescription* input_bindings; VkVertexInputBindingDescription* input_bindings;
@ -426,6 +425,7 @@ VkResult get_best_physical_device(VkInstance instance, VkPhysicalDevice* device)
VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(devices[i], &properties); vkGetPhysicalDeviceProperties(devices[i], &properties);
fprintf(stderr, "%d\n", properties.limits.maxPerStageResources);
VkPhysicalDeviceFeatures features; VkPhysicalDeviceFeatures features;
vkGetPhysicalDeviceFeatures(devices[i], &features); vkGetPhysicalDeviceFeatures(devices[i], &features);
@ -580,7 +580,7 @@ VkResult create_instance(VkInstance* instance) {
VkResult result = vkCreateInstance(&instance_info, 0, instance); VkResult result = vkCreateInstance(&instance_info, 0, instance);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
fprintf(stderr, "vkCreateInstance: 0x%02x\n", result); fprintf(stderr, "vkCreateInstance: %s\n", string_VkResult(result));
return result; return result;
} }
@ -635,6 +635,7 @@ VkResult create_logical_device(VkPhysicalDevice physical_device, QueueIndices qu
.descriptorBindingVariableDescriptorCount = VK_TRUE, .descriptorBindingVariableDescriptorCount = VK_TRUE,
.descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE, .descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE,
.descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE,
.descriptorBindingSampledImageUpdateAfterBind = VK_TRUE,
}; };
VkPhysicalDeviceFeatures device_features = { VkPhysicalDeviceFeatures device_features = {
@ -1586,34 +1587,28 @@ VkResult create_graphics_pipeline(
out->max_frames_in_flight = max_frames_in_flight; out->max_frames_in_flight = max_frames_in_flight;
VkDescriptorSetLayoutCreateInfo descriptor_layout_info = { VkResult result = vkCreateDescriptorSetLayout(device, &pipeline_info.descriptor_info, 0, &out->descriptors_layout);
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = pipeline_info.descriptor_bindings_count,
.pBindings = pipeline_info.descriptor_bindings,
};
VkResult result = vkCreateDescriptorSetLayout(device, &descriptor_layout_info, 0, &out->descriptors_layout);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
return result; return result;
} }
if(pipeline_info.descriptor_bindings_count > 0) { if(pipeline_info.descriptor_info.bindingCount > 0) {
VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*(1 + pipeline_info.descriptor_bindings_count)); VkDescriptorPoolSize* pool_sizes = malloc(sizeof(VkDescriptorPool)*(1 + pipeline_info.descriptor_info.bindingCount));
if(pool_sizes == 0) { if(pool_sizes == 0) {
return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
} }
for(uint32_t i = 0; i < pipeline_info.descriptor_bindings_count; i++) { for(uint32_t i = 0; i < pipeline_info.descriptor_info.bindingCount; i++) {
VkDescriptorPoolSize pool_size = { VkDescriptorPoolSize pool_size = {
.type = pipeline_info.descriptor_bindings[i].descriptorType, .type = pipeline_info.descriptor_info.pBindings[i].descriptorType,
.descriptorCount = pipeline_info.descriptor_bindings[i].descriptorCount*max_frames_in_flight, .descriptorCount = pipeline_info.descriptor_info.pBindings[i].descriptorCount*max_frames_in_flight,
}; };
pool_sizes[i] = pool_size; pool_sizes[i] = pool_size;
} }
VkDescriptorPoolCreateInfo pool_info = { VkDescriptorPoolCreateInfo pool_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.poolSizeCount = pipeline_info.descriptor_bindings_count, .poolSizeCount = pipeline_info.descriptor_info.bindingCount,
.maxSets = max_frames_in_flight, .maxSets = max_frames_in_flight,
.pPoolSizes = pool_sizes, .pPoolSizes = pool_sizes,
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT, .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT,
@ -1816,7 +1811,7 @@ VkResult create_graphics_pipeline(
return VK_SUCCESS; return VK_SUCCESS;
} }
VkResult create_simple_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, GraphicsPipeline* out) { VkResult create_simple_mesh_pipeline(VkDevice device, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, GraphicsPipeline* out) {
if(out == NULL) { if(out == NULL) {
return VK_ERROR_VALIDATION_FAILED_EXT; return VK_ERROR_VALIDATION_FAILED_EXT;
} }
@ -1861,7 +1856,7 @@ VkResult create_simple_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProp
}, },
}; };
VkDescriptorSetLayoutBinding descriptor_bindings[] = { VkDescriptorSetLayoutBinding set_bindings[] = {
{ {
.binding = 0, .binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
@ -1871,9 +1866,15 @@ VkResult create_simple_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProp
}, },
}; };
VkDescriptorSetLayoutCreateInfo set_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pBindings = set_bindings,
.bindingCount = sizeof(set_bindings)/sizeof(VkDescriptorSetLayoutBinding),
.pNext = NULL,
};
GraphicsPipelineInfo pipeline_info = { GraphicsPipelineInfo pipeline_info = {
.descriptor_bindings_count = sizeof(descriptor_bindings)/sizeof(VkDescriptorSetLayoutBinding), .descriptor_info = set_info,
.descriptor_bindings = descriptor_bindings,
.shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), .shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo),
.shader_stages = shader_stages, .shader_stages = shader_stages,
.scene_layout = scene_layout, .scene_layout = scene_layout,
@ -1883,16 +1884,10 @@ VkResult create_simple_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProp
.input_attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription), .input_attributes_count = sizeof(attributes)/sizeof(VkVertexInputAttributeDescription),
}; };
GPUPage* memory = NULL;
VkResult result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &memory);
if(result != VK_SUCCESS) {
return result;
}
return create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out); return create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out);
} }
VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, GraphicsPipeline* out) { VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryProperties memories, VkExtent2D extent, VkRenderPass render_pass, VkDescriptorSetLayout scene_layout, uint32_t max_frames_in_flight, VkCommandPool transfer_pool, VkQueue transfer_queue, VkQueue graphics_queue, VkCommandPool graphics_pool, uint32_t transfer_family, uint32_t graphics_family, GraphicsPipeline* out) {
if(out == NULL) { if(out == NULL) {
return VK_ERROR_VALIDATION_FAILED_EXT; return VK_ERROR_VALIDATION_FAILED_EXT;
} }
@ -1945,18 +1940,36 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro
}; };
// TODO: use bindless descriptors for textures, so each draw command will bind a large buffer that is indexed by object ID to get the address of the texture in GPU memory // TODO: use bindless descriptors for textures, so each draw command will bind a large buffer that is indexed by object ID to get the address of the texture in GPU memory
VkDescriptorSetLayoutBinding mesh_set_bindings[] = { VkDescriptorSetLayoutBinding set_bindings[] = {
{ {
.binding = 0, .binding = 0,
.descriptorCount = 1, .descriptorCount = 1000,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.pImmutableSamplers = 0, .pImmutableSamplers = 0,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
}, },
}; };
(void)mesh_set_bindings;
VkDescriptorBindingFlags set_binding_flags[] = {
VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
};
VkDescriptorSetLayoutBindingFlagsCreateInfo set_flags_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.bindingCount = sizeof(set_bindings)/sizeof(VkDescriptorSetLayoutBinding),
.pBindingFlags = set_binding_flags,
};
VkDescriptorSetLayoutCreateInfo set_info = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pBindings = set_bindings,
.bindingCount = sizeof(set_bindings)/sizeof(VkDescriptorSetLayoutBinding),
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.pNext = &set_flags_info,
};
GraphicsPipelineInfo pipeline_info = { GraphicsPipelineInfo pipeline_info = {
.descriptor_info = set_info,
.shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo), .shader_stages_count = sizeof(shader_stages)/sizeof(VkPipelineShaderStageCreateInfo),
.shader_stages = shader_stages, .shader_stages = shader_stages,
.scene_layout = scene_layout, .scene_layout = scene_layout,
@ -1972,7 +1985,92 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro
return result; return result;
} }
return create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out); result = create_graphics_pipeline(device, extent, render_pass, pipeline_info, max_frames_in_flight, out);
if(result != VK_SUCCESS) {
return result;
}
GPUPage* tex_memory = NULL;
result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &tex_memory);
if(result != VK_SUCCESS) {
return result;
}
VkExtent2D texture_size = {
.width = 10,
.height = 10,
};
(void)texture_size;
struct __attribute__((__packed__)) texel {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
struct texel WHT = {255, 255, 255, 255};
struct texel BLK = {0, 0, 0, 255};
struct texel RED = {255, 0, 0, 255};
struct texel GRN = {0, 255, 0, 255};
struct texel BLU = {0, 0, 255, 255};
struct texel texture_data[100] = {
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
};
(void)texture_data;
GPUPage* texture_memory = NULL;
result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT, 0, &texture_memory);
if(result != VK_SUCCESS) {
return result;
}
GPUPage* staging_memory = NULL;
result = gpu_page_allocate(device, memories, 100000, 0xFFFFFFFF, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 0, &staging_memory);
if(result != VK_SUCCESS) {
return result;
}
GPUBuffer staging = {0};
result = gpu_buffer_malloc(device, staging_memory, 100000, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &staging);
if(result != VK_SUCCESS) {
return result;
}
Texture test_texture = load_texture(device, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data, transfer_family, graphics_family);
for(uint32_t i = 0; i < out->max_frames_in_flight; i++) {
VkDescriptorImageInfo image_info = {
.sampler = test_texture.sampler,
.imageView = test_texture.view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet descriptor_write = {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = out->descriptors[i],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.pBufferInfo = 0,
.pImageInfo = &image_info,
.pTexelBufferView = 0,
};
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0);
}
return VK_SUCCESS;
} }
VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer destination, void* data, VkDeviceSize size, VkDeviceSize offset, VkCommandPool pool, VkQueue queue) { VkResult command_copy_to_buffer(VkDevice device, GPUBuffer staging, VkBuffer destination, void* data, VkDeviceSize size, VkDeviceSize offset, VkCommandPool pool, VkQueue queue) {
@ -2809,64 +2907,6 @@ Object create_texture_mesh_object(GraphicsPipeline* texture_mesh_pipeline, VkPhy
return zero; return zero;
} }
VkExtent2D texture_size = {
.width = 10,
.height = 10,
};
(void)texture_size;
struct __attribute__((__packed__)) texel {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
struct texel WHT = {255, 255, 255, 255};
struct texel BLK = {0, 0, 0, 255};
struct texel RED = {255, 0, 0, 255};
struct texel GRN = {0, 255, 0, 255};
struct texel BLU = {0, 0, 255, 255};
struct texel texture_data[100] = {
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, WHT,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK,
};
(void)texture_data;
/*
Texture test_texture = load_texture(device, mesh_memory, transfer_buffer, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data, transfer_family, graphics_family);
for(uint32_t i = 0; i < max_frames_in_flight; i++) {
VkDescriptorImageInfo image_info = {
.sampler = test_texture.sampler,
.imageView = test_texture.view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
};
VkWriteDescriptorSet descriptor_write = {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = sets[i],
.dstBinding = 0,
.dstArrayElement = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.pBufferInfo = 0,
.pImageInfo = &image_info,
.pTexelBufferView = 0,
};
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0);
}*/ // TODO: bindless textures
return object; return object;
} }
@ -2878,7 +2918,7 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) {
GraphicsPipeline simple_mesh_pipeline = {0}; GraphicsPipeline simple_mesh_pipeline = {0};
GraphicsPipeline texture_mesh_pipeline = {0}; GraphicsPipeline texture_mesh_pipeline = {0};
VkResult result = create_simple_mesh_pipeline(context->device, context->memories, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight, &simple_mesh_pipeline); VkResult result = create_simple_mesh_pipeline(context->device, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight, &simple_mesh_pipeline);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
fprintf(stderr, "failed to create simple mesh material: %s\n", string_VkResult(result)); fprintf(stderr, "failed to create simple mesh material: %s\n", string_VkResult(result));
return; return;
@ -2890,7 +2930,7 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) {
return; return;
} }
result = create_texture_mesh_pipeline(context->device, context->memories, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight, &texture_mesh_pipeline); result = create_texture_mesh_pipeline(context->device, context->memories, context->swapchain_extent, context->render_pass, scene.descriptor_layout, context->max_frames_in_flight, context->transfer_command_pool, context->queues.transfer, context->queues.graphics, context->extra_graphics_pool, context->queue_indices.transfer_family, context->queue_indices.graphics_index, &texture_mesh_pipeline);
if(result != VK_SUCCESS) { if(result != VK_SUCCESS) {
fprintf(stderr, "failed to create texture mesh material\n"); fprintf(stderr, "failed to create texture mesh material\n");
return; return;
@ -2918,10 +2958,12 @@ void main_loop(PlyMesh ply_mesh, GLFWwindow* window, VulkanContext* context) {
return; return;
} }
mat4* tmp = memory->ptr + buffer.memory->offset; mat4* model_1 = memory->ptr + buffer.memory->offset;
glm_mat4_identity(*tmp); mat4* model_2 = memory->ptr + buffer.memory->offset + sizeof(mat4);
vec3 scale = {2.0f, 2.0f, 2.0f}; glm_mat4_identity(*model_1);
glm_scale(*tmp, scale); glm_translate_x(*model_1, 1.0f);
glm_mat4_identity(*model_2);
glm_translate_x(*model_2, -1.0f);
VkBufferDeviceAddressInfo addr_info = { VkBufferDeviceAddressInfo addr_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,