Vulkan Samples 阅读 -- Basics(三): Push Constants & Specialization Constants & Texture Mapping

Push Constants

prepare

  • loadAssets: 加载模型等资源

  • setupSpheres: 为球模型设置随机颜色

  • prepareUniformBuffers

    • updateUniformBuffers
  • setupDescriptorSetLayout:正常操作,常量在此处进行设置

    	// Define the push constant range used by the pipeline layout
    	// Note that the spec only requires a minimum of 128 bytes, so for passing larger blocks of data you'd use UBOs or SSBOs
    	VkPushConstantRange pushConstantRange{};
    	pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
    	pushConstantRange.offset = 0;
    	pushConstantRange.size = sizeof(SpherePushConstantData);
    
    	VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayout, 1);
    	pipelineLayoutCreateInfo.pushConstantRangeCount  = 1;
    	pipelineLayoutCreateInfo.pPushConstantRanges = &pushConstantRange;
    	VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
    
  • setupDescriptorSet

  • preparePipelines

  • setupDescriptorPool

  • setupDescriptorSet

  • buildCommandBuffers:常量绑定在这里

    	vkCmdPushConstants(
    			   drawCmdBuffers[i],
    			    pipelineLayout,
    			    VK_SHADER_STAGE_VERTEX_BIT,
    			    0,
    			    sizeof(SpherePushConstantData),
    			    &spheres[j]);
    			model.draw(drawCmdBuffers[i]);
    
  • shader中常量的获取

    layout(push_constant) uniform PushConsts {
    	vec4 color;
    	vec4 position;
    } pushConsts;
    

render

  • draw
  • updateUniformBuffers

小结

   常量的设置比较简单,setupDescriptorSetLayout中设置, buildCommandBuffers中绑定,shader获取即可。

Specialization Constants

