Advertisement
Guest User

Untitled

a guest
Dec 18th, 2024
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.71 KB | None | 0 0
  1. void VK_Shader::reflect_c(const std::vector<uint32_t> &spirv) {
  2.         VkPhysicalDeviceLimits limits = device->getPhysicalDevice().getProperties().limits;
  3.         //spirv cross: https://github.com/KhronosGroup/SPIRV-Cross/wiki/Reflection-API-user-guide
  4.         spvc_context context = nullptr;
  5.         spvc_context_create(&context);
  6.         spvc_parsed_ir ir;
  7.         spvc_context_parse_spirv(context, spirv.data(), spirv.size(), &ir);
  8.         spvc_compiler compiler_glsl = nullptr;
  9.         spvc_context_create_compiler(context, SPVC_BACKEND_GLSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &compiler_glsl);
  10.         spvc_resources resources;
  11.         const spvc_reflected_resource *uniform_list = nullptr;
  12.         size_t uniform_count;
  13.         spvc_compiler_create_shader_resources(compiler_glsl, &resources);
  14.         //----------------------------------------------PUSH CONSTANTS------------------------------------------------
  15.         const spvc_reflected_resource *push_constant_list = nullptr;
  16.         size_t push_constants_count;
  17.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &push_constant_list, &push_constants_count);
  18.         for (uint32_t i = 0; i < push_constants_count; ++i) {
  19.             size_t size;
  20.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, push_constant_list[i].type_id);
  21.             spvc_compiler_get_declared_struct_size(compiler_glsl, type, &size);
  22.             HB_ASSERT(size <= limits.maxPushConstantsSize, "Push constant size is too big!");
  23.             //uint32_t binding = spvc_compiler_get_decoration(compiler_glsl, push_constant_list[i].id, SpvDecorationBinding);
  24.             std::string name = spvc_compiler_get_name(compiler_glsl, push_constant_list[i].id);
  25.             VK_PushConstantInfo push_constant_info{};
  26.             push_constant_info.name = name;
  27.             VkPushConstantRange push_constant_range{};
  28.             push_constant_range.size = size;
  29.             push_constant_range.offset = spvc_compiler_get_decoration(compiler_glsl, push_constant_list[i].id, SpvDecorationOffset);
  30.             push_constant_range.stageFlags = vk_stage;
  31.             push_constant_info.push_constant_range = push_constant_range;
  32.             push_constants.emplace_back(push_constant_info);
  33.         }
  34.         std::sort(push_constants.begin(), push_constants.end(),
  35.                   [](const VK_PushConstantInfo &a, const VK_PushConstantInfo &b) -> bool {
  36.                       return a.push_constant_range.offset < b.push_constant_range.offset;
  37.                   });
  38.         //-------------------------------------------------UNIFORM_BUFFERS-----------------------------
  39.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &uniform_list, &uniform_count);
  40.         for (uint32_t i = 0; i < uniform_count; ++i) {
  41.             std::string name = spvc_compiler_get_name(compiler_glsl, uniform_list[i].id);
  42.             size_t size;
  43.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, uniform_list[i].type_id);
  44.             spvc_compiler_get_declared_struct_size(compiler_glsl, type, &size);
  45.             VK_UniformInfo uniform_info{};
  46.             HB_ASSERT(size <= limits.maxUniformBufferRange, "Uniform buffer size is too big!");
  47.             VkDescriptorSetLayoutBinding layout_binding = {};
  48.             layout_binding.binding = spvc_compiler_get_decoration(compiler_glsl, uniform_list[i].id, SpvDecorationBinding);
  49.             layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  50.             layout_binding.stageFlags = vk_stage;
  51.             layout_binding.descriptorCount = 1;//this is for array
  52.             layout_binding.pImmutableSamplers = nullptr;
  53.             uniform_info.layout_binding = layout_binding;
  54.             uniform_info.name = name;
  55.             uniform_info.size = size;
  56.             uniforms.emplace_back(uniform_info);
  57.         }
  58.         //----------------------------------------------------------TEXTURE SAMPLERS----------------------------------------------------------
  59.         const spvc_reflected_resource *texture_sampler_list = nullptr;
  60.         size_t texture_sampler_count;
  61.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE, &texture_sampler_list, &texture_sampler_count);
  62.         for (uint32_t i = 0; i < texture_sampler_count; ++i) {
  63.             std::string name = spvc_compiler_get_name(compiler_glsl, texture_sampler_list[i].id);
  64.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, texture_sampler_list[i].type_id);
  65.             spvc_basetype base_type = spvc_type_get_basetype(type);
  66.             uint32_t descriptor_count = 1;
  67.             uint32_t num_array_dims = spvc_type_get_num_array_dimensions(type);
  68.             if (num_array_dims==1) {
  69.                 descriptor_count = spvc_type_get_array_dimension(type, 0);
  70.             }
  71.             VK_UniformInfo uniform_info{};
  72.             if (descriptor_count == 0) {
  73.                 uniform_info.variable_size = true;
  74.                 descriptor_count = limits.maxPerStageDescriptorSamplers;
  75.             }
  76.             VkDescriptorSetLayoutBinding layout_binding = {};
  77.             layout_binding.binding = spvc_compiler_get_decoration(compiler_glsl, texture_sampler_list[i].id, SpvDecorationBinding);
  78.             layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  79.             layout_binding.stageFlags = vk_stage;
  80.             layout_binding.descriptorCount = descriptor_count;//this is for arrays
  81.             layout_binding.pImmutableSamplers = nullptr;
  82.             uniform_info.layout_binding = layout_binding;
  83.             uniform_info.name = name;
  84.             uniform_info.size = 0;
  85.             uniforms.emplace_back(uniform_info);
  86.         }
  87.         //--------------------------------------------------------IMAGE----------------------------------------
  88.         const spvc_reflected_resource *separate_image_list;
  89.         size_t separate_image_count;
  90.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_SEPARATE_IMAGE, &separate_image_list, &separate_image_count);
  91.         for (uint32_t i = 0; i < separate_image_count; ++i) {
  92.             std::string name = spvc_compiler_get_name(compiler_glsl, separate_image_list[i].id);
  93.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, separate_image_list[i].type_id);
  94.             uint32_t descriptor_count = 1;
  95.             if (spvc_type_get_image_arrayed(type)) {
  96.                 descriptor_count = spvc_type_get_array_dimension(type, 0);
  97.             }
  98.             VK_UniformInfo uniform_info{};
  99.             if (descriptor_count == 0) {
  100.                 uniform_info.variable_size = true;
  101.                 descriptor_count = limits.maxPerStageDescriptorSampledImages;
  102.             }
  103.             VkDescriptorSetLayoutBinding layout_binding = {};
  104.             layout_binding.binding = spvc_compiler_get_decoration(compiler_glsl, separate_image_list[i].id, SpvDecorationBinding);
  105.             layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
  106.             layout_binding.stageFlags = vk_stage;
  107.             layout_binding.descriptorCount = descriptor_count;//this is for array
  108.             layout_binding.pImmutableSamplers = nullptr;
  109.             uniform_info.layout_binding = layout_binding;
  110.             uniform_info.name = name;
  111.             uniform_info.size = 0;
  112.             uniforms.emplace_back(uniform_info);
  113.         }
  114.         //--------------------------------------------------------STORAGE_IMAGES----------------------------------------
  115.         const spvc_reflected_resource *storage_image_list;
  116.         size_t storage_image_count;
  117.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STORAGE_IMAGE, &storage_image_list, &storage_image_count);
  118.         for (uint32_t i = 0; i < storage_image_count; ++i) {
  119.             std::string name = spvc_compiler_get_name(compiler_glsl, storage_image_list[i].id);
  120.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, storage_image_list[i].type_id);
  121.             uint32_t descriptor_count = 1;
  122.             uint32_t array_dimension = spvc_type_get_num_array_dimensions(type);
  123.             if (array_dimension == 1) {
  124.                 descriptor_count = spvc_type_get_array_dimension(type, 0);
  125.             }
  126.             VK_UniformInfo uniform_info{};
  127.             if (descriptor_count == 0) {
  128.                 uniform_info.variable_size = true;
  129.                 descriptor_count = limits.maxPerStageDescriptorStorageImages;
  130.             }
  131.             VkDescriptorSetLayoutBinding layout_binding = {};
  132.             layout_binding.binding = spvc_compiler_get_decoration(compiler_glsl, storage_image_list[i].id, SpvDecorationBinding);
  133.             layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
  134.             layout_binding.stageFlags = vk_stage;
  135.             layout_binding.descriptorCount = descriptor_count;//this is for array
  136.             layout_binding.pImmutableSamplers = nullptr;
  137.             uniform_info.layout_binding = layout_binding;
  138.             uniform_info.name = name;
  139.             uniform_info.size = 0;
  140.             uniforms.emplace_back(uniform_info);
  141.         }
  142.         //----------------------------------------------------------ACCELERATION_STRUCTURES----------------------------------------------------------
  143.         const spvc_reflected_resource *acceleration_structure_list;
  144.         size_t acceleration_structure_count;
  145.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE, &acceleration_structure_list, &acceleration_structure_count);
  146.         for (uint32_t i = 0; i < acceleration_structure_count; ++i) {
  147.             std::string name = spvc_compiler_get_name(compiler_glsl, acceleration_structure_list[i].id);
  148.             VK_UniformInfo uniform_info{};
  149.             VkDescriptorSetLayoutBinding layout_binding = {};
  150.             layout_binding.binding = spvc_compiler_get_decoration(compiler_glsl, acceleration_structure_list[i].id, SpvDecorationBinding);
  151.             layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
  152.             layout_binding.stageFlags = vk_stage;
  153.             layout_binding.descriptorCount = 1;//this is for array
  154.             layout_binding.pImmutableSamplers = nullptr;
  155.             uniform_info.layout_binding = layout_binding;
  156.             uniform_info.name = name;
  157.             uniform_info.size = 0;
  158.             uniforms.emplace_back(uniform_info);
  159.         }
  160.         //----------------------------------------------------------STORAGE BUFFERS----------------------------------------------------------
  161.         const spvc_reflected_resource *buffer_list = nullptr;
  162.         size_t buffer_count = 0;
  163.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STORAGE_BUFFER, &buffer_list, &buffer_count);
  164.         for (uint32_t i = 0; i < buffer_count; ++i) {
  165.             uint32_t descriptor_count = 1;
  166.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, buffer_list[i].type_id);
  167.             uint32_t array_dimension = spvc_type_get_num_array_dimensions(type);
  168.             if (array_dimension == 1) {
  169.                 descriptor_count = spvc_type_get_array_dimension(type, 0);
  170.             }
  171.             std::string name = spvc_compiler_get_name(compiler_glsl, buffer_list[i].id);
  172.             VK_UniformInfo uniform_info{};
  173.             if (descriptor_count == 0) {
  174.                 uniform_info.variable_size = true;
  175.                 descriptor_count = limits.maxPerStageDescriptorStorageBuffers;
  176.             }
  177.             VkDescriptorSetLayoutBinding layout_binding = {};
  178.             layout_binding.binding = spvc_compiler_get_decoration(compiler_glsl, buffer_list[i].id, SpvDecorationBinding);
  179.             layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
  180.             layout_binding.stageFlags = vk_stage;
  181.             layout_binding.descriptorCount = descriptor_count;//this is for array
  182.             layout_binding.pImmutableSamplers = nullptr;
  183.             uniform_info.layout_binding = layout_binding;
  184.             uniform_info.name = name;
  185.             uniform_info.size = 0;
  186.             uniforms.emplace_back(uniform_info);
  187.         }
  188.         //----------------------------------------------------------STORAGE TEXEL BUFFERS----------------------------------------------------------
  189.         const spvc_reflected_resource *texel_buffer_list = nullptr;
  190.         size_t texel_buffer_count = 0;
  191.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STORAGE_BUFFER, &texel_buffer_list, &buffer_count);
  192.         for (uint32_t i = 0; i < buffer_count; ++i) {
  193.             uint32_t descriptor_count = 1;
  194.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, texel_buffer_list[i].type_id);
  195.             uint32_t array_dimension = spvc_type_get_num_array_dimensions(type);
  196.             if (array_dimension == 1) {
  197.                 descriptor_count = spvc_type_get_array_dimension(type, 0);
  198.             }
  199.             std::string name = spvc_compiler_get_name(compiler_glsl, texel_buffer_list[i].id);
  200.             VK_UniformInfo uniform_info{};
  201.             if (descriptor_count == 0) {
  202.                 uniform_info.variable_size = true;
  203.                 descriptor_count = limits.maxPerStageDescriptorStorageBuffers;
  204.             }
  205.             VkDescriptorSetLayoutBinding layout_binding = {};
  206.             layout_binding.binding = spvc_compiler_get_decoration(compiler_glsl, texel_buffer_list[i].id, SpvDecorationBinding);
  207.             layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
  208.             layout_binding.stageFlags = vk_stage;
  209.             layout_binding.descriptorCount = descriptor_count;//this is for array
  210.             layout_binding.pImmutableSamplers = nullptr;
  211.             uniform_info.layout_binding = layout_binding;
  212.             uniform_info.name = name;
  213.             uniform_info.size = 0;
  214.             uniforms.emplace_back(uniform_info);
  215.         }
  216.         //----------------------------------------------------------VERTEX INPUTS-----------------------------
  217.         const spvc_reflected_resource *vertex_input_list = nullptr;
  218.         size_t vertex_inputs_count;
  219.         spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STAGE_INPUT, &vertex_input_list, &vertex_inputs_count);
  220.         for (size_t i = 0; i < vertex_inputs_count; ++i) {
  221.             spvc_type type = spvc_compiler_get_type_handle(compiler_glsl, vertex_input_list[i].type_id);
  222.             spvc_basetype basetype = spvc_type_get_basetype(type);
  223.             size_t size;
  224.             size = spvc_type_get_vector_size(type);
  225.             size_t num_col = spvc_type_get_columns(type);
  226.             uint32_t location = spvc_compiler_get_decoration(compiler_glsl, vertex_input_list[i].id, SpvDecorationLocation);
  227.             for (size_t j = 0; j < num_col; ++j) {
  228.                 VK_VertexInputInfo attribute_description{};
  229.                 attribute_description.location = location;
  230.                 attribute_description.size = size * 4;
  231.                 switch (size) {
  232.                     case 1:
  233.                         if (basetype == spvc_basetype::SPVC_BASETYPE_FP32)
  234.                             attribute_description.format = VK_FORMAT_R32_SFLOAT;
  235.                         else if (basetype == spvc_basetype::SPVC_BASETYPE_UINT32)
  236.                             attribute_description.format = VK_FORMAT_R32_UINT;
  237.                         break;
  238.                     case 2:
  239.                         if (basetype == spvc_basetype::SPVC_BASETYPE_FP32)
  240.                             attribute_description.format = VK_FORMAT_R32G32_SFLOAT;
  241.                         else if (basetype == spvc_basetype::SPVC_BASETYPE_UINT32)
  242.                             attribute_description.format = VK_FORMAT_R32G32_UINT;
  243.                         break;
  244.                     case 3:
  245.                         if (basetype == spvc_basetype::SPVC_BASETYPE_FP32)
  246.                             attribute_description.format = VK_FORMAT_R32G32B32_SFLOAT;
  247.                         else if (basetype == spvc_basetype::SPVC_BASETYPE_UINT32)
  248.                             attribute_description.format = VK_FORMAT_R32G32B32_UINT;
  249.                         break;
  250.                     case 4:
  251.                         if (basetype == spvc_basetype::SPVC_BASETYPE_FP32)
  252.                             attribute_description.format = VK_FORMAT_R32G32B32A32_SFLOAT;
  253.                         else if (basetype == spvc_basetype::SPVC_BASETYPE_UINT32)
  254.                             attribute_description.format = VK_FORMAT_R32G32B32A32_UINT;
  255.                         break;
  256.                 }
  257.                 vertex_inputs.emplace_back(attribute_description);
  258.                 location++;
  259.             }
  260.         }
  261.         std::sort(uniforms.begin(), uniforms.end(),
  262.                   [](const VK_UniformInfo &a, const VK_UniformInfo &b) -> bool {
  263.                       return a.layout_binding.binding < b.layout_binding.binding;
  264.                   });
  265.         std::sort(vertex_inputs.begin(), vertex_inputs.end(),
  266.                   [](const VK_VertexInputInfo &a, const VK_VertexInputInfo &b) -> bool {
  267.                       return a.location < b.location;
  268.                   });
  269.         spvc_context_release_allocations(context);
  270.         spvc_context_destroy(context);
  271.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement