nir: improvements to native_integers removal
[mesa.git] / src / mesa / program / program.c
index 3edeec81730a92e15c1ac2d5e0590fe056ed051a..6ab1bf50177b9919035740d622ac347cdc9fb381 100644 (file)
@@ -39,7 +39,9 @@
 #include "prog_cache.h"
 #include "prog_parameter.h"
 #include "prog_instruction.h"
+#include "util/bitscan.h"
 #include "util/ralloc.h"
+#include "util/u_atomic.h"
 
 
 /**
@@ -98,6 +100,7 @@ _mesa_init_program(struct gl_context *ctx)
                            ctx->Shared->DefaultFragmentProgram);
    assert(ctx->FragmentProgram.Current);
    ctx->FragmentProgram.Cache = _mesa_new_program_cache();
+   ctx->VertexProgram._VPMode = VP_MODE_FF;
 
    /* XXX probably move this stuff */
    ctx->ATIFragmentShader.Enabled = GL_FALSE;
@@ -181,13 +184,10 @@ struct gl_program *
 _mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id,
                       bool is_arb_asm)
 {
-   GLuint i;
-
    if (!prog)
       return NULL;
 
    memset(prog, 0, sizeof(*prog));
-   mtx_init(&prog->Mutex, mtx_plain);
    prog->Id = id;
    prog->Target = target;
    prog->RefCount = 1;
@@ -195,9 +195,22 @@ _mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id,
    prog->info.stage = _mesa_program_enum_to_shader_stage(target);
    prog->is_arb_asm = is_arb_asm;
 
-   /* default mapping from samplers to texture units */
-   for (i = 0; i < MAX_SAMPLERS; i++)
-      prog->SamplerUnits[i] = i;
+   /* Uniforms that lack an initializer in the shader code have an initial
+    * value of zero.  This includes sampler uniforms.
+    *
+    * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
+    *
+    *     "The link time initial value is either the value of the variable's
+    *     initializer, if present, or 0 if no initializer is present. Sampler
+    *     types cannot have initializers."
+    *
+    * So we only initialise ARB assembly style programs.
+    */
+   if (is_arb_asm) {
+      /* default mapping from samplers to texture units */
+      for (unsigned i = 0; i < MAX_SAMPLERS; i++)
+         prog->SamplerUnits[i] = i;
+   }
 
    return prog;
 }
@@ -260,7 +273,18 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
       ralloc_free(prog->nir);
    }
 
-   mtx_destroy(&prog->Mutex);
+   if (prog->sh.BindlessSamplers) {
+      ralloc_free(prog->sh.BindlessSamplers);
+   }
+
+   if (prog->sh.BindlessImages) {
+      ralloc_free(prog->sh.BindlessImages);
+   }
+
+   if (prog->driver_cache_blob) {
+      ralloc_free(prog->driver_cache_blob);
+   }
+
    ralloc_free(prog);
 }
 
@@ -305,17 +329,11 @@ _mesa_reference_program_(struct gl_context *ctx,
 #endif
 
    if (*ptr) {
-      GLboolean deleteFlag;
       struct gl_program *oldProg = *ptr;
 
-      mtx_lock(&oldProg->Mutex);
       assert(oldProg->RefCount > 0);
-      oldProg->RefCount--;
-
-      deleteFlag = (oldProg->RefCount == 0);
-      mtx_unlock(&oldProg->Mutex);
 
-      if (deleteFlag) {
+      if (p_atomic_dec_zero(&oldProg->RefCount)) {
          assert(ctx);
          _mesa_reference_shader_program_data(ctx, &oldProg->sh.data, NULL);
          ctx->Driver.DeleteProgram(ctx, oldProg);
@@ -326,9 +344,7 @@ _mesa_reference_program_(struct gl_context *ctx,
 
    assert(!*ptr);
    if (prog) {
-      mtx_lock(&prog->Mutex);
-      prog->RefCount++;
-      mtx_unlock(&prog->Mutex);
+      p_atomic_inc(&prog->RefCount);
    }
 
    *ptr = prog;
@@ -500,8 +516,7 @@ _mesa_find_free_register(const GLboolean used[],
  */
 GLint
 _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
-                                       const struct gl_program *prog,
-                                       bool ignore_sample_qualifier)
+                                       const struct gl_program *prog)
 {
    /* From ARB_sample_shading specification:
     * "Using gl_SampleID in a fragment shader causes the entire shader
@@ -519,11 +534,9 @@ _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
        * "Use of the "sample" qualifier on a fragment shader input
        *  forces per-sample shading"
        */
-      if (prog->info.fs.uses_sample_qualifier && !ignore_sample_qualifier)
-         return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
-
-      if (prog->info.system_values_read & (SYSTEM_BIT_SAMPLE_ID |
-                                           SYSTEM_BIT_SAMPLE_POS))
+      if (prog->info.fs.uses_sample_qualifier ||
+          (prog->info.system_values_read & (SYSTEM_BIT_SAMPLE_ID |
+                                            SYSTEM_BIT_SAMPLE_POS)))
          return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1);
       else if (ctx->Multisample.SampleShading)
          return MAX2(ceil(ctx->Multisample.MinSampleShadingValue *
@@ -533,3 +546,19 @@ _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
    }
    return 1;
 }
+
+
+GLbitfield
+gl_external_samplers(const struct gl_program *prog)
+{
+   GLbitfield external_samplers = 0;
+   GLbitfield mask = prog->SamplersUsed;
+
+   while (mask) {
+      int idx = u_bit_scan(&mask);
+      if (prog->sh.SamplerTargets[idx] == TEXTURE_EXTERNAL_INDEX)
+         external_samplers |= (1 << idx);
+   }
+
+   return external_samplers;
+}