summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_atom.c3
-rw-r--r--src/mesa/state_tracker/st_atom.h3
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c5
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c6
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c9
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c337
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c8
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c5
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c5
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c153
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c18
-rw-r--r--src/mesa/state_tracker/st_cb_program.c43
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c16
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c54
-rw-r--r--src/mesa/state_tracker/st_context.h4
-rw-r--r--src/mesa/state_tracker/st_debug.c3
-rw-r--r--src/mesa/state_tracker/st_draw.c136
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c11
-rw-r--r--src/mesa/state_tracker/st_extensions.c4
-rw-r--r--src/mesa/state_tracker/st_format.c114
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c44
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c89
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.h7
-rw-r--r--src/mesa/state_tracker/st_program.c423
-rw-r--r--src/mesa/state_tracker/st_program.h78
-rw-r--r--src/mesa/state_tracker/st_texture.c43
26 files changed, 723 insertions, 898 deletions
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index 0e89a624c4..73df44d198 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -46,7 +46,8 @@ static const struct st_tracked_state *atoms[] =
&st_update_clip,
&st_finalize_textures,
- &st_update_shader,
+ &st_update_fp,
+ &st_update_vp,
&st_update_rasterizer,
&st_update_polygon_stipple,
diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h
index c7cffd85c8..f34b49203b 100644
--- a/src/mesa/state_tracker/st_atom.h
+++ b/src/mesa/state_tracker/st_atom.h
@@ -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_clip;
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_polygon_stipple;
extern const struct st_tracked_state st_update_viewport;
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index e18c0f6e0a..8ca4335e33 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -40,6 +40,7 @@
#include "pipe/p_inlines.h"
#include "cso_cache/cso_context.h"
#include "util/u_rect.h"
+#include "util/u_math.h"
@@ -64,8 +65,8 @@ update_renderbuffer_surface(struct st_context *st,
GLuint level;
/* find matching mipmap level size */
for (level = 0; level <= texture->last_level; level++) {
- if (texture->width[level] == rtt_width &&
- texture->height[level] == rtt_height) {
+ if (u_minify(texture->width0, level) == rtt_width &&
+ u_minify(texture->height0, level) == rtt_height) {
pipe_surface_reference(&strb->surface, NULL);
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index babfcc87b4..6a5854e9ba 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -145,7 +145,7 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
const GLuint gSize = ctx->PixelMaps.GtoG.Size;
const GLuint bSize = ctx->PixelMaps.BtoB.Size;
const GLuint aSize = ctx->PixelMaps.AtoA.Size;
- const uint texSize = pt->width[0];
+ const uint texSize = pt->width0;
uint *dest;
uint i, j;
@@ -162,12 +162,14 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt)
*/
for (i = 0; i < texSize; i++) {
for (j = 0; j < texSize; j++) {
+ union util_color uc;
int k = (i * texSize + j);
ubyte r = ctx->PixelMaps.RtoR.Map8[j * rSize / texSize];
ubyte g = ctx->PixelMaps.GtoG.Map8[i * gSize / texSize];
ubyte b = ctx->PixelMaps.BtoB.Map8[j * bSize / texSize];
ubyte a = ctx->PixelMaps.AtoA.Map8[i * aSize / texSize];
- util_pack_color_ub(r, g, b, a, pt->format, dest + k);
+ util_pack_color_ub(r, g, b, a, pt->format, &uc);
+ *(dest + k) = uc.ui;
}
}
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index 6611956ae8..d6e3a3e561 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -229,14 +229,23 @@ update_samplers(struct st_context *st)
/*printf("%s su=%u non-null\n", __FUNCTION__, su);*/
cso_single_sampler(st->cso_context, su, sampler);
+ if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
+ cso_single_vertex_sampler(st->cso_context, su, sampler);
+ }
}
else {
/*printf("%s su=%u null\n", __FUNCTION__, su);*/
cso_single_sampler(st->cso_context, su, NULL);
+ if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
+ cso_single_vertex_sampler(st->cso_context, su, NULL);
+ }
}
}
cso_single_sampler_done(st->cso_context);
+ if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
+ cso_single_vertex_sampler_done(st->cso_context);
+ }
}
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 9208f3f446..46c8cbb309 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -56,82 +56,18 @@
#include "st_mesa_to_tgsi.h"
-/**
- * This represents a vertex program, especially translated to match
- * the inputs of a particular fragment shader.
- */
-struct translated_vertex_program
-{
- 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.
+/*
+ * Translate fragment program if needed.
*/
-static struct translated_vertex_program *
-find_translated_vp(struct st_context *st,
- struct st_vertex_program *stvp,
- struct st_fragment_program *stfp)
+static void
+translate_fp(struct st_context *st,
+ struct st_fragment_program *stfp)
{
- static const GLuint UNUSED = ~0;
- struct translated_vertex_program *xvp;
const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;
- /*
- * Translate fragment program if needed.
- */
if (!stfp->state.tokens) {
GLuint inAttr, numIn = 0;
@@ -141,7 +77,7 @@ find_translated_vp(struct st_context *st,
numIn++;
}
else {
- stfp->input_to_slot[inAttr] = UNUSED;
+ stfp->input_to_slot[inAttr] = -1;
}
}
@@ -151,168 +87,74 @@ find_translated_vp(struct st_context *st,
st_translate_fragment_program(st, stfp, stfp->input_to_slot);
}
+}
- /* See if we've got a translated vertex program whose outputs match
- * 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) {
- if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) {
- break;
- }
- }
-
- /* No? Allocate translated vp object now */
- if (!xvp) {
- xvp = ST_CALLOC_STRUCT(translated_vertex_program);
- xvp->frag_inputs = fragInputsRead;
- xvp->master = stvp;
-
- xvp->next = stfp->vertex_programs;
- stfp->vertex_programs = xvp;
- }
- /* See if we need to translate vertex program to TGSI form */
- 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
- }
+/**
+ * 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;
- /* 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);
- }
+ /* Nothing in our key yet. This will change:
+ */
+ memset(&key, 0, sizeof key);
+
+ /* When this is true, we will add an extra input to the vertex
+ * shader translation (for edgeflags), an extra output with
+ * edgeflag semantics, and extend the vertex shader to pass through
+ * the input to the output. We'll need to use similar logic to set
+ * up the extra vertex_element input for edgeflags.
+ * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
+ */
+ key.passthrough_edgeflags = (st->vertdata_edgeflags && (
+ st->ctx->Polygon.FrontMode != GL_FILL ||
+ st->ctx->Polygon.BackMode != GL_FILL));
- /* 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.
+ /* 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.
*/
- 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;
- }
- }
+ st_prepare_vertex_program( st, stvp );
-#if 0 /*debug*/
- printf("vp output_to_slot[%d] = %d\n", outAttr,
- xvp->output_to_slot[outAttr]);
-#endif
+ /* We are now up-to-date:
+ */
+ stvp->lastSerialNo = stvp->serialNo;
+ }
+
+ /* See if we've got a translated vertex program whose outputs match
+ * the fragment program's inputs.
+ */
+ for (vpv = stvp->varients; vpv; vpv = vpv->next) {
+ if (memcmp(&vpv->key, &key, sizeof key) == 0) {
+ break;
}
+ }
- 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;
+ /* No? Perform new translation here. */
+ if (!vpv) {
+ vpv = st_translate_vertex_program(st, stvp, &key);
+ if (!vpv)
+ return NULL;
+
+ vpv->next = stvp->varients;
+ stvp->varients = vpv;
}
- return xvp;
+ return vpv;
}
-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 *
@@ -326,32 +168,19 @@ get_passthrough_fs(struct st_context *st)
return st->passthrough_fs;
}
-
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 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);
stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
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);
- cso_set_vertex_shader_handle(st->cso_context, stvp->driver_shader);
-
if (st->missing_textures) {
/* use a pass-through frag shader that uses no textures */
void *fs = get_passthrough_fs(st);
@@ -360,16 +189,48 @@ update_linkage( struct st_context *st )
else {
cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
}
+}
+
+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;
- st->vertex_result_to_slot = xvp->output_to_slot;
+ /* 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 = {
- "st_update_shader", /* name */
+const struct st_tracked_state st_update_vp = {
+ "st_update_vp", /* name */
{ /* dirty */
- 0, /* mesa */
- ST_NEW_VERTEX_PROGRAM | ST_NEW_FRAGMENT_PROGRAM /* st */
+ _NEW_POLYGON, /* mesa */
+ ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA /* st */
},
- update_linkage /* update */
+ update_vp /* update */
};
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 4d4f97da7e..0b68447d21 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -32,6 +32,8 @@
*/
+#include "main/macros.h"
+
#include "st_context.h"
#include "st_atom.h"
#include "st_texture.h"
@@ -99,6 +101,12 @@ update_textures(struct st_context *st)
cso_set_sampler_textures(st->cso_context,
st->state.num_textures,
st->state.sampler_texture);
+ if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
+ cso_set_vertex_sampler_textures(st->cso_context,
+ MIN2(st->state.num_textures,
+ st->ctx->Const.MaxVertexTextureImageUnits),
+ st->state.sampler_texture);
+ }
}
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 1960d171bf..1bdeaccda3 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -169,11 +169,6 @@ make_bitmap_fragment_program(GLcontext *ctx, GLuint samplerIndex)
stfp = (struct st_fragment_program *) p;
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;
}
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index e83b6c92ef..72b30e7c04 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -52,6 +52,7 @@
#include "pipe/p_inlines.h"
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
+#include "util/u_format.h"
#include "util/u_pack_color.h"
#include "util/u_simple_shaders.h"
#include "util/u_draw_quad.h"
@@ -341,7 +342,7 @@ static INLINE GLboolean
check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
{
const struct st_renderbuffer *strb = st_renderbuffer(rb);
- const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format);
+ const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
if (ctx->Scissor.Enabled &&
(ctx->Scissor.X != 0 ||
@@ -365,7 +366,7 @@ static INLINE GLboolean
check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
{
const struct st_renderbuffer *strb = st_renderbuffer(rb);
- const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format);
+ const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
const GLuint stencilMax = 0xff;
const GLboolean maskStencil
= (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 1d33e81c2c..7c664267d4 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -60,8 +60,10 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
+#include "tgsi/tgsi_ureg.h"
#include "util/u_tile.h"
#include "util/u_draw_quad.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_rect.h"
#include "shader/prog_instruction.h"
@@ -236,78 +238,41 @@ make_fragment_shader_z(struct st_context *st)
* Create a simple vertex shader that just passes through the
* vertex position and texcoord (and optionally, color).
*/
-static struct st_vertex_program *
-st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
+static void *
+st_make_passthrough_vertex_shader(struct st_context *st,
+ GLboolean passColor)
{
- GLcontext *ctx = st->ctx;
- struct st_vertex_program *stvp;
- struct gl_program *p;
- GLuint ic = 0;
-
- if (st->drawpix.vert_shaders[passColor])
- return st->drawpix.vert_shaders[passColor];
-
- /*
- * Create shader now
- */
- p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
- if (!p)
- return NULL;
-
- if (passColor)
- p->NumInstructions = 4;
- else
- p->NumInstructions = 3;
-
- 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; */
- p->Instructions[ic].Opcode = OPCODE_END;
- ic++;
-
- assert(ic == p->NumInstructions);
+ if (!st->drawpix.vert_shaders[passColor]) {
+ struct ureg_program *ureg =
+ ureg_create( TGSI_PROCESSOR_VERTEX );
+
+ if (ureg == NULL)
+ return NULL;
+
+ /* MOV result.pos, vertex.pos; */
+ ureg_MOV(ureg,
+ ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ),
+ ureg_DECL_vs_input( ureg, 0 ));
+
+ /* 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 ));
+ }
- 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);
+ ureg_END( ureg );
+
+ st->drawpix.vert_shaders[passColor] =
+ ureg_create_shader_and_destroy( ureg, st->pipe );
}
- stvp = (struct st_vertex_program *) p;
- st_translate_vertex_program(st, stvp, NULL, NULL, NULL);
-
- st->drawpix.vert_shaders[passColor] = stvp;
-
- return stvp;
+ return st->drawpix.vert_shaders[passColor];
}
@@ -539,8 +504,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
GLsizei width, GLsizei height,
GLfloat zoomX, GLfloat zoomY,
struct pipe_texture *pt,
- struct st_vertex_program *stvp,
- struct st_fragment_program *stfp,
+ void *driver_vp,
+ void *driver_fp,
const GLfloat *color,
GLboolean invertTex)
{
@@ -575,10 +540,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
}
/* 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 */
- cso_set_vertex_shader_handle(cso, stvp->driver_shader);
+ cso_set_vertex_shader_handle(cso, driver_vp);
/* texture sampling state: */
@@ -621,10 +586,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
struct pipe_texture *textures[2];
textures[0] = pt;
textures[1] = st->pixel_xfer.pixelmap_texture;
- pipe->set_sampler_textures(pipe, 2, textures);
+ pipe->set_fragment_sampler_textures(pipe, 2, textures);
}
else {
- pipe->set_sampler_textures(pipe, 1, &pt);
+ pipe->set_fragment_sampler_textures(pipe, 1, &pt);
}
/* Compute window coords (y=0=bottom) with pixel zoom.
@@ -637,8 +602,8 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
y1 = y + height * ctx->Pixel.ZoomY;
draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
- (GLfloat) width / pt->width[0],
- (GLfloat) height / pt->height[0]);
+ (GLfloat) width / pt->width0,
+ (GLfloat) height / pt->height0);
/* restore state */
cso_restore_rasterizer(cso);
@@ -683,7 +648,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
if(format != GL_DEPTH_STENCIL &&
- pf_get_component_bits( strb->format, PIPE_FORMAT_COMP_Z ) != 0)
+ util_format_get_component_bits(strb->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
usage = PIPE_TRANSFER_READ_WRITE;
else
usage = PIPE_TRANSFER_WRITE;
@@ -737,7 +702,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
/* now pack the stencil (and Z) values in the dest format */
- switch (pt->format) {
+ switch (pt->texture->format) {
case PIPE_FORMAT_S8_UNORM:
{
ubyte *dest = stmap + spanY * pt->stride + spanX;
@@ -806,7 +771,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
{
struct st_fragment_program *stfp;
- struct st_vertex_program *stvp;
+ void *driver_vp;
struct st_context *st = st_context(ctx);
struct pipe_surface *ps;
const GLfloat *color;
@@ -826,13 +791,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (format == GL_DEPTH_COMPONENT) {
ps = st->state.framebuffer.zsbuf;
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;
}
else {
ps = st->state.framebuffer.cbufs[0];
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;
}
@@ -843,7 +808,10 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (pt) {
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
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);
}
}
@@ -875,7 +843,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
&ctx->DefaultPacking, buffer);
- if(pf_get_component_bits( rbDraw->format, PIPE_FORMAT_COMP_Z ) != 0)
+ if(util_format_get_component_bits(rbDraw->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
usage = PIPE_TRANSFER_READ_WRITE;
else
usage = PIPE_TRANSFER_WRITE;
@@ -889,8 +857,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
usage, dstx, dsty,
width, height);
- assert(ptDraw->block.width == 1);
- assert(ptDraw->block.height == 1);
+ assert(util_format_get_blockwidth(ptDraw->texture->format) == 1);
+ assert(util_format_get_blockheight(ptDraw->texture->format) == 1);
/* map the stencil buffer */
drawMap = screen->transfer_map(screen, ptDraw);
@@ -911,7 +879,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
dst = drawMap + y * ptDraw->stride;
src = buffer + i * width;
- switch (ptDraw->format) {
+ switch (ptDraw->texture->format) {
case PIPE_FORMAT_S8Z24_UNORM:
{
uint *dst4 = (uint *) dst;
@@ -960,7 +928,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *rbRead;
- struct st_vertex_program *stvp;
+ void *driver_vp;
struct st_fragment_program *stfp;
struct pipe_texture *pt;
GLfloat *color;
@@ -1009,14 +977,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
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 {
assert(type == GL_DEPTH);
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
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;
@@ -1116,7 +1084,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
- if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
+ if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
@@ -1148,7 +1116,10 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
/* draw textured quad */
draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
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);
}
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 65ce12ccd4..45ce34a85f 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -49,6 +49,7 @@
#include "st_public.h"
#include "st_texture.h"
+#include "util/u_format.h"
#include "util/u_rect.h"
@@ -98,16 +99,14 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
strb->defined = GL_FALSE; /* undefined contents now */
if(strb->software) {
- struct pipe_format_block block;
size_t size;
_mesa_free(strb->data);
assert(strb->format != PIPE_FORMAT_NONE);
- pf_get_block(strb->format, &block);
- strb->stride = pf_get_stride(&block, width);
- size = pf_get_2d_size(&block, strb->stride, height);
+ strb->stride = util_format_get_stride(strb->format, width);
+ size = util_format_get_2d_size(strb->format, strb->stride, height);
strb->data = _mesa_malloc(size);
@@ -127,13 +126,12 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
template.format = format;
- pf_get_block(format, &template.block);
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
+ template.width0 = width;
+ template.height0 = height;
+ template.depth0 = 1;
template.last_level = 0;
template.nr_samples = rb->NumSamples;
- if (pf_is_depth_stencil(format)) {
+ if (util_format_is_depth_or_stencil(format)) {
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
}
else {
@@ -376,7 +374,7 @@ st_render_texture(GLcontext *ctx,
rb->_BaseFormat = texImage->_BaseFormat;
/*printf("***** render to texture level %d: %d x %d\n", att->TextureLevel, rb->Width, rb->Height);*/
- /*printf("***** pipe texture %d x %d\n", pt->width[0], pt->height[0]);*/
+ /*printf("***** pipe texture %d x %d\n", pt->width0, pt->height0);*/
pipe_texture_reference( &strb->texture, pt );
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index b2d5c39a3a..8c276f8128 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -138,24 +138,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
case GL_VERTEX_PROGRAM_ARB:
{
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
-
- 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;
- }
+ st_vp_release_varients( st, stvp );
}
break;
case GL_FRAGMENT_PROGRAM_ARB:
@@ -177,8 +160,6 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
_mesa_reference_program(ctx, &prg, NULL);
stfp->bitmap_program = NULL;
}
-
- st_free_translated_vertex_programs(st, stfp->vertex_programs);
}
break;
default:
@@ -219,8 +200,6 @@ static void st_program_string_notify( GLcontext *ctx,
stfp->state.tokens = NULL;
}
- stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
-
if (st->fp == stfp)
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
}
@@ -229,25 +208,7 @@ static void st_program_string_notify( GLcontext *ctx,
stvp->serialNo++;
- 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;
- }
-
- stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
+ st_vp_release_varients( st, stvp );
if (st->vp == stvp)
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 772bb3bb69..6fa7bb64f2 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -103,7 +103,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
/* get stencil (and Z) values */
- switch (pt->format) {
+ switch (pt->texture->format) {
case PIPE_FORMAT_S8_UNORM:
{
const ubyte *src = stmap + srcY * pt->stride;
@@ -243,7 +243,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,
GLint row, col, dy, dstStride;
if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
- y = strb->texture->height[0] - y - height;
+ y = strb->texture->height0 - y - height;
}
trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture,
@@ -431,8 +431,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width,
format, type);
- if (trans->format == PIPE_FORMAT_S8Z24_UNORM ||
- trans->format == PIPE_FORMAT_X8Z24_UNORM) {
+ if (trans->texture->format == PIPE_FORMAT_S8Z24_UNORM ||
+ trans->texture->format == PIPE_FORMAT_X8Z24_UNORM) {
if (format == GL_DEPTH_COMPONENT) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH];
@@ -463,8 +463,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
}
}
- else if (trans->format == PIPE_FORMAT_Z24S8_UNORM ||
- trans->format == PIPE_FORMAT_Z24X8_UNORM) {
+ else if (trans->texture->format == PIPE_FORMAT_Z24S8_UNORM ||
+ trans->texture->format == PIPE_FORMAT_Z24X8_UNORM) {
if (format == GL_DEPTH_COMPONENT) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH];
@@ -490,7 +490,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
}
}
- else if (trans->format == PIPE_FORMAT_Z16_UNORM) {
+ else if (trans->texture->format == PIPE_FORMAT_Z16_UNORM) {
for (i = 0; i < height; i++) {
GLushort ztemp[MAX_WIDTH];
GLfloat zfloat[MAX_WIDTH];
@@ -505,7 +505,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
dst += dstStride;
}
}
- else if (trans->format == PIPE_FORMAT_Z32_UNORM) {
+ else if (trans->texture->format == PIPE_FORMAT_Z32_UNORM) {
for (i = 0; i < height; i++) {
GLuint ztemp[MAX_WIDTH];
GLfloat zfloat[MAX_WIDTH];
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index d4630a514f..6e1ecb1c50 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -62,6 +62,7 @@
#include "pipe/p_shader_tokens.h"
#include "util/u_tile.h"
#include "util/u_blit.h"
+#include "util/u_format.h"
#include "util/u_surface.h"
#include "util/u_math.h"
@@ -204,7 +205,7 @@ static GLuint
default_usage(enum pipe_format fmt)
{
GLuint usage = PIPE_TEXTURE_USAGE_SAMPLER;
- if (pf_is_depth_stencil(fmt))
+ if (util_format_is_depth_or_stencil(fmt))
usage |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
else
usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
@@ -405,10 +406,9 @@ compress_with_blit(GLcontext * ctx,
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.format = st_mesa_format_to_pipe_format(mesa_format);
- pf_get_block(templ.format, &templ.block);
- templ.width[0] = width;
- templ.height[0] = height;
- templ.depth[0] = 1;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
templ.last_level = 0;
templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
src_tex = screen->texture_create(screen, &templ);
@@ -634,7 +634,7 @@ st_TexImage(GLcontext * ctx,
if (stImage->pt) {
if (format == GL_DEPTH_COMPONENT &&
- pf_is_depth_and_stencil(stImage->pt->format))
+ util_format_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
@@ -833,7 +833,7 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level,
/* copy/pack data into user buffer */
if (st_equal_formats(stImage->pt->format, format, type)) {
/* memcpy */
- const uint bytesPerRow = width * pf_get_size(stImage->pt->format);
+ const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format);
ubyte *map = screen->transfer_map(screen, tex_xfer);
GLuint row;
for (row = 0; row < height; row++) {
@@ -890,7 +890,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
GLubyte *dest;
if (stImage->pt &&
- pf_is_compressed(stImage->pt->format) &&
+ util_format_is_compressed(stImage->pt->format) &&
!compressed_dst) {
/* Need to decompress the texture.
* We'll do this by rendering a textured quad.
@@ -915,7 +915,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
PIPE_TRANSFER_READ, 0, 0,
stImage->base.Width,
stImage->base.Height);
- texImage->RowStride = stImage->transfer->stride / stImage->pt->block.size;
+ texImage->RowStride = stImage->transfer->stride / util_format_get_blocksize(stImage->pt->format);
}
else {
/* Otherwise, the image should actually be stored in
@@ -1041,7 +1041,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
unsigned face = _mesa_tex_target_to_face(target);
if (format == GL_DEPTH_COMPONENT &&
- pf_is_depth_and_stencil(stImage->pt->format))
+ util_format_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
@@ -1163,10 +1163,10 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_image *texImage)
{
struct st_texture_image *stImage = st_texture_image(texImage);
- struct pipe_format_block block;
int srcBlockStride;
int dstBlockStride;
int y;
+ enum pipe_format pformat= stImage->pt->format;
if (stImage->pt) {
unsigned face = _mesa_tex_target_to_face(target);
@@ -1178,8 +1178,7 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
xoffset, yoffset,
width, height);
- block = stImage->pt->block;
- srcBlockStride = pf_get_stride(&block, width);
+ srcBlockStride = util_format_get_stride(pformat, width);
dstBlockStride = stImage->transfer->stride;
} else {
assert(stImage->pt);
@@ -1193,16 +1192,16 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
return;
}
- assert(xoffset % block.width == 0);
- assert(yoffset % block.height == 0);
- assert(width % block.width == 0);
- assert(height % block.height == 0);
+ assert(xoffset % util_format_get_blockwidth(pformat) == 0);
+ assert(yoffset % util_format_get_blockheight(pformat) == 0);
+ assert(width % util_format_get_blockwidth(pformat) == 0);
+ assert(height % util_format_get_blockheight(pformat) == 0);
- for (y = 0; y < height; y += block.height) {
+ for (y = 0; y < height; y += util_format_get_blockheight(pformat)) {
/* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */
- const char *src = (const char*)data + srcBlockStride * pf_get_nblocksy(&block, y);
- char *dst = (char*)texImage->Data + dstBlockStride * pf_get_nblocksy(&block, y);
- memcpy(dst, src, pf_get_stride(&block, width));
+ const char *src = (const char*)data + srcBlockStride * util_format_get_nblocksy(pformat, y);
+ char *dst = (char*)texImage->Data + dstBlockStride * util_format_get_nblocksy(pformat, y);
+ memcpy(dst, src, util_format_get_stride(pformat, width));
}
if (stImage->pt) {
@@ -1266,7 +1265,7 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
if ((baseFormat == GL_DEPTH_COMPONENT ||
baseFormat == GL_DEPTH_STENCIL) &&
- pf_is_depth_and_stencil(stImage->pt->format))
+ util_format_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
@@ -1692,10 +1691,10 @@ copy_image_data_to_texture(struct st_context *st,
dstLevel,
stImage->base.Data,
stImage->base.RowStride *
- stObj->pt->block.size,
+ util_format_get_blocksize(stObj->pt->format),
stImage->base.RowStride *
stImage->base.Height *
- stObj->pt->block.size);
+ util_format_get_blocksize(stObj->pt->format));
_mesa_align_free(stImage->base.Data);
stImage->base.Data = NULL;
}
@@ -1761,10 +1760,9 @@ st_finalize_texture(GLcontext *ctx,
if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
stObj->pt->format != fmt ||
stObj->pt->last_level < stObj->lastLevel ||
- stObj->pt->width[0] != firstImage->base.Width2 ||
- stObj->pt->height[0] != firstImage->base.Height2 ||
- stObj->pt->depth[0] != firstImage->base.Depth2 ||
- stObj->pt->block.size != blockSize)
+ stObj->pt->width0 != firstImage->base.Width2 ||
+ stObj->pt->height0 != firstImage->base.Height2 ||
+ stObj->pt->depth0 != firstImage->base.Depth2)
{
pipe_texture_reference(&stObj->pt, NULL);
ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 18adb35e87..831909a3f8 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -55,6 +55,7 @@ struct bitmap_cache;
#define ST_NEW_FRAGMENT_PROGRAM 0x2
#define ST_NEW_VERTEX_PROGRAM 0x4
#define ST_NEW_FRAMEBUFFER 0x8
+#define ST_NEW_EDGEFLAGS_DATA 0x10
struct st_state_flags {
@@ -120,6 +121,7 @@ struct st_context
struct st_state_flags dirty;
GLboolean missing_textures;
+ GLboolean vertdata_edgeflags;
/** Mapping from VERT_RESULT_x to post-transformed vertex slot */
const GLuint *vertex_result_to_slot;
@@ -127,6 +129,8 @@ struct st_context
struct st_vertex_program *vp; /**< Currently bound vertex program */
struct st_fragment_program *fp; /**< Currently bound fragment program */
+ struct st_vp_varient *vp_varient;
+
struct gl_texture_object *default_texture;
struct {
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 3009cde9d5..6e699ca552 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -86,7 +86,8 @@ st_print_current(void)
}
#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)
_mesa_print_parameter_list(st->vp->Base.Base.Parameters);
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 5c6af1125a..e54f21be60 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -217,59 +217,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
}
-/*
- * If edge flags are needed, setup an bitvector of flags and call
- * pipe->set_edgeflags().
- * XXX memleak: need to free the returned pointer at some point
- */
-static void *
-setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
- const struct gl_client_array *array)
-{
- struct pipe_context *pipe = ctx->st->pipe;
-
- if ((primMode == GL_TRIANGLES ||
- primMode == GL_QUADS ||
- primMode == GL_POLYGON) &&
- (ctx->Polygon.FrontMode != GL_FILL ||
- ctx->Polygon.BackMode != GL_FILL)) {
- /* need edge flags */
- GLint i;
- unsigned *vec;
- struct st_buffer_object *stobj = st_buffer_object(array->BufferObj);
- ubyte *map;
-
- if (!stobj || stobj->Base.Name == 0) {
- /* edge flags are not in a VBO */
- return NULL;
- }
-
- vec = (unsigned *) _mesa_calloc(sizeof(unsigned) * ((count + 31) / 32));
- if (!vec)
- return NULL;
- map = pipe_buffer_map(pipe->screen, stobj->buffer, PIPE_BUFFER_USAGE_CPU_READ);
- map = ADD_POINTERS(map, array->Ptr);
-
- for (i = 0; i < count; i++) {
- if (*((float *) map))
- vec[i/32] |= 1 << (i % 32);
-
- map += array->StrideB;
- }
-
- pipe_buffer_unmap(pipe->screen, stobj->buffer);
-
- pipe->set_edgeflags(pipe, vec);
-
- return vec;
- }
- else {
- /* edge flags not needed */
- pipe->set_edgeflags(pipe, NULL);
- return NULL;
- }
-}
/**
@@ -279,6 +227,7 @@ setup_edgeflags(GLcontext *ctx, GLenum primMode, GLint start, GLint count,
*/
static GLboolean
is_interleaved_arrays(const struct st_vertex_program *vp,
+ const struct st_vp_varient *vpv,
const struct gl_client_array **arrays,
GLboolean *userSpace)
{
@@ -288,7 +237,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
GLuint num_client_arrays = 0;
const GLubyte *client_addr = NULL;
- for (attr = 0; attr < vp->num_inputs; attr++) {
+ for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
const struct gl_buffer_object *bufObj = arrays[mesaAttr]->BufferObj;
const GLsizei stride = arrays[mesaAttr]->StrideB; /* in bytes */
@@ -321,7 +270,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
}
}
- *userSpace = (num_client_arrays == vp->num_inputs);
+ *userSpace = (num_client_arrays == vpv->num_inputs);
/* printf("user space: %d (%d %d)\n", (int) *userSpace,num_client_arrays,vp->num_inputs); */
return GL_TRUE;
@@ -333,15 +282,16 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
*/
static void
get_arrays_bounds(const struct st_vertex_program *vp,
- const struct gl_client_array **arrays,
- GLuint max_index,
- const GLubyte **low, const GLubyte **high)
+ const struct st_vp_varient *vpv,
+ const struct gl_client_array **arrays,
+ GLuint max_index,
+ const GLubyte **low, const GLubyte **high)
{
const GLubyte *low_addr = NULL;
const GLubyte *high_addr = NULL;
GLuint attr;
- for (attr = 0; attr < vp->num_inputs; attr++) {
+ for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
const GLint stride = arrays[mesaAttr]->StrideB;
const GLubyte *start = arrays[mesaAttr]->Ptr;
@@ -373,6 +323,7 @@ get_arrays_bounds(const struct st_vertex_program *vp,
static void
setup_interleaved_attribs(GLcontext *ctx,
const struct st_vertex_program *vp,
+ const struct st_vp_varient *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
GLboolean userSpace,
@@ -383,7 +334,7 @@ setup_interleaved_attribs(GLcontext *ctx,
GLuint attr;
const GLubyte *offset0 = NULL;
- for (attr = 0; attr < vp->num_inputs; attr++) {
+ for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
struct st_buffer_object *stobj = st_buffer_object(bufobj);
@@ -394,7 +345,7 @@ setup_interleaved_attribs(GLcontext *ctx,
if (attr == 0) {
const GLubyte *low, *high;
- get_arrays_bounds(vp, arrays, max_index, &low, &high);
+ get_arrays_bounds(vp, vpv, arrays, max_index, &low, &high);
/*printf("buffer range: %p %p %d\n", low, high, high-low);*/
offset0 = low;
@@ -435,6 +386,7 @@ setup_interleaved_attribs(GLcontext *ctx,
static void
setup_non_interleaved_attribs(GLcontext *ctx,
const struct st_vertex_program *vp,
+ const struct st_vp_varient *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
GLboolean *userSpace,
@@ -444,7 +396,7 @@ setup_non_interleaved_attribs(GLcontext *ctx,
struct pipe_context *pipe = ctx->st->pipe;
GLuint attr;
- for (attr = 0; attr < vp->num_inputs; attr++) {
+ for (attr = 0; attr < vpv->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
GLsizei stride = arrays[mesaAttr]->StrideB;
@@ -538,6 +490,20 @@ check_uniforms(GLcontext *ctx)
}
+static unsigned translate_prim( GLcontext *ctx,
+ unsigned prim )
+{
+ /* Avoid quadstrips if it's easy to do so:
+ */
+ if (prim == GL_QUAD_STRIP &&
+ ctx->Light.ShadeModel != GL_FLAT &&
+ ctx->Polygon.FrontMode == GL_FILL &&
+ ctx->Polygon.BackMode == GL_FILL)
+ prim = GL_TRIANGLE_STRIP;
+
+ return prim;
+}
+
/**
* This function gets plugged into the VBO module and is called when
* we have something to render.
@@ -555,25 +521,36 @@ st_draw_vbo(GLcontext *ctx,
{
struct pipe_context *pipe = ctx->st->pipe;
const struct st_vertex_program *vp;
+ const struct st_vp_varient *vpv;
const struct pipe_shader_state *vs;
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
GLuint attr;
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
unsigned num_vbuffers, num_velements;
GLboolean userSpace = GL_FALSE;
+ GLboolean vertDataEdgeFlags;
/* Gallium probably doesn't want this in some cases. */
if (!index_bounds_valid)
- vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+ if (!vbo_all_varyings_in_vbos(arrays))
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
/* sanity check for pointer arithmetic below */
assert(sizeof(arrays[0]->Ptr[0]) == 1);
+ vertDataEdgeFlags = arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj &&
+ arrays[VERT_ATTRIB_EDGEFLAG]->BufferObj->Name;
+ if (vertDataEdgeFlags != ctx->st->vertdata_edgeflags) {
+ ctx->st->vertdata_edgeflags = vertDataEdgeFlags;
+ ctx->st->dirty.st |= ST_NEW_EDGEFLAGS_DATA;
+ }
+
st_validate_state(ctx->st);
/* must get these after state validation! */
vp = ctx->st->vp;
- vs = &ctx->st->vp->state;
+ vpv = ctx->st->vp_varient;
+ vs = &vpv->state;
#if 0
if (MESA_VERBOSE & VERBOSE_GLSL) {
@@ -586,21 +563,21 @@ st_draw_vbo(GLcontext *ctx,
/*
* Setup the vbuffer[] and velements[] arrays.
*/
- if (is_interleaved_arrays(vp, arrays, &userSpace)) {
+ if (is_interleaved_arrays(vp, vpv, arrays, &userSpace)) {
/*printf("Draw interleaved\n");*/
- setup_interleaved_attribs(ctx, vp, arrays, max_index, userSpace,
+ setup_interleaved_attribs(ctx, vp, vpv, arrays, max_index, userSpace,
vbuffer, velements);
num_vbuffers = 1;
- num_velements = vp->num_inputs;
+ num_velements = vpv->num_inputs;
if (num_velements == 0)
num_vbuffers = 0;
}
else {
/*printf("Draw non-interleaved\n");*/
- setup_non_interleaved_attribs(ctx, vp, arrays, max_index,
+ setup_non_interleaved_attribs(ctx, vp, vpv, arrays, max_index,
&userSpace, vbuffer, velements);
- num_vbuffers = vp->num_inputs;
- num_velements = vp->num_inputs;
+ num_vbuffers = vpv->num_inputs;
+ num_velements = vpv->num_inputs;
}
#if 0
@@ -633,6 +610,7 @@ st_draw_vbo(GLcontext *ctx,
struct gl_buffer_object *bufobj = ib->obj;
struct pipe_buffer *indexBuf = NULL;
unsigned indexSize, indexOffset, i;
+ unsigned prim;
switch (ib->type) {
case GL_UNSIGNED_INT:
@@ -671,24 +649,20 @@ st_draw_vbo(GLcontext *ctx,
* through to driver & draw module. These interfaces still
* need a bit of work...
*/
- setup_edgeflags(ctx, prims[i].mode,
- prims[i].start + indexOffset, prims[i].count,
- arrays[VERT_ATTRIB_EDGEFLAG]);
+ prim = translate_prim( ctx, prims[i].mode );
pipe->draw_range_elements(pipe, indexBuf, indexSize,
min_index,
max_index,
- prims[i].mode,
+ prim,
prims[i].start + indexOffset, prims[i].count);
}
else {
for (i = 0; i < nr_prims; i++) {
- setup_edgeflags(ctx, prims[i].mode,
- prims[i].start + indexOffset, prims[i].count,
- arrays[VERT_ATTRIB_EDGEFLAG]);
+ prim = translate_prim( ctx, prims[i].mode );
pipe->draw_elements(pipe, indexBuf, indexSize,
- prims[i].mode,
+ prim,
prims[i].start + indexOffset, prims[i].count);
}
}
@@ -698,12 +672,12 @@ st_draw_vbo(GLcontext *ctx,
else {
/* non-indexed */
GLuint i;
+ GLuint prim;
+
for (i = 0; i < nr_prims; i++) {
- setup_edgeflags(ctx, prims[i].mode,
- prims[i].start, prims[i].count,
- arrays[VERT_ATTRIB_EDGEFLAG]);
+ prim = translate_prim( ctx, prims[i].mode );
- pipe->draw_arrays(pipe, prims[i].mode, prims[i].start, prims[i].count);
+ pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count);
}
}
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index b2d682ef64..cfc0caac98 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -120,10 +120,10 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* must get these after state validation! */
vp = ctx->st->vp;
- vs = &st->vp->state;
+ vs = &st->vp_varient->state;
- if (!st->vp->draw_shader) {
- st->vp->draw_shader = draw_create_vertex_shader(draw, vs);
+ if (!st->vp_varient->draw_shader) {
+ 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_clip_state(draw, &st->state.clip);
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);
/* loop over TGSI shader inputs to determine vertex buffer
@@ -241,7 +241,8 @@ st_feedback_draw_vbo(GLcontext *ctx,
mapped_constants = pipe_buffer_map(pipe->screen,
st->state.constants[PIPE_SHADER_VERTEX].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_constant_buffer(st->draw, mapped_constants,
+ draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX,
+ mapped_constants,
st->state.constants[PIPE_SHADER_VERTEX].buffer->size);
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 57fe72d76a..ef3cbc53ee 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -92,6 +92,10 @@ void st_init_limits(struct st_context *st)
= _min(screen->get_param(screen, PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS),
MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ c->MaxCombinedTextureImageUnits
+ = _min(screen->get_param(screen, PIPE_CAP_MAX_COMBINED_SAMPLERS),
+ MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+
c->MaxTextureCoordUnits
= _min(c->MaxTextureImageUnits, MAX_TEXTURE_COORD_UNITS);
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 091f68190e..3e165c9feb 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -42,42 +42,34 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "util/u_format.h"
#include "st_context.h"
#include "st_format.h"
-static GLuint
-format_bits(
- pipe_format_rgbazs_t info,
- GLuint comp )
-{
- return pf_get_component_bits( (enum pipe_format) info, comp );
-}
static GLuint
-format_max_bits(
- pipe_format_rgbazs_t info )
+format_max_bits(enum pipe_format format)
{
- GLuint size = format_bits( info, PIPE_FORMAT_COMP_R );
+ GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
- size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_G ) );
- size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_B ) );
- size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_A ) );
- size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_Z ) );
- size = MAX2( size, format_bits( info, PIPE_FORMAT_COMP_S ) );
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0));
+ size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1));
return size;
}
static GLuint
-format_size(
- pipe_format_rgbazs_t info )
+format_size(enum pipe_format format)
{
return
- format_bits( info, PIPE_FORMAT_COMP_R ) +
- format_bits( info, PIPE_FORMAT_COMP_G ) +
- format_bits( info, PIPE_FORMAT_COMP_B ) +
- format_bits( info, PIPE_FORMAT_COMP_A ) +
- format_bits( info, PIPE_FORMAT_COMP_Z ) +
- format_bits( info, PIPE_FORMAT_COMP_S );
+ util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) +
+ util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1) +
+ util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2) +
+ util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) +
+ util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0) +
+ util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1);
}
/*
@@ -86,11 +78,13 @@ format_size(
GLboolean
st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
{
- if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) {
- pipe_format_rgbazs_t info;
+ const struct util_format_description *desc;
- info = format;
+ desc = util_format_description(format);
+ assert(desc);
+ if (desc->layout == UTIL_FORMAT_LAYOUT_ARITH ||
+ desc->layout == UTIL_FORMAT_LAYOUT_ARRAY) {
#if 0
printf("%s\n", pf_name( format ) );
#endif
@@ -103,22 +97,22 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
pinfo->datatype = GL_UNSIGNED_INT_24_8;
}
else {
- const GLuint size = format_max_bits( info );
+ const GLuint size = format_max_bits(format);
if (size == 8) {
- if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
pinfo->datatype = GL_UNSIGNED_BYTE;
else
pinfo->datatype = GL_BYTE;
}
else if (size == 16) {
- if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
pinfo->datatype = GL_UNSIGNED_SHORT;
else
pinfo->datatype = GL_SHORT;
}
else {
assert( size <= 32 );
- if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
pinfo->datatype = GL_UNSIGNED_INT;
else
pinfo->datatype = GL_INT;
@@ -126,23 +120,23 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
}
/* Component bits */
- pinfo->red_bits = format_bits( info, PIPE_FORMAT_COMP_R );
- pinfo->green_bits = format_bits( info, PIPE_FORMAT_COMP_G );
- pinfo->blue_bits = format_bits( info, PIPE_FORMAT_COMP_B );
- pinfo->alpha_bits = format_bits( info, PIPE_FORMAT_COMP_A );
- pinfo->depth_bits = format_bits( info, PIPE_FORMAT_COMP_Z );
- pinfo->stencil_bits = format_bits( info, PIPE_FORMAT_COMP_S );
+ pinfo->red_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
+ pinfo->green_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1);
+ pinfo->blue_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2);
+ pinfo->alpha_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3);
+ pinfo->depth_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0);
+ pinfo->stencil_bits = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1);
pinfo->luminance_bits = 0;
pinfo->intensity_bits = 0;
/* Format size */
- pinfo->size = format_size( info ) / 8;
+ pinfo->size = format_size(format) / 8;
/* Luminance & Intensity bits */
- if( pf_swizzle_x(info) == PIPE_FORMAT_COMP_R &&
- pf_swizzle_y(info) == PIPE_FORMAT_COMP_R &&
- pf_swizzle_z(info) == PIPE_FORMAT_COMP_R ) {
- if( pf_swizzle_w(info) == PIPE_FORMAT_COMP_R ) {
+ if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
+ desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X &&
+ desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X) {
+ if (desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) {
pinfo->intensity_bits = pinfo->red_bits;
}
else {
@@ -153,7 +147,7 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
pinfo->mesa_format = st_pipe_format_to_mesa_format(format);
}
- else if (pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR) {
+ else if (desc->layout == UTIL_FORMAT_LAYOUT_YUV) {
pinfo->mesa_format = MESA_FORMAT_YCBCR;
pinfo->datatype = GL_UNSIGNED_SHORT;
pinfo->size = 2; /* two bytes per "texel" */
@@ -391,6 +385,33 @@ default_rgba_format(struct pipe_screen *screen,
}
/**
+ * Find an RGB format supported by the context/winsys.
+ */
+static enum pipe_format
+default_rgb_format(struct pipe_screen *screen,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags)
+{
+ static const enum pipe_format colorFormats[] = {
+ PIPE_FORMAT_X8R8G8B8_UNORM,
+ PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_R8G8B8X8_UNORM,
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
+ PIPE_FORMAT_R5G6B5_UNORM
+ };
+ uint i;
+ for (i = 0; i < Elements(colorFormats); i++) {
+ if (screen->is_format_supported( screen, colorFormats[i], target, tex_usage, geom_flags )) {
+ return colorFormats[i];
+ }
+ }
+ return PIPE_FORMAT_NONE;
+}
+
+/**
* Find an sRGBA format supported by the context/winsys.
*/
static enum pipe_format
@@ -474,13 +495,14 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
case 4:
case GL_RGBA:
case GL_COMPRESSED_RGBA:
- case 3:
- case GL_RGB:
- case GL_COMPRESSED_RGB:
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
return default_rgba_format( screen, target, tex_usage, geom_flags );
+ case 3:
+ case GL_RGB:
+ case GL_COMPRESSED_RGB:
+ return default_rgb_format( screen, target, tex_usage, geom_flags );
case GL_RGBA16:
if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
return default_deep_rgba_format( screen, target, tex_usage, geom_flags );
@@ -502,7 +524,7 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
- return default_rgba_format( screen, target, tex_usage, geom_flags );
+ return default_rgb_format( screen, target, tex_usage, geom_flags );
case GL_RGB5:
case GL_RGB4:
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 2d404d5f42..2c283d464a 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -37,7 +37,9 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_gen_mipmap.h"
+#include "util/u_math.h"
#include "cso_cache/cso_cache.h"
#include "cso_cache/cso_context.h"
@@ -133,29 +135,33 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
srcLevel, zslice,
PIPE_TRANSFER_READ, 0, 0,
- pt->width[srcLevel],
- pt->height[srcLevel]);
+ u_minify(pt->width0, srcLevel),
+ u_minify(pt->height0, srcLevel));
dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
dstLevel, zslice,
PIPE_TRANSFER_WRITE, 0, 0,
- pt->width[dstLevel],
- pt->height[dstLevel]);
+ u_minify(pt->width0, dstLevel),
+ u_minify(pt->height0, dstLevel));
srcData = (ubyte *) screen->transfer_map(screen, srcTrans);
dstData = (ubyte *) screen->transfer_map(screen, dstTrans);
- srcStride = srcTrans->stride / srcTrans->block.size;
- dstStride = dstTrans->stride / dstTrans->block.size;
+ srcStride = srcTrans->stride / util_format_get_blocksize(srcTrans->texture->format);
+ dstStride = dstTrans->stride / util_format_get_blocksize(dstTrans->texture->format);
_mesa_generate_mipmap_level(target, datatype, comps,
- 0 /*border*/,
- pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel],
- srcData,
- srcStride, /* stride in texels */
- pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel],
- dstData,
- dstStride); /* stride in texels */
+ 0 /*border*/,
+ u_minify(pt->width0, srcLevel),
+ u_minify(pt->height0, srcLevel),
+ u_minify(pt->depth0, srcLevel),
+ srcData,
+ srcStride, /* stride in texels */
+ u_minify(pt->width0, dstLevel),
+ u_minify(pt->height0, dstLevel),
+ u_minify(pt->depth0, dstLevel),
+ dstData,
+ dstStride); /* stride in texels */
screen->transfer_unmap(screen, srcTrans);
screen->transfer_unmap(screen, dstTrans);
@@ -235,9 +241,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target,
oldTex->target,
oldTex->format,
lastLevel,
- oldTex->width[0],
- oldTex->height[0],
- oldTex->depth[0],
+ oldTex->width0,
+ oldTex->height0,
+ oldTex->depth0,
oldTex->tex_usage);
/* The texture isn't in a "complete" state yet so set the expected
@@ -272,9 +278,9 @@ st_generate_mipmap(GLcontext *ctx, GLenum target,
= _mesa_get_tex_image(ctx, texObj, target, srcLevel);
struct gl_texture_image *dstImage;
struct st_texture_image *stImage;
- uint dstWidth = pt->width[dstLevel];
- uint dstHeight = pt->height[dstLevel];
- uint dstDepth = pt->depth[dstLevel];
+ uint dstWidth = u_minify(pt->width0, dstLevel);
+ uint dstHeight = u_minify(pt->height0, dstLevel);
+ uint dstDepth = u_minify(pt->depth0, dstLevel);
uint border = srcImage->Border;
dstImage = _mesa_get_tex_image(ctx, texObj, target, dstLevel);
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index bd94c9d79e..5c9be46a77 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -396,6 +396,23 @@ static void emit_swz( struct st_translate *t,
}
+/**
+ * Negate the value of DDY to match GL semantics where (0,0) is the
+ * lower-left corner of the window.
+ * Note that the GL_ARB_fragment_coord_conventions extension will
+ * effect this someday.
+ */
+static void emit_ddy( struct st_translate *t,
+ struct ureg_dst dst,
+ const struct prog_src_register *SrcReg )
+{
+ struct ureg_program *ureg = t->ureg;
+ struct ureg_src src = translate_src( t, SrcReg );
+ src = ureg_negate( src );
+ ureg_DDY( ureg, dst, src );
+}
+
+
static unsigned
translate_opcode( unsigned op )
@@ -619,7 +636,9 @@ compile_instruction(
ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) );
break;
-
+ case OPCODE_DDY:
+ emit_ddy( t, dst[0], &inst->SrcReg[0] );
+ break;
default:
ureg_insn( ureg,
@@ -676,6 +695,41 @@ emit_inverted_wpos( struct st_translate *t,
/**
+ * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back.
+ * TGSI uses +1 for front, -1 for back.
+ * This function converts the TGSI value to the GL value. Simply clamping/
+ * saturating the value to [0,1] does the job.
+ */
+static void
+emit_face_var( struct st_translate *t,
+ const struct gl_program *program )
+{
+ struct ureg_program *ureg = t->ureg;
+ struct ureg_dst face_temp = ureg_DECL_temporary( ureg );
+ struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]];
+
+ /* MOV_SAT face_temp, input[face]
+ */
+ face_temp = ureg_saturate( face_temp );
+ ureg_MOV( ureg, face_temp, face_input );
+
+ /* Use face_temp as face input from here on:
+ */
+ t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp);
+}
+
+static void
+emit_edgeflags( struct st_translate *t,
+ const struct gl_program *program )
+{
+ struct ureg_program *ureg = t->ureg;
+ struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]];
+ struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]];
+
+ ureg_MOV( ureg, edge_dst, edge_src );
+}
+
+/**
* Translate Mesa program to TGSI format.
* \param program the program to translate
* \param numInputs number of input registers used
@@ -694,26 +748,24 @@ emit_inverted_wpos( struct st_translate *t,
*
* \return array of translated tokens, caller's responsibility to free
*/
-const struct tgsi_token *
+enum pipe_error
st_translate_mesa_program(
GLcontext *ctx,
uint procType,
+ struct ureg_program *ureg,
const struct gl_program *program,
GLuint numInputs,
const GLuint inputMapping[],
const ubyte inputSemanticName[],
const ubyte inputSemanticIndex[],
const GLuint interpMode[],
- const GLbitfield inputFlags[],
GLuint numOutputs,
const GLuint outputMapping[],
const ubyte outputSemanticName[],
const ubyte outputSemanticIndex[],
- const GLbitfield outputFlags[] )
+ boolean passthrough_edgeflags )
{
struct st_translate translate, *t;
- struct ureg_program *ureg;
- const struct tgsi_token *tokens = NULL;
unsigned i;
t = &translate;
@@ -722,11 +774,7 @@ st_translate_mesa_program(
t->procType = procType;
t->inputMapping = inputMapping;
t->outputMapping = outputMapping;
- t->ureg = ureg_create( procType );
- if (t->ureg == NULL)
- return NULL;
-
- ureg = t->ureg;
+ t->ureg = ureg;
/*_mesa_print_program(program);*/
@@ -748,6 +796,10 @@ st_translate_mesa_program(
emit_inverted_wpos( t, program );
}
+ if (program->InputsRead & FRAG_BIT_FACE) {
+ emit_face_var( t, program );
+ }
+
/*
* Declare output attributes.
*/
@@ -782,6 +834,8 @@ st_translate_mesa_program(
outputSemanticName[i],
outputSemanticIndex[i] );
}
+ if (passthrough_edgeflags)
+ emit_edgeflags( t, program );
}
/* Declare address register.
@@ -853,8 +907,7 @@ st_translate_mesa_program(
t->insn[t->labels[i].branch_target] );
}
- tokens = ureg_get_tokens( ureg, NULL );
- ureg_destroy( ureg );
+ return PIPE_OK;
out:
FREE(t->insn);
@@ -863,17 +916,9 @@ out:
if (t->error) {
debug_printf("%s: translate error flag set\n", __FUNCTION__);
- FREE((void *)tokens);
- tokens = NULL;
- }
-
- if (!tokens) {
- debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
- _mesa_print_program(program);
- debug_assert(0);
}
- return tokens;
+ return PIPE_ERROR_OUT_OF_MEMORY;
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h
index c0d1ff59e1..e3c5bd1d94 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.h
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h
@@ -30,6 +30,7 @@
#define ST_MESA_TO_TGSI_H
#include "main/mtypes.h"
+#include "tgsi/tgsi_ureg.h"
#if defined __cplusplus
@@ -39,22 +40,22 @@ extern "C" {
struct tgsi_token;
struct gl_program;
-const struct tgsi_token *
+enum pipe_error
st_translate_mesa_program(
GLcontext *ctx,
uint procType,
+ struct ureg_program *ureg,
const struct gl_program *program,
GLuint numInputs,
const GLuint inputMapping[],
const ubyte inputSemanticName[],
const ubyte inputSemanticIndex[],
const GLuint interpMode[],
- const GLbitfield inputFlags[],
GLuint numOutputs,
const GLuint outputMapping[],
const ubyte outputSemanticName[],
const ubyte outputSemanticIndex[],
- const GLbitfield outputFlags[] );
+ boolean passthrough_edgeflags );
void
st_free_tokens(const struct tgsi_token *tokens);
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index cf19f8f1a8..6a869fae90 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -50,6 +50,39 @@
#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.
* \param outputMapping to map vertex program output registers (VERT_RESULT_x)
@@ -58,31 +91,13 @@
* \return pointer to cached pipe_shader object.
*/
void
-st_translate_vertex_program(struct st_context *st,
- struct st_vertex_program *stvp,
- const GLuint outputMapping[],
- const ubyte *outputSemanticName,
- const ubyte *outputSemanticIndex)
+st_prepare_vertex_program(struct st_context *st,
+ struct st_vertex_program *stvp)
{
- struct pipe_context *pipe = st->pipe;
- GLuint defaultOutputMapping[VERT_RESULT_MAX];
- GLuint attr, i;
- GLuint num_generic = 0;
-
- ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
- ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
- 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];
+ GLuint attr;
- /*memset(&vs, 0, sizeof(vs));*/
- memset(input_flags, 0, sizeof(input_flags));
- memset(output_flags, 0, sizeof(output_flags));
+ stvp->num_inputs = 0;
+ stvp->num_outputs = 0;
if (stvp->Base.IsPositionInvariant)
_mesa_insert_mvp_code(st->ctx, &stvp->Base);
@@ -95,162 +110,59 @@ st_translate_vertex_program(struct st_context *st,
*/
for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
if (stvp->Base.Base.InputsRead & (1 << attr)) {
- const GLuint slot = vs_num_inputs;
-
- vs_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];
+ stvp->input_to_index[attr] = stvp->num_inputs;
+ stvp->index_to_input[stvp->num_inputs] = attr;
+ stvp->num_inputs++;
}
}
+ /* bit of a hack, presetup potentially unused edgeflag input */
+ stvp->input_to_index[VERT_ATTRIB_EDGEFLAG] = stvp->num_inputs;
+ stvp->index_to_input[stvp->num_inputs] = VERT_ATTRIB_EDGEFLAG;
-#if 0
- 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.
+ /* Compute mapping of vertex program outputs to slots.
*/
for (attr = 0; attr < VERT_RESULT_MAX; attr++) {
- if (stvp->Base.Base.OutputsWritten & (1 << attr)) {
- GLuint slot;
-
- /* XXX
- * 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;
- }
+ if ((stvp->Base.Base.OutputsWritten & (1 << attr)) == 0) {
+ stvp->result_to_output[attr] = ~0;
+ }
+ else {
+ unsigned slot = stvp->num_outputs++;
+
+ stvp->result_to_output[attr] = slot;
switch (attr) {
case VERT_RESULT_HPOS:
- assert(slot == 0);
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
- vs_output_semantic_index[slot] = 0;
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ stvp->output_semantic_index[slot] = 0;
break;
case VERT_RESULT_COL0:
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- vs_output_semantic_index[slot] = 0;
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ stvp->output_semantic_index[slot] = 0;
break;
case VERT_RESULT_COL1:
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- vs_output_semantic_index[slot] = 1;
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ stvp->output_semantic_index[slot] = 1;
break;
case VERT_RESULT_BFC0:
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
- vs_output_semantic_index[slot] = 0;
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+ stvp->output_semantic_index[slot] = 0;
break;
case VERT_RESULT_BFC1:
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
- vs_output_semantic_index[slot] = 1;
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+ stvp->output_semantic_index[slot] = 1;
break;
case VERT_RESULT_FOGC:
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
- vs_output_semantic_index[slot] = 0;
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ stvp->output_semantic_index[slot] = 0;
break;
case VERT_RESULT_PSIZ:
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
- vs_output_semantic_index[slot] = 0;
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
+ stvp->output_semantic_index[slot] = 0;
break;
case VERT_RESULT_EDGE:
assert(0);
break;
+
case VERT_RESULT_TEX0:
case VERT_RESULT_TEX1:
case VERT_RESULT_TEX2:
@@ -259,92 +171,79 @@ st_translate_vertex_program(struct st_context *st,
case VERT_RESULT_TEX5:
case VERT_RESULT_TEX6:
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:
- /* fall-through */
default:
- assert(slot < Elements(vs_output_semantic_name));
- if (outputSemanticName) {
- /* use provided semantic into */
- assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
- vs_output_semantic_name[slot] = outputSemanticName[attr];
- vs_output_semantic_index[slot] = outputSemanticIndex[attr];
- }
- else {
- /* use default semantic info */
- vs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- vs_output_semantic_index[slot] = num_generic++;
- }
+ assert(attr < VERT_RESULT_MAX);
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stvp->output_semantic_index[slot] = (FRAG_ATTRIB_VAR0 -
+ FRAG_ATTRIB_TEX0 +
+ attr -
+ VERT_RESULT_VAR0);
+ break;
}
-
- assert(slot < Elements(output_flags));
- output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
}
}
+ /* similar hack to above, presetup potentially unused edgeflag output */
+ stvp->result_to_output[VERT_RESULT_EDGE] = stvp->num_outputs;
+ stvp->output_semantic_name[stvp->num_outputs] = TGSI_SEMANTIC_EDGEFLAG;
+ stvp->output_semantic_index[stvp->num_outputs] = 0;
+}
- 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;
+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;
+ struct ureg_program *ureg;
+ enum pipe_error error;
+ unsigned num_outputs;
+
+ ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+ if (ureg == NULL)
+ return NULL;
+
+ vpv->num_inputs = stvp->num_inputs;
+ num_outputs = stvp->num_outputs;
+ if (key->passthrough_edgeflags) {
+ vpv->num_inputs++;
+ num_outputs++;
}
- stvp->state.tokens =
+ error =
st_translate_mesa_program(st->ctx,
TGSI_PROCESSOR_VERTEX,
+ ureg,
&stvp->Base.Base,
/* inputs */
- vs_num_inputs,
+ vpv->num_inputs,
stvp->input_to_index,
- vs_input_semantic_name,
- vs_input_semantic_index,
+ NULL, /* input semantic name */
+ NULL, /* input semantic index */
NULL,
- input_flags,
/* outputs */
- vs_num_outputs,
- outputMapping,
- vs_output_semantic_name,
- vs_output_semantic_index,
- output_flags );
+ num_outputs,
+ stvp->result_to_output,
+ stvp->output_semantic_name,
+ stvp->output_semantic_index,
+ key->passthrough_edgeflags );
+
+ if (error)
+ goto fail;
- stvp->num_inputs = vs_num_inputs;
- stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state);
+ vpv->state.tokens = ureg_get_tokens( ureg, NULL );
+ if (!vpv->state.tokens)
+ goto fail;
+
+ ureg_destroy( ureg );
+
+ vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
_mesa_print_program(&stvp->Base.Base);
@@ -352,9 +251,19 @@ st_translate_vertex_program(struct st_context *st,
}
if (ST_DEBUG & DEBUG_TGSI) {
- tgsi_dump( stvp->state.tokens, 0 );
+ tgsi_dump( vpv->state.tokens, 0 );
debug_printf("\n");
}
+
+ return vpv;
+
+fail:
+ debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
+ _mesa_print_program(&stvp->Base.Base);
+ debug_assert(0);
+
+ ureg_destroy( ureg );
+ return NULL;
}
@@ -375,9 +284,10 @@ st_translate_fragment_program(struct st_context *st,
GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
GLuint interpMode[16]; /* XXX size? */
GLuint attr;
+ enum pipe_error error;
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
+ struct ureg_program *ureg;
GLuint vslot = 0;
- GLuint num_generic = 0;
uint fs_num_inputs = 0;
@@ -385,13 +295,6 @@ st_translate_fragment_program(struct st_context *st,
ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
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: */
if (inputsRead & FRAG_BIT_WPOS)
vslot = 0;
@@ -434,14 +337,25 @@ st_translate_fragment_program(struct st_context *st,
break;
case FRAG_ATTRIB_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;
break;
- case FRAG_ATTRIB_PNTC:
- stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- stfp->input_semantic_index[slot] = num_generic++;
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- break;
+
+ /* In most cases, there is nothing special about these
+ * inputs, so adopt a convention to use the generic
+ * semantic name and the mesa FRAG_ATTRIB_ number as the
+ * 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_TEX1:
case FRAG_ATTRIB_TEX2:
@@ -450,19 +364,18 @@ st_translate_fragment_program(struct st_context *st,
case FRAG_ATTRIB_TEX5:
case FRAG_ATTRIB_TEX6:
case FRAG_ATTRIB_TEX7:
- stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- stfp->input_semantic_index[slot] = num_generic++;
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- break;
+ case FRAG_ATTRIB_PNTC:
case FRAG_ATTRIB_VAR0:
- /* fall-through */
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_index[slot] = num_generic++;
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
+ break;
}
-
- input_flags[slot] = stfp->Base.Base.InputFlags[attr];
}
}
@@ -500,8 +413,6 @@ st_translate_fragment_program(struct st_context *st,
break;
}
- output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
-
fs_num_outputs++;
}
}
@@ -510,9 +421,15 @@ st_translate_fragment_program(struct st_context *st,
if (!inputMapping)
inputMapping = defaultInputMapping;
- stfp->state.tokens =
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return;
+
+
+ error =
st_translate_mesa_program(st->ctx,
TGSI_PROCESSOR_FRAGMENT,
+ ureg,
&stfp->Base.Base,
/* inputs */
fs_num_inputs,
@@ -520,14 +437,14 @@ st_translate_fragment_program(struct st_context *st,
stfp->input_semantic_name,
stfp->input_semantic_index,
interpMode,
- input_flags,
/* outputs */
fs_num_outputs,
outputMapping,
fs_output_semantic_name,
- fs_output_semantic_index,
- output_flags );
+ fs_output_semantic_index, FALSE );
+ stfp->state.tokens = ureg_get_tokens( ureg, NULL );
+ ureg_destroy( ureg );
stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index e2e5eddef2..6b9a9226df 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -64,41 +64,73 @@ struct st_fragment_program
struct pipe_shader_state state;
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 */
struct st_fragment_program *bitmap_program;
uint bitmap_sampler;
};
+
+struct st_vp_varient_key
+{
+ boolean passthrough_edgeflags;
+};
+
+
+/**
+ * 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;
+
+ /** similar to that in st_vertex_program, but with information about edgeflags too */
+ GLuint num_inputs;
+};
+
+
+
+
/**
* Derived from Mesa gl_fragment_program:
*/
struct st_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 */
GLuint input_to_index[VERT_ATTRIB_MAX];
/** maps a TGSI input index back to a Mesa VERT_ATTRIB_x */
GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
-
GLuint num_inputs;
- struct pipe_shader_state state;
- void *driver_shader;
+ /** Maps VERT_RESULT_x to slot */
+ 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) */
- struct draw_vertex_shader *draw_shader;
-
- GLuint param_state;
+ /** List of translated varients of this vertex program.
+ */
+ struct st_vp_varient *varients;
};
@@ -143,13 +175,21 @@ st_translate_fragment_program(struct st_context *st,
const GLuint inputMapping[]);
+/* Called after program string change, discard all previous
+ * compilation results.
+ */
extern void
+st_prepare_vertex_program(struct st_context *st,
+ struct st_vertex_program *stvp);
+
+extern struct st_vp_varient *
st_translate_vertex_program(struct st_context *st,
- struct st_vertex_program *vp,
- const GLuint vert_output_to_slot[],
- const ubyte *fs_input_semantic_name,
- const ubyte *fs_input_semantic_index);
+ 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
st_print_shaders(GLcontext *ctx);
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 10f1351283..8a3e4cd3ac 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -43,7 +43,9 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_rect.h"
+#include "util/u_math.h"
#define DBG if(0) printf
@@ -100,10 +102,9 @@ st_texture_create(struct st_context *st,
pt.target = target;
pt.format = format;
pt.last_level = last_level;
- pt.width[0] = width0;
- pt.height[0] = height0;
- pt.depth[0] = depth0;
- pf_get_block(format, &pt.block);
+ pt.width0 = width0;
+ pt.height0 = height0;
+ pt.depth0 = depth0;
pt.tex_usage = usage;
newtex = screen->texture_create(screen, &pt);
@@ -135,9 +136,9 @@ st_texture_match_image(const struct pipe_texture *pt,
/* Test if this image's size matches what's expected in the
* established texture.
*/
- if (image->Width != pt->width[level] ||
- image->Height != pt->height[level] ||
- image->Depth != pt->depth[level])
+ if (image->Width != u_minify(pt->width0, level) ||
+ image->Height != u_minify(pt->height0, level) ||
+ image->Depth != u_minify(pt->depth0, level))
return GL_FALSE;
return GL_TRUE;
@@ -241,8 +242,9 @@ st_surface_data(struct pipe_context *pipe,
struct pipe_screen *screen = pipe->screen;
void *map = screen->transfer_map(screen, dst);
+ assert(dst->texture);
util_copy_rect(map,
- &dst->block,
+ dst->texture->format,
dst->stride,
dstx, dsty,
width, height,
@@ -265,7 +267,7 @@ st_texture_image_data(struct st_context *st,
{
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
- GLuint depth = dst->depth[level];
+ GLuint depth = u_minify(dst->depth0, level);
GLuint i;
const GLubyte *srcUB = src;
struct pipe_transfer *dst_transfer;
@@ -275,15 +277,16 @@ st_texture_image_data(struct st_context *st,
for (i = 0; i < depth; i++) {
dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i,
PIPE_TRANSFER_WRITE, 0, 0,
- dst->width[level],
- dst->height[level]);
+ u_minify(dst->width0, level),
+ u_minify(dst->height0, level));
st_surface_data(pipe, dst_transfer,
0, 0, /* dstx, dsty */
srcUB,
src_row_stride,
0, 0, /* source x, y */
- dst->width[level], dst->height[level]); /* width, height */
+ u_minify(dst->width0, level),
+ u_minify(dst->height0, level)); /* width, height */
screen->tex_transfer_destroy(dst_transfer);
@@ -301,9 +304,9 @@ st_texture_image_copy(struct pipe_context *pipe,
GLuint face)
{
struct pipe_screen *screen = pipe->screen;
- GLuint width = dst->width[dstLevel];
- GLuint height = dst->height[dstLevel];
- GLuint depth = dst->depth[dstLevel];
+ GLuint width = u_minify(dst->width0, dstLevel);
+ GLuint height = u_minify(dst->height0, dstLevel);
+ GLuint depth = u_minify(dst->depth0, dstLevel);
struct pipe_surface *src_surface;
struct pipe_surface *dst_surface;
GLuint i;
@@ -313,13 +316,13 @@ st_texture_image_copy(struct pipe_context *pipe,
/* find src texture level of needed size */
for (srcLevel = 0; srcLevel <= src->last_level; srcLevel++) {
- if (src->width[srcLevel] == width &&
- src->height[srcLevel] == height) {
+ if (u_minify(src->width0, srcLevel) == width &&
+ u_minify(src->height0, srcLevel) == height) {
break;
}
}
- assert(src->width[srcLevel] == width);
- assert(src->height[srcLevel] == height);
+ assert(u_minify(src->width0, srcLevel) == width);
+ assert(u_minify(src->height0, srcLevel) == height);
#if 0
{
@@ -403,7 +406,7 @@ st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
}
/* map pipe format to base format for now */
- if (pf_get_component_bits(format, PIPE_FORMAT_COMP_A) > 0)
+ if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
internalFormat = GL_RGBA;
else
internalFormat = GL_RGB;