vulkan游戏引擎renderer文件下的vulkan下的shaders代码实现

1.vulkan_object_shader.h

#pragma once

#include "renderer/vulkan/vulkan_types.inl"

#include "renderer/renderer_types.inl"


 

b8 vulkan_object_shader_create(vulkan_context* context,vulkan_object_shader* out_shader);


 

void vulkan_object_shader_destroy(vulkan_context* context,struct vulkan_object_shader* shader);


 

void vulkan_object_shader_use(vulkan_context* context,struct vulkan_object_shader* shader);

void vulkan_object_shader_update_global_state(vulkan_context* context,struct vulkan_object_shader* shader);

void vulkan_object_shader_update_object(vulkan_context* context,struct vulkan_object_shader* shader,mat4 model);


2.vulkan_object_shader.c

#include "vulkan_object_shader.h"

#include "core/logger.h"

#include "core/kmemory.h"

#include "math/math_types.h"



 

#include "renderer/vulkan/vulkan_shader_utils.h"

#include "renderer/vulkan/vulkan_pipeline.h"

#include "renderer/vulkan/vulkan_buffer.h"


 

#define BUILTIN_SHADER_NAME_OBJECT "Builtin.ObjectShader"

b8 vulkan_object_shader_create(vulkan_context* context,vulkan_object_shader* out_shader)

{

    //Shader mddule init per stage

    char stage_type_strs[OBJECT_SHADER_STAGE_COUNT][5] = {"vert","frag"};

    VkShaderStageFlagBits stage_types[OBJECT_SHADER_STAGE_COUNT] = {VK_SHADER_STAGE_VERTEX_BIT,VK_SHADER_STAGE_FRAGMENT_BIT};


 

    for(u32 i = 0;i

    {

        if(!create_shader_module(context,BUILTIN_SHADER_NAME_OBJECT,stage_type_strs[i],stage_types[i],i,out_shader->stages))

        {

            KERROR("Unable to create %s shader module for '%s",stage_type_strs[i],BUILTIN_SHADER_NAME_OBJECT);

        }

    }

    //TODO:Global Descriptors

    VkDescriptorSetLayoutBinding global_ubo_layout_binding;

    global_ubo_layout_binding.binding = 0;

    global_ubo_layout_binding.descriptorCount = 1;

    global_ubo_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;

    global_ubo_layout_binding.pImmutableSamplers = 0;

    global_ubo_layout_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;

    VkDescriptorSetLayoutCreateInfo global_layout_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};

    global_layout_info.bindingCount = 1;

    global_layout_info.pBindings = &global_ubo_layout_binding;

    VK_CHECK(vkCreateDescriptorSetLayout(context->device.logical_device,&global_layout_info,context->allocator,&out_shader->global_descriptor_set_layout));

    //gLobal pool

    VkDescriptorPoolSize global_pool_size;

    global_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;

    global_pool_size.descriptorCount = context->swapchain.image_count;

    VkDescriptorPoolCreateInfo global_pool_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};

    global_pool_info.poolSizeCount = 1;

    global_pool_info.pPoolSizes = &global_pool_size;

    global_pool_info.maxSets = context->swapchain.image_count;

    VK_CHECK(vkCreateDescriptorPool(context->device.logical_device,&global_pool_info,context->allocator,&out_shader->global_descriptor_pool));



 

    //Pipeline creation

    VkViewport viewport;

    viewport.x = 0.0f;

    viewport.y = (f32)context->framebuffer_height;

    viewport.width = (f32)context->framebuffer_width;

    viewport.height = -(f32)context->framebuffer_height;

    viewport.minDepth = 0.0f;

    viewport.maxDepth = 1.0f;

    //Scissor

    VkRect2D scissor;

    scissor.offset.x = scissor.offset.y = 0;

    scissor.extent.width = context->framebuffer_width;

    scissor.extent.height = context->framebuffer_height;

    //Attributes

    u32 offset = 0;

    const i32 attribute_count = 1;

    VkVertexInputAttributeDescription attribute_descriptions[attribute_count];

    //Position

    VkFormat formats[attribute_count] =

    {

        VK_FORMAT_R32G32B32_SFLOAT


 

    };

    u64 sizes[attribute_count] = {

        sizeof(vec3)


 

    };

    for(u32 i = 0;i

    {

        attribute_descriptions[i].binding = 0;

        attribute_descriptions[i].location = i;

        attribute_descriptions[i].format = formats[i];

        attribute_descriptions[i].offset = offset;

        offset += sizes[i];

    }

    //TODO:Descriptor set layouts

    const i32 descriptor_set_layout_count = 1;

    VkDescriptorSetLayout layouts[1] = {

        out_shader->global_descriptor_set_layout

       

        };

    //Stages

    VkPipelineShaderStageCreateInfo stage_create_infos[OBJECT_SHADER_STAGE_COUNT];

    kzero_memory(stage_create_infos,sizeof(stage_create_infos));

    for(u32 i = 0;i

    {

        stage_create_infos[i].sType = out_shader->stages[i].shader_stage_create_info.sType;

        stage_create_infos[i] = out_shader->stages[i].shader_stage_create_info;

    }


 

    if(!vulkan_graphics_pipeline_create(

        context,

        &context->main_renderpass,

        attribute_count,

        attribute_descriptions,

        descriptor_set_layout_count,

        layouts,

        OBJECT_SHADER_STAGE_COUNT,

        stage_create_infos,

        viewport,

        scissor,

        false,

        &out_shader->pipeline



 

    ))

    {

        KERROR("failed to load graphics pipeline for object shader.");

        return false;






 

    }


 

    //Create uniform buffer

    if(!vulkan_buffer_create(

        context,

        sizeof(global_uniform_object),

        VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,

        VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,

        true,

        &out_shader->global_uniform_buffer

    ))

    {

        KERROR("Failed to create uniform buffer for object shader.");

        return false;


 

    }


 

    VkDescriptorSetLayout global_layouts[3] =

    {

        out_shader->global_descriptor_set_layout,

        out_shader->global_descriptor_set_layout,

        out_shader->global_descriptor_set_layout

    };

    VkDescriptorSetAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO};

    alloc_info.descriptorPool = out_shader->global_descriptor_pool;

    alloc_info.descriptorSetCount = 3;

    alloc_info.pSetLayouts = global_layouts;

    VK_CHECK(vkAllocateDescriptorSets(context->device.logical_device,&alloc_info,out_shader->global_descriptor_sets));



 

    return true;

}


 

