首页 > 其他分享 >vulkan/descriptorSet

vulkan/descriptorSet

时间:2023-12-13 16:11:06浏览次数:55  
标签:descriptorWrites layout VK binding uniform descriptorSet DESCRIPTOR vulkan

参考Shader

layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
    mat4 view;
    mat4 proj;
} 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;
}
layout(location = 0) in vec2 fragTexCoord;
layout(location = 0) out vec4 outColor;
layout(binding = 1) uniform sampler2D texSampler;

void main() {
    outColor = texture(texSampler, fragTexCoord);
}

 

1. 是vs的uniform UniformBufferObject;需要vulkan传入对应的uniform buffer数据,

2. 是ps的uniform sampler2D texSampler,需要vulkan传入Sampler需要sample哪个image,以及sample的采样模式信息。

那么 vulkan 中需要对 uniform 进行抽象封装:

VkDescriptorSetLayoutBinding ubo  =  {};
    ubo.binding         = 0;
    ubo.descriptorType  = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
    ubo.descriptorCount = 1;
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
    samplerLayoutBinding.binding            = 1;
    samplerLayoutBinding.descriptorCount    = 1;
    samplerLayoutBinding.descriptorType     = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;//point out this descript type is sampler
    samplerLayoutBinding.pImmutableSamplers = nullptr;
    samplerLayoutBinding.stageFlags         = VK_SHADER_STAGE_FRAGMENT_BIT;

其中重要的信息点: binding 对应 layout(binding =  ? )

  1. binding = 0 的 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER 对象,只作用于vertex shader
  2. binding = 1 的 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER对象,作用于fragment shader

将这两类descriptor type封装到各自的VkDescriptorSetLay

