Merge commit 'origin/st-shader-varients'
Conflicts: src/mesa/state_tracker/st_atom_shader.c src/mesa/state_tracker/st_program.c
This commit is contained in:
commit
4dcdf3b9c6
|
@ -46,7 +46,8 @@ static const struct st_tracked_state *atoms[] =
|
||||||
&st_update_clip,
|
&st_update_clip,
|
||||||
|
|
||||||
&st_finalize_textures,
|
&st_finalize_textures,
|
||||||
&st_update_shader,
|
&st_update_fp,
|
||||||
|
&st_update_vp,
|
||||||
|
|
||||||
&st_update_rasterizer,
|
&st_update_rasterizer,
|
||||||
&st_update_polygon_stipple,
|
&st_update_polygon_stipple,
|
||||||
|
|
|
@ -47,7 +47,8 @@ void st_validate_state( struct st_context *st );
|
||||||
extern const struct st_tracked_state st_update_framebuffer;
|
extern const struct st_tracked_state st_update_framebuffer;
|
||||||
extern const struct st_tracked_state st_update_clip;
|
extern const struct st_tracked_state st_update_clip;
|
||||||
extern const struct st_tracked_state st_update_depth_stencil_alpha;
|
extern const struct st_tracked_state st_update_depth_stencil_alpha;
|
||||||
extern const struct st_tracked_state st_update_shader;
|
extern const struct st_tracked_state st_update_fp;
|
||||||
|
extern const struct st_tracked_state st_update_vp;
|
||||||
extern const struct st_tracked_state st_update_rasterizer;
|
extern const struct st_tracked_state st_update_rasterizer;
|
||||||
extern const struct st_tracked_state st_update_polygon_stipple;
|
extern const struct st_tracked_state st_update_polygon_stipple;
|
||||||
extern const struct st_tracked_state st_update_viewport;
|
extern const struct st_tracked_state st_update_viewport;
|
||||||
|
|
|
@ -56,82 +56,18 @@
|
||||||
#include "st_mesa_to_tgsi.h"
|
#include "st_mesa_to_tgsi.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This represents a vertex program, especially translated to match
|
|
||||||
* the inputs of a particular fragment shader.
|
|
||||||
|
/*
|
||||||
|
* Translate fragment program if needed.
|
||||||
*/
|
*/
|
||||||
struct translated_vertex_program
|
static void
|
||||||
|
translate_fp(struct st_context *st,
|
||||||
|
struct st_fragment_program *stfp)
|
||||||
{
|
{
|
||||||
struct st_vertex_program *master;
|
|
||||||
|
|
||||||
/** The fragment shader "signature" this vertex shader is meant for: */
|
|
||||||
GLbitfield frag_inputs;
|
|
||||||
|
|
||||||
/** Compared against master vertex program's serialNo: */
|
|
||||||
GLuint serialNo;
|
|
||||||
|
|
||||||
/** Maps VERT_RESULT_x to slot */
|
|
||||||
GLuint output_to_slot[VERT_RESULT_MAX];
|
|
||||||
ubyte output_to_semantic_name[VERT_RESULT_MAX];
|
|
||||||
ubyte output_to_semantic_index[VERT_RESULT_MAX];
|
|
||||||
|
|
||||||
/** Pointer to the translated vertex program */
|
|
||||||
struct st_vertex_program *vp;
|
|
||||||
|
|
||||||
struct translated_vertex_program *next; /**< next in linked list */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a vertex program output attribute, return the corresponding
|
|
||||||
* fragment program input attribute.
|
|
||||||
* \return -1 for vertex outputs that have no corresponding fragment input
|
|
||||||
*/
|
|
||||||
static GLint
|
|
||||||
vp_out_to_fp_in(GLuint vertResult)
|
|
||||||
{
|
|
||||||
if (vertResult >= VERT_RESULT_TEX0 &&
|
|
||||||
vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS)
|
|
||||||
return FRAG_ATTRIB_TEX0 + (vertResult - VERT_RESULT_TEX0);
|
|
||||||
|
|
||||||
if (vertResult >= VERT_RESULT_VAR0 &&
|
|
||||||
vertResult < VERT_RESULT_VAR0 + MAX_VARYING)
|
|
||||||
return FRAG_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0);
|
|
||||||
|
|
||||||
switch (vertResult) {
|
|
||||||
case VERT_RESULT_HPOS:
|
|
||||||
return FRAG_ATTRIB_WPOS;
|
|
||||||
case VERT_RESULT_COL0:
|
|
||||||
return FRAG_ATTRIB_COL0;
|
|
||||||
case VERT_RESULT_COL1:
|
|
||||||
return FRAG_ATTRIB_COL1;
|
|
||||||
case VERT_RESULT_FOGC:
|
|
||||||
return FRAG_ATTRIB_FOGC;
|
|
||||||
default:
|
|
||||||
/* Back-face colors, edge flags, etc */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a translated vertex program that corresponds to stvp and
|
|
||||||
* has outputs matched to stfp's inputs.
|
|
||||||
* This performs vertex and fragment translation (to TGSI) when needed.
|
|
||||||
*/
|
|
||||||
static struct translated_vertex_program *
|
|
||||||
find_translated_vp(struct st_context *st,
|
|
||||||
struct st_vertex_program *stvp,
|
|
||||||
struct st_fragment_program *stfp)
|
|
||||||
{
|
|
||||||
static const GLuint UNUSED = ~0;
|
|
||||||
struct translated_vertex_program *xvp;
|
|
||||||
const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;
|
const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;
|
||||||
|
|
||||||
/*
|
|
||||||
* Translate fragment program if needed.
|
|
||||||
*/
|
|
||||||
if (!stfp->state.tokens) {
|
if (!stfp->state.tokens) {
|
||||||
GLuint inAttr, numIn = 0;
|
GLuint inAttr, numIn = 0;
|
||||||
|
|
||||||
|
@ -141,7 +77,7 @@ find_translated_vp(struct st_context *st,
|
||||||
numIn++;
|
numIn++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
stfp->input_to_slot[inAttr] = UNUSED;
|
stfp->input_to_slot[inAttr] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,170 +87,63 @@ find_translated_vp(struct st_context *st,
|
||||||
|
|
||||||
st_translate_fragment_program(st, stfp, stfp->input_to_slot);
|
st_translate_fragment_program(st, stfp, stfp->input_to_slot);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a translated vertex program that corresponds to stvp and
|
||||||
|
* has outputs matched to stfp's inputs.
|
||||||
|
* This performs vertex and fragment translation (to TGSI) when needed.
|
||||||
|
*/
|
||||||
|
static struct st_vp_varient *
|
||||||
|
find_translated_vp(struct st_context *st,
|
||||||
|
struct st_vertex_program *stvp )
|
||||||
|
{
|
||||||
|
struct st_vp_varient *vpv;
|
||||||
|
struct st_vp_varient_key key;
|
||||||
|
|
||||||
|
/* Nothing in our key yet. This will change:
|
||||||
|
*/
|
||||||
|
memset(&key, 0, sizeof key);
|
||||||
|
key.dummy = 0;
|
||||||
|
|
||||||
|
/* Do we need to throw away old translations after a change in the
|
||||||
|
* GL program string?
|
||||||
|
*/
|
||||||
|
if (stvp->serialNo != stvp->lastSerialNo) {
|
||||||
|
/* These may have changed if the program string changed.
|
||||||
|
*/
|
||||||
|
st_prepare_vertex_program( st, stvp );
|
||||||
|
|
||||||
|
/* We are now up-to-date:
|
||||||
|
*/
|
||||||
|
stvp->lastSerialNo = stvp->serialNo;
|
||||||
|
}
|
||||||
|
|
||||||
/* See if we've got a translated vertex program whose outputs match
|
/* See if we've got a translated vertex program whose outputs match
|
||||||
* the fragment program's inputs.
|
* the fragment program's inputs.
|
||||||
* XXX This could be a hash lookup, using InputsRead as the key.
|
|
||||||
*/
|
*/
|
||||||
for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) {
|
for (vpv = stvp->varients; vpv; vpv = vpv->next) {
|
||||||
if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) {
|
if (memcmp(&vpv->key, &key, sizeof key) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No? Allocate translated vp object now */
|
/* No? Perform new translation here. */
|
||||||
if (!xvp) {
|
if (!vpv) {
|
||||||
xvp = ST_CALLOC_STRUCT(translated_vertex_program);
|
vpv = st_translate_vertex_program(st, stvp, &key);
|
||||||
xvp->frag_inputs = fragInputsRead;
|
if (!vpv)
|
||||||
xvp->master = stvp;
|
return NULL;
|
||||||
|
|
||||||
xvp->next = stfp->vertex_programs;
|
vpv->next = stvp->varients;
|
||||||
stfp->vertex_programs = xvp;
|
stvp->varients = vpv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if we need to translate vertex program to TGSI form */
|
return vpv;
|
||||||
if (xvp->serialNo != stvp->serialNo) {
|
|
||||||
GLuint outAttr;
|
|
||||||
const GLbitfield64 outputsWritten = stvp->Base.Base.OutputsWritten;
|
|
||||||
GLuint numVpOuts = 0;
|
|
||||||
GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
|
|
||||||
GLbitfield usedGenerics = 0x0;
|
|
||||||
GLbitfield usedOutputSlots = 0x0;
|
|
||||||
|
|
||||||
/* Compute mapping of vertex program outputs to slots, which depends
|
|
||||||
* on the fragment program's input->slot mapping.
|
|
||||||
*/
|
|
||||||
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
|
|
||||||
/* set defaults: */
|
|
||||||
xvp->output_to_slot[outAttr] = UNUSED;
|
|
||||||
xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
|
|
||||||
xvp->output_to_semantic_index[outAttr] = 99;
|
|
||||||
|
|
||||||
if (outAttr == VERT_RESULT_HPOS) {
|
|
||||||
/* always put xformed position into slot zero */
|
|
||||||
GLuint slot = 0;
|
|
||||||
xvp->output_to_slot[VERT_RESULT_HPOS] = slot;
|
|
||||||
xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
|
|
||||||
xvp->output_to_semantic_index[outAttr] = 0;
|
|
||||||
numVpOuts++;
|
|
||||||
usedOutputSlots |= (1 << slot);
|
|
||||||
}
|
|
||||||
else if (outputsWritten & (1 << outAttr)) {
|
|
||||||
/* see if the frag prog wants this vert output */
|
|
||||||
GLint fpInAttrib = vp_out_to_fp_in(outAttr);
|
|
||||||
if (fpInAttrib >= 0) {
|
|
||||||
GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
|
|
||||||
if (fpInSlot != ~0) {
|
|
||||||
/* match this vp output to the fp input */
|
|
||||||
GLuint vpOutSlot = stfp->input_map[fpInSlot];
|
|
||||||
xvp->output_to_slot[outAttr] = vpOutSlot;
|
|
||||||
xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
|
|
||||||
xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
|
|
||||||
numVpOuts++;
|
|
||||||
usedOutputSlots |= (1 << vpOutSlot);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
#if 0 /*debug*/
|
|
||||||
printf("VP output %d not used by FP\n", outAttr);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (outAttr == VERT_RESULT_PSIZ)
|
|
||||||
emitPntSize = GL_TRUE;
|
|
||||||
else if (outAttr == VERT_RESULT_BFC0)
|
|
||||||
emitBFC0 = GL_TRUE;
|
|
||||||
else if (outAttr == VERT_RESULT_BFC1)
|
|
||||||
emitBFC1 = GL_TRUE;
|
|
||||||
}
|
|
||||||
#if 0 /*debug*/
|
|
||||||
printf("assign vp output_to_slot[%d] = %d\n", outAttr,
|
|
||||||
xvp->output_to_slot[outAttr]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* must do these last */
|
|
||||||
if (emitPntSize) {
|
|
||||||
GLuint slot = numVpOuts++;
|
|
||||||
xvp->output_to_slot[VERT_RESULT_PSIZ] = slot;
|
|
||||||
xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
|
|
||||||
xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
|
|
||||||
usedOutputSlots |= (1 << slot);
|
|
||||||
}
|
|
||||||
if (emitBFC0) {
|
|
||||||
GLuint slot = numVpOuts++;
|
|
||||||
xvp->output_to_slot[VERT_RESULT_BFC0] = slot;
|
|
||||||
xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
|
|
||||||
xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
|
|
||||||
usedOutputSlots |= (1 << slot);
|
|
||||||
}
|
|
||||||
if (emitBFC1) {
|
|
||||||
GLuint slot = numVpOuts++;
|
|
||||||
xvp->output_to_slot[VERT_RESULT_BFC1] = slot;
|
|
||||||
xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR;
|
|
||||||
xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1;
|
|
||||||
usedOutputSlots |= (1 << slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* build usedGenerics mask */
|
|
||||||
usedGenerics = 0x0;
|
|
||||||
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
|
|
||||||
if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
|
|
||||||
usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For each vertex program output that doesn't match up to a fragment
|
|
||||||
* program input, map the vertex program output to a free slot and
|
|
||||||
* free generic attribute.
|
|
||||||
*/
|
|
||||||
for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
|
|
||||||
if (outputsWritten & (1 << outAttr)) {
|
|
||||||
if (xvp->output_to_slot[outAttr] == UNUSED) {
|
|
||||||
GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1;
|
|
||||||
GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1;
|
|
||||||
usedGenerics |= (1 << freeGeneric);
|
|
||||||
usedOutputSlots |= (1 << freeSlot);
|
|
||||||
xvp->output_to_slot[outAttr] = freeSlot;
|
|
||||||
xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
xvp->output_to_semantic_index[outAttr] = freeGeneric;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /*debug*/
|
|
||||||
printf("vp output_to_slot[%d] = %d\n", outAttr,
|
|
||||||
xvp->output_to_slot[outAttr]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(stvp->Base.Base.NumInstructions > 1);
|
|
||||||
|
|
||||||
st_translate_vertex_program(st, stvp, xvp->output_to_slot,
|
|
||||||
xvp->output_to_semantic_name,
|
|
||||||
xvp->output_to_semantic_index);
|
|
||||||
|
|
||||||
xvp->vp = stvp;
|
|
||||||
|
|
||||||
/* translated VP is up to date now */
|
|
||||||
xvp->serialNo = stvp->serialNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return xvp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
st_free_translated_vertex_programs(struct st_context *st,
|
|
||||||
struct translated_vertex_program *xvp)
|
|
||||||
{
|
|
||||||
struct translated_vertex_program *next;
|
|
||||||
|
|
||||||
while (xvp) {
|
|
||||||
next = xvp->next;
|
|
||||||
_mesa_free(xvp);
|
|
||||||
xvp = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
@ -328,32 +157,19 @@ get_passthrough_fs(struct st_context *st)
|
||||||
return st->passthrough_fs;
|
return st->passthrough_fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_linkage( struct st_context *st )
|
update_fp( struct st_context *st )
|
||||||
{
|
{
|
||||||
struct st_vertex_program *stvp;
|
|
||||||
struct st_fragment_program *stfp;
|
struct st_fragment_program *stfp;
|
||||||
struct translated_vertex_program *xvp;
|
|
||||||
|
|
||||||
/* find active shader and params -- Should be covered by
|
|
||||||
* ST_NEW_VERTEX_PROGRAM
|
|
||||||
*/
|
|
||||||
assert(st->ctx->VertexProgram._Current);
|
|
||||||
stvp = st_vertex_program(st->ctx->VertexProgram._Current);
|
|
||||||
assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
|
|
||||||
|
|
||||||
assert(st->ctx->FragmentProgram._Current);
|
assert(st->ctx->FragmentProgram._Current);
|
||||||
stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
|
stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
|
||||||
assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
|
assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
|
||||||
|
|
||||||
xvp = find_translated_vp(st, stvp, stfp);
|
translate_fp(st, stfp);
|
||||||
|
|
||||||
st_reference_vertprog(st, &st->vp, stvp);
|
|
||||||
st_reference_fragprog(st, &st->fp, stfp);
|
st_reference_fragprog(st, &st->fp, stfp);
|
||||||
|
|
||||||
cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
|
|
||||||
|
|
||||||
if (st->missing_textures) {
|
if (st->missing_textures) {
|
||||||
/* use a pass-through frag shader that uses no textures */
|
/* use a pass-through frag shader that uses no textures */
|
||||||
void *fs = get_passthrough_fs(st);
|
void *fs = get_passthrough_fs(st);
|
||||||
|
@ -362,16 +178,48 @@ update_linkage( struct st_context *st )
|
||||||
else {
|
else {
|
||||||
cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
|
cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
st->vertex_result_to_slot = xvp->output_to_slot;
|
const struct st_tracked_state st_update_fp = {
|
||||||
|
"st_update_fp", /* name */
|
||||||
|
{ /* dirty */
|
||||||
|
0, /* mesa */
|
||||||
|
ST_NEW_FRAGMENT_PROGRAM /* st */
|
||||||
|
},
|
||||||
|
update_fp /* update */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_vp( struct st_context *st )
|
||||||
|
{
|
||||||
|
struct st_vertex_program *stvp;
|
||||||
|
|
||||||
|
/* find active shader and params -- Should be covered by
|
||||||
|
* ST_NEW_VERTEX_PROGRAM
|
||||||
|
*/
|
||||||
|
assert(st->ctx->VertexProgram._Current);
|
||||||
|
stvp = st_vertex_program(st->ctx->VertexProgram._Current);
|
||||||
|
assert(stvp->Base.Base.Target == GL_VERTEX_PROGRAM_ARB);
|
||||||
|
|
||||||
|
st->vp_varient = find_translated_vp(st, stvp);
|
||||||
|
|
||||||
|
st_reference_vertprog(st, &st->vp, stvp);
|
||||||
|
|
||||||
|
cso_set_vertex_shader_handle(st->cso_context,
|
||||||
|
st->vp_varient->driver_shader);
|
||||||
|
|
||||||
|
st->vertex_result_to_slot = stvp->result_to_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const struct st_tracked_state st_update_shader = {
|
const struct st_tracked_state st_update_vp = {
|
||||||
"st_update_shader", /* name */
|
"st_update_vp", /* name */
|
||||||
{ /* dirty */
|
{ /* dirty */
|
||||||
0, /* mesa */
|
0, /* mesa */
|
||||||
ST_NEW_VERTEX_PROGRAM | ST_NEW_FRAGMENT_PROGRAM /* st */
|
ST_NEW_VERTEX_PROGRAM /* st */
|
||||||
},
|
},
|
||||||
update_linkage /* update */
|
update_vp /* update */
|
||||||
};
|
};
|
||||||
|
|
|
@ -169,11 +169,6 @@ make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex)
|
||||||
stfp = (struct st_fragment_program *) p;
|
stfp = (struct st_fragment_program *) p;
|
||||||
stfp->Base.UsesKill = GL_TRUE;
|
stfp->Base.UsesKill = GL_TRUE;
|
||||||
|
|
||||||
/* No need to send this incomplete program down to hardware:
|
|
||||||
*
|
|
||||||
* st_translate_fragment_program(ctx->st, stfp, NULL);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return stfp;
|
return stfp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
#include "pipe/p_inlines.h"
|
#include "pipe/p_inlines.h"
|
||||||
|
#include "tgsi/tgsi_ureg.h"
|
||||||
#include "util/u_tile.h"
|
#include "util/u_tile.h"
|
||||||
#include "util/u_draw_quad.h"
|
#include "util/u_draw_quad.h"
|
||||||
#include "util/u_math.h"
|
#include "util/u_math.h"
|
||||||
|
@ -236,78 +237,41 @@ make_fragment_shader_z(struct st_context *st)
|
||||||
* Create a simple vertex shader that just passes through the
|
* Create a simple vertex shader that just passes through the
|
||||||
* vertex position and texcoord (and optionally, color).
|
* vertex position and texcoord (and optionally, color).
|
||||||
*/
|
*/
|
||||||
static struct st_vertex_program *
|
static void *
|
||||||
st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
|
st_make_passthrough_vertex_shader(struct st_context *st,
|
||||||
|
GLboolean passColor)
|
||||||
{
|
{
|
||||||
GLcontext *ctx = st->ctx;
|
if (!st->drawpix.vert_shaders[passColor]) {
|
||||||
struct st_vertex_program *stvp;
|
struct ureg_program *ureg =
|
||||||
struct gl_program *p;
|
ureg_create( TGSI_PROCESSOR_VERTEX );
|
||||||
GLuint ic = 0;
|
|
||||||
|
|
||||||
if (st->drawpix.vert_shaders[passColor])
|
if (ureg == NULL)
|
||||||
return st->drawpix.vert_shaders[passColor];
|
return NULL;
|
||||||
|
|
||||||
/*
|
/* MOV result.pos, vertex.pos; */
|
||||||
* Create shader now
|
ureg_MOV(ureg,
|
||||||
*/
|
ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ),
|
||||||
p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
|
ureg_DECL_vs_input( ureg, 0 ));
|
||||||
if (!p)
|
|
||||||
return NULL;
|
/* MOV result.texcoord0, vertex.texcoord0; */
|
||||||
|
ureg_MOV(ureg,
|
||||||
|
ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ),
|
||||||
|
ureg_DECL_vs_input( ureg, 1 ));
|
||||||
|
|
||||||
|
if (passColor) {
|
||||||
|
/* MOV result.color0, vertex.color0; */
|
||||||
|
ureg_MOV(ureg,
|
||||||
|
ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ),
|
||||||
|
ureg_DECL_vs_input( ureg, 2 ));
|
||||||
|
}
|
||||||
|
|
||||||
if (passColor)
|
ureg_END( ureg );
|
||||||
p->NumInstructions = 4;
|
|
||||||
else
|
st->drawpix.vert_shaders[passColor] =
|
||||||
p->NumInstructions = 3;
|
ureg_create_shader_and_destroy( ureg, st->pipe );
|
||||||
|
|
||||||
p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
|
|
||||||
if (!p->Instructions) {
|
|
||||||
ctx->Driver.DeleteProgram(ctx, p);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
_mesa_init_instructions(p->Instructions, p->NumInstructions);
|
|
||||||
/* MOV result.pos, vertex.pos; */
|
|
||||||
p->Instructions[0].Opcode = OPCODE_MOV;
|
|
||||||
p->Instructions[0].DstReg.File = PROGRAM_OUTPUT;
|
|
||||||
p->Instructions[0].DstReg.Index = VERT_RESULT_HPOS;
|
|
||||||
p->Instructions[0].SrcReg[0].File = PROGRAM_INPUT;
|
|
||||||
p->Instructions[0].SrcReg[0].Index = VERT_ATTRIB_POS;
|
|
||||||
/* MOV result.texcoord0, vertex.texcoord0; */
|
|
||||||
p->Instructions[1].Opcode = OPCODE_MOV;
|
|
||||||
p->Instructions[1].DstReg.File = PROGRAM_OUTPUT;
|
|
||||||
p->Instructions[1].DstReg.Index = VERT_RESULT_TEX0;
|
|
||||||
p->Instructions[1].SrcReg[0].File = PROGRAM_INPUT;
|
|
||||||
p->Instructions[1].SrcReg[0].Index = VERT_ATTRIB_TEX0;
|
|
||||||
ic = 2;
|
|
||||||
if (passColor) {
|
|
||||||
/* MOV result.color0, vertex.color0; */
|
|
||||||
p->Instructions[ic].Opcode = OPCODE_MOV;
|
|
||||||
p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
|
|
||||||
p->Instructions[ic].DstReg.Index = VERT_RESULT_COL0;
|
|
||||||
p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
|
|
||||||
p->Instructions[ic].SrcReg[0].Index = VERT_ATTRIB_COLOR0;
|
|
||||||
ic++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* END; */
|
return st->drawpix.vert_shaders[passColor];
|
||||||
p->Instructions[ic].Opcode = OPCODE_END;
|
|
||||||
ic++;
|
|
||||||
|
|
||||||
assert(ic == p->NumInstructions);
|
|
||||||
|
|
||||||
p->InputsRead = VERT_BIT_POS | VERT_BIT_TEX0;
|
|
||||||
p->OutputsWritten = ((1 << VERT_RESULT_TEX0) |
|
|
||||||
(1 << VERT_RESULT_HPOS));
|
|
||||||
if (passColor) {
|
|
||||||
p->InputsRead |= VERT_BIT_COLOR0;
|
|
||||||
p->OutputsWritten |= (1 << VERT_RESULT_COL0);
|
|
||||||
}
|
|
||||||
|
|
||||||
stvp = (struct st_vertex_program *) p;
|
|
||||||
st_translate_vertex_program(st, stvp, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
st->drawpix.vert_shaders[passColor] = stvp;
|
|
||||||
|
|
||||||
return stvp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -539,8 +503,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||||
GLsizei width, GLsizei height,
|
GLsizei width, GLsizei height,
|
||||||
GLfloat zoomX, GLfloat zoomY,
|
GLfloat zoomX, GLfloat zoomY,
|
||||||
struct pipe_texture *pt,
|
struct pipe_texture *pt,
|
||||||
struct st_vertex_program *stvp,
|
void *driver_vp,
|
||||||
struct st_fragment_program *stfp,
|
void *driver_fp,
|
||||||
const GLfloat *color,
|
const GLfloat *color,
|
||||||
GLboolean invertTex)
|
GLboolean invertTex)
|
||||||
{
|
{
|
||||||
|
@ -575,10 +539,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fragment shader state: TEX lookup program */
|
/* fragment shader state: TEX lookup program */
|
||||||
cso_set_fragment_shader_handle(cso, stfp->driver_shader);
|
cso_set_fragment_shader_handle(cso, driver_fp);
|
||||||
|
|
||||||
/* vertex shader state: position + texcoord pass-through */
|
/* vertex shader state: position + texcoord pass-through */
|
||||||
cso_set_vertex_shader_handle(cso, stvp->driver_shader);
|
cso_set_vertex_shader_handle(cso, driver_vp);
|
||||||
|
|
||||||
|
|
||||||
/* texture sampling state: */
|
/* texture sampling state: */
|
||||||
|
@ -806,7 +770,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
|
const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
|
||||||
{
|
{
|
||||||
struct st_fragment_program *stfp;
|
struct st_fragment_program *stfp;
|
||||||
struct st_vertex_program *stvp;
|
void *driver_vp;
|
||||||
struct st_context *st = st_context(ctx);
|
struct st_context *st = st_context(ctx);
|
||||||
struct pipe_surface *ps;
|
struct pipe_surface *ps;
|
||||||
const GLfloat *color;
|
const GLfloat *color;
|
||||||
|
@ -826,13 +790,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
if (format == GL_DEPTH_COMPONENT) {
|
if (format == GL_DEPTH_COMPONENT) {
|
||||||
ps = st->state.framebuffer.zsbuf;
|
ps = st->state.framebuffer.zsbuf;
|
||||||
stfp = make_fragment_shader_z(st);
|
stfp = make_fragment_shader_z(st);
|
||||||
stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
|
driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
|
||||||
color = ctx->Current.RasterColor;
|
color = ctx->Current.RasterColor;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ps = st->state.framebuffer.cbufs[0];
|
ps = st->state.framebuffer.cbufs[0];
|
||||||
stfp = combined_drawpix_fragment_program(ctx);
|
stfp = combined_drawpix_fragment_program(ctx);
|
||||||
stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
|
driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE);
|
||||||
color = NULL;
|
color = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,7 +807,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
if (pt) {
|
if (pt) {
|
||||||
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
|
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
|
||||||
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
|
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
|
||||||
pt, stvp, stfp, color, GL_FALSE);
|
pt,
|
||||||
|
driver_vp,
|
||||||
|
stfp->driver_shader,
|
||||||
|
color, GL_FALSE);
|
||||||
pipe_texture_reference(&pt, NULL);
|
pipe_texture_reference(&pt, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -960,7 +927,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
||||||
struct pipe_context *pipe = st->pipe;
|
struct pipe_context *pipe = st->pipe;
|
||||||
struct pipe_screen *screen = pipe->screen;
|
struct pipe_screen *screen = pipe->screen;
|
||||||
struct st_renderbuffer *rbRead;
|
struct st_renderbuffer *rbRead;
|
||||||
struct st_vertex_program *stvp;
|
void *driver_vp;
|
||||||
struct st_fragment_program *stfp;
|
struct st_fragment_program *stfp;
|
||||||
struct pipe_texture *pt;
|
struct pipe_texture *pt;
|
||||||
GLfloat *color;
|
GLfloat *color;
|
||||||
|
@ -1009,14 +976,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
||||||
rbRead = st_get_color_read_renderbuffer(ctx);
|
rbRead = st_get_color_read_renderbuffer(ctx);
|
||||||
color = NULL;
|
color = NULL;
|
||||||
stfp = combined_drawpix_fragment_program(ctx);
|
stfp = combined_drawpix_fragment_program(ctx);
|
||||||
stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
|
driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(type == GL_DEPTH);
|
assert(type == GL_DEPTH);
|
||||||
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
|
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
|
||||||
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
|
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
|
||||||
stfp = make_fragment_shader_z(st);
|
stfp = make_fragment_shader_z(st);
|
||||||
stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
|
driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
srcFormat = rbRead->texture->format;
|
srcFormat = rbRead->texture->format;
|
||||||
|
@ -1148,7 +1115,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
|
||||||
/* draw textured quad */
|
/* draw textured quad */
|
||||||
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
|
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
|
||||||
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
|
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
|
||||||
pt, stvp, stfp, color, GL_TRUE);
|
pt,
|
||||||
|
driver_vp,
|
||||||
|
stfp->driver_shader,
|
||||||
|
color, GL_TRUE);
|
||||||
|
|
||||||
pipe_texture_reference(&pt, NULL);
|
pipe_texture_reference(&pt, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,24 +138,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
|
||||||
case GL_VERTEX_PROGRAM_ARB:
|
case GL_VERTEX_PROGRAM_ARB:
|
||||||
{
|
{
|
||||||
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
|
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
|
||||||
|
st_vp_release_varients( st, stvp );
|
||||||
if (stvp->driver_shader) {
|
|
||||||
cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
|
|
||||||
stvp->driver_shader = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stvp->draw_shader) {
|
|
||||||
#if FEATURE_feedback || FEATURE_drawpix
|
|
||||||
/* this would only have been allocated for the RasterPos path */
|
|
||||||
draw_delete_vertex_shader(st->draw, stvp->draw_shader);
|
|
||||||
stvp->draw_shader = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stvp->state.tokens) {
|
|
||||||
st_free_tokens(stvp->state.tokens);
|
|
||||||
stvp->state.tokens = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_FRAGMENT_PROGRAM_ARB:
|
case GL_FRAGMENT_PROGRAM_ARB:
|
||||||
|
@ -177,8 +160,6 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
|
||||||
_mesa_reference_program(ctx, &prg, NULL);
|
_mesa_reference_program(ctx, &prg, NULL);
|
||||||
stfp->bitmap_program = NULL;
|
stfp->bitmap_program = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
st_free_translated_vertex_programs(st, stfp->vertex_programs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -219,8 +200,6 @@ static void st_program_string_notify( GLcontext *ctx,
|
||||||
stfp->state.tokens = NULL;
|
stfp->state.tokens = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
|
|
||||||
|
|
||||||
if (st->fp == stfp)
|
if (st->fp == stfp)
|
||||||
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
|
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
|
||||||
}
|
}
|
||||||
|
@ -229,25 +208,7 @@ static void st_program_string_notify( GLcontext *ctx,
|
||||||
|
|
||||||
stvp->serialNo++;
|
stvp->serialNo++;
|
||||||
|
|
||||||
if (stvp->driver_shader) {
|
st_vp_release_varients( st, stvp );
|
||||||
cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
|
|
||||||
stvp->driver_shader = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stvp->draw_shader) {
|
|
||||||
#if FEATURE_feedback || FEATURE_drawpix
|
|
||||||
/* this would only have been allocated for the RasterPos path */
|
|
||||||
draw_delete_vertex_shader(st->draw, stvp->draw_shader);
|
|
||||||
stvp->draw_shader = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stvp->state.tokens) {
|
|
||||||
st_free_tokens(stvp->state.tokens);
|
|
||||||
stvp->state.tokens = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
|
|
||||||
|
|
||||||
if (st->vp == stvp)
|
if (st->vp == stvp)
|
||||||
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
|
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
|
||||||
|
|
|
@ -127,6 +127,8 @@ struct st_context
|
||||||
struct st_vertex_program *vp; /**< Currently bound vertex program */
|
struct st_vertex_program *vp; /**< Currently bound vertex program */
|
||||||
struct st_fragment_program *fp; /**< Currently bound fragment program */
|
struct st_fragment_program *fp; /**< Currently bound fragment program */
|
||||||
|
|
||||||
|
struct st_vp_varient *vp_varient;
|
||||||
|
|
||||||
struct gl_texture_object *default_texture;
|
struct gl_texture_object *default_texture;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -86,7 +86,8 @@ st_print_current(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tgsi_dump( st->vp->state.tokens, 0 );
|
if (st->vp->varients)
|
||||||
|
tgsi_dump( st->vp->varients[0].state.tokens, 0 );
|
||||||
if (st->vp->Base.Base.Parameters)
|
if (st->vp->Base.Base.Parameters)
|
||||||
_mesa_print_parameter_list(st->vp->Base.Base.Parameters);
|
_mesa_print_parameter_list(st->vp->Base.Base.Parameters);
|
||||||
|
|
||||||
|
|
|
@ -573,7 +573,7 @@ st_draw_vbo(GLcontext *ctx,
|
||||||
|
|
||||||
/* must get these after state validation! */
|
/* must get these after state validation! */
|
||||||
vp = ctx->st->vp;
|
vp = ctx->st->vp;
|
||||||
vs = &ctx->st->vp->state;
|
vs = &ctx->st->vp_varient->state;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (MESA_VERBOSE & VERBOSE_GLSL) {
|
if (MESA_VERBOSE & VERBOSE_GLSL) {
|
||||||
|
|
|
@ -120,10 +120,10 @@ st_feedback_draw_vbo(GLcontext *ctx,
|
||||||
|
|
||||||
/* must get these after state validation! */
|
/* must get these after state validation! */
|
||||||
vp = ctx->st->vp;
|
vp = ctx->st->vp;
|
||||||
vs = &st->vp->state;
|
vs = &st->vp_varient->state;
|
||||||
|
|
||||||
if (!st->vp->draw_shader) {
|
if (!st->vp_varient->draw_shader) {
|
||||||
st->vp->draw_shader = draw_create_vertex_shader(draw, vs);
|
st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -136,7 +136,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
|
||||||
draw_set_viewport_state(draw, &st->state.viewport);
|
draw_set_viewport_state(draw, &st->state.viewport);
|
||||||
draw_set_clip_state(draw, &st->state.clip);
|
draw_set_clip_state(draw, &st->state.clip);
|
||||||
draw_set_rasterizer_state(draw, &st->state.rasterizer);
|
draw_set_rasterizer_state(draw, &st->state.rasterizer);
|
||||||
draw_bind_vertex_shader(draw, st->vp->draw_shader);
|
draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
|
||||||
set_feedback_vertex_format(ctx);
|
set_feedback_vertex_format(ctx);
|
||||||
|
|
||||||
/* loop over TGSI shader inputs to determine vertex buffer
|
/* loop over TGSI shader inputs to determine vertex buffer
|
||||||
|
|
|
@ -704,12 +704,10 @@ st_translate_mesa_program(
|
||||||
const ubyte inputSemanticName[],
|
const ubyte inputSemanticName[],
|
||||||
const ubyte inputSemanticIndex[],
|
const ubyte inputSemanticIndex[],
|
||||||
const GLuint interpMode[],
|
const GLuint interpMode[],
|
||||||
const GLbitfield inputFlags[],
|
|
||||||
GLuint numOutputs,
|
GLuint numOutputs,
|
||||||
const GLuint outputMapping[],
|
const GLuint outputMapping[],
|
||||||
const ubyte outputSemanticName[],
|
const ubyte outputSemanticName[],
|
||||||
const ubyte outputSemanticIndex[],
|
const ubyte outputSemanticIndex[] )
|
||||||
const GLbitfield outputFlags[] )
|
|
||||||
{
|
{
|
||||||
struct st_translate translate, *t;
|
struct st_translate translate, *t;
|
||||||
struct ureg_program *ureg;
|
struct ureg_program *ureg;
|
||||||
|
|
|
@ -49,12 +49,10 @@ st_translate_mesa_program(
|
||||||
const ubyte inputSemanticName[],
|
const ubyte inputSemanticName[],
|
||||||
const ubyte inputSemanticIndex[],
|
const ubyte inputSemanticIndex[],
|
||||||
const GLuint interpMode[],
|
const GLuint interpMode[],
|
||||||
const GLbitfield inputFlags[],
|
|
||||||
GLuint numOutputs,
|
GLuint numOutputs,
|
||||||
const GLuint outputMapping[],
|
const GLuint outputMapping[],
|
||||||
const ubyte outputSemanticName[],
|
const ubyte outputSemanticName[],
|
||||||
const ubyte outputSemanticIndex[],
|
const ubyte outputSemanticIndex[] );
|
||||||
const GLbitfield outputFlags[] );
|
|
||||||
|
|
||||||
void
|
void
|
||||||
st_free_tokens(const struct tgsi_token *tokens);
|
st_free_tokens(const struct tgsi_token *tokens);
|
||||||
|
|
|
@ -49,6 +49,36 @@
|
||||||
#include "st_mesa_to_tgsi.h"
|
#include "st_mesa_to_tgsi.h"
|
||||||
#include "cso_cache/cso_context.h"
|
#include "cso_cache/cso_context.h"
|
||||||
|
|
||||||
|
/* Clean out any old compilations:
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
st_vp_release_varients( struct st_context *st,
|
||||||
|
struct st_vertex_program *stvp )
|
||||||
|
{
|
||||||
|
struct st_vp_varient *vpv;
|
||||||
|
|
||||||
|
for (vpv = stvp->varients; vpv; ) {
|
||||||
|
struct st_vp_varient *next = vpv->next;
|
||||||
|
|
||||||
|
if (vpv->driver_shader)
|
||||||
|
cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
|
||||||
|
|
||||||
|
if (vpv->draw_shader)
|
||||||
|
draw_delete_vertex_shader( st->draw, vpv->draw_shader );
|
||||||
|
|
||||||
|
if (vpv->state.tokens)
|
||||||
|
st_free_tokens(vpv->state.tokens);
|
||||||
|
|
||||||
|
FREE( vpv );
|
||||||
|
|
||||||
|
vpv = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
stvp->varients = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate a Mesa vertex shader into a TGSI shader.
|
* Translate a Mesa vertex shader into a TGSI shader.
|
||||||
|
@ -58,31 +88,13 @@
|
||||||
* \return pointer to cached pipe_shader object.
|
* \return pointer to cached pipe_shader object.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
st_translate_vertex_program(struct st_context *st,
|
st_prepare_vertex_program(struct st_context *st,
|
||||||
struct st_vertex_program *stvp,
|
struct st_vertex_program *stvp)
|
||||||
const GLuint outputMapping[],
|
|
||||||
const ubyte *outputSemanticName,
|
|
||||||
const ubyte *outputSemanticIndex)
|
|
||||||
{
|
{
|
||||||
struct pipe_context *pipe = st->pipe;
|
GLuint attr;
|
||||||
GLuint defaultOutputMapping[VERT_RESULT_MAX];
|
|
||||||
GLuint attr, i;
|
|
||||||
GLuint num_generic = 0;
|
|
||||||
|
|
||||||
ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
|
stvp->num_inputs = 0;
|
||||||
ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
|
stvp->num_outputs = 0;
|
||||||
uint vs_num_inputs = 0;
|
|
||||||
|
|
||||||
ubyte vs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
|
|
||||||
ubyte vs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
|
|
||||||
uint vs_num_outputs = 0;
|
|
||||||
|
|
||||||
GLbitfield input_flags[MAX_PROGRAM_INPUTS];
|
|
||||||
GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
|
|
||||||
|
|
||||||
/*memset(&vs, 0, sizeof(vs));*/
|
|
||||||
memset(input_flags, 0, sizeof(input_flags));
|
|
||||||
memset(output_flags, 0, sizeof(output_flags));
|
|
||||||
|
|
||||||
if (stvp->Base.IsPositionInvariant)
|
if (stvp->Base.IsPositionInvariant)
|
||||||
_mesa_insert_mvp_code(st->ctx, &stvp->Base);
|
_mesa_insert_mvp_code(st->ctx, &stvp->Base);
|
||||||
|
@ -93,162 +105,56 @@ st_translate_vertex_program(struct st_context *st,
|
||||||
*/
|
*/
|
||||||
for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
|
for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
|
||||||
if (stvp->Base.Base.InputsRead & (1 << attr)) {
|
if (stvp->Base.Base.InputsRead & (1 << attr)) {
|
||||||
const GLuint slot = vs_num_inputs;
|
stvp->input_to_index[attr] = stvp->num_inputs;
|
||||||
|
stvp->index_to_input[stvp->num_inputs] = attr;
|
||||||
vs_num_inputs++;
|
stvp->num_inputs++;
|
||||||
|
|
||||||
stvp->input_to_index[attr] = slot;
|
|
||||||
stvp->index_to_input[slot] = attr;
|
|
||||||
|
|
||||||
switch (attr) {
|
|
||||||
case VERT_ATTRIB_POS:
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
|
||||||
vs_input_semantic_index[slot] = 0;
|
|
||||||
break;
|
|
||||||
case VERT_ATTRIB_WEIGHT:
|
|
||||||
/* fall-through */
|
|
||||||
case VERT_ATTRIB_NORMAL:
|
|
||||||
/* just label as a generic */
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
vs_input_semantic_index[slot] = 0;
|
|
||||||
break;
|
|
||||||
case VERT_ATTRIB_COLOR0:
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
|
||||||
vs_input_semantic_index[slot] = 0;
|
|
||||||
break;
|
|
||||||
case VERT_ATTRIB_COLOR1:
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
|
||||||
vs_input_semantic_index[slot] = 1;
|
|
||||||
break;
|
|
||||||
case VERT_ATTRIB_FOG:
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
|
||||||
vs_input_semantic_index[slot] = 0;
|
|
||||||
break;
|
|
||||||
case VERT_ATTRIB_POINT_SIZE:
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
|
|
||||||
vs_input_semantic_index[slot] = 0;
|
|
||||||
break;
|
|
||||||
case VERT_ATTRIB_TEX0:
|
|
||||||
case VERT_ATTRIB_TEX1:
|
|
||||||
case VERT_ATTRIB_TEX2:
|
|
||||||
case VERT_ATTRIB_TEX3:
|
|
||||||
case VERT_ATTRIB_TEX4:
|
|
||||||
case VERT_ATTRIB_TEX5:
|
|
||||||
case VERT_ATTRIB_TEX6:
|
|
||||||
case VERT_ATTRIB_TEX7:
|
|
||||||
assert(slot < Elements(vs_input_semantic_name));
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
vs_input_semantic_index[slot] = num_generic++;
|
|
||||||
break;
|
|
||||||
case VERT_ATTRIB_GENERIC0:
|
|
||||||
case VERT_ATTRIB_GENERIC1:
|
|
||||||
case VERT_ATTRIB_GENERIC2:
|
|
||||||
case VERT_ATTRIB_GENERIC3:
|
|
||||||
case VERT_ATTRIB_GENERIC4:
|
|
||||||
case VERT_ATTRIB_GENERIC5:
|
|
||||||
case VERT_ATTRIB_GENERIC6:
|
|
||||||
case VERT_ATTRIB_GENERIC7:
|
|
||||||
case VERT_ATTRIB_GENERIC8:
|
|
||||||
case VERT_ATTRIB_GENERIC9:
|
|
||||||
case VERT_ATTRIB_GENERIC10:
|
|
||||||
case VERT_ATTRIB_GENERIC11:
|
|
||||||
case VERT_ATTRIB_GENERIC12:
|
|
||||||
case VERT_ATTRIB_GENERIC13:
|
|
||||||
case VERT_ATTRIB_GENERIC14:
|
|
||||||
case VERT_ATTRIB_GENERIC15:
|
|
||||||
assert(attr < VERT_ATTRIB_MAX);
|
|
||||||
assert(slot < Elements(vs_input_semantic_name));
|
|
||||||
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
vs_input_semantic_index[slot] = num_generic++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_flags[slot] = stvp->Base.Base.InputFlags[attr];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
/* Compute mapping of vertex program outputs to slots.
|
||||||
if (outputMapping && outputSemanticName) {
|
|
||||||
printf("VERT_RESULT written out_slot semantic_name semantic_index\n");
|
|
||||||
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
|
|
||||||
printf(" %-2d %c %3d %2d %2d\n",
|
|
||||||
attr,
|
|
||||||
((stvp->Base.Base.OutputsWritten & (1 << attr)) ? 'Y' : ' '),
|
|
||||||
outputMapping[attr],
|
|
||||||
outputSemanticName[attr],
|
|
||||||
outputSemanticIndex[attr]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* initialize output semantics to defaults */
|
|
||||||
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
|
|
||||||
assert(i < Elements(vs_output_semantic_name));
|
|
||||||
vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
vs_output_semantic_index[i] = 0;
|
|
||||||
output_flags[i] = 0x0;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_generic = 0;
|
|
||||||
/*
|
|
||||||
* Determine number of outputs, the (default) output register
|
|
||||||
* mapping and the semantic information for each output.
|
|
||||||
*/
|
*/
|
||||||
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
|
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
|
||||||
if (stvp->Base.Base.OutputsWritten & (1 << attr)) {
|
if ((stvp->Base.Base.OutputsWritten & (1 << attr)) == 0) {
|
||||||
GLuint slot;
|
stvp->result_to_output[attr] = ~0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unsigned slot = stvp->num_outputs++;
|
||||||
|
|
||||||
/* XXX
|
stvp->result_to_output[attr] = slot;
|
||||||
* Pass in the fragment program's input's semantic info.
|
|
||||||
* Use the generic semantic indexes from there, instead of
|
|
||||||
* guessing below.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (outputMapping) {
|
|
||||||
slot = outputMapping[attr];
|
|
||||||
assert(slot != ~0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
slot = vs_num_outputs;
|
|
||||||
vs_num_outputs++;
|
|
||||||
defaultOutputMapping[attr] = slot;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
case VERT_RESULT_HPOS:
|
case VERT_RESULT_HPOS:
|
||||||
assert(slot == 0);
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
|
stvp->output_semantic_index[slot] = 0;
|
||||||
vs_output_semantic_index[slot] = 0;
|
|
||||||
break;
|
break;
|
||||||
case VERT_RESULT_COL0:
|
case VERT_RESULT_COL0:
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||||
vs_output_semantic_index[slot] = 0;
|
stvp->output_semantic_index[slot] = 0;
|
||||||
break;
|
break;
|
||||||
case VERT_RESULT_COL1:
|
case VERT_RESULT_COL1:
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
|
||||||
vs_output_semantic_index[slot] = 1;
|
stvp->output_semantic_index[slot] = 1;
|
||||||
break;
|
break;
|
||||||
case VERT_RESULT_BFC0:
|
case VERT_RESULT_BFC0:
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
||||||
vs_output_semantic_index[slot] = 0;
|
stvp->output_semantic_index[slot] = 0;
|
||||||
break;
|
break;
|
||||||
case VERT_RESULT_BFC1:
|
case VERT_RESULT_BFC1:
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
|
||||||
vs_output_semantic_index[slot] = 1;
|
stvp->output_semantic_index[slot] = 1;
|
||||||
break;
|
break;
|
||||||
case VERT_RESULT_FOGC:
|
case VERT_RESULT_FOGC:
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
|
||||||
vs_output_semantic_index[slot] = 0;
|
stvp->output_semantic_index[slot] = 0;
|
||||||
break;
|
break;
|
||||||
case VERT_RESULT_PSIZ:
|
case VERT_RESULT_PSIZ:
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
|
||||||
vs_output_semantic_index[slot] = 0;
|
stvp->output_semantic_index[slot] = 0;
|
||||||
break;
|
break;
|
||||||
case VERT_RESULT_EDGE:
|
case VERT_RESULT_EDGE:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VERT_RESULT_TEX0:
|
case VERT_RESULT_TEX0:
|
||||||
case VERT_RESULT_TEX1:
|
case VERT_RESULT_TEX1:
|
||||||
case VERT_RESULT_TEX2:
|
case VERT_RESULT_TEX2:
|
||||||
|
@ -257,92 +163,50 @@ st_translate_vertex_program(struct st_context *st,
|
||||||
case VERT_RESULT_TEX5:
|
case VERT_RESULT_TEX5:
|
||||||
case VERT_RESULT_TEX6:
|
case VERT_RESULT_TEX6:
|
||||||
case VERT_RESULT_TEX7:
|
case VERT_RESULT_TEX7:
|
||||||
/* fall-through */
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||||
|
stvp->output_semantic_index[slot] = attr - VERT_RESULT_TEX0;
|
||||||
|
break;
|
||||||
|
|
||||||
case VERT_RESULT_VAR0:
|
case VERT_RESULT_VAR0:
|
||||||
/* fall-through */
|
|
||||||
default:
|
default:
|
||||||
assert(slot < Elements(vs_output_semantic_name));
|
assert(attr < VERT_RESULT_MAX);
|
||||||
if (outputSemanticName) {
|
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||||
/* use provided semantic into */
|
stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 -
|
||||||
assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
|
FRAG_ATTRIB_TEX0 +
|
||||||
vs_output_semantic_name[slot] = outputSemanticName[attr];
|
attr -
|
||||||
vs_output_semantic_index[slot] = outputSemanticIndex[attr];
|
VERT_RESULT_VAR0);
|
||||||
}
|
break;
|
||||||
else {
|
|
||||||
/* use default semantic info */
|
|
||||||
vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
vs_output_semantic_index[slot] = num_generic++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(slot < Elements(output_flags));
|
|
||||||
output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outputMapping) {
|
|
||||||
/* find max output slot referenced to compute vs_num_outputs */
|
|
||||||
GLuint maxSlot = 0;
|
|
||||||
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
|
|
||||||
if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
|
|
||||||
maxSlot = outputMapping[attr];
|
|
||||||
}
|
|
||||||
vs_num_outputs = maxSlot + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
outputMapping = defaultOutputMapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 /* debug */
|
|
||||||
{
|
|
||||||
GLuint i;
|
|
||||||
printf("outputMapping? %d\n", outputMapping ? 1 : 0);
|
|
||||||
if (outputMapping) {
|
|
||||||
printf("attr -> slot\n");
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
printf(" %2d %3d\n", i, outputMapping[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("slot sem_name sem_index\n");
|
|
||||||
for (i = 0; i < vs_num_outputs; i++) {
|
|
||||||
printf(" %2d %d %d\n",
|
|
||||||
i,
|
|
||||||
vs_output_semantic_name[i],
|
|
||||||
vs_output_semantic_index[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
|
||||||
/* free old shader state, if any */
|
|
||||||
if (stvp->state.tokens) {
|
|
||||||
st_free_tokens(stvp->state.tokens);
|
|
||||||
stvp->state.tokens = NULL;
|
|
||||||
}
|
|
||||||
if (stvp->driver_shader) {
|
|
||||||
cso_delete_vertex_shader(st->cso_context, stvp->driver_shader);
|
|
||||||
stvp->driver_shader = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
stvp->state.tokens =
|
struct st_vp_varient *
|
||||||
|
st_translate_vertex_program(struct st_context *st,
|
||||||
|
struct st_vertex_program *stvp,
|
||||||
|
const struct st_vp_varient_key *key)
|
||||||
|
{
|
||||||
|
struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient);
|
||||||
|
struct pipe_context *pipe = st->pipe;
|
||||||
|
|
||||||
|
vpv->state.tokens =
|
||||||
st_translate_mesa_program(st->ctx,
|
st_translate_mesa_program(st->ctx,
|
||||||
TGSI_PROCESSOR_VERTEX,
|
TGSI_PROCESSOR_VERTEX,
|
||||||
&stvp->Base.Base,
|
&stvp->Base.Base,
|
||||||
/* inputs */
|
/* inputs */
|
||||||
vs_num_inputs,
|
stvp->num_inputs,
|
||||||
stvp->input_to_index,
|
stvp->input_to_index,
|
||||||
vs_input_semantic_name,
|
NULL, /* input semantic name */
|
||||||
vs_input_semantic_index,
|
NULL, /* input semantic index */
|
||||||
NULL,
|
NULL,
|
||||||
input_flags,
|
|
||||||
/* outputs */
|
/* outputs */
|
||||||
vs_num_outputs,
|
stvp->num_outputs,
|
||||||
outputMapping,
|
stvp->result_to_output,
|
||||||
vs_output_semantic_name,
|
stvp->output_semantic_name,
|
||||||
vs_output_semantic_index,
|
stvp->output_semantic_index );
|
||||||
output_flags );
|
|
||||||
|
|
||||||
stvp->num_inputs = vs_num_inputs;
|
vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
|
||||||
stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state);
|
|
||||||
|
|
||||||
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
|
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
|
||||||
_mesa_print_program(&stvp->Base.Base);
|
_mesa_print_program(&stvp->Base.Base);
|
||||||
|
@ -350,9 +214,11 @@ st_translate_vertex_program(struct st_context *st,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ST_DEBUG & DEBUG_TGSI) {
|
if (ST_DEBUG & DEBUG_TGSI) {
|
||||||
tgsi_dump( stvp->state.tokens, 0 );
|
tgsi_dump( vpv->state.tokens, 0 );
|
||||||
debug_printf("\n");
|
debug_printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return vpv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -375,7 +241,6 @@ st_translate_fragment_program(struct st_context *st,
|
||||||
GLuint attr;
|
GLuint attr;
|
||||||
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
|
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
|
||||||
GLuint vslot = 0;
|
GLuint vslot = 0;
|
||||||
GLuint num_generic = 0;
|
|
||||||
|
|
||||||
uint fs_num_inputs = 0;
|
uint fs_num_inputs = 0;
|
||||||
|
|
||||||
|
@ -383,13 +248,6 @@ st_translate_fragment_program(struct st_context *st,
|
||||||
ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
|
ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
|
||||||
uint fs_num_outputs = 0;
|
uint fs_num_outputs = 0;
|
||||||
|
|
||||||
GLbitfield input_flags[MAX_PROGRAM_INPUTS];
|
|
||||||
GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
|
|
||||||
|
|
||||||
/*memset(&fs, 0, sizeof(fs));*/
|
|
||||||
memset(input_flags, 0, sizeof(input_flags));
|
|
||||||
memset(output_flags, 0, sizeof(output_flags));
|
|
||||||
|
|
||||||
/* which vertex output goes to the first fragment input: */
|
/* which vertex output goes to the first fragment input: */
|
||||||
if (inputsRead & FRAG_BIT_WPOS)
|
if (inputsRead & FRAG_BIT_WPOS)
|
||||||
vslot = 0;
|
vslot = 0;
|
||||||
|
@ -432,14 +290,25 @@ st_translate_fragment_program(struct st_context *st,
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_FACE:
|
case FRAG_ATTRIB_FACE:
|
||||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
|
||||||
stfp->input_semantic_index[slot] = num_generic++;
|
stfp->input_semantic_index[slot] = 0;
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
|
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_PNTC:
|
|
||||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
/* In most cases, there is nothing special about these
|
||||||
stfp->input_semantic_index[slot] = num_generic++;
|
* inputs, so adopt a convention to use the generic
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
* semantic name and the mesa FRAG_ATTRIB_ number as the
|
||||||
break;
|
* index.
|
||||||
|
*
|
||||||
|
* All that is required is that the vertex shader labels
|
||||||
|
* its own outputs similarly, and that the vertex shader
|
||||||
|
* generates at least every output required by the
|
||||||
|
* fragment shader plus fixed-function hardware (such as
|
||||||
|
* BFC).
|
||||||
|
*
|
||||||
|
* There is no requirement that semantic indexes start at
|
||||||
|
* zero or be restricted to a particular range -- nobody
|
||||||
|
* should be building tables based on semantic index.
|
||||||
|
*/
|
||||||
case FRAG_ATTRIB_TEX0:
|
case FRAG_ATTRIB_TEX0:
|
||||||
case FRAG_ATTRIB_TEX1:
|
case FRAG_ATTRIB_TEX1:
|
||||||
case FRAG_ATTRIB_TEX2:
|
case FRAG_ATTRIB_TEX2:
|
||||||
|
@ -448,19 +317,18 @@ st_translate_fragment_program(struct st_context *st,
|
||||||
case FRAG_ATTRIB_TEX5:
|
case FRAG_ATTRIB_TEX5:
|
||||||
case FRAG_ATTRIB_TEX6:
|
case FRAG_ATTRIB_TEX6:
|
||||||
case FRAG_ATTRIB_TEX7:
|
case FRAG_ATTRIB_TEX7:
|
||||||
|
case FRAG_ATTRIB_PNTC:
|
||||||
|
case FRAG_ATTRIB_VAR0:
|
||||||
|
default:
|
||||||
|
/* Actually, let's try and zero-base this just for
|
||||||
|
* readability of the generated TGSI.
|
||||||
|
*/
|
||||||
|
assert(attr >= FRAG_ATTRIB_TEX0);
|
||||||
|
stfp->input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
|
||||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
||||||
stfp->input_semantic_index[slot] = num_generic++;
|
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||||
break;
|
break;
|
||||||
case FRAG_ATTRIB_VAR0:
|
|
||||||
/* fall-through */
|
|
||||||
default:
|
|
||||||
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
|
|
||||||
stfp->input_semantic_index[slot] = num_generic++;
|
|
||||||
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input_flags[slot] = stfp->Base.Base.InputFlags[attr];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,8 +366,6 @@ st_translate_fragment_program(struct st_context *st,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
|
|
||||||
|
|
||||||
fs_num_outputs++;
|
fs_num_outputs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,13 +384,11 @@ st_translate_fragment_program(struct st_context *st,
|
||||||
stfp->input_semantic_name,
|
stfp->input_semantic_name,
|
||||||
stfp->input_semantic_index,
|
stfp->input_semantic_index,
|
||||||
interpMode,
|
interpMode,
|
||||||
input_flags,
|
|
||||||
/* outputs */
|
/* outputs */
|
||||||
fs_num_outputs,
|
fs_num_outputs,
|
||||||
outputMapping,
|
outputMapping,
|
||||||
fs_output_semantic_name,
|
fs_output_semantic_name,
|
||||||
fs_output_semantic_index,
|
fs_output_semantic_index );
|
||||||
output_flags );
|
|
||||||
|
|
||||||
stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
|
stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
|
||||||
|
|
||||||
|
|
|
@ -64,41 +64,70 @@ struct st_fragment_program
|
||||||
struct pipe_shader_state state;
|
struct pipe_shader_state state;
|
||||||
void *driver_shader;
|
void *driver_shader;
|
||||||
|
|
||||||
GLuint param_state;
|
|
||||||
|
|
||||||
/** List of vertex programs which have been translated such that their
|
|
||||||
* outputs match this fragment program's inputs.
|
|
||||||
*/
|
|
||||||
struct translated_vertex_program *vertex_programs;
|
|
||||||
|
|
||||||
/** Program prefixed with glBitmap prologue */
|
/** Program prefixed with glBitmap prologue */
|
||||||
struct st_fragment_program *bitmap_program;
|
struct st_fragment_program *bitmap_program;
|
||||||
uint bitmap_sampler;
|
uint bitmap_sampler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct st_vp_varient_key
|
||||||
|
{
|
||||||
|
char dummy; /* currently unused */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This represents a vertex program, especially translated to match
|
||||||
|
* the inputs of a particular fragment shader.
|
||||||
|
*/
|
||||||
|
struct st_vp_varient
|
||||||
|
{
|
||||||
|
/* Parameters which generated this translated version of a vertex
|
||||||
|
* shader:
|
||||||
|
*/
|
||||||
|
struct st_vp_varient_key key;
|
||||||
|
|
||||||
|
/** TGSI tokens -- why?
|
||||||
|
*/
|
||||||
|
struct pipe_shader_state state;
|
||||||
|
|
||||||
|
/** Driver's compiled shader */
|
||||||
|
void *driver_shader;
|
||||||
|
|
||||||
|
/** For using our private draw module (glRasterPos) */
|
||||||
|
struct draw_vertex_shader *draw_shader;
|
||||||
|
|
||||||
|
/** Next in linked list */
|
||||||
|
struct st_vp_varient *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derived from Mesa gl_fragment_program:
|
* Derived from Mesa gl_fragment_program:
|
||||||
*/
|
*/
|
||||||
struct st_vertex_program
|
struct st_vertex_program
|
||||||
{
|
{
|
||||||
struct gl_vertex_program Base; /**< The Mesa vertex program */
|
struct gl_vertex_program Base; /**< The Mesa vertex program */
|
||||||
GLuint serialNo;
|
GLuint serialNo, lastSerialNo;
|
||||||
|
|
||||||
/** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
|
/** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
|
||||||
GLuint input_to_index[VERT_ATTRIB_MAX];
|
GLuint input_to_index[VERT_ATTRIB_MAX];
|
||||||
/** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
|
/** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
|
||||||
GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
|
GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
|
||||||
|
|
||||||
GLuint num_inputs;
|
GLuint num_inputs;
|
||||||
|
|
||||||
struct pipe_shader_state state;
|
/** Maps VERT_RESULT_x to slot */
|
||||||
void *driver_shader;
|
GLuint result_to_output[VERT_RESULT_MAX];
|
||||||
|
ubyte output_semantic_name[VERT_RESULT_MAX];
|
||||||
|
ubyte output_semantic_index[VERT_RESULT_MAX];
|
||||||
|
GLuint num_outputs;
|
||||||
|
|
||||||
/** For using our private draw module (glRasterPos) */
|
/** List of translated varients of this vertex program.
|
||||||
struct draw_vertex_shader *draw_shader;
|
*/
|
||||||
|
struct st_vp_varient *varients;
|
||||||
GLuint param_state;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,13 +172,21 @@ st_translate_fragment_program(struct st_context *st,
|
||||||
const GLuint inputMapping[]);
|
const GLuint inputMapping[]);
|
||||||
|
|
||||||
|
|
||||||
|
/* Called after program string change, discard all previous
|
||||||
|
* compilation results.
|
||||||
|
*/
|
||||||
extern void
|
extern void
|
||||||
st_translate_vertex_program(struct st_context *st,
|
st_prepare_vertex_program(struct st_context *st,
|
||||||
struct st_vertex_program *vp,
|
struct st_vertex_program *stvp);
|
||||||
const GLuint vert_output_to_slot[],
|
|
||||||
const ubyte *fs_input_semantic_name,
|
|
||||||
const ubyte *fs_input_semantic_index);
|
|
||||||
|
|
||||||
|
extern struct st_vp_varient *
|
||||||
|
st_translate_vertex_program(struct st_context *st,
|
||||||
|
struct st_vertex_program *stvp,
|
||||||
|
const struct st_vp_varient_key *key);
|
||||||
|
|
||||||
|
void
|
||||||
|
st_vp_release_varients( struct st_context *st,
|
||||||
|
struct st_vertex_program *stvp );
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
st_print_shaders(GLcontext *ctx);
|
st_print_shaders(GLcontext *ctx);
|
||||||
|
|
Loading…
Reference in New Issue