<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Jan 8, 2017 at 9:26 PM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>><br>
---<br>
 src/intel/vulkan/anv_<wbr>pipeline.c | 156 ++++++++++++++++++++++++++++++<wbr>+++++++++-<br>
 1 file changed, 154 insertions(+), 2 deletions(-)<br>
<br>
There's one majorly bogus thing here: caching is totally disabled.<br>
We set key fields based on the NIR, which breaks the dataflow expectations<br>
for the program cache.  A few of those we could look up from the SPIR-V.<br>
Others...not so much.  I'm not sure what to do about it.<br>
<br>
Another somewhat bogus thing: we might need to apply the PointMode "it can<br>
be in either stage" hack to more fields.  It's ugly, but unfortunately<br>
SPIR-V opted not to decide, so we have to look in either place...<br>
<br>
diff --git a/src/intel/vulkan/anv_pipelin<wbr>e.c b/src/intel/vulkan/anv_pipelin<wbr>e.c<br>
index b34759a5406..743f82ad69c 100644<br>
--- a/src/intel/vulkan/anv_pipelin<wbr>e.c<br>
+++ b/src/intel/vulkan/anv_pipelin<wbr>e.c<br>
@@ -492,6 +492,151 @@ anv_pipeline_compile_vs(struct anv_pipeline *pipeline,<br>
 }<br>
<br>
 static VkResult<br>
