diff --git a/shader_src/texture.frag b/shader_src/texture.frag index 1d6f919..b73684d 100644 --- a/shader_src/texture.frag +++ b/shader_src/texture.frag @@ -7,5 +7,5 @@ layout(location = 0) out vec4 outColor; layout(set = 1, binding = 0) uniform sampler2D texSamplers[1000]; void main() { - outColor = texture(texSamplers[1], fragTex); + outColor = texture(texSamplers[0], fragTex); } diff --git a/src/main.c b/src/main.c index 0b085ae..1673feb 100644 --- a/src/main.c +++ b/src/main.c @@ -1066,126 +1066,6 @@ VkResult command_copy_buffer_to_image(VkDevice device, VkCommandPool transfer_po return command_end_single(device, command_buffer, transfer_pool, transfer_queue); } -Texture load_texture(VkDevice device, GPUPage* page, GPUBuffer staging, VkCommandPool transfer_pool, Queue transfer_queue, VkCommandPool graphics_pool, Queue graphics_queue, VkExtent2D size, VkFormat format, void* image_data){ - Texture ret = { - .image.page = NULL, - .image.memory = NULL, - .image.handle = VK_NULL_HANDLE, - .view = VK_NULL_HANDLE, - }; - - VkExtent3D full_extent = { - .width = size.width, - .height = size.height, - .depth = 1, - }; - - VkImageCreateInfo info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .imageType = VK_IMAGE_TYPE_2D, - .extent = full_extent, - .mipLevels = 1, - .arrayLayers = 1, - .format = format, - .tiling = VK_IMAGE_TILING_OPTIMAL, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .samples = VK_SAMPLE_COUNT_1_BIT, - .flags = 0, - }; - - GPUImage image = {0}; - VkResult result = gpu_image_malloc(device, page, &info, &image); - if(result != VK_SUCCESS) { - return ret; - } - - memcpy(staging.page->ptr + staging.memory->offset, image_data, image.memory->size); - - result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.handle, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, transfer_queue.family, transfer_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); - if(result != VK_SUCCESS) { - gpu_image_free(device, image); - return ret; - } - - result = command_copy_buffer_to_image(device, transfer_pool, transfer_queue, full_extent, staging.handle, image.handle); - if(result != VK_SUCCESS) { - gpu_image_free(device, image); - return ret; - } - - result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.handle, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_queue.family, graphics_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); - if(result != VK_SUCCESS) { - gpu_image_free(device, image); - return ret; - } - - result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.handle, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_queue.family, graphics_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); - if(result != VK_SUCCESS) { - gpu_image_free(device, image); - return ret; - } - - VkImageView view; - VkImageViewCreateInfo view_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = image.handle, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .components = { - .a = VK_COMPONENT_SWIZZLE_IDENTITY, - .b = VK_COMPONENT_SWIZZLE_IDENTITY, - .g = VK_COMPONENT_SWIZZLE_IDENTITY, - .r = VK_COMPONENT_SWIZZLE_IDENTITY, - }, - .format = format, - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .layerCount = 1, - .levelCount = 1, - .baseArrayLayer = 0, - .baseMipLevel = 0, - }, - }; - - result = vkCreateImageView(device, &view_info, 0, &view); - if(result != VK_SUCCESS) { - gpu_image_free(device, image); - return ret; - } - - VkSampler sampler; - VkSamplerCreateInfo sampler_info = { - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .magFilter = VK_FILTER_NEAREST, - .minFilter = VK_FILTER_NEAREST, - .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT, - .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT, - .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, - .anisotropyEnable = VK_FALSE, - .maxAnisotropy = 2.0f, - .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK, - .unnormalizedCoordinates = VK_FALSE, - .compareEnable = VK_FALSE, - .compareOp = VK_COMPARE_OP_ALWAYS, - .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR, - .mipLodBias = 0.0f, - .minLod = 0.0f, - .maxLod = 0.0f, - }; - - result = vkCreateSampler(device, &sampler_info, 0, &sampler); - if(result != VK_SUCCESS) { - gpu_image_free(device, image); - vkDestroyImageView(device, view, 0); - return ret; - } - - ret.image = image; - ret.view = view; - ret.sampler = sampler; - return ret; -} int create_depth_image(VulkanContext* context) { VkExtent3D depth_extent = { @@ -1581,17 +1461,164 @@ Object create_renderable(Mesh* mesh, GraphicsPipeline* pipeline) { } typedef struct TextureSetStruct { - uint32_t max_images; - Texture* textures; + uint32_t max_images; + Texture** textures; VkDescriptorSet descriptor; VkDescriptorPool pool; } TextureSet; -// TODO -/*VkResult texture_set_add(VkDevice device, GPUPage* page, GPUBuffer staging, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, VkExtent2D size, VkFormat format, void* image_data, uint32_t transfer_family, uint32_t graphics_family) { +VkResult texture_set_add(VkDevice device, TextureSet* set, GPUPage* page, GPUBuffer staging, VkCommandPool transfer_pool, Queue transfer_queue, VkCommandPool graphics_pool, Queue graphics_queue, VkExtent2D size, VkFormat format, void* image_data, uint32_t* index, Texture* texture) { + if(texture == NULL || index == NULL || image_data == NULL || page == NULL || set == NULL) { + return VK_ERROR_VALIDATION_FAILED_EXT; + } + + *index = 0xFFFFFFFF; + for(uint32_t i = 0; i < set->max_images; i++) { + if(set->textures[i] == NULL) { + *index = i; + break; + } + } + + if(*index == 0xFFFFFFFF) { + return VK_ERROR_TOO_MANY_OBJECTS; + } + + VkExtent3D size3d = { + .width = size.width, + .height = size.height, + .depth = 1, + }; + + VkImageCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = VK_IMAGE_TYPE_2D, + .extent = size3d, + .mipLevels = 1, + .arrayLayers = 1, + .format = format, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .samples = VK_SAMPLE_COUNT_1_BIT, + .flags = 0, + .pNext = NULL, + }; + + // Create the image in GPU memory + VkResult result = gpu_image_malloc(device, page, &info, &texture->image); + if(result != VK_SUCCESS) { + return result; + } + + memcpy(staging.page->ptr + staging.memory->offset, image_data, texture->image.memory->size); + + // Transition the image from UNDEFINED to TRANSFER_DST_OPTIMAL + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texture->image.handle, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, transfer_queue.family, transfer_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); + if(result != VK_SUCCESS) { + gpu_image_free(device, texture->image); + return result; + } + + // Copy the image from the staging buffer to the GPU memory + result = command_copy_buffer_to_image(device, transfer_pool, transfer_queue, size3d, staging.handle, texture->image.handle); + if(result != VK_SUCCESS) { + gpu_image_free(device, texture->image); + return result; + } + + // Transition the image from TRANSFER_DST_OPTIMAL to SHADER_READ_ONLY_OPTIMAL in the transfer queue + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, texture->image.handle, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_queue.family, graphics_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); + if(result != VK_SUCCESS) { + gpu_image_free(device, texture->image); + return result; + } + + // Complete the image transition in the graphics queue to transfer ownership + result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, texture->image.handle, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_queue.family, graphics_queue.family, VK_IMAGE_ASPECT_COLOR_BIT); + if(result != VK_SUCCESS) { + gpu_image_free(device, texture->image); + return result; + } + + VkImageViewCreateInfo view_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = texture->image.handle, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .components = { + .a = VK_COMPONENT_SWIZZLE_IDENTITY, + .b = VK_COMPONENT_SWIZZLE_IDENTITY, + .g = VK_COMPONENT_SWIZZLE_IDENTITY, + .r = VK_COMPONENT_SWIZZLE_IDENTITY, + }, + .format = format, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .layerCount = 1, + .levelCount = 1, + .baseArrayLayer = 0, + .baseMipLevel = 0, + }, + }; + + result = vkCreateImageView(device, &view_info, 0, &texture->view); + if(result != VK_SUCCESS) { + gpu_image_free(device, texture->image); + return result; + } + + VkSamplerCreateInfo sampler_info = { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = VK_FILTER_NEAREST, + .minFilter = VK_FILTER_NEAREST, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT, + .anisotropyEnable = VK_FALSE, + .maxAnisotropy = 2.0f, + .borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK, + .unnormalizedCoordinates = VK_FALSE, + .compareEnable = VK_FALSE, + .compareOp = VK_COMPARE_OP_ALWAYS, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR, + .mipLodBias = 0.0f, + .minLod = 0.0f, + .maxLod = 0.0f, + }; + + result = vkCreateSampler(device, &sampler_info, 0, &texture->sampler); + if(result != VK_SUCCESS) { + gpu_image_free(device, texture->image); + vkDestroyImageView(device, texture->view, 0); + return result; + } + + VkDescriptorImageInfo image_info = { + .sampler = texture->sampler, + .imageView = texture->view, + .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + }; + + VkWriteDescriptorSet write_info = { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = set->descriptor, + .dstArrayElement = *index, + .pImageInfo = &image_info, + .dstBinding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorCount = 1, + .pBufferInfo = 0, + .pTexelBufferView = 0, + }; + + vkUpdateDescriptorSets(device, 1, &write_info, 0, 0); + + set->textures[*index] = texture; + return VK_SUCCESS; -}*/ +} VkResult create_texture_set(VkDevice device, VkDescriptorSetLayout layout, uint32_t max_images, TextureSet* out) { if(out == NULL) { @@ -1604,6 +1631,7 @@ VkResult create_texture_set(VkDevice device, VkDescriptorSetLayout layout, uint3 if(out->textures == NULL) { return VK_ERROR_OUT_OF_HOST_MEMORY; } + memset(out->textures, 0x00, sizeof(Texture*)*max_images); VkDescriptorPoolSize sizes[] = { { @@ -2025,8 +2053,8 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro return result; } - TextureSet texture_set = {0}; - result = create_texture_set(device, set_layout, 1000, &texture_set); + TextureSet* texture_set = malloc(sizeof(TextureSet)); + result = create_texture_set(device, set_layout, 1000, texture_set); if(result != VK_SUCCESS) { return result; } @@ -2121,42 +2149,21 @@ VkResult create_texture_mesh_pipeline(VkDevice device, VkPhysicalDeviceMemoryPro return result; } - Texture test_texture_0 = load_texture(device, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data_0); - - Texture test_texture_1 = load_texture(device, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data_1); - - VkDescriptorImageInfo image_info_0 = { - .sampler = test_texture_0.sampler, - .imageView = test_texture_0.view, - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }; - - VkDescriptorImageInfo image_info_1 = { - .sampler = test_texture_1.sampler, - .imageView = test_texture_1.view, - .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - }; - - VkWriteDescriptorSet descriptor_write = { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = texture_set.descriptor, - .dstBinding = 0, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = 1, - .pBufferInfo = 0, - .pTexelBufferView = 0, - }; + uint32_t texture_index = 0; + Texture* test_texture_0 = malloc(sizeof(Texture)); + Texture* test_texture_1 = malloc(sizeof(Texture)); + result = texture_set_add(device, texture_set, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data_0, &texture_index, test_texture_0); + if(result != VK_SUCCESS) { + return result; + } - descriptor_write.pImageInfo = &image_info_0; - descriptor_write.dstArrayElement = 0; - vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0); - - descriptor_write.pImageInfo = &image_info_1; - descriptor_write.dstArrayElement = 1; - vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, 0); + result = texture_set_add(device, texture_set, texture_memory, staging, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data_1, &texture_index, test_texture_1); + if(result != VK_SUCCESS) { + return result; + } for(uint32_t i = 0; i < out->max_frames_in_flight; i++) { - out->descriptors[i] = texture_set.descriptor; + out->descriptors[i] = texture_set->descriptor; } return VK_SUCCESS;