std::array<VkDescriptorSetLayoutBinding, 2> bindings = {ubo, samplerLayoutBinding};
    VkDescriptorSetLayoutCreateInfo layoutInfo{};
    layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
    layoutInfo.bindingCount = 2;
    layoutInfo.pBindings = bindings.data();

    if (vkCreateDescriptorSetLayout(vulkanDevice->device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
        throw std::runtime_error("failed to create descriptor set layout!");
    }

这里需要是创建layout ,但是并没有给定数据,具体给什么数据,则由于 VkDescriptorSet 指定

std::vector<VkDescriptorSetLayout> layouts(MAX_FRAMES_IN_FLIGHT, descriptorSetLayout);
    VkDescriptorSetAllocateInfo allocInfo{};

    allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    allocInfo.descriptorPool = descriptorPool;
    allocInfo.descriptorSetCount = static_cast<uint32_t>(MAX_FRAMES_IN_FLIGHT);
    allocInfo.pSetLayouts = layouts.data(); //layout has uniform format  information(descriptorSetLayout)

    //create descrpitsets array
    descriptorSets.resize(MAX_FRAMES_IN_FLIGHT);

    if (vkAllocateDescriptorSets(vulkanDevice->device, &allocInfo, descriptorSets.data()) != VK_SUCCESS) {
        throw std::runtime_error("failed to allocate descriptor sets!");
    }

数据上传:

for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
        VkDescriptorBufferInfo bufferInfo{};
        bufferInfo.buffer = uniformBuffers[i];
        bufferInfo.offset = 0;
        bufferInfo.range = sizeof(UniformBufferObject);

        /*binding sampler and vkImage here*/
        VkDescriptorImageInfo imageInfo{};
        imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
        imageInfo.imageView = textureImageView;
        imageInfo.sampler = textureSampler;

        //this struct link descript set we created before in this function and uniform buffer created before 
        std::array<VkWriteDescriptorSet, 2> descriptorWrites{};

        descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
        descriptorWrites[0].dstSet = descriptorSets[i]; //get descriptor set object
        descriptorWrites[0].dstBinding = 0;//uniform buffer , now it is set as 0 in shader
        descriptorWrites[0].dstArrayElement = 0;//descriptor can be array so we specify 0
        descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;//descriptor type is uniform 
        descriptorWrites[0].descriptorCount = 1;//
        descriptorWrites[0].pBufferInfo = &bufferInfo;//link uniform buffer

        descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
        descriptorWrites[1].dstSet = descriptorSets[i];
        descriptorWrites[1].dstBinding = 1; //binding code relate to shader code : layout(binding = 1) uniform sampler2D texSampler;
        descriptorWrites[1].dstArrayElement = 0;
        descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;//descriptor type is sampler 
        descriptorWrites[1].descriptorCount = 1;
        descriptorWrites[1].pImageInfo = &imageInfo;//link image info with vkImage and sampler

        //link descript set(include descript layout (uniform data format)) and uniform buffer
        vkUpdateDescriptorSets(vulkanDevice->device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
    }

 

 

 

 

标签:descriptorWrites,layout,VK,binding,uniform,descriptorSet,DESCRIPTOR,vulkan
From: https://www.cnblogs.com/FastEarth/p/17899276.html

相关文章

  • Vulkan/VkPresentModeKHR
    呈现模式:对于交换链对显示模式的设置应该是最重要的,因为它代表实际显示图像到屏幕的时机。在Vulkan中有四种显示模式:1.VK_PRESENT_MODE_IMMEDIATE_KHR由应用提交的图像立刻被传输到屏幕。这种方式可能导致图像不完整。2.VK_PRESENT_MODE_FIFO_KHR交换链是一个队列,当......
  • Vulkan/Graphics Pipelines
    渲染是vulkan最基础的功能,也是众多图形化应用最核心的部分。vulkan的渲染过程可以当作是通过执行不同阶段的命令以此来在展示设备上渲染出图片的过程。 vulkan中,渲染管线可以看作是一条生产流水线,命令在管线的开头进入,并且在管线内不同阶段执行。每个阶段都有诸如变换,读取命令......
  • Vulkan/Renderpasses
    能将渲染管线和运算管线区别开了的要素之一是——通用,在你使用一个渲染管线渲染图像之后也可能进行其他处理或展示给yoghurt。在复杂的图形应用中,图像需要经过许多通道才能生成,每个通道都负责不同的部分,比如全屏幕的后处理或合成,或渲染UI元素等。这些通道可以由vulkan的一个渲染......
  • Vulkan/FrameBuffer
    帧缓冲(Framebuffer)代表由渲染管线进行渲染的一组图像。它们影响管线的最后几个阶段:深度模板测试,颜色混合,逻辑运算,多重采样等等。一个帧缓冲对象总是附着在一个渲染通道上并且可以用在多个具有相似模板编排的渲染通道中。调用vkCreateFramebuffer创建帧缓冲对象。在VkFramebuffer......
  • Visual Studio 2022:Vulkan 环境配置
    (前置)安装VulkanSDK,并确认安装目录,此后记为%VulkanDir%(例如:C:/VulkanSDK/1.3.261.1)VisualStudio中新建C++项目,进入“项目”>>“[项目名]属性”,上方两个选项设置为“所有配置”“所有平台”C/C++>>常规>>附加包含目录:添加%VulkanDir%/Include(替换%VulkanDir%为实际目录,下同)......
  • 【小沐学Vulkan】Vulkan开发环境配置
    1、简介https://www.vulkan.org/Vulkan是新一代图形和计算API,用于高效、跨平台访问GPU。Vulkan是一个跨平台的2D和3D绘图应用程序接口(API),最早由科纳斯组织在2015年游戏开发者大会(GDC)上发表。号称是glNext。旨在提供更低的CPU开销与更直接的GPU控制,其理念大致与Direct3D12......
  • 构造Vulkan图形管线:VkGraphicsPipeline
     创建Pipeline构造信息:它包括:基本构造信息VkStructureType构建Pipeline额外需要的结构:constvoid*pNext构建Pipeline时指定的Flags:VkPipelineCreateFlags多个ShaderStage信息:VkPipelineShaderStageCreateInfo*(数组)......
  • Vulkan Descriptor绑定过程
    如果shader中的资源是这么排布的://vslayout(set=0,binding=0,std140)uniformUBO{mat4projection;mat4view;mat4model;}ubo;layout(location=0)invec3inPos;layout(location=0)outvec3outUVW;//fslayout(set=0,binding=1)uni......
  • Vulkan Video实现GPU加速视频编码/解码
    正文字数:929 阅读时长:2分钟Vulkan是一套跨平台的图形API,由Khronos组织牵头进行制定,普遍被看作是OpenGL的后继者,目前版本已经来到1.2.175,仍然在不停地进行更新,其在非Windows平台上面已经逐渐变成了首选使用的图形API。在未来,Vulkan甚至会提供模拟DirectX等其他图形API的功能,有很大......
  • OpenGL不够用?为何还要开发Vulkan?
    相信不少朋友和我一样有这样的疑问既然已经有广泛应用的OpenGL图形接口,为什么Khronos还要花费精力重新开发一套Vulkan图形API接口呢?查询相关资料后,总结为一句话为了更高的性能、更低的驱动程序开销。对于许多图形开发者来说,OpenGL是一个非常熟悉和广泛使用的图形API接口。然而......