#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"
/**
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;
_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;
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;
}
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);
}
#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);
assert(!*ptr);
if (prog) {
- mtx_lock(&prog->Mutex);
- prog->RefCount++;
- mtx_unlock(&prog->Mutex);
+ p_atomic_inc(&prog->RefCount);
}
*ptr = prog;
*/
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
* "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 *
}
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;
+}