microsoft/clc: If local size isn't specified either in the shader or at runtime,...
authorJesse Natalie <jenatali@microsoft.com>
Sun, 18 Apr 2021 00:26:37 +0000 (17:26 -0700)
committerMarge Bot <eric+marge@anholt.net>
Mon, 19 Apr 2021 15:38:57 +0000 (15:38 +0000)
Otherwise we can end up in situations like having divide-by-zero. If the optimization is smart enough
that we end up with a *constant* divide-by-zero, then the DXIL validator will fail to sign, which
can trigger fatal errors with CLOn12.

We want to run an initial translation of all kernels during program build, but at that point we don't
know the local size to be able to specify it through kernel specialization data.

v2: Metadata output of 0 is used to indicate that the size wasn't explicitly specific. Copy the
    size to the metadata before overriding it to (1,1,1). If conf was explicitly specified,
    update the metadata again (though nobody should be paying attention to it).

Closes: https://github.com/microsoft/OpenCLOn12/issues/20
Closes: https://github.com/darktable-org/darktable/issues/8700
Reviewed-By: Bill Kristiansen <billkris@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10303>

src/microsoft/clc/clc_compiler.c

index 6fc9d0c..853cc63 100644 (file)
@@ -1340,6 +1340,11 @@ clc_to_dxil(struct clc_context *ctx,
    nir_variable *work_properties_var =
       add_work_properties_var(dxil, nir, &cbv_id);
 
+   memcpy(metadata->local_size, nir->info.cs.local_size,
+          sizeof(metadata->local_size));
+   memcpy(metadata->local_size_hint, nir->info.cs.local_size_hint,
+          sizeof(metadata->local_size));
+
    // Patch the localsize before calling clc_nir_lower_system_values().
    if (conf) {
       for (unsigned i = 0; i < ARRAY_SIZE(nir->info.cs.local_size); i++) {
@@ -1355,6 +1360,14 @@ clc_to_dxil(struct clc_context *ctx,
 
          nir->info.cs.local_size[i] = conf->local_size[i];
       }
+      memcpy(metadata->local_size, nir->info.cs.local_size,
+            sizeof(metadata->local_size));
+   } else {
+      /* Make sure there's at least one thread that's set to run */
+      for (unsigned i = 0; i < ARRAY_SIZE(nir->info.cs.local_size); i++) {
+         if (nir->info.cs.local_size[i] == 0)
+            nir->info.cs.local_size[i] = 1;
+      }
    }
 
    NIR_PASS_V(nir, clc_nir_lower_kernel_input_loads, inputs_var);
@@ -1428,11 +1441,6 @@ clc_to_dxil(struct clc_context *ctx,
       goto err_free_dxil;
    }
 
-   memcpy(metadata->local_size, nir->info.cs.local_size,
-          sizeof(metadata->local_size));
-   memcpy(metadata->local_size_hint, nir->info.cs.local_size_hint,
-          sizeof(metadata->local_size));
-
    nir_foreach_variable_with_modes(var, nir, nir_var_mem_ssbo) {
       if (var->constant_initializer) {
          if (glsl_type_is_array(var->type)) {