* If this assertion fails, we need to increase the field
* size for register indexes (see INST_INDEX_BITS).
*/
- ASSERT(ctx->Const.VertexProgram.MaxUniformComponents / 4
+ assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents / 4
<= (1 << INST_INDEX_BITS));
- ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents / 4
<= (1 << INST_INDEX_BITS));
- ASSERT(ctx->Const.VertexProgram.MaxTemps <= (1 << INST_INDEX_BITS));
- ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= (1 << INST_INDEX_BITS));
- ASSERT(ctx->Const.FragmentProgram.MaxTemps <= (1 << INST_INDEX_BITS));
- ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= (1 << INST_INDEX_BITS));
+ assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps <= (1 << INST_INDEX_BITS));
+ assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxLocalParams <= (1 << INST_INDEX_BITS));
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTemps <= (1 << INST_INDEX_BITS));
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= (1 << INST_INDEX_BITS));
- ASSERT(ctx->Const.VertexProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS);
- ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS);
+ assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents <= 4 * MAX_UNIFORMS);
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents <= 4 * MAX_UNIFORMS);
- ASSERT(ctx->Const.VertexProgram.MaxAddressOffset <= (1 << INST_INDEX_BITS));
- ASSERT(ctx->Const.FragmentProgram.MaxAddressOffset <= (1 << INST_INDEX_BITS));
+ assert(ctx->Const.Program[MESA_SHADER_VERTEX].MaxAddressOffset <= (1 << INST_INDEX_BITS));
+ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAddressOffset <= (1 << INST_INDEX_BITS));
/* If this fails, increase prog_instruction::TexSrcUnit size */
STATIC_ASSERT(MAX_TEXTURE_UNITS <= (1 << 5));
STATIC_ASSERT(NUM_TEXTURE_TARGETS <= (1 << 4));
ctx->Program.ErrorPos = -1;
- ctx->Program.ErrorString = _mesa_strdup("");
+ ctx->Program.ErrorString = strdup("");
ctx->VertexProgram.Enabled = GL_FALSE;
ctx->VertexProgram.PointSizeEnabled =
/* right now by default we don't have a geometry program */
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
NULL);
- ctx->GeometryProgram.Cache = _mesa_new_program_cache();
/* XXX probably move this stuff */
ctx->ATIFragmentShader.Enabled = GL_FALSE;
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
_mesa_delete_shader_cache(ctx, ctx->FragmentProgram.Cache);
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
- _mesa_delete_program_cache(ctx, ctx->GeometryProgram.Cache);
/* XXX probably move this stuff */
if (ctx->ATIFragmentShader.Current) {
free((void *) ctx->Program.ErrorString);
if (!string)
string = "";
- ctx->Program.ErrorString = _mesa_strdup(string);
+ ctx->Program.ErrorString = strdup(string);
}
/**
- * Initialize a new vertex/fragment program object.
+ * Initialize a new gl_program object.
*/
-static struct gl_program *
-_mesa_init_program_struct( struct gl_context *ctx, struct gl_program *prog,
- GLenum target, GLuint id)
+static void
+init_program_struct(struct gl_program *prog, GLenum target, GLuint id)
{
- (void) ctx;
- if (prog) {
- GLuint i;
- memset(prog, 0, sizeof(*prog));
- prog->Id = id;
- prog->Target = target;
- prog->RefCount = 1;
- prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
-
- /* default mapping from samplers to texture units */
- for (i = 0; i < MAX_SAMPLERS; i++)
- prog->SamplerUnits[i] = i;
- }
+ GLuint i;
- return prog;
+ assert(prog);
+
+ memset(prog, 0, sizeof(*prog));
+ prog->Id = id;
+ prog->Target = target;
+ prog->RefCount = 1;
+ prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+
+ /* default mapping from samplers to texture units */
+ for (i = 0; i < MAX_SAMPLERS; i++)
+ prog->SamplerUnits[i] = i;
}
* Initialize a new fragment program object.
*/
struct gl_program *
-_mesa_init_fragment_program( struct gl_context *ctx, struct gl_fragment_program *prog,
- GLenum target, GLuint id)
+_mesa_init_fragment_program(struct gl_context *ctx,
+ struct gl_fragment_program *prog,
+ GLenum target, GLuint id)
{
- if (prog)
- return _mesa_init_program_struct( ctx, &prog->Base, target, id );
- else
- return NULL;
+ if (prog) {
+ init_program_struct(&prog->Base, target, id);
+ return &prog->Base;
+ }
+ return NULL;
}
* Initialize a new vertex program object.
*/
struct gl_program *
-_mesa_init_vertex_program( struct gl_context *ctx, struct gl_vertex_program *prog,
+_mesa_init_vertex_program(struct gl_context *ctx,
+ struct gl_vertex_program *prog,
+ GLenum target, GLuint id)
+{
+ if (prog) {
+ init_program_struct(&prog->Base, target, id);
+ return &prog->Base;
+ }
+ return NULL;
+}
+
+
+/**
+ * Initialize a new compute program object.
+ */
+struct gl_program *
+_mesa_init_compute_program(struct gl_context *ctx,
+ struct gl_compute_program *prog,
GLenum target, GLuint id)
{
- if (prog)
- return _mesa_init_program_struct( ctx, &prog->Base, target, id );
- else
- return NULL;
+ if (prog) {
+ init_program_struct(&prog->Base, target, id);
+ return &prog->Base;
+ }
+ return NULL;
}
* Initialize a new geometry program object.
*/
struct gl_program *
-_mesa_init_geometry_program( struct gl_context *ctx, struct gl_geometry_program *prog,
- GLenum target, GLuint id)
+_mesa_init_geometry_program(struct gl_context *ctx,
+ struct gl_geometry_program *prog,
+ GLenum target, GLuint id)
{
- if (prog)
- return _mesa_init_program_struct( ctx, &prog->Base, target, id );
- else
- return NULL;
+ if (prog) {
+ init_program_struct(&prog->Base, target, id);
+ return &prog->Base;
+ }
+ return NULL;
}
CALLOC_STRUCT(gl_geometry_program),
target, id);
break;
+ case GL_COMPUTE_PROGRAM_NV:
+ prog = _mesa_init_compute_program(ctx,
+ CALLOC_STRUCT(gl_compute_program),
+ target, id);
+ break;
default:
_mesa_problem(ctx, "bad target in _mesa_new_program");
prog = NULL;
_mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
{
(void) ctx;
- ASSERT(prog);
- ASSERT(prog->RefCount==0);
+ assert(prog);
+ assert(prog->RefCount==0);
if (prog == &_mesa_DummyProgram)
return;
free(prog->String);
+ free(prog->LocalParams);
if (prog->Instructions) {
_mesa_free_instructions(prog->Instructions, prog->NumInstructions);
if (*ptr && prog) {
/* sanity check */
if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
- ASSERT(prog->Target == GL_VERTEX_PROGRAM_ARB);
+ assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
- ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
+ assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
prog->Target == GL_FRAGMENT_PROGRAM_NV);
else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM)
- ASSERT(prog->Target == MESA_GEOMETRY_PROGRAM);
+ assert(prog->Target == MESA_GEOMETRY_PROGRAM);
}
#endif
if (*ptr) {
GLboolean deleteFlag;
- /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/
+ /*mtx_lock(&(*ptr)->Mutex);*/
#if 0
printf("Program %p ID=%u Target=%s Refcount-- to %d\n",
*ptr, (*ptr)->Id,
((*ptr)->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
(*ptr)->RefCount - 1);
#endif
- ASSERT((*ptr)->RefCount > 0);
+ assert((*ptr)->RefCount > 0);
(*ptr)->RefCount--;
deleteFlag = ((*ptr)->RefCount == 0);
- /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/
+ /*mtx_lock(&(*ptr)->Mutex);*/
if (deleteFlag) {
- ASSERT(ctx);
+ assert(ctx);
ctx->Driver.DeleteProgram(ctx, *ptr);
}
assert(!*ptr);
if (prog) {
- /*_glthread_LOCK_MUTEX(prog->Mutex);*/
+ /*mtx_lock(&prog->Mutex);*/
prog->RefCount++;
#if 0
printf("Program %p ID=%u Target=%s Refcount++ to %d\n",
(prog->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
prog->RefCount);
#endif
- /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
+ /*mtx_unlock(&prog->Mutex);*/
}
*ptr = prog;
assert(clone->Target == prog->Target);
assert(clone->RefCount == 1);
- clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
+ clone->String = (GLubyte *) strdup((char *) prog->String);
clone->Format = prog->Format;
clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
if (!clone->Instructions) {
if (prog->Parameters)
clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
- memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+ if (prog->LocalParams) {
+ clone->LocalParams = malloc(MAX_PROGRAM_LOCAL_PARAMS *
+ sizeof(float[4]));
+ if (!clone->LocalParams) {
+ _mesa_reference_program(ctx, &clone, NULL);
+ return NULL;
+ }
+ memcpy(clone->LocalParams, prog->LocalParams,
+ MAX_PROGRAM_LOCAL_PARAMS * sizeof(float[4]));
+ }
clone->IndirectRegisterFiles = prog->IndirectRegisterFiles;
clone->NumInstructions = prog->NumInstructions;
clone->NumTemporaries = prog->NumTemporaries;
struct gl_geometry_program *gpc = gl_geometry_program(clone);
gpc->VerticesOut = gp->VerticesOut;
gpc->InputType = gp->InputType;
+ gpc->Invocations = gp->Invocations;
gpc->OutputType = gp->OutputType;
+ gpc->UsesEndPrimitive = gp->UsesEndPrimitive;
+ gpc->UsesStreams = gp->UsesStreams;
}
break;
default:
GLbitfield64 inputsB;
GLuint i;
- ASSERT(progA->Target == progB->Target);
+ assert(progA->Target == progB->Target);
newInst = _mesa_alloc_instructions(newLength);
if (!newInst)
const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
if (inst->DstReg.File == file) {
- ASSERT(inst->DstReg.Index < usedSize);
+ assert(inst->DstReg.Index < usedSize);
if(inst->DstReg.Index < usedSize)
used[inst->DstReg.Index] = GL_TRUE;
}
for (j = 0; j < n; j++) {
if (inst->SrcReg[j].File == file) {
- ASSERT(inst->SrcReg[j].Index < (GLint) usedSize);
+ assert(inst->SrcReg[j].Index < (GLint) usedSize);
if (inst->SrcReg[j].Index < (GLint) usedSize)
used[inst->SrcReg[j].Index] = GL_TRUE;
}
*/
GLboolean
_mesa_valid_register_index(const struct gl_context *ctx,
- gl_shader_type shaderType,
+ gl_shader_stage shaderType,
gl_register_file file, GLint index)
{
const struct gl_program_constants *c;
- switch (shaderType) {
- case MESA_SHADER_VERTEX:
- c = &ctx->Const.VertexProgram;
- break;
- case MESA_SHADER_FRAGMENT:
- c = &ctx->Const.FragmentProgram;
- break;
- case MESA_SHADER_GEOMETRY:
- c = &ctx->Const.GeometryProgram;
- break;
- default:
- _mesa_problem(ctx,
- "unexpected shader type in _mesa_valid_register_index()");
- return GL_FALSE;
- }
+ assert(0 <= shaderType && shaderType < MESA_SHADER_STAGES);
+ c = &ctx->Const.Program[shaderType];
switch (file) {
case PROGRAM_UNDEFINED:
*/
GLint
_mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
- const struct gl_fragment_program *prog)
+ const struct gl_fragment_program *prog,
+ bool ignore_sample_qualifier)
{
/* From ARB_sample_shading specification:
* "Using gl_SampleID in a fragment shader causes the entire shader
* has no effect."
*/
if (ctx->Multisample.Enabled) {
+ /* The ARB_gpu_shader5 specification says:
+ *
+ * "Use of the "sample" qualifier on a fragment shader input
+ * forces per-sample shading"
+ */
+ if (prog->IsSample && !ignore_sample_qualifier)
+ return MAX2(ctx->DrawBuffer->Visual.samples, 1);
+
if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
SYSTEM_BIT_SAMPLE_POS))
return MAX2(ctx->DrawBuffer->Visual.samples, 1);