2
* Mesa 3-D graphics library
5
* Copyright (C) 2007 Brian Paul All Rights Reserved.
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
* and/or sell copies of the Software, and to permit persons to whom the
12
* Software is furnished to do so, subject to the following conditions:
14
* The above copyright notice and this permission notice shall be included
15
* in all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36
#include "prog_instruction.h"
37
#include "prog_parameter.h"
38
#include "prog_print.h"
39
#include "prog_statevars.h"
40
#include "shader_api.h"
41
#include "slang_link.h"
47
link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
49
GLuint *map, i, firstVarying, newFile;
50
GLbitfield varsWritten, varsRead;
52
map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
56
for (i = 0; i < prog->Varying->NumParameters; i++) {
57
/* see if this varying is in the linked varying list */
58
const struct gl_program_parameter *var
59
= prog->Varying->Parameters + i;
61
GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
63
/* already in list, check size */
64
if (var->Size != shProg->Varying->Parameters[j].Size) {
70
/* not already in linked list */
71
j = _mesa_add_varying(shProg->Varying, var->Name, var->Size);
79
/* Varying variables are treated like other vertex program outputs
80
* (and like other fragment program inputs). The position of the
81
* first varying differs for vertex/fragment programs...
82
* Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT.
84
if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
85
firstVarying = VERT_RESULT_VAR0;
86
newFile = PROGRAM_OUTPUT;
89
assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
90
firstVarying = FRAG_ATTRIB_VAR0;
91
newFile = PROGRAM_INPUT;
94
/* keep track of which varying vars we read and write */
95
varsWritten = varsRead = 0x0;
97
/* OK, now scan the program/shader instructions looking for varying vars,
98
* replacing the old index with the new index.
100
for (i = 0; i < prog->NumInstructions; i++) {
101
struct prog_instruction *inst = prog->Instructions + i;
104
if (inst->DstReg.File == PROGRAM_VARYING) {
105
inst->DstReg.File = newFile;
106
inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying;
107
varsWritten |= (1 << inst->DstReg.Index);
110
for (j = 0; j < 3; j++) {
111
if (inst->SrcReg[j].File == PROGRAM_VARYING) {
112
inst->SrcReg[j].File = newFile;
113
inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying;
114
varsRead |= (1 << inst->SrcReg[j].Index);
119
if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
120
prog->OutputsWritten |= varsWritten;
121
/*printf("VERT OUTPUTS: 0x%x \n", varsWritten);*/
124
assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
125
prog->InputsRead |= varsRead;
126
/*printf("FRAG INPUTS: 0x%x\n", varsRead);*/
136
is_uniform(GLuint file)
138
return (file == PROGRAM_ENV_PARAM ||
139
file == PROGRAM_STATE_VAR ||
140
file == PROGRAM_NAMED_PARAM ||
141
file == PROGRAM_CONSTANT ||
142
file == PROGRAM_SAMPLER ||
143
file == PROGRAM_UNIFORM);
148
link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
153
printf("================ pre link uniforms ===============\n");
154
_mesa_print_parameter_list(shProg->Uniforms);
157
map = (GLuint *) malloc(prog->Parameters->NumParameters * sizeof(GLuint));
161
for (i = 0; i < prog->Parameters->NumParameters; /* incr below*/) {
162
/* see if this uniform is in the linked uniform list */
163
const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
164
const GLfloat *pVals = prog->Parameters->ParameterValues[i];
169
assert(is_uniform(p->Type));
172
j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name);
176
ASSERT(p->Type == PROGRAM_CONSTANT);
177
if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals,
178
p->Size, &j, NULL)) {
187
/* already in list, check size XXX check this */
189
assert(p->Size == shProg->Uniforms->Parameters[j].Size);
193
/* not already in linked list */
195
case PROGRAM_ENV_PARAM:
196
j = _mesa_add_named_parameter(shProg->Uniforms, p->Name, pVals);
198
case PROGRAM_CONSTANT:
199
j = _mesa_add_named_constant(shProg->Uniforms, p->Name, pVals, p->Size);
201
case PROGRAM_STATE_VAR:
202
j = _mesa_add_state_reference(shProg->Uniforms, p->StateIndexes);
204
case PROGRAM_UNIFORM:
205
j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size, p->DataType);
207
case PROGRAM_SAMPLER:
208
j = _mesa_add_sampler(shProg->Uniforms, p->Name, p->DataType);
211
_mesa_problem(NULL, "bad parameter type in link_uniform_vars()");
229
printf("================ post link uniforms ===============\n");
230
_mesa_print_parameter_list(shProg->Uniforms);
236
for (i = 0; i < prog->Parameters->NumParameters; i++) {
237
printf("map[%d] = %d\n", i, map[i]);
239
_mesa_print_parameter_list(shProg->Uniforms);
243
/* OK, now scan the program/shader instructions looking for uniform vars,
244
* replacing the old index with the new index.
246
for (i = 0; i < prog->NumInstructions; i++) {
247
struct prog_instruction *inst = prog->Instructions + i;
250
if (is_uniform(inst->DstReg.File)) {
251
inst->DstReg.Index = map[ inst->DstReg.Index ];
254
for (j = 0; j < 3; j++) {
255
if (is_uniform(inst->SrcReg[j].File)) {
256
inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ];
260
if (inst->Opcode == OPCODE_TEX ||
261
inst->Opcode == OPCODE_TXB ||
262
inst->Opcode == OPCODE_TXP) {
264
printf("====== remap sampler from %d to %d\n",
265
inst->Sampler, map[ inst->Sampler ]);
267
inst->Sampler = map[ inst->Sampler ];
278
* Resolve binding of generic vertex attributes.
279
* For example, if the vertex shader declared "attribute vec4 foobar" we'll
280
* allocate a generic vertex attribute for "foobar" and plug that value into
281
* the vertex program instructions.
284
_slang_resolve_attributes(struct gl_shader_program *shProg,
285
struct gl_program *prog)
288
GLbitfield usedAttributes;
289
GLint size = 4; /* XXX fix */
291
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
293
if (!shProg->Attributes)
294
shProg->Attributes = _mesa_new_parameter_list();
296
/* Build a bitmask indicating which attribute indexes have been
297
* explicitly bound by the user with glBindAttributeLocation().
299
usedAttributes = 0x0;
300
for (i = 0; i < shProg->Attributes->NumParameters; i++) {
301
GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0];
302
usedAttributes |= attr;
306
* Scan program for generic attribute references
308
for (i = 0; i < prog->NumInstructions; i++) {
309
struct prog_instruction *inst = prog->Instructions + i;
310
for (j = 0; j < 3; j++) {
311
if (inst->SrcReg[j].File == PROGRAM_INPUT &&
312
inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
313
/* this is a generic attrib */
314
const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0;
315
const char *name = prog->Attributes->Parameters[k].Name;
316
/* See if this attrib name is in the program's attribute list
317
* (i.e. was bound by the user).
319
GLint index = _mesa_lookup_parameter_index(shProg->Attributes,
323
/* found, user must have specified a binding */
324
attr = shProg->Attributes->Parameters[index].StateIndexes[0];
327
/* Not found, choose our own attribute number.
328
* Start at 1 since generic attribute 0 always aliases
331
for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) {
332
if (((1 << attr) & usedAttributes) == 0) {
333
usedAttributes |= (1 << attr);
337
if (attr == MAX_VERTEX_ATTRIBS) {
338
/* too many! XXX record error log */
341
_mesa_add_attribute(shProg->Attributes, name, size, attr);
344
inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;
353
* Scan program instructions to update the program's InputsRead and
354
* OutputsWritten fields.
357
_slang_update_inputs_outputs(struct gl_program *prog)
361
prog->InputsRead = 0x0;
362
prog->OutputsWritten = 0x0;
364
for (i = 0; i < prog->NumInstructions; i++) {
365
const struct prog_instruction *inst = prog->Instructions + i;
366
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
367
for (j = 0; j < numSrc; j++) {
368
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
369
prog->InputsRead |= 1 << inst->SrcReg[j].Index;
372
if (inst->DstReg.File == PROGRAM_OUTPUT) {
373
prog->OutputsWritten |= 1 << inst->DstReg.Index;
380
* Scan a vertex program looking for instances of
381
* (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + oldAttrib) and replace with
382
* (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + newAttrib).
383
* This is used when the user calls glBindAttribLocation on an already linked
387
_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib)
391
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
393
for (i = 0; i < prog->NumInstructions; i++) {
394
struct prog_instruction *inst = prog->Instructions + i;
395
for (j = 0; j < 3; j++) {
396
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
397
if (inst->SrcReg[j].Index == VERT_ATTRIB_GENERIC0 + oldAttrib) {
398
inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + newAttrib;
404
_slang_update_inputs_outputs(prog);
410
* Scan program for texture instructions, lookup sampler/uniform's value
411
* to determine which texture unit to use.
412
* Also, update the program's TexturesUsed[] array.
415
_slang_resolve_samplers(struct gl_shader_program *shProg,
416
struct gl_program *prog)
420
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
421
prog->TexturesUsed[i] = 0;
423
for (i = 0; i < prog->NumInstructions; i++) {
424
struct prog_instruction *inst = prog->Instructions + i;
425
if (inst->Opcode == OPCODE_TEX ||
426
inst->Opcode == OPCODE_TXB ||
427
inst->Opcode == OPCODE_TXP) {
428
GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0];
429
assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS);
430
inst->TexSrcUnit = sampleUnit;
432
prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget);
440
static struct gl_vertex_program *
441
vertex_program(struct gl_program *prog)
443
assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
444
return (struct gl_vertex_program *) prog;
449
static struct gl_fragment_program *
450
fragment_program(struct gl_program *prog)
452
assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
453
return (struct gl_fragment_program *) prog;
458
* Record a linking error.
461
link_error(struct gl_shader_program *shProg, const char *msg)
463
if (shProg->InfoLog) {
464
_mesa_free(shProg->InfoLog);
466
shProg->InfoLog = _mesa_strdup(msg);
467
shProg->LinkStatus = GL_FALSE;
473
* Shader linker. Currently:
475
* 1. The last attached vertex shader and fragment shader are linked.
476
* 2. Varying vars in the two shaders are combined so their locations
477
* agree between the vertex and fragment stages. They're treated as
478
* vertex program output attribs and as fragment program input attribs.
479
* 3. Uniform vars (including state references, constants, etc) from the
480
* vertex and fragment shaders are merged into one group. Recall that
481
* GLSL uniforms are shared by all linked shaders.
482
* 4. The vertex and fragment programs are cloned and modified to update
483
* src/dst register references so they use the new, linked uniform/
484
* varying storage locations.
487
_slang_link(GLcontext *ctx,
488
GLhandleARB programObj,
489
struct gl_shader_program *shProg)
491
const struct gl_vertex_program *vertProg;
492
const struct gl_fragment_program *fragProg;
495
_mesa_clear_shader_program_data(ctx, shProg);
497
shProg->Uniforms = _mesa_new_parameter_list();
498
shProg->Varying = _mesa_new_parameter_list();
501
* Find attached vertex shader, fragment shader
505
for (i = 0; i < shProg->NumShaders; i++) {
506
if (shProg->Shaders[i]->Type == GL_VERTEX_SHADER)
507
vertProg = vertex_program(shProg->Shaders[i]->Programs[0]);
508
else if (shProg->Shaders[i]->Type == GL_FRAGMENT_SHADER)
509
fragProg = fragment_program(shProg->Shaders[i]->Programs[0]);
511
_mesa_problem(ctx, "unexpected shader target in slang_link()");
515
* Make copies of the vertex/fragment programs now since we'll be
516
* changing src/dst registers after merging the uniforms and varying vars.
519
shProg->VertexProgram
520
= vertex_program(_mesa_clone_program(ctx, &vertProg->Base));
523
shProg->VertexProgram = NULL;
527
shProg->FragmentProgram
528
= fragment_program(_mesa_clone_program(ctx, &fragProg->Base));
531
shProg->FragmentProgram = NULL;
534
if (shProg->VertexProgram)
535
link_varying_vars(shProg, &shProg->VertexProgram->Base);
536
if (shProg->FragmentProgram)
537
link_varying_vars(shProg, &shProg->FragmentProgram->Base);
539
if (shProg->VertexProgram)
540
link_uniform_vars(shProg, &shProg->VertexProgram->Base);
541
if (shProg->FragmentProgram)
542
link_uniform_vars(shProg, &shProg->FragmentProgram->Base);
544
/* The vertex and fragment programs share a common set of uniforms now */
545
if (shProg->VertexProgram) {
546
_mesa_free_parameter_list(shProg->VertexProgram->Base.Parameters);
547
shProg->VertexProgram->Base.Parameters = shProg->Uniforms;
549
if (shProg->FragmentProgram) {
550
_mesa_free_parameter_list(shProg->FragmentProgram->Base.Parameters);
551
shProg->FragmentProgram->Base.Parameters = shProg->Uniforms;
554
if (shProg->VertexProgram) {
555
_slang_resolve_samplers(shProg, &shProg->VertexProgram->Base);
557
if (shProg->FragmentProgram) {
558
_slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base);
561
if (shProg->VertexProgram) {
562
if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) {
564
_mesa_problem(ctx, "_slang_resolve_attributes() failed");
569
if (shProg->VertexProgram) {
570
_slang_update_inputs_outputs(&shProg->VertexProgram->Base);
571
if (!(shProg->VertexProgram->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
572
/* the vertex program did not compute a vertex position */
574
"gl_Position was not written by vertex shader\n");
578
if (shProg->FragmentProgram)
579
_slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
581
/* Check that all the varying vars needed by the fragment shader are
582
* actually produced by the vertex shader.
584
if (shProg->FragmentProgram) {
585
const GLbitfield varyingRead
586
= shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0;
587
const GLbitfield varyingWritten = shProg->VertexProgram ?
588
shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0;
589
if ((varyingRead & varyingWritten) != varyingRead) {
591
"Fragment program using varying vars not written by vertex shader\n");
597
if (fragProg && shProg->FragmentProgram) {
598
/* notify driver that a new fragment program has been compiled/linked */
599
ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
600
&shProg->FragmentProgram->Base);
602
printf("************** original fragment program\n");
603
_mesa_print_program(&fragProg->Base);
604
_mesa_print_program_parameters(ctx, &fragProg->Base);
607
printf("************** linked fragment prog\n");
608
_mesa_print_program(&shProg->FragmentProgram->Base);
609
_mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
613
if (vertProg && shProg->VertexProgram) {
614
/* notify driver that a new vertex program has been compiled/linked */
615
ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
616
&shProg->VertexProgram->Base);
618
printf("************** original vertex program\n");
619
_mesa_print_program(&vertProg->Base);
620
_mesa_print_program_parameters(ctx, &vertProg->Base);
623
printf("************** linked vertex prog\n");
624
_mesa_print_program(&shProg->VertexProgram->Base);
625
_mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base);
629
shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);