X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fprogram%2Fprogram.c;h=0defa012aee9f1680c3d6e853fb387f758d58fb0;hb=030abc61091a38596427aa04022066719be9add5;hp=61cc6fe9e96514369e9e527ca24778160eea5874;hpb=9605b98a078654f6f76e85221599e5fa8c073de6;p=mesa.git diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c index 61cc6fe9e96..0defa012aee 100644 --- a/src/mesa/program/program.c +++ b/src/mesa/program/program.c @@ -34,11 +34,13 @@ #include "main/framebuffer.h" #include "main/hash.h" #include "main/macros.h" +#include "main/shaderobj.h" #include "program.h" #include "prog_cache.h" #include "prog_parameter.h" #include "prog_instruction.h" #include "util/ralloc.h" +#include "util/u_atomic.h" /** @@ -93,8 +95,8 @@ _mesa_init_program(struct gl_context *ctx) ctx->VertexProgram.Cache = _mesa_new_program_cache(); ctx->FragmentProgram.Enabled = GL_FALSE; - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, - ctx->Shared->DefaultFragmentProgram); + _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, + ctx->Shared->DefaultFragmentProgram); assert(ctx->FragmentProgram.Current); ctx->FragmentProgram.Cache = _mesa_new_program_cache(); @@ -114,7 +116,7 @@ _mesa_free_program_data(struct gl_context *ctx) { _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL); _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); + _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL); _mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache); /* XXX probably move this stuff */ @@ -141,7 +143,7 @@ _mesa_update_default_objects_program(struct gl_context *ctx) ctx->Shared->DefaultVertexProgram); assert(ctx->VertexProgram.Current); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, ctx->Shared->DefaultFragmentProgram); assert(ctx->FragmentProgram.Current); @@ -177,23 +179,36 @@ _mesa_set_program_error(struct gl_context *ctx, GLint pos, const char *string) * Initialize a new gl_program object. */ struct gl_program * -_mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id) +_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->Format = GL_PROGRAM_FORMAT_ASCII_ARB; + 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; } @@ -212,20 +227,18 @@ _mesa_init_gl_program(struct gl_program *prog, GLenum target, GLuint id) * \return pointer to new program object */ struct gl_program * -_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id) +_mesa_new_program(struct gl_context *ctx, GLenum target, GLuint id, + bool is_arb_asm) { switch (target) { - case GL_FRAGMENT_PROGRAM_ARB: { - struct gl_fragment_program *prog = CALLOC_STRUCT(gl_fragment_program); - return _mesa_init_gl_program(&prog->Base, target, id); - } case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ case GL_GEOMETRY_PROGRAM_NV: case GL_TESS_CONTROL_PROGRAM_NV: case GL_TESS_EVALUATION_PROGRAM_NV: + case GL_FRAGMENT_PROGRAM_ARB: case GL_COMPUTE_PROGRAM_NV: { - struct gl_program *prog = CALLOC_STRUCT(gl_program); - return _mesa_init_gl_program(prog, target, id); + struct gl_program *prog = rzalloc(NULL, struct gl_program); + return _mesa_init_gl_program(prog, target, id, is_arb_asm); } default: _mesa_problem(ctx, "bad target in _mesa_new_program"); @@ -250,12 +263,6 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog) if (prog == &_mesa_DummyProgram) return; - free(prog->String); - free(prog->LocalParams); - - if (prog->Instructions) { - _mesa_free_instructions(prog->Instructions, prog->NumInstructions); - } if (prog->Parameters) { _mesa_free_parameter_list(prog->Parameters); } @@ -264,8 +271,15 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog) ralloc_free(prog->nir); } - mtx_destroy(&prog->Mutex); - free(prog); + if (prog->sh.BindlessSamplers) { + ralloc_free(prog->sh.BindlessSamplers); + } + + if (prog->sh.BindlessImages) { + ralloc_free(prog->sh.BindlessImages); + } + + ralloc_free(prog); } @@ -309,18 +323,13 @@ _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); } @@ -329,9 +338,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; @@ -345,14 +352,14 @@ _mesa_reference_program_(struct gl_context *ctx, GLboolean _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count) { - const GLuint origLen = prog->NumInstructions; + const GLuint origLen = prog->arb.NumInstructions; const GLuint newLen = origLen + count; struct prog_instruction *newInst; GLuint i; /* adjust branches */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; + for (i = 0; i < prog->arb.NumInstructions; i++) { + struct prog_instruction *inst = prog->arb.Instructions + i; if (inst->BranchTarget > 0) { if ((GLuint)inst->BranchTarget >= start) { inst->BranchTarget += count; @@ -361,28 +368,28 @@ _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count) } /* Alloc storage for new instructions */ - newInst = _mesa_alloc_instructions(newLen); + newInst = rzalloc_array(prog, struct prog_instruction, newLen); if (!newInst) { return GL_FALSE; } /* Copy 'start' instructions into new instruction buffer */ - _mesa_copy_instructions(newInst, prog->Instructions, start); + _mesa_copy_instructions(newInst, prog->arb.Instructions, start); /* init the new instructions */ _mesa_init_instructions(newInst + start, count); /* Copy the remaining/tail instructions to new inst buffer */ _mesa_copy_instructions(newInst + start + count, - prog->Instructions + start, + prog->arb.Instructions + start, origLen - start); /* free old instructions */ - _mesa_free_instructions(prog->Instructions, origLen); + ralloc_free(prog->arb.Instructions); /* install new instructions */ - prog->Instructions = newInst; - prog->NumInstructions = newLen; + prog->arb.Instructions = newInst; + prog->arb.NumInstructions = newLen; return GL_TRUE; } @@ -392,16 +399,17 @@ _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count) * Adjust branch targets accordingly. */ GLboolean -_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count) +_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count, + void *mem_ctx) { - const GLuint origLen = prog->NumInstructions; + const GLuint origLen = prog->arb.NumInstructions; const GLuint newLen = origLen - count; struct prog_instruction *newInst; GLuint i; /* adjust branches */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; + for (i = 0; i < prog->arb.NumInstructions; i++) { + struct prog_instruction *inst = prog->arb.Instructions + i; if (inst->BranchTarget > 0) { if (inst->BranchTarget > (GLint) start) { inst->BranchTarget -= count; @@ -410,25 +418,25 @@ _mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count) } /* Alloc storage for new instructions */ - newInst = _mesa_alloc_instructions(newLen); + newInst = rzalloc_array(mem_ctx, struct prog_instruction, newLen); if (!newInst) { return GL_FALSE; } /* Copy 'start' instructions into new instruction buffer */ - _mesa_copy_instructions(newInst, prog->Instructions, start); + _mesa_copy_instructions(newInst, prog->arb.Instructions, start); /* Copy the remaining/tail instructions to new inst buffer */ _mesa_copy_instructions(newInst + start, - prog->Instructions + start + count, + prog->arb.Instructions + start + count, newLen - start); /* free old instructions */ - _mesa_free_instructions(prog->Instructions, origLen); + ralloc_free(prog->arb.Instructions); /* install new instructions */ - prog->Instructions = newInst; - prog->NumInstructions = newLen; + prog->arb.Instructions = newInst; + prog->arb.NumInstructions = newLen; return GL_TRUE; } @@ -450,8 +458,8 @@ _mesa_find_used_registers(const struct gl_program *prog, memset(used, 0, usedSize); - for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; + for (i = 0; i < prog->arb.NumInstructions; i++) { + const struct prog_instruction *inst = prog->arb.Instructions + i; const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); if (inst->DstReg.File == file) { @@ -502,7 +510,7 @@ _mesa_find_free_register(const GLboolean used[], */ GLint _mesa_get_min_invocations_per_fragment(struct gl_context *ctx, - const struct gl_fragment_program *prog, + const struct gl_program *prog, bool ignore_sample_qualifier) { /* From ARB_sample_shading specification: @@ -521,11 +529,11 @@ _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->IsSample && !ignore_sample_qualifier) + if (prog->info.fs.uses_sample_qualifier && !ignore_sample_qualifier) return MAX2(_mesa_geometric_samples(ctx->DrawBuffer), 1); - if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID | - SYSTEM_BIT_SAMPLE_POS)) + if (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 *