New pipeline and set layouts design.

Pipeline layout consists of two identical descriptor sets.
Each descriptor set defines single descriptor of combined image sampler type.
This commit is contained in:
Artem Kharytoniuk 2017-04-13 19:37:11 +03:00
parent fb74befd75
commit 8c5fc8f674
14 changed files with 132 additions and 219 deletions

View File

@ -1,7 +1,7 @@
#version 450 #version 450
layout(binding = 0) uniform sampler2D texture0; layout(set = 0, binding = 0) uniform sampler2D texture0;
layout(binding = 1) uniform sampler2D texture1; layout(set = 1, binding = 0) uniform sampler2D texture1;
layout(location = 0) in vec4 frag_color; layout(location = 0) in vec4 frag_color;
layout(location = 1) in vec2 frag_tex_coord0; layout(location = 1) in vec2 frag_tex_coord0;

View File

@ -1,7 +1,7 @@
#version 450 #version 450
layout(binding = 0) uniform sampler2D texture0; layout(set = 0, binding = 0) uniform sampler2D texture0;
layout(binding = 1) uniform sampler2D texture1; layout(set = 1, binding = 0) uniform sampler2D texture1;
layout(location = 0) in vec4 frag_color; layout(location = 0) in vec4 frag_color;
layout(location = 1) in vec2 frag_tex_coord0; layout(location = 1) in vec2 frag_tex_coord0;

View File

@ -1,6 +1,6 @@
#version 450 #version 450
layout(binding = 0) uniform sampler2D texture0; layout(set = 0, binding = 0) uniform sampler2D texture0;
layout(location = 0) in vec4 frag_color; layout(location = 0) in vec4 frag_color;
layout(location = 1) in vec2 frag_tex_coord; layout(location = 1) in vec2 frag_tex_coord;

View File

@ -24,8 +24,8 @@ unsigned char multi_texture_add_frag_spv[] = {
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,

View File

@ -23,8 +23,8 @@ unsigned char multi_texture_mul_frag_spv[] = {
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00,

View File

@ -735,7 +735,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
std::array<VkWriteDescriptorSet, 1> descriptor_writes; std::array<VkWriteDescriptorSet, 1> descriptor_writes;
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_writes[0].dstSet = vulkan_demo->image_descriptor_sets[ tr.scratchImage[client] ]; descriptor_writes[0].dstSet = tr.scratchImage[client]->vk_descriptor_set;
descriptor_writes[0].dstBinding = 0; descriptor_writes[0].dstBinding = 0;
descriptor_writes[0].dstArrayElement = 0; descriptor_writes[0].dstArrayElement = 0;
descriptor_writes[0].descriptorCount = 1; descriptor_writes[0].descriptorCount = 1;

View File

@ -779,7 +779,7 @@ image_t *R_CreateImage( const char *name, const byte *pic, int width, int height
// VULKAN // VULKAN
image->vk_image = vulkan_demo->create_texture(pic, 4, width, height, image->vk_image_view); image->vk_image = vulkan_demo->create_texture(pic, 4, width, height, image->vk_image_view);
vulkan_demo->create_image_descriptor_set(image); image->vk_descriptor_set = vk_create_descriptor_set(image->vk_image_view);
return image; return image;
} }

View File

@ -108,6 +108,10 @@ typedef struct image_s {
VkImageView vk_image_view = VK_NULL_HANDLE; VkImageView vk_image_view = VK_NULL_HANDLE;
Vk_Staging_Buffer vk_staging_buffer; // for cinematic images Vk_Staging_Buffer vk_staging_buffer; // for cinematic images
// One to one correspondence between images and descriptor sets.
// We update descriptor set during image initialization and then never touch it again (except for cinematic images).
VkDescriptorSet vk_descriptor_set;
struct image_s* next; struct image_s* next;
} image_t; } image_t;

View File