void vulkan_object_shader_destroy(vulkan_context* context,struct vulkan_object_shader* shader)

{

    VkDevice logical_device = context->device.logical_device;

    vulkan_buffer_destroy(context,&shader->global_uniform_buffer);

    vulkan_pipeline_destroy(context,&shader->pipeline);

    vkDestroyDescriptorPool(logical_device,shader->global_descriptor_pool,context->allocator);

    vkDestroyDescriptorSetLayout(logical_device,shader->global_descriptor_set_layout,context->allocator);


 

    for(u32 i = 0;i

    {

        vkDestroyShaderModule(context->device.logical_device,shader->stages[i].handle,context->allocator);

        shader->stages[i].handle = 0;



 

    }


 

}


 

void vulkan_object_shader_use(vulkan_context* context,struct vulkan_object_shader* shader)

{

    u32 image_index = context->image_index;

    vulkan_pipeline_bind(&context->graphics_command_buffers[image_index],VK_PIPELINE_BIND_POINT_GRAPHICS,&shader->pipeline);


 

}

void vulkan_object_shader_update_global_state(vulkan_context* context,struct vulkan_object_shader* shader)

{

    u32 image_index = context->image_index;

    VkCommandBuffer command_buffer = context->graphics_command_buffers[image_index].handle;

    VkDescriptorSet global_descriptor = shader->global_descriptor_sets[image_index];

   

   

    /*

    if(!shader->descriptor_updated[image_index])

    {

        u32 range = sizeof(global_uniform_object);

        u64 offset = sizeof(global_uniform_object)*image_index;

        vulkan_buffer_load_data(context,&shader->global_uniform_buffer,offset,range,0,&shader->global_ubo);

        VkDescriptorBufferInfo bufferInfo;

        bufferInfo.buffer = shader->global_uniform_buffer.handle;

        bufferInfo.offset = offset;

        bufferInfo.range = range;

        VkWriteDescriptorSet descriptor_write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};

        descriptor_write.dstSet = global_descriptor;

        descriptor_write.dstBinding = 0;

        descriptor_write.dstArrayElement = 0;

        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;

        descriptor_write.descriptorCount = 1;

        descriptor_write.pBufferInfo = &bufferInfo;

        vkUpdateDescriptorSets(context->device.logical_device,1,&descriptor_write,0,0);

        shader->descriptor_updated[image_index] = true;



 

    }

    */


 

    vkCmdBindDescriptorSets(command_buffer,VK_PIPELINE_BIND_POINT_GRAPHICS,shader->pipeline.pipeline_layout,0,1,&global_descriptor,0,0);

   

    u32 range = sizeof(global_uniform_object);

    u64 offset = 0;

    vulkan_buffer_load_data(context,&shader->global_uniform_buffer,offset,range,0,&shader->global_ubo);


 

    VkDescriptorBufferInfo bufferInfo;

    bufferInfo.buffer = shader->global_uniform_buffer.handle;

    bufferInfo.offset = offset;

    bufferInfo.range = range;

    VkWriteDescriptorSet descriptor_write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};

    descriptor_write.dstSet = shader->global_descriptor_sets[image_index];

    descriptor_write.dstBinding = 0;

    descriptor_write.dstArrayElement = 0;

    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;

    descriptor_write.descriptorCount = 1;

    descriptor_write.pBufferInfo = &bufferInfo;

    vkUpdateDescriptorSets(context->device.logical_device,1,&descriptor_write,0,0);

   

   

}


 

void vulkan_object_shader_update_object(vulkan_context* context,struct vulkan_object_shader* shader,mat4 model)

{

    u32 image_index = context->image_index;

    VkCommandBuffer command_buffer = context->graphics_command_buffers[image_index].handle;

    vkCmdPushConstants(command_buffer,shader->pipeline.pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0,sizeof(mat4),&model);



 

}



 

你可能感兴趣的:(游戏引擎)