prepare

  • loadAssets:

  • prepareUniformBuffers

    • updateUniformBuffers
  • setupDescriptorSetLayout:与常量不同 Specialization Constants 设置只在 preparePipelines 中

  • preparePipelines

    	// Host data to take specialization constants from
    	// 常量结构体定义,命名随意,只要靠绑定id获取值
    	struct SpecializationData {
    		// Sets the lighting model used in the fragment "uber" shader
    		uint32_t lightingModel;
    		// Parameter for the toon shading part of the fragment shader
    		float toonDesaturationFactor = 0.5f;
    	} specializationData;
    
    	// Each shader constant of a shader stage corresponds to one map entry
    	//绑定常量实体
    	std::array<VkSpecializationMapEntry, 2> specializationMapEntries;
    	// Shader bindings based on specialization constants are marked by the new "constant_id" layout qualifier:
    	//	layout (constant_id = 0) const int LIGHTING_MODEL = 0;
    	//	layout (constant_id = 1) const float PARAM_TOON_DESATURATION = 0.0f;
    	
    	// Map entry for the lighting model to be used by the fragment shader
    	//id是shader中获取值的索引
    	specializationMapEntries[0].constantID = 0;
    	specializationMapEntries[0].size = sizeof(specializationData.lightingModel);
    	specializationMapEntries[0].offset = 0;
    
    	// Map entry for the toon shader parameter
    	specializationMapEntries[1].constantID = 1;
    	specializationMapEntries[1].size = sizeof(specializationData.toonDesaturationFactor);
    	specializationMapEntries[1].offset = offsetof(SpecializationData, toonDesaturationFactor);
    
    	// Prepare specialization info block for the shader stage
    	VkSpecializationInfo specializationInfo{};
    	specializationInfo.dataSize = sizeof(specializationData);
    	specializationInfo.mapEntryCount = static_cast<uint32_t>(specializationMapEntries.size());
    	specializationInfo.pMapEntries = specializationMapEntries.data();
    	specializationInfo.pData = &specializationData;
    
    	// Create pipelines
    	// All pipelines will use the same "uber" shader and specialization constants to change branching and parameters of that shader
    	shaderStages[0] = loadShader(getShadersPath() + "specializationconstants/uber.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
    	shaderStages[1] = loadShader(getShadersPath() + "specializationconstants/uber.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
    	// Specialization info is assigned is part of the shader stage (modul) and must be set after creating the module and before creating the pipeline
    	//选择常量绑定在哪个shader中
    	shaderStages[1].pSpecializationInfo = &specializationInfo;
    
    • setupDescriptorPool
    • setupDescriptorSet
    • buildCommandBuffers
    • shader中常量的获取
    	//变量名称可以自定义
    	layout (constant_id = 0) const int LIGHTING_MODEL = 0;
    	layout (constant_id = 1) const float PARAM_TOON_DESATURATION = 0.0f;
    

render

  • draw
  • updateUniformBuffers

小结

   Specialization 常量是shader域绑定的,只在preparePipelines中设置即可。与 Constants 的区别是,Specialization Constants 作用域是shader域,而 Constants 的作用域为 pipeline。

Texture Mapping

prepare

  • loadTexture: 加载图片
    • ktx_uint8_t *textureData 从读图API中将纹理读入
    • 纹理结构体
      VkSampler sampler;
      VkImage image;
      VkImageLayout imageLayout;
      VkDeviceMemory deviceMemory;
      VkImageView view;
      uint32_t width, height; //从textureData 中获取
      uint32_t mipLevels; //从textureData 中获取
      
    • 官方给出两种将图片资源导入GPU的方式, 一种是线性式平铺, 一种是优化式平铺.
      • 线性平铺是可以直接将存储图片信息的内存空间数据直接复制到GPU上, 因此对于纹理的格式和功能支持非常有限
        • vkCreateImage
        • vkGetImageMemoryRequirements
        • vkAllocateMemory
        • vkBindImageMemory
        • vkMapMemory – memcpy – vkUnmapMemory
        • vkCmdPipelineBarrier: 直接将图片从 HOST Barrier 到 FRAGMENT_SHADER
        • flushCommandBuffer
      • 优化式平铺将图片内存空间数据与硬件支持的功能进行匹配, 然后生成specific layout, 这样能支持更多格式和相应功能. 而且Copy速度更快. 但是这种方式存储图片信息, 是存储在drive中, 主机无法访问.
        • vkCreateBuffer: 创建stagingBuffer
        • vkGetBufferMemoryRequirements: 申请buffer使用的内存
        • vkAllocateMemory: 分配内存
        • vkBindBufferMemory: 绑定内存
        • vkMapMemory – memcpy – vkUnmapMemory: 将图片信息复制到 host local staging buffer (specific layout)
        • std::vector bufferCopyRegions: 为每个 mip 设置缓冲区复制区域
        • vkCreateImage: Create optimal tiled target image on the device
          • 其中主要的是 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
        • vkGetImageMemoryRequirements: 申请内存
        • vkAllocateMemory: 分配内存
        • vkBindImageMemory: 绑定资源
        • createCommandBuffer:创建复制命令
        • imageMemoryBarrier:: Image memory barriers for the texture image
          • 为每个pipeline 设置 image layout 过度,下面的操作就是从stagingBuffer中将图片数据复制到GPU
        • vkCmdPipelineBarrier:从 HOST Barrier 到 TRANSFER
        • vkCmdCopyBufferToImage:Copy mip levels from staging buffer
        • vkCmdPipelineBarrier:从TRANSFER Barrier 到 FRAGMENT_SHADER
        • flushCommandBuffer
        • vkFreeMemory:Clean up staging resources
        • vkDestroyBuffer:Clean up staging resources
    • ktxTexture_Destroy:释放从磁盘读取图片的内存
    • vkCreateSampler
    • vkCreateImageView
  • generateQuad:创建一个面片
  • setupVertexDescriptions
  • prepareUniformBuffers
    • updateUniformBuffers
  • setupDescriptorSetLayout
  • preparePipelines
  • setupDescriptorPool
  • setupDescriptorSet
  • buildCommandBuffers

render

  • draw

小结

   本节主要讲如何更高效的读取贴图。与一般的直接从本地读取贴图数据,然后直接复制到GPU相比,使用 specific layout,能支持更多的格式和功能。并且有更高效的性能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
realesrgan-ncnn-vulkan-20211212-windows是一个基于ncnn框架和Vulkan图形API开发的图像超分辨率增强模型。它是由GitHub用户realsrgan开发的最新版本,最新发布日期为2021年12月12日,专为Windows操作系统而设计。 该模型的主要应用是图像超分辨率增强,通过提高图像的分辨率和细节,使图像看起来更加清晰和真实。它采用深度学习和卷积神经网络等先进的技术,能够将低分辨率的图像转换成高分辨率的图像,从而提升图像的质量和视觉效果。 realesrgan-ncnn-vulkan-20211212-windows的开发使用了ncnn框架和Vulkan图形API,这使得它能够在Windows系统上实现快速且高效的图像处理。ncnn是一个轻量级的深度学习框架,专注于在移动平台和嵌入式设备上实现高性能和低延迟的推理。而Vulkan图形API是一种跨平台的图形渲染和计算API,可以充分利用计算设备的性能,提供高效的图像处理和渲染能力。 realesrgan-ncnn-vulkan-20211212-windows的使用可以通过命令行或者图形界面进行,用户可以根据自己的需求和偏好选择适合的方式。该模型提供了训练好的权重参数,用户可以直接加载这些参数并进行图像超分辨率增强。此外,该模型还支持批量处理和视频处理,方便用户对多个图像进行处理。 总之,realesrgan-ncnn-vulkan-20211212-windows是一个高效、快速且易于使用的图像超分辨率增强模型,适用于Windows系统,并利用了ncnn框架和Vulkan图形API的优势,为用户提供了出色的图像处理效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值