anv/pipeline: Call nir_gather_info later
[mesa.git] / src / intel / vulkan / anv_pipeline.c
index 7d939ebabe94565172f629c946e1251d26248b6b..599286c216945f1783f4a1464e5cb939c46bfb00 100644 (file)
@@ -30,7 +30,7 @@
 #include "util/mesa-sha1.h"
 #include "common/gen_l3_config.h"
 #include "anv_private.h"
-#include "brw_nir.h"
+#include "compiler/brw_nir.h"
 #include "anv_nir.h"
 #include "spirv/nir_spirv.h"
 
@@ -87,15 +87,13 @@ void anv_DestroyShaderModule(
  * we can't do that yet because we don't have the ability to copy nir.
  */
 static nir_shader *
-anv_shader_compile_to_nir(struct anv_device *device,
+anv_shader_compile_to_nir(struct anv_pipeline *pipeline,
                           struct anv_shader_module *module,
                           const char *entrypoint_name,
                           gl_shader_stage stage,
                           const VkSpecializationInfo *spec_info)
 {
-   if (strcmp(entrypoint_name, "main") != 0) {
-      anv_finishme("Multiple shaders per module not really supported");
-   }
+   const struct anv_device *device = pipeline->device;
 
    const struct brw_compiler *compiler =
       device->instance->physicalDevice.compiler;
@@ -126,7 +124,10 @@ anv_shader_compile_to_nir(struct anv_device *device,
 
    const struct nir_spirv_supported_extensions supported_ext = {
       .float64 = device->instance->physicalDevice.info.gen >= 8,
+      .int64 = device->instance->physicalDevice.info.gen >= 8,
       .tessellation = true,
+      .draw_parameters = true,
+      .image_write_without_format = true,
    };
 
    nir_function *entry_point =
@@ -159,7 +160,7 @@ anv_shader_compile_to_nir(struct anv_device *device,
               nir_var_shader_in | nir_var_shader_out | nir_var_system_value);
 
    if (stage == MESA_SHADER_FRAGMENT)
-      NIR_PASS_V(nir, nir_lower_wpos_center);
+      NIR_PASS_V(nir, nir_lower_wpos_center, pipeline->sample_shading_enable);
 
    /* Now that we've deleted all but the main function, we can go ahead and
     * lower the rest of the constant initializers.
@@ -180,8 +181,6 @@ anv_shader_compile_to_nir(struct anv_device *device,
    if (stage == MESA_SHADER_FRAGMENT)
       NIR_PASS_V(nir, anv_nir_lower_input_attachments);
 
-   nir_shader_gather_info(nir, entry_point->impl);
-
    return nir;
 }
 
@@ -226,6 +225,25 @@ static void
 populate_sampler_prog_key(const struct gen_device_info *devinfo,
                           struct brw_sampler_prog_key_data *key)
 {
+   /* Almost all multisampled textures are compressed.  The only time when we
+    * don't compress a multisampled texture is for 16x MSAA with a surface
+    * width greater than 8k which is a bit of an edge case.  Since the sampler
+    * just ignores the MCS parameter to ld2ms when MCS is disabled, it's safe
+    * to tell the compiler to always assume compression.
+    */
+   key->compressed_multisample_layout_mask = ~0;
+
+   /* SkyLake added support for 16x MSAA.  With this came a new message for
+    * reading from a 16x MSAA surface with compression.  The new message was
+    * needed because now the MCS data is 64 bits instead of 32 or lower as is
+    * the case for 8x, 4x, and 2x.  The key->msaa_16 bit-field controls which
+    * message we use.  Fortunately, the 16x message works for 8x, 4x, and 2x
+    * so we can just use it unconditionally.  This may not be quite as
+    * efficient but it saves us from recompiling.
+    */
+   if (devinfo->gen >= 9)
+      key->msaa_16 = ~0;
+
    /* XXX: Handle texture swizzle on HSW- */
    for (int i = 0; i < MAX_SAMPLERS; i++) {
       /* Assume color sampler, no swizzling. (Works for BDW+) */
@@ -270,7 +288,7 @@ populate_wm_prog_key(const struct anv_pipeline *pipeline,
    /* TODO: we could set this to 0 based on the information in nir_shader, but
     * this function is called before spirv_to_nir. */
    const struct brw_vue_map *vue_map =
-      anv_pipeline_get_fs_input_map(pipeline);
+      &anv_pipeline_get_last_vue_prog_data(pipeline)->vue_map;
    key->input_slots_valid = vue_map->slots_valid;
 
    /* Vulkan doesn't specify a default */
@@ -286,14 +304,19 @@ populate_wm_prog_key(const struct anv_pipeline *pipeline,
                           info->pMultisampleState &&
                           info->pMultisampleState->alphaToCoverageEnable;
 
-   if (info->pMultisampleState && info->pMultisampleState->rasterizationSamples > 1) {
+   if (info->pMultisampleState) {
       /* We should probably pull this out of the shader, but it's fairly
        * harmless to compute it and then let dead-code take care of it.
        */
-      key->persample_interp =
-         (info->pMultisampleState->minSampleShading *
-          info->pMultisampleState->rasterizationSamples) > 1;
-      key->multisample_fbo = true;
+      if (info->pMultisampleState->rasterizationSamples > 1) {
+         key->persample_interp =
+            (info->pMultisampleState->minSampleShading *
+             info->pMultisampleState->rasterizationSamples) > 1;
+         key->multisample_fbo = true;
+      }
+
+      key->frag_coord_adds_sample_pos =
+         info->pMultisampleState->sampleShadingEnable;
    }
 }
 
@@ -306,6 +329,34 @@ populate_cs_prog_key(const struct gen_device_info *devinfo,
    populate_sampler_prog_key(devinfo, &key->tex);
 }
 
+static void
+anv_pipeline_hash_shader(struct anv_pipeline *pipeline,
+                         struct anv_shader_module *module,
+                         const char *entrypoint,
+                         gl_shader_stage stage,
+                         const VkSpecializationInfo *spec_info,
+                         const void *key, size_t key_size,
+                         unsigned char *sha1_out)
+{
+   struct mesa_sha1 ctx;
+
+   _mesa_sha1_init(&ctx);
+   if (pipeline->layout) {
+      _mesa_sha1_update(&ctx, pipeline->layout->sha1,
+                        sizeof(pipeline->layout->sha1));
+   }
+   _mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
+   _mesa_sha1_update(&ctx, entrypoint, strlen(entrypoint));
+   _mesa_sha1_update(&ctx, &stage, sizeof(stage));
+   if (spec_info) {
+      _mesa_sha1_update(&ctx, spec_info->pMapEntries,
+                        spec_info->mapEntryCount * sizeof(*spec_info->pMapEntries));
+      _mesa_sha1_update(&ctx, spec_info->pData, spec_info->dataSize);
+   }
+   _mesa_sha1_update(&ctx, key, key_size);
+   _mesa_sha1_final(&ctx, sha1_out);
+}
+
 static nir_shader *
 anv_pipeline_compile(struct anv_pipeline *pipeline,
                      struct anv_shader_module *module,
@@ -315,7 +366,7 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
                      struct brw_stage_prog_data *prog_data,
                      struct anv_pipeline_bind_map *map)
 {
-   nir_shader *nir = anv_shader_compile_to_nir(pipeline->device,
+   nir_shader *nir = anv_shader_compile_to_nir(pipeline,
                                                module, entrypoint, stage,
                                                spec_info);
    if (nir == NULL)
@@ -323,6 +374,8 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
 
    NIR_PASS_V(nir, anv_nir_lower_push_constants);
 
+   nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
+
    /* Figure out the number of parameters */
    prog_data->nr_params = 0;
 
@@ -334,9 +387,6 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
       prog_data->nr_params += MAX_PUSH_CONSTANTS_SIZE / sizeof(float);
    }
 
-   if (pipeline->layout && pipeline->layout->stage[stage].has_dynamic_offsets)
-      prog_data->nr_params += MAX_DYNAMIC_BUFFERS * 2;
-
    if (nir->info->num_images > 0) {
       prog_data->nr_params += nir->info->num_images * BRW_IMAGE_PARAM_SIZE;
       pipeline->needs_data_cache = true;
@@ -368,9 +418,6 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
       }
    }
 
-   /* Set up dynamic offsets */
-   anv_nir_apply_dynamic_offsets(pipeline, nir, prog_data);
-
    /* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
    if (pipeline->layout)
       anv_nir_apply_pipeline_layout(pipeline, nir, prog_data, map);
@@ -444,8 +491,9 @@ anv_pipeline_compile_vs(struct anv_pipeline *pipeline,
    populate_vs_prog_key(&pipeline->device->info, &key);
 
    if (cache) {
-      anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
-                      pipeline->layout, spec_info);
+      anv_pipeline_hash_shader(pipeline, module, entrypoint,
+                               MESA_SHADER_VERTEX, spec_info,
+                               &key, sizeof(key), sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -568,10 +616,12 @@ anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline,
    tcs_key.input_vertices = info->pTessellationState->patchControlPoints;
 
    if (cache) {
-      anv_hash_shader(tcs_sha1, &tcs_key, sizeof(tcs_key), tcs_module,
-                      tcs_entrypoint, pipeline->layout, tcs_spec_info);
-      anv_hash_shader(tes_sha1, &tes_key, sizeof(tes_key), tes_module,
-                      tes_entrypoint, pipeline->layout, tes_spec_info);
+      anv_pipeline_hash_shader(pipeline, tcs_module, tcs_entrypoint,
+                               MESA_SHADER_TESS_CTRL, tcs_spec_info,
+                               &tcs_key, sizeof(tcs_key), tcs_sha1);
+      anv_pipeline_hash_shader(pipeline, tes_module, tes_entrypoint,
+                               MESA_SHADER_TESS_EVAL, tes_spec_info,
+                               &tes_key, sizeof(tes_key), tes_sha1);
       memcpy(&tcs_sha1[20], tes_sha1, 20);
       memcpy(&tes_sha1[20], tcs_sha1, 20);
       tcs_bin = anv_pipeline_cache_search(cache, tcs_sha1, sizeof(tcs_sha1));
@@ -705,8 +755,9 @@ anv_pipeline_compile_gs(struct anv_pipeline *pipeline,
    populate_gs_prog_key(&pipeline->device->info, &key);
 
    if (cache) {
-      anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
-                      pipeline->layout, spec_info);
+      anv_pipeline_hash_shader(pipeline, module, entrypoint,
+                               MESA_SHADER_GEOMETRY, spec_info,
+                               &key, sizeof(key), sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -782,8 +833,9 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
    populate_wm_prog_key(pipeline, info, &key);
 
    if (cache) {
-      anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
-                      pipeline->layout, spec_info);
+      anv_pipeline_hash_shader(pipeline, module, entrypoint,
+                               MESA_SHADER_FRAGMENT, spec_info,
+                               &key, sizeof(key), sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -904,8 +956,9 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
    populate_cs_prog_key(&pipeline->device->info, &key);
 
    if (cache) {
-      anv_hash_shader(sha1, &key, sizeof(key), module, entrypoint,
-                      pipeline->layout, spec_info);
+      anv_pipeline_hash_shader(pipeline, module, entrypoint,
+                               MESA_SHADER_COMPUTE, spec_info,
+                               &key, sizeof(key), sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -1035,7 +1088,7 @@ copy_non_dynamic_state(struct anv_pipeline *pipeline,
     */
    bool uses_color_att = false;
    for (unsigned i = 0; i < subpass->color_count; ++i) {
-      if (subpass->color_attachments[i] != VK_ATTACHMENT_UNUSED) {
+      if (subpass->color_attachments[i].attachment != VK_ATTACHMENT_UNUSED) {
          uses_color_att = true;
          break;
       }
@@ -1063,7 +1116,7 @@ copy_non_dynamic_state(struct anv_pipeline *pipeline,
     *    against does not use a depth/stencil attachment.
     */
    if (!pCreateInfo->pRasterizationState->rasterizerDiscardEnable &&
-       subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
+       subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
       assert(pCreateInfo->pDepthStencilState);
 
       if (states & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) {
@@ -1101,6 +1154,7 @@ copy_non_dynamic_state(struct anv_pipeline *pipeline,
 static void
 anv_pipeline_validate_create_info(const VkGraphicsPipelineCreateInfo *info)
 {
+#ifdef DEBUG
    struct anv_render_pass *renderpass = NULL;
    struct anv_subpass *subpass = NULL;
 
@@ -1123,7 +1177,7 @@ anv_pipeline_validate_create_info(const VkGraphicsPipelineCreateInfo *info)
       assert(info->pViewportState);
       assert(info->pMultisampleState);
 
-      if (subpass && subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED)
+      if (subpass && subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED)
          assert(info->pDepthStencilState);
 
       if (subpass && subpass->color_count > 0)
@@ -1140,6 +1194,7 @@ anv_pipeline_validate_create_info(const VkGraphicsPipelineCreateInfo *info)
          break;
       }
    }
+#endif
 }
 
 /**
@@ -1171,9 +1226,7 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
 {
    VkResult result;
 
-   anv_validate {
-      anv_pipeline_validate_create_info(pCreateInfo);
-   }
+   anv_pipeline_validate_create_info(pCreateInfo);
 
    if (alloc == NULL)
       alloc = &device->alloc;
@@ -1189,11 +1242,15 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
    pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
    pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
    pipeline->batch.relocs = &pipeline->batch_relocs;
+   pipeline->batch.status = VK_SUCCESS;
 
    copy_non_dynamic_state(pipeline, pCreateInfo);
    pipeline->depth_clamp_enable = pCreateInfo->pRasterizationState &&
                                   pCreateInfo->pRasterizationState->depthClampEnable;
 
+   pipeline->sample_shading_enable = pCreateInfo->pMultisampleState &&
+                                     pCreateInfo->pMultisampleState->sampleShadingEnable;
+
    pipeline->needs_data_cache = false;
 
    /* When we free the pipeline, we detect stages based on the NULL status