tu: Support pipelines without a fragment shader
authorConnor Abbott <cwabbott0@gmail.com>
Wed, 6 May 2020 22:07:48 +0000 (00:07 +0200)
committerMarge Bot <eric+marge@anholt.net>
Thu, 7 May 2020 16:05:53 +0000 (16:05 +0000)
Apparently this is allowed, and the CTS started doing this more often
recently which resulted in frequent hangs running the entire CTS. I
copied the code to create an empty FS from radv.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4928>

src/freedreno/vulkan/tu_pipeline.c
src/freedreno/vulkan/tu_shader.c

index 1e376a120b5566a96ca371e9cf8755ae2fdb5c56..3362945728928880de0c449b5874f918ea10a130 100644 (file)
@@ -2116,7 +2116,7 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder)
    for (gl_shader_stage stage = MESA_SHADER_STAGES - 1;
         stage > MESA_SHADER_NONE; stage--) {
       const VkPipelineShaderStageCreateInfo *stage_info = stage_infos[stage];
    for (gl_shader_stage stage = MESA_SHADER_STAGES - 1;
         stage > MESA_SHADER_NONE; stage--) {
       const VkPipelineShaderStageCreateInfo *stage_info = stage_infos[stage];
-      if (!stage_info)
+      if (!stage_info && stage != MESA_SHADER_FRAGMENT)
          continue;
 
       struct tu_shader *shader =
          continue;
 
       struct tu_shader *shader =
index 33826e37691db5e75fc76aae1e281bcc6c8e06fd..4fda6538fdf8b4ed5bbcf47dec68ca93b1808f75 100644 (file)
@@ -472,8 +472,6 @@ tu_shader_create(struct tu_device *dev,
                  struct tu_pipeline_layout *layout,
                  const VkAllocationCallbacks *alloc)
 {
                  struct tu_pipeline_layout *layout,
                  const VkAllocationCallbacks *alloc)
 {
-   const struct tu_shader_module *module =
-      tu_shader_module_from_handle(stage_info->module);
    struct tu_shader *shader;
 
    const uint32_t max_variant_count = (stage == MESA_SHADER_VERTEX) ? 2 : 1;
    struct tu_shader *shader;
 
    const uint32_t max_variant_count = (stage == MESA_SHADER_VERTEX) ? 2 : 1;
@@ -484,11 +482,25 @@ tu_shader_create(struct tu_device *dev,
    if (!shader)
       return NULL;
 
    if (!shader)
       return NULL;
 
-   /* translate SPIR-V to NIR */
-   assert(module->code_size % 4 == 0);
-   nir_shader *nir = tu_spirv_to_nir(
-      dev->compiler, (const uint32_t *) module->code, module->code_size / 4,
-      stage, stage_info->pName, stage_info->pSpecializationInfo);
+   nir_shader *nir;
+   if (stage_info) {
+      /* translate SPIR-V to NIR */
+      const struct tu_shader_module *module =
+         tu_shader_module_from_handle(stage_info->module);
+      assert(module->code_size % 4 == 0);
+      nir = tu_spirv_to_nir(
+         dev->compiler, (const uint32_t *) module->code, module->code_size / 4,
+         stage, stage_info->pName, stage_info->pSpecializationInfo);
+   } else {
+      assert(stage == MESA_SHADER_FRAGMENT);
+      nir_builder fs_b;
+      const nir_shader_compiler_options *nir_options =
+         ir3_get_compiler_options(dev->compiler);
+      nir_builder_init_simple_shader(&fs_b, NULL, MESA_SHADER_FRAGMENT, nir_options);
+      fs_b.shader->info.name = ralloc_strdup(fs_b.shader, "noop_fs");
+      nir = fs_b.shader;
+   }
+
    if (!nir) {
       vk_free2(&dev->alloc, alloc, shader);
       return NULL;
    if (!nir) {
       vk_free2(&dev->alloc, alloc, shader);
       return NULL;