+anv_pipeline_compile_tcs_tes(<wbr>struct anv_pipeline *pipeline,<br>
+                             struct anv_pipeline_cache *cache,<br>
+                             const VkGraphicsPipelineCreateInfo *info,<br>
+                             struct anv_shader_module *tcs_module,<br>
+                             const char *tcs_entrypoint,<br>
+                             const VkSpecializationInfo *tcs_spec_info,<br>
+                             struct anv_shader_module *tes_module,<br>
+                             const char *tes_entrypoint,<br>
+                             const VkSpecializationInfo *tes_spec_info)<br>
+{<br>
+   const struct gen_device_info *devinfo = &pipeline->device->info;<br>
+   const struct brw_compiler *compiler =<br>
+      pipeline->device->instance->ph<wbr>ysicalDevice.compiler;<br>
+   struct anv_pipeline_bind_map tcs_map;<br>
+   struct anv_pipeline_bind_map tes_map;<br>
+   struct brw_tcs_prog_key tcs_key = { 0, };<br>
+   struct brw_tes_prog_key tes_key = { 0, };<br>
+   struct anv_shader_bin *tcs_bin = NULL;<br>
+   struct anv_shader_bin *tes_bin = NULL;<br>
+   unsigned char tcs_sha1[20];<br>
+   unsigned char tes_sha1[20];<br>
+<br>
+   populate_sampler_prog_key(&pi<wbr>peline->device->info, &tcs_key.tex);<br>
+   populate_sampler_prog_key(&pi<wbr>peline->device->info, &tes_key.tex);<br>
+   tcs_key.input_vertices = info->pTessellationState->patc<wbr>hControlPoints;<br>
+<br>
+   if (tcs_module->size > 0 || tes_module->size > 0) {<br>
+      anv_hash_shader(tcs_sha1, &tcs_key, sizeof(tcs_key), tcs_module,<br>
+                      tcs_entrypoint, pipeline->layout, tcs_spec_info);<br>
+      anv_hash_shader(tes_sha1, &tes_key, sizeof(tes_key), tes_module,<br>
+                      tes_entrypoint, pipeline->layout, tes_spec_info);<br>
+      //tcs_bin = anv_pipeline_cache_search(cach<wbr>e, tcs_sha1, 20);<br>
+      //tes_bin = anv_pipeline_cache_search(cach<wbr>e, tes_sha1, 20);<br></blockquote><div><br></div><div>Um... Did you intend to leave these commented out?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   }<br>
+<br>
+   if (tcs_bin == NULL || tes_bin == NULL) {<br>
+      struct brw_tcs_prog_data tcs_prog_data = { 0, };<br>
+      struct brw_tes_prog_data tes_prog_data = { 0, };<br>
+      struct anv_pipeline_binding tcs_surface_to_descriptor[256]<wbr>;<br>
+      struct anv_pipeline_binding tcs_sampler_to_descriptor[256]<wbr>;<br>
+      struct anv_pipeline_binding tes_surface_to_descriptor[256]<wbr>;<br>
+      struct anv_pipeline_binding tes_sampler_to_descriptor[256]<wbr>;<br>
+<br>
+      tcs_map = (struct anv_pipeline_bind_map) {<br>
+         .surface_to_descriptor = tcs_surface_to_descriptor,<br>
+         .sampler_to_descriptor = tcs_sampler_to_descriptor<br>
+      };<br>
+      tes_map = (struct anv_pipeline_bind_map) {<br>
+         .surface_to_descriptor = tes_surface_to_descriptor,<br>
+         .sampler_to_descriptor = tes_sampler_to_descriptor<br>
+      };<br>
+<br>
+      nir_shader *tcs_nir =<br>
+         anv_pipeline_compile(<wbr>pipeline, tcs_module, tcs_entrypoint,<br>
+                              MESA_SHADER_TESS_CTRL, tcs_spec_info,<br>
+                              &tcs_prog_data.base.base, &tcs_map);<br>
+      nir_shader *tes_nir =<br>
+         anv_pipeline_compile(<wbr>pipeline, tes_module, tes_entrypoint,<br>
+                              MESA_SHADER_TESS_EVAL, tes_spec_info,<br>
+                              &tes_prog_data.base.base, &tes_map);<br>
+      if (tcs_nir == NULL || tes_nir == NULL)<br>
+         return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
+<br>
+      nir_lower_tes_patch_vertices(t<wbr>es_nir, tcs_nir->info->tcs.vertices_ou<wbr>t);<br>
+<br>
+      /* The Vulkan 1.0.29 spec, section 21.1 Tessellator says:<br>
+       *<br>
+       *    "PointMode. Controls generation of points rather than triangles<br>
+       *     or lines. This functionality defaults to disabled, and is<br>
+       *     enabled if either shader stage includes the execution mode.<br>
+       *<br>
+       * The backend looks at the TES, so OR in the flag from the TCS.<br>
+       */<br>
+      tes_nir->info->tes.point_mode |= tcs_nir->info->tes.point_mode;<br></blockquote><div><br></div><div>tes and tcs are in a union in shader_info so if we need point_mode available in both stages, we need to either add it to both or pull it out and make it apply to all stages.  I think I'd prefer the former but we need to be more careful here.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+      anv_fill_binding_table(&tcs_pr<wbr>og_data.base.base, 0);<br>
+      anv_fill_binding_table(&tes_pr<wbr>og_data.base.base, 0);<br>
+<br>
+      void *mem_ctx = ralloc_context(NULL);<br>
+<br>
+      ralloc_steal(mem_ctx, tcs_nir);<br>
+      ralloc_steal(mem_ctx, tes_nir);<br>
+<br>
+      tcs_key.tes_primitive_mode = tes_nir->info->tes.primitive_m<wbr>ode;<br>
+      tcs_key.outputs_written = tcs_nir->info->outputs_written<wbr>;<br>
+      tcs_key.patch_outputs_written = tcs_nir->info->patch_outputs_w<wbr>ritten;<br>
+      tcs_key.quads_workaround =<br>
+         devinfo->gen < 9 &&<br>
+         tes_nir->info->tes.primitive_<wbr>mode == 7 /* GL_QUADS */ &&<br>
+         tes_nir->info->tes.spacing == TESS_SPACING_EQUAL;<br></blockquote><div><br></div><div>Why are all of these in the key if we pull them out of shader_info?  Is GL more dynamic about them?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+      tes_key.inputs_read = tcs_key.outputs_written;<br>
+      tes_key.patch_inputs_read = tcs_key.patch_outputs_written;<br>
+<br>
+      unsigned code_size;<br>
+      const int shader_time_index = -1;<br>
+      const unsigned *shader_code;<br>
+<br>
+      shader_code =<br>
+         brw_compile_tcs(compiler, NULL, mem_ctx, &tcs_key, &tcs_prog_data,<br>
+                         tcs_nir, shader_time_index, &code_size, NULL);<br>
+      if (shader_code == NULL) {<br>
+         ralloc_free(mem_ctx);<br>
+         return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
+      }<br>
+<br>
+      tcs_bin = anv_pipeline_upload_kernel(pip<wbr>eline, cache, tcs_sha1, 20,<br>
+                                           shader_code, code_size,<br>
+                                           &tcs_prog_data.base.base,<br>
+                                           sizeof(tcs_prog_data),<br>
+                                           &tcs_map);<br>
+      if (!tcs_bin) {<br>
+         ralloc_free(mem_ctx);<br>
+         return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
+      }<br>
+<br>
+      shader_code =<br>
+         brw_compile_tes(compiler, NULL, mem_ctx, &tes_key,<br>
+                         &tcs_prog_data.base.vue_map, &tes_prog_data, tes_nir,<br>
+                         NULL, shader_time_index, &code_size, NULL);<br>
+      if (shader_code == NULL) {<br>
+         ralloc_free(mem_ctx);<br>
+         return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
+      }<br>
+<br>
+      tes_bin = anv_pipeline_upload_kernel(pip<wbr>eline, cache, tes_sha1, 20,<br>
+                                           shader_code, code_size,<br>
+                                           &tes_prog_data.base.base,<br>
+                                           sizeof(tes_prog_data),<br>
+                                           &tes_map);<br>
+      if (!tes_bin) {<br>
+         ralloc_free(mem_ctx);<br>
+         return vk_error(VK_ERROR_OUT_OF_HOST_<wbr>MEMORY);<br>
+      }<br>
+<br>
+      ralloc_free(mem_ctx);<br>
+   }<br>
+<br>
+   anv_pipeline_add_compiled_sta<wbr>ge(pipeline, MESA_SHADER_TESS_CTRL, tcs_bin);<br>
+   anv_pipeline_add_compiled_sta<wbr>ge(pipeline, MESA_SHADER_TESS_EVAL, tes_bin);<br>
+<br>
+   return VK_SUCCESS;<br>
+}<br>
+<br>
+static VkResult<br>
 anv_pipeline_compile_gs(<wbr>struct anv_pipeline *pipeline,<br>
                         struct anv_pipeline_cache *cache,<br>
                         const VkGraphicsPipelineCreateInfo *info,<br>
@@ -1024,8 +1169,15 @@ anv_pipeline_init(struct anv_pipeline *pipeline,<br>
          goto compile_fail;<br>
    }<br>
<br>
-   if (modules[MESA_SHADER_TESS_CTRL<wbr>] || modules[MESA_SHADER_TESS_EVAL]<wbr>)<br>
-      anv_finishme("no tessellation support");<br>
+   if (modules[MESA_SHADER_TESS_EVAL<wbr>]) {<br>
+      anv_pipeline_compile_tcs_tes(p<wbr>ipeline, cache, pCreateInfo,<br>
+                                   modules[MESA_SHADER_TESS_<wbr>CTRL],<br>
+                                   pStages[MESA_SHADER_TESS_<wbr>CTRL]->pName,<br>
+                                   pStages[MESA_SHADER_TESS_<wbr>CTRL]->pSpecializationInfo,<br>
+                                   modules[MESA_SHADER_TESS_<wbr>EVAL],<br>
+                                   pStages[MESA_SHADER_TESS_<wbr>EVAL]->pName,<br>
+                                   pStages[MESA_SHADER_TESS_<wbr>EVAL]->pSpecializationInfo);<br>
+   }<br>
<br>
    if (modules[MESA_SHADER_GEOMETRY]<wbr>) {<br>
       result = anv_pipeline_compile_gs(pipeli<wbr>ne, cache, pCreateInfo,<br>
<span class="m_-4638062333385878654HOEnZb"><font color="#888888">--<br>
2.11.0<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>