Browse Source

Create samplers and use them in shaders.

master
Amber 2 years ago
parent
commit
cc580c3edd
  1. 5
      src/fragment_simple.frag
  2. 138
      src/main.c
  3. 3
      src/vertex_simple.vert

5
src/fragment_simple.frag

@ -1,9 +1,12 @@ @@ -1,9 +1,12 @@
#version 450
layout(binding = 1) uniform sampler2D texSampler;
layout(location = 0) in vec3 fragColor;
layout(location = 1) in vec2 fragTexCoord;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0);
outColor = texture(texSampler, fragTexCoord);
}

138
src/main.c

@ -93,6 +93,8 @@ typedef struct ApplicationState { @@ -93,6 +93,8 @@ typedef struct ApplicationState {
VkImage texture_image;
VkDeviceMemory texture_image_memory;
VkImageView texture_image_view;
VkSampler texture_sampler;
} ApplicationState;
typedef struct QueueFamilyIndices {
@ -105,13 +107,14 @@ typedef struct QueueFamilyIndices { @@ -105,13 +107,14 @@ typedef struct QueueFamilyIndices {
typedef struct Vertex {
vec2 position;
vec3 color;
vec2 tex_coord;
} Vertex;
const Vertex vertices[] = {
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}},
{{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}},
{{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}},
{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}}
{{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}},
{{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
{{0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}, {0.0f, 1.0f}},
{{-0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}
};
const uint16_t indices[] = {
@ -335,6 +338,13 @@ void pick_physical_device(ApplicationState* state) { @@ -335,6 +338,13 @@ void pick_physical_device(ApplicationState* state) {
if (families.graphics_present && families.present_present && extensions_supported(state, device) &&
//we only care that at least one mode and one format exist
details.num_modes != 0 && details.num_formats != 0) {
VkPhysicalDeviceFeatures supportedFeatures;
vkGetPhysicalDeviceFeatures(device, &supportedFeatures);
if (!supportedFeatures.samplerAnisotropy) {
free (details.present_modes);
free (details.formats);
continue;
}
state->details = details;
printf("graphics queue at %x, present queue at %x\n", families.graphics_queue, families.present_queue);
break;
@ -386,6 +396,7 @@ void create_logical_device(ApplicationState* state) {; @@ -386,6 +396,7 @@ void create_logical_device(ApplicationState* state) {;
//for now we won't use any features
VkPhysicalDeviceFeatures device_features = {0};
device_features.samplerAnisotropy = VK_TRUE;
//now create a logical device knowing which features and queues we need
VkDeviceCreateInfo create_info = {0};
@ -694,10 +705,19 @@ void create_descriptor_set_layout(ApplicationState* state) { @@ -694,10 +705,19 @@ void create_descriptor_set_layout(ApplicationState* state) {
ubo_layout_binding.descriptorCount = 1;
ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
VkDescriptorSetLayoutBinding sampler_layout_binding = {0};
sampler_layout_binding.binding = 1;
sampler_layout_binding.descriptorCount = 1;
sampler_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
sampler_layout_binding.pImmutableSamplers = NULL;
sampler_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutBinding bindings[2] = {ubo_layout_binding, sampler_layout_binding};
VkDescriptorSetLayoutCreateInfo layout_info = {0};
layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layout_info.bindingCount = 1;
layout_info.pBindings = &ubo_layout_binding;
layout_info.bindingCount = ARRSIZE(bindings);
layout_info.pBindings = bindings;
if (vkCreateDescriptorSetLayout(state->device, &layout_info, NULL, &state->descriptor_set_layout)) {
printf("could not create descriptor set layout\n");
@ -765,9 +785,10 @@ void create_graphics_pipeline(ApplicationState* state) { @@ -765,9 +785,10 @@ void create_graphics_pipeline(ApplicationState* state) {
};
//We have position and color, so we need two descriptions
VkVertexInputAttributeDescription attribute_description[2] = {
VkVertexInputAttributeDescription attribute_description[3] = {
{.binding = 0, .location = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(Vertex, position)},
{.binding = 0, .location = 1, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = offsetof(Vertex, color)},
{.binding = 0, .location = 2, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(Vertex, tex_coord)},
};
//vertex input format
@ -1239,15 +1260,67 @@ void create_texture_image(ApplicationState* state) { @@ -1239,15 +1260,67 @@ void create_texture_image(ApplicationState* state) {
vkFreeMemory(state->device, staging_buffer_memory, NULL);
}
void create_texture_image_view(ApplicationState* state) {
VkImageViewCreateInfo view_info = {0};
view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
view_info.image = state->texture_image;
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_info.format = VK_FORMAT_R8G8B8A8_SRGB;
view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
view_info.subresourceRange.baseMipLevel = 0;
view_info.subresourceRange.levelCount = 1;
view_info.subresourceRange.baseArrayLayer = 0;
view_info.subresourceRange.layerCount = 1;
if (vkCreateImageView(state->device, &view_info, NULL, &state->texture_image_view) != VK_SUCCESS) {
printf("failed to create texture image view\n");
exit(1);
}
}
void create_texture_image_sampler(ApplicationState* state) {
VkSamplerCreateInfo sampler_info = {0};
sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
sampler_info.magFilter = VK_FILTER_LINEAR;
sampler_info.minFilter = VK_FILTER_LINEAR;
sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
sampler_info.anisotropyEnable = VK_TRUE;
VkPhysicalDeviceProperties properties = {0};
vkGetPhysicalDeviceProperties(state->physical_device, &properties);
sampler_info.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
sampler_info.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
sampler_info.unnormalizedCoordinates = VK_FALSE;
sampler_info.compareEnable = VK_FALSE;
sampler_info.compareOp = VK_COMPARE_OP_ALWAYS;
sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
sampler_info.mipLodBias = 0.0f;
sampler_info.minLod = 0.0f;
sampler_info.maxLod = 0.0f;
if (vkCreateSampler(state->device, &sampler_info, NULL, &state->texture_sampler) != VK_SUCCESS) {
printf("failed to create sampler\n");
exit(1);
}
}
void create_descriptor_pool(ApplicationState* state) {
VkDescriptorPoolSize pool_size = {0};
pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
pool_size.descriptorCount = MAX_FRAMES_IN_FLIGHT;
VkDescriptorPoolSize pool_size[2] = {0};
pool_size[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
pool_size[0].descriptorCount = MAX_FRAMES_IN_FLIGHT;
pool_size[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
pool_size[1].descriptorCount = MAX_FRAMES_IN_FLIGHT;
VkDescriptorPoolCreateInfo pool_info = {0};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.poolSizeCount = 1;
pool_info.pPoolSizes = &pool_size;
pool_info.poolSizeCount = ARRSIZE(pool_size);
pool_info.pPoolSizes = pool_size;
pool_info.maxSets = MAX_FRAMES_IN_FLIGHT;
if (vkCreateDescriptorPool(state->device, &pool_info, NULL, &state->descriptor_pool) != VK_SUCCESS) {
@ -1279,18 +1352,31 @@ void create_descriptor_sets(ApplicationState* state) { @@ -1279,18 +1352,31 @@ void create_descriptor_sets(ApplicationState* state) {
buffer_info.offset = 0;
buffer_info.range = sizeof(UBO);
VkWriteDescriptorSet descriptor_write = {0};
descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_write.dstSet = state->descriptor_sets[i];
descriptor_write.dstBinding = 0;
descriptor_write.dstArrayElement = 0;
descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptor_write.descriptorCount = 1;
descriptor_write.pBufferInfo = &buffer_info;
descriptor_write.pImageInfo = NULL;
descriptor_write.pTexelBufferView = NULL;
vkUpdateDescriptorSets(state->device, 1, &descriptor_write, 0, NULL);
VkDescriptorImageInfo image_info = {0};
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
image_info.imageView = state->texture_image_view;
image_info.sampler = state->texture_sampler;
VkWriteDescriptorSet descriptor_writes[2] = {0};
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_writes[0].dstSet = state->descriptor_sets[i];
descriptor_writes[0].dstBinding = 0;
descriptor_writes[0].dstArrayElement = 0;
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptor_writes[0].descriptorCount = 1;
descriptor_writes[0].pBufferInfo = &buffer_info;
descriptor_writes[0].pImageInfo = NULL;
descriptor_writes[0].pTexelBufferView = NULL;
descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_writes[1].dstSet = state->descriptor_sets[i];
descriptor_writes[1].dstBinding = 1;
descriptor_writes[1].dstArrayElement = 0;
descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
descriptor_writes[1].descriptorCount = 1;
descriptor_writes[1].pImageInfo = &image_info;
vkUpdateDescriptorSets(state->device, ARRSIZE(descriptor_writes), descriptor_writes, 0, NULL);
}
printf("created descriptor sets\n");
@ -1413,6 +1499,8 @@ void init_vulkan(ApplicationState* state) { @@ -1413,6 +1499,8 @@ void init_vulkan(ApplicationState* state) {
create_framebuffers(state);
create_command_pool(state);
create_texture_image(state);
create_texture_image_view(state);
create_texture_image_sampler(state);
create_vertex_buffer(state);
create_index_buffer(state);
create_uniform_buffers(state);
@ -1534,6 +1622,8 @@ void terminate(ApplicationState* state) { @@ -1534,6 +1622,8 @@ void terminate(ApplicationState* state) {
vkFreeMemory(state->device, state->vertex_buffer_memory, NULL);
vkDestroyBuffer(state->device, state->index_buffer, NULL);
vkFreeMemory(state->device, state->index_buffer_memory, NULL);
vkDestroySampler(state->device, state->texture_sampler, NULL);
vkDestroyImageView(state->device, state->texture_image_view, NULL);
vkDestroyImage(state->device, state->texture_image, NULL);
vkFreeMemory(state->device, state->texture_image_memory, NULL);

3
src/vertex_simple.vert

@ -8,10 +8,13 @@ layout(binding = 0) uniform UBO { @@ -8,10 +8,13 @@ layout(binding = 0) uniform UBO {
layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec2 fragTexCoord;
void main() {
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
fragColor = inColor;
fragTexCoord = inTexCoord;
}

Loading…
Cancel
Save