@ -421,6 +421,72 @@ bool vk_initialize(HWND hwnd) {
} }
} }
//
// Descriptor pool.
//
{
VkDescriptorPoolSize pool_size;
pool_size.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
pool_size.descriptorCount = MAX_DRAWIMAGES;
VkDescriptorPoolCreateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
desc.pNext = nullptr;
desc.flags = 0;
desc.maxSets = MAX_DRAWIMAGES;
desc.poolSizeCount = 1;
desc.pPoolSizes = &pool_size;
VkResult result = vkCreateDescriptorPool(vk.device, &desc, nullptr, &vk.descriptor_pool);
check_vk_result(result, "vkCreateDescriptorPool");
}
//
// Descriptor set layout.
//
{
VkDescriptorSetLayoutBinding descriptor_binding;
descriptor_binding.binding = 0;
descriptor_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_binding.descriptorCount = 1;
descriptor_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
descriptor_binding.pImmutableSamplers = nullptr;
VkDescriptorSetLayoutCreateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
desc.pNext = nullptr;
desc.flags = 0;
desc.bindingCount = 1;
desc.pBindings = &descriptor_binding;
VkResult result = vkCreateDescriptorSetLayout(vk.device, &desc, nullptr, &vk.set_layout);
check_vk_result(result, "vkCreateDescriptorSetLayout");
}
//
// Pipeline layout.
//
{
VkPushConstantRange push_range;
push_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
push_range.offset = 0;
push_range.size = 64; // sizeof(float[16])
VkDescriptorSetLayout set_layouts[2] = {vk.set_layout, vk.set_layout};
VkPipelineLayoutCreateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
desc.pNext = nullptr;
desc.flags = 0;
desc.setLayoutCount = 2;
desc.pSetLayouts = set_layouts;
desc.pushConstantRangeCount = 1;
desc.pPushConstantRanges = &push_range;
VkResult result = vkCreatePipelineLayout(vk.device, &desc, nullptr, &vk.pipeline_layout);
check_vk_result(result, "vkCreatePipelineLayout");
}
} catch (const std::exception&) { } catch (const std::exception&) {
return false; return false;
} }
@ -449,6 +515,10 @@ void vk_deinitialize() {
vkDestroyImageView(g.device, g.swapchain_image_views[i], nullptr); vkDestroyImageView(g.device, g.swapchain_image_views[i], nullptr);
} }
vkDestroyDescriptorPool(vk.device, vk.descriptor_pool, nullptr);
vkDestroyDescriptorSetLayout(vk.device, vk.set_layout, nullptr);
vkDestroyPipelineLayout(vk.device, vk.pipeline_layout, nullptr);
vkDestroySwapchainKHR(g.device, g.swapchain, nullptr); vkDestroySwapchainKHR(g.device, g.swapchain, nullptr);
vkDestroyDevice(g.device, nullptr); vkDestroyDevice(g.device, nullptr);
vkDestroySurfaceKHR(g.instance, g.surface, nullptr); vkDestroySurfaceKHR(g.instance, g.surface, nullptr);
@ -800,7 +870,7 @@ static VkPipeline create_pipeline(const Vk_Pipeline_Desc& desc) {
create_info.pDepthStencilState = &depth_stencil_state; create_info.pDepthStencilState = &depth_stencil_state;
create_info.pColorBlendState = &blend_state; create_info.pColorBlendState = &blend_state;
create_info.pDynamicState = &dynamic_state; create_info.pDynamicState = &dynamic_state;
create_info.layout = vulkan_demo->pipeline_layout; create_info.layout = vk.pipeline_layout;
create_info.renderPass = vk.render_pass; create_info.renderPass = vk.render_pass;
create_info.subpass = 0; create_info.subpass = 0;
create_info.basePipelineHandle = VK_NULL_HANDLE; create_info.basePipelineHandle = VK_NULL_HANDLE;
@ -859,6 +929,39 @@ static void vk_destroy_pipelines() {
pipeline_create_time = 0.0f; pipeline_create_time = 0.0f;
} }
VkDescriptorSet vk_create_descriptor_set(VkImageView image_view) {
VkDescriptorSetAllocateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
desc.pNext = nullptr;
desc.descriptorPool = vk.descriptor_pool;
desc.descriptorSetCount = 1;
desc.pSetLayouts = &vk.set_layout;
VkDescriptorSet set;
VkResult result = vkAllocateDescriptorSets(vk.device, &desc, &set);
check_vk_result(result, "vkAllocateDescriptorSets");
VkDescriptorImageInfo image_info;
image_info.sampler = vulkan_demo->texture_image_sampler;
image_info.imageView = image_view;
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
std::array<VkWriteDescriptorSet, 1> descriptor_writes;
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_writes[0].dstSet = set;
descriptor_writes[0].dstBinding = 0;
descriptor_writes[0].dstArrayElement = 0;
descriptor_writes[0].descriptorCount = 1;
descriptor_writes[0].pNext = nullptr;
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_writes[0].pImageInfo = &image_info;
descriptor_writes[0].pBufferInfo = nullptr;
descriptor_writes[0].pTexelBufferView = nullptr;
vkUpdateDescriptorSets(vk.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr);
return set;
}
void vk_destroy_resources() { void vk_destroy_resources() {
vkDeviceWaitIdle(vk.device); vkDeviceWaitIdle(vk.device);
vk_destroy_pipelines(); vk_destroy_pipelines();

View File

@ -52,6 +52,8 @@ struct Vk_Pipeline_Desc {
VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc); VkPipeline vk_find_pipeline(const Vk_Pipeline_Desc& desc);
VkDescriptorSet vk_create_descriptor_set(VkImageView image_view);
// Vertex formats // Vertex formats
struct Vk_Vertex { struct Vk_Vertex {
vec3_t pos; vec3_t pos;
@ -159,6 +161,10 @@ struct Vulkan_Instance {
VkRenderPass render_pass = VK_NULL_HANDLE; VkRenderPass render_pass = VK_NULL_HANDLE;
VkFramebuffer framebuffers[MAX_SWAPCHAIN_IMAGES]; VkFramebuffer framebuffers[MAX_SWAPCHAIN_IMAGES];
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
VkDescriptorSetLayout set_layout = VK_NULL_HANDLE;
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
}; };
const int MAX_VK_PIPELINES = 1024; const int MAX_VK_PIPELINES = 1024;

View File

@ -32,32 +32,11 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height)
VkResult result = vkCreateFence(vk.device, &fence_desc, nullptr, &rendering_finished_fence); VkResult result = vkCreateFence(vk.device, &fence_desc, nullptr, &rendering_finished_fence);
check_vk_result(result, "vkCreateFence"); check_vk_result(result, "vkCreateFence");
create_descriptor_pool();
create_texture_sampler(); create_texture_sampler();
create_descriptor_set_layout();
create_pipeline_layout();
upload_geometry(); upload_geometry();
} }
void Vulkan_Demo::create_descriptor_pool() {
std::array<VkDescriptorPoolSize, 1> pool_sizes;
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
pool_sizes[0].descriptorCount = 1024;
VkDescriptorPoolCreateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
desc.pNext = nullptr;
desc.flags = 0;
desc.maxSets = 1024;
desc.poolSizeCount = static_cast<uint32_t>(pool_sizes.size());
desc.pPoolSizes = pool_sizes.data();
descriptor_pool = get_resource_manager()->create_descriptor_pool(desc);
}
VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel, int image_width, int image_height, VkImageView& image_view) { VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel, int image_width, int image_height, VkImageView& image_view) {
VkImage staging_image = create_staging_texture(image_width, image_height, VkImage staging_image = create_staging_texture(image_width, image_height,
bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM, pixels, bytes_per_pixel); bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM, pixels, bytes_per_pixel);
@ -131,133 +110,6 @@ void Vulkan_Demo::create_texture_sampler() {
texture_image_sampler = get_resource_manager()->create_sampler(desc); texture_image_sampler = get_resource_manager()->create_sampler(desc);
} }
void Vulkan_Demo::create_descriptor_set_layout() {
std::array<VkDescriptorSetLayoutBinding, 2> descriptor_bindings;
descriptor_bindings[0].binding = 0;
descriptor_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_bindings[0].descriptorCount = 1;
descriptor_bindings[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
descriptor_bindings[0].pImmutableSamplers = nullptr;
descriptor_bindings[1].binding = 1;
descriptor_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_bindings[1].descriptorCount = 1;
descriptor_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
descriptor_bindings[1].pImmutableSamplers = nullptr;
VkDescriptorSetLayoutCreateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
desc.pNext = nullptr;
desc.flags = 0;
desc.bindingCount = static_cast<uint32_t>(descriptor_bindings.size());
desc.pBindings = descriptor_bindings.data();
descriptor_set_layout = get_resource_manager()->create_descriptor_set_layout(desc);
}
void Vulkan_Demo::create_image_descriptor_set(const image_t* image) {
VkDescriptorSetAllocateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
desc.pNext = nullptr;
desc.descriptorPool = descriptor_pool;
desc.descriptorSetCount = 1;
desc.pSetLayouts = &descriptor_set_layout;
VkDescriptorSet set;
VkResult result = vkAllocateDescriptorSets(vk.device, &desc, &set);
check_vk_result(result, "vkAllocateDescriptorSets");
VkDescriptorImageInfo image_info;
image_info.sampler = texture_image_sampler;
image_info.imageView = image->vk_image_view;
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
std::array<VkWriteDescriptorSet, 1> descriptor_writes;
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_writes[0].dstSet = set;
descriptor_writes[0].dstBinding = 0;
descriptor_writes[0].dstArrayElement = 0;
descriptor_writes[0].descriptorCount = 1;
descriptor_writes[0].pNext = nullptr;
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_writes[0].pImageInfo = &image_info;
descriptor_writes[0].pBufferInfo = nullptr;
descriptor_writes[0].pTexelBufferView = nullptr;
vkUpdateDescriptorSets(vk.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr);
image_descriptor_sets[image] = set;
}
void Vulkan_Demo::create_multitexture_descriptor_set(const image_t* image, const image_t* image2) {
VkDescriptorSetAllocateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
desc.pNext = nullptr;
desc.descriptorPool = descriptor_pool;
desc.descriptorSetCount = 1;
desc.pSetLayouts = &descriptor_set_layout;
VkDescriptorSet set;
VkResult result = vkAllocateDescriptorSets(vk.device, &desc, &set);
check_vk_result(result, "vkAllocateDescriptorSets");
VkDescriptorImageInfo image_info[2];
image_info[0].sampler = texture_image_sampler;
image_info[0].imageView = image->vk_image_view;
image_info[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
image_info[1].sampler = texture_image_sampler;
image_info[1].imageView = image2->vk_image_view;
image_info[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
std::array<VkWriteDescriptorSet, 2> descriptor_writes;
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_writes[0].dstSet = set;
descriptor_writes[0].dstBinding = 0;
descriptor_writes[0].dstArrayElement = 0;
descriptor_writes[0].descriptorCount = 1;
descriptor_writes[0].pNext = nullptr;
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_writes[0].pImageInfo = &image_info[0];
descriptor_writes[0].pBufferInfo = nullptr;
descriptor_writes[0].pTexelBufferView = nullptr;
descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_writes[1].dstSet = set;
descriptor_writes[1].dstBinding = 1;
descriptor_writes[1].dstArrayElement = 0;
descriptor_writes[1].descriptorCount = 1;
descriptor_writes[1].pNext = nullptr;
descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_writes[1].pImageInfo = &image_info[1];
descriptor_writes[1].pBufferInfo = nullptr;
descriptor_writes[1].pTexelBufferView = nullptr;
vkUpdateDescriptorSets(vk.device, (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr);
auto images = std::make_pair(image, image2);
multitexture_descriptor_sets[images] = set;
}
void Vulkan_Demo::create_pipeline_layout() {
VkPushConstantRange push_range;
push_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
push_range.offset = 0;
push_range.size = 64;
VkPipelineLayoutCreateInfo desc;
desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
desc.pNext = nullptr;
desc.flags = 0;
desc.setLayoutCount = 1;
desc.pSetLayouts = &descriptor_set_layout;
desc.pushConstantRangeCount = 1;
desc.pPushConstantRanges = &push_range;
VkResult result = vkCreatePipelineLayout(vk.device, &desc, nullptr, &pipeline_layout);
check_vk_result(result, "vkCreatePipelineLayout");
}
void Vulkan_Demo::upload_geometry() { void Vulkan_Demo::upload_geometry() {
{ {
@ -360,14 +212,13 @@ void Vulkan_Demo::render_tess(const shaderStage_t* stage) {
vkCmdBindVertexBuffers(vk.command_buffer, 0, 1, &tess_vertex_buffer, &tess_vertex_buffer_offset); vkCmdBindVertexBuffers(vk.command_buffer, 0, 1, &tess_vertex_buffer, &tess_vertex_buffer_offset);
vkCmdBindIndexBuffer(vk.command_buffer, tess_index_buffer, tess_index_buffer_offset, VK_INDEX_TYPE_UINT32); vkCmdBindIndexBuffer(vk.command_buffer, tess_index_buffer, tess_index_buffer_offset, VK_INDEX_TYPE_UINT32);
image_t* image = glState.vk_current_images[0]; VkDescriptorSet set = glState.vk_current_images[0]->vk_descriptor_set;
VkDescriptorSet set = image_descriptor_sets[image];
float mvp[16]; float mvp[16];
vk_get_mvp_transform(mvp); vk_get_mvp_transform(mvp);
vkCmdPushConstants(vk.command_buffer, pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, mvp); vkCmdPushConstants(vk.command_buffer, vk.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, mvp);
vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &set, 0, nullptr); vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk.pipeline_layout, 0, 1, &set, 0, nullptr);
vkCmdBindPipeline(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stage->vk_pipeline); vkCmdBindPipeline(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stage->vk_pipeline);
@ -431,19 +282,14 @@ void Vulkan_Demo::render_tess_multi(const shaderStage_t* stage) {
image_t* image = glState.vk_current_images[0]; image_t* image = glState.vk_current_images[0];
image_t* image2 = glState.vk_current_images[1]; image_t* image2 = glState.vk_current_images[1];
auto images = std::make_pair(image, image2);
auto it = multitexture_descriptor_sets.find(images); VkDescriptorSet sets[2] = { image->vk_descriptor_set, image2->vk_descriptor_set };
if (it == multitexture_descriptor_sets.cend()) {
create_multitexture_descriptor_set(image, image2);
it = multitexture_descriptor_sets.find(images);
}
auto set = it->second;
float mvp[16]; float mvp[16];
vk_get_mvp_transform(mvp); vk_get_mvp_transform(mvp);
vkCmdPushConstants(vk.command_buffer, pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, mvp); vkCmdPushConstants(vk.command_buffer, vk.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0, 64, mvp);
vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &set, 0, nullptr); vkCmdBindDescriptorSets(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vk.pipeline_layout, 0, 2, sets, 0, nullptr);
vkCmdBindPipeline(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stage->vk_pipeline); vkCmdBindPipeline(vk.command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stage->vk_pipeline);

View File

@ -18,16 +18,9 @@ public:
void render_tess_multi(const shaderStage_t* stage); void render_tess_multi(const shaderStage_t* stage);
public: public:
void create_descriptor_pool();
VkImage create_texture(const uint8_t* pixels, int bytes_per_pixel, int width, int height, VkImageView& image_view); VkImage create_texture(const uint8_t* pixels, int bytes_per_pixel, int width, int height, VkImageView& image_view);
void create_texture_sampler(); void create_texture_sampler();
void create_descriptor_set_layout();
void create_image_descriptor_set(const image_t* image);
void create_multitexture_descriptor_set(const image_t* image, const image_t* image2);
void create_pipeline_layout();
void upload_geometry(); void upload_geometry();
public: public:
@ -38,22 +31,13 @@ public:
VkSemaphore rendering_finished = VK_NULL_HANDLE; VkSemaphore rendering_finished = VK_NULL_HANDLE;
VkFence rendering_finished_fence = VK_NULL_HANDLE; VkFence rendering_finished_fence = VK_NULL_HANDLE;
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
VkSampler texture_image_sampler = VK_NULL_HANDLE; VkSampler texture_image_sampler = VK_NULL_HANDLE;
VkDescriptorSetLayout descriptor_set_layout = VK_NULL_HANDLE;
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
VkBuffer tess_vertex_buffer = VK_NULL_HANDLE; VkBuffer tess_vertex_buffer = VK_NULL_HANDLE;
VkDeviceMemory tess_vertex_buffer_memory = VK_NULL_HANDLE; VkDeviceMemory tess_vertex_buffer_memory = VK_NULL_HANDLE;
VkDeviceSize tess_vertex_buffer_offset = 0; VkDeviceSize tess_vertex_buffer_offset = 0;
VkBuffer tess_index_buffer = VK_NULL_HANDLE; VkBuffer tess_index_buffer = VK_NULL_HANDLE;
VkDeviceMemory tess_index_buffer_memory = VK_NULL_HANDLE; VkDeviceMemory tess_index_buffer_memory = VK_NULL_HANDLE;
VkDeviceSize tess_index_buffer_offset = 0; VkDeviceSize tess_index_buffer_offset = 0;
std::map<const image_t*, VkDescriptorSet> image_descriptor_sets; // quick UI prototyping
std::map<std::pair<const image_t*, const image_t*>, VkDescriptorSet> multitexture_descriptor_sets;
uint32_t swapchain_image_index = -1; uint32_t swapchain_image_index = -1;
}; };

View File

@ -16,11 +16,6 @@ void Resource_Manager::release_resources() {
} }
semaphores.clear(); semaphores.clear();
for (auto descriptor_pool : descriptor_pools) {
vkDestroyDescriptorPool(device, descriptor_pool, nullptr);
}
descriptor_pools.clear();
for (auto buffer : buffers) { for (auto buffer : buffers) {
vkDestroyBuffer(device, buffer, nullptr); vkDestroyBuffer(device, buffer, nullptr);
} }
@ -30,11 +25,6 @@ void Resource_Manager::release_resources() {
vkDestroySampler(device, sampler, nullptr); vkDestroySampler(device, sampler, nullptr);
} }
samplers.clear(); samplers.clear();
for (auto descriptor_set_layout : descriptor_set_layouts) {
vkDestroyDescriptorSetLayout(device, descriptor_set_layout, nullptr);
}
descriptor_set_layouts.clear();
} }
VkSemaphore Resource_Manager::create_semaphore() { VkSemaphore Resource_Manager::create_semaphore() {
@ -50,14 +40,6 @@ VkSemaphore Resource_Manager::create_semaphore() {
return semaphore; return semaphore;
} }
VkDescriptorPool Resource_Manager::create_descriptor_pool(const VkDescriptorPoolCreateInfo& desc) {
VkDescriptorPool descriptor_pool;
VkResult result = vkCreateDescriptorPool(device, &desc, nullptr, &descriptor_pool);
check_vk_result(result, "vkCreateDescriptorPool");
descriptor_pools.push_back(descriptor_pool);
return descriptor_pool;
}
VkBuffer Resource_Manager::create_buffer(const VkBufferCreateInfo& desc) { VkBuffer Resource_Manager::create_buffer(const VkBufferCreateInfo& desc) {
VkBuffer buffer; VkBuffer buffer;
VkResult result = vkCreateBuffer(device, &desc, nullptr, &buffer); VkResult result = vkCreateBuffer(device, &desc, nullptr, &buffer);
@ -73,11 +55,3 @@ VkSampler Resource_Manager::create_sampler(const VkSamplerCreateInfo& desc) {
samplers.push_back(sampler); samplers.push_back(sampler);
return sampler; return sampler;
} }
VkDescriptorSetLayout Resource_Manager::create_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo& desc) {
VkDescriptorSetLayout descriptor_set_layout;
VkResult result = vkCreateDescriptorSetLayout(device, &desc, nullptr, &descriptor_set_layout);
check_vk_result(result, "vkCreateDescriptorSetLayout");
descriptor_set_layouts.push_back(descriptor_set_layout);
return descriptor_set_layout;
}

View File

@ -9,18 +9,14 @@ public:
void release_resources(); void release_resources();
VkSemaphore create_semaphore(); VkSemaphore create_semaphore();
VkDescriptorPool create_descriptor_pool(const VkDescriptorPoolCreateInfo& desc);
VkBuffer create_buffer(const VkBufferCreateInfo& desc); VkBuffer create_buffer(const VkBufferCreateInfo& desc);
VkSampler create_sampler(const VkSamplerCreateInfo& desc); VkSampler create_sampler(const VkSamplerCreateInfo& desc);
VkDescriptorSetLayout create_descriptor_set_layout(const VkDescriptorSetLayoutCreateInfo& desc);
private: private:
VkDevice device = VK_NULL_HANDLE; VkDevice device = VK_NULL_HANDLE;
std::vector<VkSemaphore> semaphores; std::vector<VkSemaphore> semaphores;
std::vector<VkDescriptorPool> descriptor_pools;
std::vector<VkBuffer> buffers; std::vector<VkBuffer> buffers;
std::vector<VkSampler> samplers; std::vector<VkSampler> samplers;
std::vector<VkDescriptorSetLayout> descriptor_set_layouts;
}; };
Resource_Manager* get_resource_manager(); Resource_Manager* get_resource_manager();