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.c11
-rw-r--r--src/mesa/state_tracker/st_atom.h3
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c3
-rw-r--r--src/mesa/state_tracker/st_atom_depth.c4
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c21
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c9
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c11
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c326
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c8
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c13
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c20
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c58
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c3
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c26
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c234
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c62
-rw-r--r--src/mesa/state_tracker/st_cb_get.c97
-rw-r--r--src/mesa/state_tracker/st_cb_get.h37
-rw-r--r--src/mesa/state_tracker/st_cb_program.c48
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c20
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c340
-rw-r--r--src/mesa/state_tracker/st_context.c8
-rw-r--r--src/mesa/state_tracker/st_context.h2
-rw-r--r--src/mesa/state_tracker/st_debug.c31
-rw-r--r--src/mesa/state_tracker/st_debug.h36
-rw-r--r--src/mesa/state_tracker/st_draw.c32
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c8
-rw-r--r--src/mesa/state_tracker/st_extensions.c5
-rw-r--r--src/mesa/state_tracker/st_format.c225
-rw-r--r--src/mesa/state_tracker/st_format.h15
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c25
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c123
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c111
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.h7
-rw-r--r--src/mesa/state_tracker/st_program.c391
-rw-r--r--src/mesa/state_tracker/st_program.h75
-rw-r--r--src/mesa/state_tracker/st_texture.c71
37 files changed, 1254 insertions, 1265 deletions
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index ca15ce1b47..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,
@@ -137,7 +138,7 @@ void st_validate_state( struct st_context *st )
if (state->st == 0)
return;
-// _mesa_printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);
+ /*_mesa_printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/
if (1) {
/* Debug version which enforces various sanity checks on the
@@ -152,7 +153,7 @@ void st_validate_state( struct st_context *st )
const struct st_tracked_state *atom = atoms[i];
struct st_state_flags generated;
-// _mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);
+ /*_mesa_printf("atom %s %x/%x\n", atom->name, atom->dirty.mesa, atom->dirty.st);*/
if (!(atom->dirty.mesa || atom->dirty.st) ||
!atom->update) {
@@ -162,7 +163,7 @@ void st_validate_state( struct st_context *st )
if (check_state(state, &atom->dirty)) {
atoms[i]->update( st );
-// _mesa_printf("after: %x\n", atom->dirty.mesa);
+ /*_mesa_printf("after: %x\n", atom->dirty.mesa);*/
}
accumulate_state(&examined, &atom->dirty);
@@ -175,7 +176,7 @@ void st_validate_state( struct st_context *st )
assert(!check_state(&examined, &generated));
prev = *state;
}
-// _mesa_printf("\n");
+ /*_mesa_printf("\n");*/
}
else {
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_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 5d4d8eee02..77153889b6 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -39,6 +39,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
+#include "st_debug.h"
#include "st_context.h"
#include "st_atom.h"
#include "st_atom_constbuf.h"
@@ -75,7 +76,7 @@ void st_upload_constants( struct st_context *st,
PIPE_BUFFER_USAGE_CONSTANT,
paramBytes );
- if (0) {
+ if (ST_DEBUG & DEBUG_CONSTANTS) {
debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
__FUNCTION__, shader_type, params->NumParameters,
params->StateFlags);
diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c
index 0aa128f947..88b80a07fc 100644
--- a/src/mesa/state_tracker/st_atom_depth.c
+++ b/src/mesa/state_tracker/st_atom_depth.c
@@ -104,10 +104,6 @@ update_depth_stencil_alpha(struct st_context *st)
dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func);
}
- if (ctx->Query.CurrentOcclusionObject &&
- ctx->Query.CurrentOcclusionObject->Active)
- dsa->depth.occlusion_count = 1;
-
if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) {
dsa->stencil[0].enabled = 1;
dsa->stencil[0].func = st_compare_func_to_pipe(ctx->Stencil.Function[0]);
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 5209a6a0c9..8ca4335e33 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -39,6 +39,8 @@
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
#include "cso_cache/cso_context.h"
+#include "util/u_rect.h"
+#include "util/u_math.h"
@@ -63,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);
@@ -162,10 +164,17 @@ update_framebuffer_state( struct st_context *st )
(void) st_get_framebuffer_surface(stfb, ST_SURFACE_FRONT_LEFT, &surf_front);
(void) st_get_framebuffer_surface(stfb, ST_SURFACE_BACK_LEFT, &surf_back);
- st->pipe->surface_copy(st->pipe,
- surf_front, 0, 0, /* dest */
- surf_back, 0, 0, /* src */
- fb->Width, fb->Height);
+ if (st->pipe->surface_copy) {
+ st->pipe->surface_copy(st->pipe,
+ surf_front, 0, 0, /* dest */
+ surf_back, 0, 0, /* src */
+ fb->Width, fb->Height);
+ } else {
+ util_surface_copy(st->pipe, FALSE,
+ surf_front, 0, 0,
+ surf_back, 0, 0,
+ fb->Width, fb->Height);
+ }
}
/* we're assuming we'll really draw to the front buffer */
st->frontbuffer_status = FRONT_STATUS_DIRTY;
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index eff3666ca8..6a5854e9ba 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -122,7 +122,8 @@ create_color_map_texture(GLcontext *ctx)
const uint texSize = 256; /* simple, and usually perfect */
/* find an RGBA texture format */
- format = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER);
+ format = st_choose_format(pipe->screen, GL_RGBA,
+ PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER);
/* create texture for color map/table */
pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0,
@@ -144,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;
@@ -161,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 50ce82811c..d6e3a3e561 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -209,7 +209,7 @@ update_samplers(struct st_context *st)
}
xlate_border_color(texobj->BorderColor,
- teximg ? teximg->TexFormat->BaseFormat : GL_RGBA,
+ teximg ? teximg->_BaseFormat : GL_RGBA,
sampler->border_color);
sampler->max_anisotropy = texobj->MaxAnisotropy;
@@ -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 ee649be885..09baff875b 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
+/*
+ * Translate fragment program if needed.
*/
-static GLint
-vp_out_to_fp_in(GLuint vertResult)
-{
- if (vertResult >= VERT_RESULT_TEX0 &&
- vertResult < VERT_RESULT_TEX0 + MAX_TEXTURE_COORD_UNITS)
- return FRAG_ATTRIB_TEX0 + (vertResult - VERT_RESULT_TEX0);
-
- if (vertResult >= VERT_RESULT_VAR0 &&
- vertResult < VERT_RESULT_VAR0 + MAX_VARYING)
- return FRAG_ATTRIB_VAR0 + (vertResult - VERT_RESULT_VAR0);
-
- switch (vertResult) {
- case VERT_RESULT_HPOS:
- return FRAG_ATTRIB_WPOS;
- case VERT_RESULT_COL0:
- return FRAG_ATTRIB_COL0;
- case VERT_RESULT_COL1:
- return FRAG_ATTRIB_COL1;
- case VERT_RESULT_FOGC:
- return FRAG_ATTRIB_FOGC;
- default:
- /* Back-face colors, edge flags, etc */
- return -1;
- }
-}
-
-
-/**
- * Find a translated vertex program that corresponds to stvp and
- * has outputs matched to stfp's inputs.
- * This performs vertex and fragment translation (to TGSI) when needed.
- */
-static struct translated_vertex_program *
-find_translated_vp(struct st_context *st,
- struct st_vertex_program *stvp,
- struct st_fragment_program *stfp)
+static 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,170 +87,63 @@ 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;
+/**
+ * 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;
- xvp->next = stfp->vertex_programs;
- stfp->vertex_programs = xvp;
- }
+ /* Nothing in our key yet. This will change:
+ */
+ memset(&key, 0, sizeof key);
+ key.dummy = 0;
- /* See if we need to translate vertex program to TGSI form */
- if (xvp->serialNo != stvp->serialNo) {
- GLuint outAttr;
- const GLbitfield 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.
+ /* 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++) {
- /* set defaults: */
- xvp->output_to_slot[outAttr] = UNUSED;
- xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
- xvp->output_to_semantic_index[outAttr] = 99;
-
- if (outAttr == VERT_RESULT_HPOS) {
- /* always put xformed position into slot zero */
- GLuint slot = 0;
- xvp->output_to_slot[VERT_RESULT_HPOS] = slot;
- xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
- xvp->output_to_semantic_index[outAttr] = 0;
- numVpOuts++;
- usedOutputSlots |= (1 << slot);
- }
- else if (outputsWritten & (1 << outAttr)) {
- /* see if the frag prog wants this vert output */
- GLint fpInAttrib = vp_out_to_fp_in(outAttr);
- if (fpInAttrib >= 0) {
- GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
- if (fpInSlot != ~0) {
- /* match this vp output to the fp input */
- GLuint vpOutSlot = stfp->input_map[fpInSlot];
- xvp->output_to_slot[outAttr] = vpOutSlot;
- xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
- xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
- numVpOuts++;
- usedOutputSlots |= (1 << vpOutSlot);
- }
- else {
-#if 0 /*debug*/
- printf("VP output %d not used by FP\n", outAttr);
-#endif
- }
- }
- else if (outAttr == VERT_RESULT_PSIZ)
- emitPntSize = GL_TRUE;
- else if (outAttr == VERT_RESULT_BFC0)
- emitBFC0 = GL_TRUE;
- else if (outAttr == VERT_RESULT_BFC1)
- emitBFC1 = GL_TRUE;
- }
-#if 0 /*debug*/
- printf("assign vp output_to_slot[%d] = %d\n", outAttr,
- xvp->output_to_slot[outAttr]);
-#endif
- }
-
- /* must do these last */
- if (emitPntSize) {
- GLuint slot = numVpOuts++;
- xvp->output_to_slot[VERT_RESULT_PSIZ] = slot;
- xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
- xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
- usedOutputSlots |= (1 << slot);
- }
- if (emitBFC0) {
- GLuint slot = numVpOuts++;
- xvp->output_to_slot[VERT_RESULT_BFC0] = slot;
- xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
- xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
- usedOutputSlots |= (1 << slot);
- }
- if (emitBFC1) {
- GLuint slot = numVpOuts++;
- xvp->output_to_slot[VERT_RESULT_BFC1] = slot;
- xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR;
- xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1;
- usedOutputSlots |= (1 << slot);
- }
-
- /* build usedGenerics mask */
- usedGenerics = 0x0;
- for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
- if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
- usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]);
- }
- }
+ st_prepare_vertex_program( st, stvp );
- /* 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.
+ /* We are now up-to-date:
*/
- for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
- if (outputsWritten & (1 << outAttr)) {
- if (xvp->output_to_slot[outAttr] == UNUSED) {
- GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1;
- GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1;
- usedGenerics |= (1 << freeGeneric);
- usedOutputSlots |= (1 << freeSlot);
- xvp->output_to_slot[outAttr] = freeSlot;
- xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
- xvp->output_to_semantic_index[outAttr] = freeGeneric;
- }
- }
-
-#if 0 /*debug*/
- printf("vp output_to_slot[%d] = %d\n", outAttr,
- xvp->output_to_slot[outAttr]);
-#endif
+ 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;
}
+ }
- assert(stvp->Base.Base.NumInstructions > 1);
-
- st_translate_vertex_program(st, stvp, xvp->output_to_slot,
- xvp->output_to_semantic_name,
- xvp->output_to_semantic_index);
-
- xvp->vp = stvp;
-
- /* translated VP is up to date now */
- xvp->serialNo = stvp->serialNo;
+ /* 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 *
@@ -328,32 +157,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);
@@ -362,16 +178,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;
+
+ /* 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 = xvp->output_to_slot;
+ 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 */
+ ST_NEW_VERTEX_PROGRAM /* 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_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 95181578f6..a6b9765452 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -34,6 +34,7 @@
#include "main/image.h"
#include "main/macros.h"
+#include "st_debug.h"
#include "st_context.h"
#include "st_cb_accum.h"
#include "st_cb_fbo.h"
@@ -136,6 +137,9 @@ accum_accum(struct st_context *st, GLfloat value,
GLubyte *data = acc_strb->data;
GLfloat *buf;
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
+
color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, xpos, ypos,
@@ -181,6 +185,10 @@ accum_load(struct st_context *st, GLfloat value,
GLubyte *data = acc_strb->data;
GLfloat *buf;
+
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
+
color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, xpos, ypos,
@@ -228,6 +236,9 @@ accum_return(GLcontext *ctx, GLfloat value,
const GLubyte *data = acc_strb->data;
GLfloat *buf;
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
+
buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3])
@@ -241,7 +252,7 @@ accum_return(GLcontext *ctx, GLfloat value,
xpos, ypos,
width, height);
- if (usage != PIPE_TRANSFER_WRITE)
+ if (usage & PIPE_TRANSFER_READ)
pipe_get_tile_rgba(color_trans, 0, 0, width, height, buf);
switch (acc_strb->format) {
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 902fb38d1a..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;
}
@@ -330,7 +325,18 @@ setup_bitmap_vertex_data(struct st_context *st,
const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
- const GLuint max_slots = 4096 / sizeof(st->bitmap.vertices);
+
+ /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
+ * no_flush) updates to buffers where we know there is no conflict
+ * with previous data. Currently using max_slots > 1 will cause
+ * synchronous rendering if the driver flushes its command buffers
+ * between one bitmap and the next. Our flush hook below isn't
+ * sufficient to catch this as the driver doesn't tell us when it
+ * flushes its own command buffers. Until this gets fixed, pay the
+ * price of allocating a new buffer for each bitmap cache-flush to
+ * avoid synchronous rendering.
+ */
+ const GLuint max_slots = 1; /* 4096 / sizeof(st->bitmap.vertices); */
GLuint i;
if (st->bitmap.vbuf_slot >= max_slots) {
@@ -515,7 +521,7 @@ reset_cache(struct st_context *st)
struct pipe_screen *screen = pipe->screen;
struct bitmap_cache *cache = st->bitmap.cache;
- //memset(cache->buffer, 0xff, sizeof(cache->buffer));
+ /*memset(cache->buffer, 0xff, sizeof(cache->buffer));*/
cache->empty = GL_TRUE;
cache->xmin = 1000000;
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index c741940bcf..563615ed0d 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -39,6 +39,7 @@
#include "shader/prog_print.h"
#include "st_context.h"
+#include "st_texture.h"
#include "st_program.h"
#include "st_cb_blit.h"
#include "st_cb_fbo.h"
@@ -63,6 +64,7 @@ st_destroy_blit(struct st_context *st)
}
+#if FEATURE_EXT_framebuffer_blit
static void
st_BlitFramebuffer(GLcontext *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@@ -110,17 +112,50 @@ st_BlitFramebuffer(GLcontext *ctx,
}
if (mask & GL_COLOR_BUFFER_BIT) {
- struct st_renderbuffer *srcRb =
- st_renderbuffer(readFB->_ColorReadBuffer);
- struct st_renderbuffer *dstRb =
- st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
- struct pipe_surface *srcSurf = srcRb->surface;
- struct pipe_surface *dstSurf = dstRb->surface;
-
- util_blit_pixels(st->blit,
- srcSurf, srcX0, srcY0, srcX1, srcY1,
- dstSurf, dstX0, dstY0, dstX1, dstY1,
- 0.0, pFilter);
+ struct gl_renderbuffer_attachment *srcAtt =
+ &readFB->Attachment[readFB->_ColorReadBufferIndex];
+
+ if(srcAtt->Type == GL_TEXTURE) {
+ struct pipe_screen *screen = ctx->st->pipe->screen;
+ const struct st_texture_object *srcObj =
+ st_texture_object(srcAtt->Texture);
+ struct st_renderbuffer *dstRb =
+ st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
+ struct pipe_surface *srcSurf;
+ struct pipe_surface *dstSurf = dstRb->surface;
+
+ if (!srcObj->pt)
+ return;
+
+ srcSurf = screen->get_tex_surface(screen,
+ srcObj->pt,
+ srcAtt->CubeMapFace,
+ srcAtt->TextureLevel,
+ srcAtt->Zoffset,
+ PIPE_BUFFER_USAGE_GPU_READ);
+ if(!srcSurf)
+ return;
+
+ util_blit_pixels(st->blit,
+ srcSurf, srcX0, srcY0, srcX1, srcY1,
+ dstSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter);
+
+ pipe_surface_reference(&srcSurf, NULL);
+ }
+ else {
+ struct st_renderbuffer *srcRb =
+ st_renderbuffer(readFB->_ColorReadBuffer);
+ struct st_renderbuffer *dstRb =
+ st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
+ struct pipe_surface *srcSurf = srcRb->surface;
+ struct pipe_surface *dstSurf = dstRb->surface;
+
+ util_blit_pixels(st->blit,
+ srcSurf, srcX0, srcY0, srcX1, srcY1,
+ dstSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter);
+ }
}
if (mask & depthStencil) {
@@ -172,6 +207,7 @@ st_BlitFramebuffer(GLcontext *ctx,
}
}
}
+#endif /* FEATURE_EXT_framebuffer_blit */
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 8e09d0b932..63196afba9 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -239,6 +239,9 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target,
if (access & GL_MAP_FLUSH_EXPLICIT_BIT)
flags |= PIPE_BUFFER_USAGE_FLUSH_EXPLICIT;
+ if (access & GL_MAP_UNSYNCHRONIZED_BIT)
+ flags |= PIPE_BUFFER_USAGE_UNSYNCHRONIZED;
+
/* ... other flags ...
*/
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 8a8c99f7e1..e83b6c92ef 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -34,6 +34,7 @@
*/
#include "main/glheader.h"
+#include "main/formats.h"
#include "main/macros.h"
#include "shader/prog_instruction.h"
#include "st_context.h"
@@ -116,7 +117,18 @@ draw_quad(GLcontext *ctx,
{
struct st_context *st = ctx->st;
struct pipe_context *pipe = st->pipe;
- const GLuint max_slots = 1024 / sizeof(st->clear.vertices);
+
+ /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
+ * no_flush) updates to buffers where we know there is no conflict
+ * with previous data. Currently using max_slots > 1 will cause
+ * synchronous rendering if the driver flushes its command buffers
+ * between one bitmap and the next. Our flush hook below isn't
+ * sufficient to catch this as the driver doesn't tell us when it
+ * flushes its own command buffers. Until this gets fixed, pay the
+ * price of allocating a new buffer for each bitmap cache-flush to
+ * avoid synchronous rendering.
+ */
+ const GLuint max_slots = 1; /* 1024 / sizeof(st->clear.vertices); */
GLuint i;
if (st->clear.vbuf_slot >= max_slots) {
@@ -300,10 +312,14 @@ check_clear_color_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
static INLINE GLboolean
check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
{
- const GLuint stencilMax = (1 << rb->StencilBits) - 1;
+ const GLuint stencilMax = 0xff;
GLboolean maskStencil
= (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
+ assert(rb->Format == MESA_FORMAT_S8 ||
+ rb->Format == MESA_FORMAT_Z24_S8 ||
+ rb->Format == MESA_FORMAT_S8_Z24);
+
if (ctx->Scissor.Enabled &&
(ctx->Scissor.X != 0 ||
ctx->Scissor.Y != 0 ||
@@ -350,10 +366,14 @@ 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 GLuint stencilMax = (1 << rb->StencilBits) - 1;
+ const GLuint stencilMax = 0xff;
const GLboolean maskStencil
= (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
+ assert(rb->Format == MESA_FORMAT_S8 ||
+ rb->Format == MESA_FORMAT_Z24_S8 ||
+ rb->Format == MESA_FORMAT_S8_Z24);
+
if (maskStencil)
return TRUE;
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 99f3ba678b..1baff19040 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -35,11 +35,13 @@
#include "main/bufferobj.h"
#include "main/macros.h"
#include "main/texformat.h"
+#include "main/texstore.h"
#include "main/state.h"
#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
+#include "st_debug.h"
#include "st_context.h"
#include "st_atom.h"
#include "st_atom_constbuf.h"
@@ -58,9 +60,11 @@
#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_math.h"
+#include "util/u_rect.h"
#include "shader/prog_instruction.h"
#include "cso_cache/cso_context.h"
@@ -233,78 +237,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];
}
@@ -337,7 +304,7 @@ make_texture(struct st_context *st,
GLcontext *ctx = st->ctx;
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
- const struct gl_texture_format *mformat;
+ gl_format mformat;
struct pipe_texture *pt;
enum pipe_format pipeFormat;
GLuint cpp;
@@ -349,7 +316,7 @@ make_texture(struct st_context *st,
mformat = st_ChooseTextureFormat(ctx, baseFormat, format, type);
assert(mformat);
- pipeFormat = st_mesa_format_to_pipe_format(mformat->MesaFormat);
+ pipeFormat = st_mesa_format_to_pipe_format(mformat);
assert(pipeFormat);
cpp = st_sizeof_format(pipeFormat);
@@ -402,21 +369,22 @@ make_texture(struct st_context *st,
/* map texture transfer */
dest = screen->transfer_map(screen, transfer);
+
/* Put image into texture transfer.
* Note that the image is actually going to be upside down in
* the texture. We deal with that with texcoords.
*/
- success = mformat->StoreImage(ctx, 2, /* dims */
- baseFormat, /* baseInternalFormat */
- mformat, /* gl_texture_format */
- dest, /* dest */
- 0, 0, 0, /* dstX/Y/Zoffset */
- transfer->stride, /* dstRowStride, bytes */
- &dstImageOffsets, /* dstImageOffsets */
- width, height, 1, /* size */
- format, type, /* src format/type */
- pixels, /* data source */
- unpack);
+ success = _mesa_texstore(ctx, 2, /* dims */
+ baseFormat, /* baseInternalFormat */
+ mformat, /* gl_format */
+ dest, /* dest */
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ transfer->stride, /* dstRowStride, bytes */
+ &dstImageOffsets, /* dstImageOffsets */
+ width, height, 1, /* size */
+ format, type, /* src format/type */
+ pixels, /* data source */
+ unpack);
/* unmap */
screen->transfer_unmap(screen, transfer);
@@ -535,8 +503,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)
{
@@ -571,10 +539,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: */
@@ -598,15 +566,15 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
/* viewport state: viewport matching window dims */
{
- const float width = (float) ctx->DrawBuffer->Width;
- const float height = (float) ctx->DrawBuffer->Height;
+ const float w = (float) ctx->DrawBuffer->Width;
+ const float h = (float) ctx->DrawBuffer->Height;
struct pipe_viewport_state vp;
- vp.scale[0] = 0.5f * width;
- vp.scale[1] = -0.5f * height;
+ vp.scale[0] = 0.5f * w;
+ vp.scale[1] = -0.5f * h;
vp.scale[2] = 1.0f;
vp.scale[3] = 1.0f;
- vp.translate[0] = 0.5f * width;
- vp.translate[1] = 0.5f * height;
+ vp.translate[0] = 0.5f * w;
+ vp.translate[1] = 0.5f * h;
vp.translate[2] = 0.0f;
vp.translate[3] = 0.0f;
cso_set_viewport(cso, &vp);
@@ -617,10 +585,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.
@@ -633,8 +601,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);
@@ -661,6 +629,15 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
GLint skipPixels;
ubyte *stmap;
+ struct gl_pixelstore_attrib clippedUnpack = *unpack;
+
+ if (!zoom) {
+ if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
+ &clippedUnpack)) {
+ /* totally clipped */
+ return;
+ }
+ }
strb = st_renderbuffer(ctx->DrawBuffer->
Attachment[BUFFER_STENCIL].Renderbuffer);
@@ -681,7 +658,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
stmap = screen->transfer_map(screen, pt);
- pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
+ pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
assert(pixels);
/* if width > MAX_WIDTH, have to process image in chunks */
@@ -694,17 +671,18 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
GLubyte sValues[MAX_WIDTH];
GLuint zValues[MAX_WIDTH];
GLenum destType = GL_UNSIGNED_BYTE;
- const GLvoid *source = _mesa_image_address2d(unpack, pixels,
+ const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels,
width, height,
format, type,
row, skipPixels);
_mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues,
- type, source, unpack,
+ type, source, &clippedUnpack,
ctx->_ImageTransferState);
if (format == GL_DEPTH_STENCIL) {
_mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues,
- (1 << 24) - 1, type, source, unpack);
+ (1 << 24) - 1, type, source,
+ &clippedUnpack);
}
if (zoom) {
@@ -723,7 +701,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;
@@ -775,7 +753,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
skipPixels += spanWidth;
}
- _mesa_unmap_pbo_source(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, &clippedUnpack);
/* unmap the stencil buffer */
screen->transfer_unmap(screen, pt);
@@ -792,7 +770,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;
@@ -812,13 +790,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;
}
@@ -829,7 +807,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,8 +856,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(pf_get_blockwidth(ptDraw->texture->format) == 1);
+ assert(pf_get_blockheight(ptDraw->texture->format) == 1);
/* map the stencil buffer */
drawMap = screen->transfer_map(screen, ptDraw);
@@ -897,7 +878,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;
@@ -946,7 +927,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;
@@ -995,14 +976,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;
@@ -1014,13 +995,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
else {
/* srcFormat can't be used as a texture format */
if (type == GL_DEPTH) {
- texFormat = st_choose_format(pipe, GL_DEPTH_COMPONENT, PIPE_TEXTURE_2D,
+ texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
+ PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL);
assert(texFormat != PIPE_FORMAT_NONE); /* XXX no depth texture formats??? */
}
else {
/* default color format */
- texFormat = st_choose_format(pipe, GL_RGBA, PIPE_TEXTURE_2D,
+ texFormat = st_choose_format(screen, GL_RGBA, PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_SAMPLER);
assert(texFormat != PIPE_FORMAT_NONE);
}
@@ -1073,11 +1055,19 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
PIPE_BUFFER_USAGE_GPU_READ);
struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE );
- pipe->surface_copy(pipe,
- psTex, /* dest */
- 0, 0, /* destx/y */
- psRead,
- srcx, srcy, width, height);
+ if (pipe->surface_copy) {
+ pipe->surface_copy(pipe,
+ psTex, /* dest */
+ 0, 0, /* destx/y */
+ psRead,
+ srcx, srcy, width, height);
+ } else {
+ util_surface_copy(pipe, FALSE,
+ psTex,
+ 0, 0,
+ psRead,
+ srcx, srcy, width, height);
+ }
pipe_surface_reference(&psRead, NULL);
pipe_surface_reference(&psTex, NULL);
}
@@ -1090,6 +1080,9 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
struct pipe_transfer *ptTex;
enum pipe_transfer_usage transfer_usage;
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
+
if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
@@ -1122,7 +1115,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 a96602878e..ead8e22888 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_rect.h"
/**
@@ -64,13 +65,7 @@ init_renderbuffer_bits(struct st_renderbuffer *strb,
assert( 0 );
}
- strb->Base._ActualFormat = info.base_format;
- strb->Base.RedBits = info.red_bits;
- strb->Base.GreenBits = info.green_bits;
- strb->Base.BlueBits = info.blue_bits;
- strb->Base.AlphaBits = info.alpha_bits;
- strb->Base.DepthBits = info.depth_bits;
- strb->Base.StencilBits = info.stencil_bits;
+ strb->Base.Format = info.mesa_format;
strb->Base.DataType = st_format_datatype(pipeFormat);
return info.size;
@@ -93,7 +88,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
if (strb->format != PIPE_FORMAT_NONE)
format = strb->format;
else
- format = st_choose_renderbuffer_format(pipe, internalFormat);
+ format = st_choose_renderbuffer_format(pipe->screen, internalFormat);
/* init renderbuffer fields */
strb->Base.Width = width;
@@ -103,16 +98,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 = pf_get_stride(strb->format, width);
+ size = pf_get_2d_size(strb->format, strb->stride, height);
strb->data = _mesa_malloc(size);
@@ -132,10 +125,9 @@ 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)) {
@@ -165,12 +157,12 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
strb->texture,
0, 0, 0,
surface_usage );
-
- assert(strb->surface->texture);
- assert(strb->surface->format);
- assert(strb->surface->width == width);
- assert(strb->surface->height == height);
-
+ if (strb->surface) {
+ assert(strb->surface->texture);
+ assert(strb->surface->format);
+ assert(strb->surface->width == width);
+ assert(strb->surface->height == height);
+ }
return strb->surface != NULL;
}
@@ -258,6 +250,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
strb->Base.ClassID = 0x4242; /* just a unique value */
strb->Base.NumSamples = samples;
strb->format = format;
+ init_renderbuffer_bits(strb, format);
strb->software = sw;
switch (format) {
@@ -269,34 +262,29 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
case PIPE_FORMAT_A4R4G4B4_UNORM:
case PIPE_FORMAT_R5G6B5_UNORM:
strb->Base.InternalFormat = GL_RGBA;
- strb->Base._BaseFormat = GL_RGBA;
break;
case PIPE_FORMAT_Z16_UNORM:
strb->Base.InternalFormat = GL_DEPTH_COMPONENT16;
- strb->Base._BaseFormat = GL_DEPTH_COMPONENT;
break;
case PIPE_FORMAT_Z32_UNORM:
strb->Base.InternalFormat = GL_DEPTH_COMPONENT32;
- strb->Base._BaseFormat = GL_DEPTH_COMPONENT;
break;
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_Z24S8_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_Z24X8_UNORM:
strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
- strb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT;
break;
case PIPE_FORMAT_S8_UNORM:
strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
- strb->Base._BaseFormat = GL_STENCIL_INDEX;
break;
case PIPE_FORMAT_R16G16B16A16_SNORM:
strb->Base.InternalFormat = GL_RGBA16;
- strb->Base._BaseFormat = GL_RGBA;
break;
default:
_mesa_problem(NULL,
"Unexpected format in st_new_renderbuffer_fb");
+ _mesa_free(strb);
return NULL;
}
@@ -382,9 +370,10 @@ st_render_texture(GLcontext *ctx,
rb->Width = texImage->Width2;
rb->Height = texImage->Height2;
+ 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 );
@@ -535,10 +524,17 @@ copy_back_to_front(struct st_context *st,
(void) st_get_framebuffer_surface(stfb, backIndex, &surf_back);
if (surf_front && surf_back) {
- st->pipe->surface_copy(st->pipe,
- surf_front, 0, 0, /* dest */
- surf_back, 0, 0, /* src */
- fb->Width, fb->Height);
+ if (st->pipe->surface_copy) {
+ st->pipe->surface_copy(st->pipe,
+ surf_front, 0, 0, /* dest */
+ surf_back, 0, 0, /* src */
+ fb->Width, fb->Height);
+ } else {
+ util_surface_copy(st->pipe, FALSE,
+ surf_front, 0, 0,
+ surf_back, 0, 0,
+ fb->Width, fb->Height);
+ }
}
}
diff --git a/src/mesa/state_tracker/st_cb_get.c b/src/mesa/state_tracker/st_cb_get.c
deleted file mode 100644
index e7d7f03bc9..0000000000
--- a/src/mesa/state_tracker/st_cb_get.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * glGet functions
- *
- * \author Brian Paul
- */
-
-#include "main/imports.h"
-#include "main/context.h"
-
-#include "pipe/p_defines.h"
-
-#include "st_cb_fbo.h"
-#include "st_cb_get.h"
-
-
-
-/**
- * Examine the current color read buffer format to determine
- * which GL pixel format/type combo is the best match.
- */
-static void
-get_preferred_read_format_type(GLcontext *ctx, GLint *format, GLint *type)
-{
- struct gl_framebuffer *fb = ctx->ReadBuffer;
- struct st_renderbuffer *strb = st_renderbuffer(fb->_ColorReadBuffer);
-
- /* defaults */
- *format = ctx->Const.ColorReadFormat;
- *type = ctx->Const.ColorReadType;
-
- if (strb) {
- /* XXX could add more cases here... */
- if (strb->format == PIPE_FORMAT_A8R8G8B8_UNORM) {
- *format = GL_BGRA;
- if (_mesa_little_endian())
- *type = GL_UNSIGNED_INT_8_8_8_8_REV;
- else
- *type = GL_UNSIGNED_INT_8_8_8_8;
- }
- }
-}
-
-
-/**
- * We only intercept the OES preferred ReadPixels format/type.
- * Everything else goes to the default _mesa_GetIntegerv.
- */
-static GLboolean
-st_GetIntegerv(GLcontext *ctx, GLenum pname, GLint *params)
-{
- GLint dummy;
-
- switch (pname) {
- case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
- get_preferred_read_format_type(ctx, &dummy, params);
- return GL_TRUE;
- case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
- get_preferred_read_format_type(ctx, params, &dummy);
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-void st_init_get_functions(struct dd_function_table *functions)
-{
- functions->GetIntegerv = st_GetIntegerv;
-}
diff --git a/src/mesa/state_tracker/st_cb_get.h b/src/mesa/state_tracker/st_cb_get.h
deleted file mode 100644
index 8e9f3e9306..0000000000
--- a/src/mesa/state_tracker/st_cb_get.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef ST_CB_GET_H
-#define ST_CB_GET_H
-
-
-extern void
-st_init_get_functions(struct dd_function_table *functions);
-
-
-#endif
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 4398ab2839..8c276f8128 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -45,6 +45,7 @@
#include "st_context.h"
#include "st_program.h"
#include "st_atom_shader.h"
+#include "st_mesa_to_tgsi.h"
#include "st_cb_program.h"
@@ -137,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) {
- _mesa_free((void *) stvp->state.tokens);
- stvp->state.tokens = NULL;
- }
+ st_vp_release_varients( st, stvp );
}
break;
case GL_FRAGMENT_PROGRAM_ARB:
@@ -167,7 +151,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
}
if (stfp->state.tokens) {
- _mesa_free((void *) stfp->state.tokens);
+ st_free_tokens(stfp->state.tokens);
stfp->state.tokens = NULL;
}
@@ -176,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:
@@ -214,12 +196,10 @@ static void st_program_string_notify( GLcontext *ctx,
}
if (stfp->state.tokens) {
- _mesa_free((void *) stfp->state.tokens);
+ st_free_tokens(stfp->state.tokens);
stfp->state.tokens = NULL;
}
- stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
-
if (st->fp == stfp)
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
}
@@ -228,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) {
- _mesa_free((void *) 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 75424aa2e7..6fa7bb64f2 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -43,6 +43,7 @@
#include "pipe/p_inlines.h"
#include "util/u_tile.h"
+#include "st_debug.h"
#include "st_context.h"
#include "st_cb_bitmap.h"
#include "st_cb_readpixels.h"
@@ -102,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;
@@ -242,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,
@@ -416,6 +417,9 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
yStep = 1;
}
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
+
/*
* Copy pixels from pipe_transfer to user memory
*/
@@ -427,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];
@@ -459,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];
@@ -486,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];
@@ -501,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 c0ace3b9ea..6d136f5abf 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -31,18 +31,21 @@
#include "main/convolve.h"
#endif
#include "main/enums.h"
+#include "main/formats.h"
#include "main/image.h"
#include "main/imports.h"
#include "main/macros.h"
#include "main/mipmap.h"
#include "main/pixel.h"
#include "main/texcompress.h"
+#include "main/texfetch.h"
#include "main/texformat.h"
#include "main/texgetimage.h"
#include "main/teximage.h"
#include "main/texobj.h"
#include "main/texstore.h"
+#include "state_tracker/st_debug.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_cb_fbo.h"
#include "state_tracker/st_cb_texture.h"
@@ -90,51 +93,6 @@ gl_target_to_pipe(GLenum target)
}
-/**
- * Return nominal bytes per texel for a compressed format, 0 for non-compressed
- * format.
- */
-static GLuint
-compressed_num_bytes(GLuint mesaFormat)
-{
- switch(mesaFormat) {
-#if FEATURE_texture_fxt1
- case MESA_FORMAT_RGB_FXT1:
- case MESA_FORMAT_RGBA_FXT1:
-#endif
-#if FEATURE_texture_s3tc
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- return 2;
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- return 4;
-#endif
- default:
- return 0;
- }
-}
-
-
-static GLboolean
-is_compressed_mesa_format(const struct gl_texture_format *format)
-{
- switch (format->MesaFormat) {
- case MESA_FORMAT_RGB_DXT1:
- case MESA_FORMAT_RGBA_DXT1:
- case MESA_FORMAT_RGBA_DXT3:
- case MESA_FORMAT_RGBA_DXT5:
- case MESA_FORMAT_SRGB_DXT1:
- case MESA_FORMAT_SRGBA_DXT1:
- case MESA_FORMAT_SRGBA_DXT3:
- case MESA_FORMAT_SRGBA_DXT5:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
/** called via ctx->Driver.NewTextureImage() */
static struct gl_texture_image *
st_NewTextureImage(GLcontext * ctx)
@@ -328,17 +286,20 @@ guess_and_alloc_texture(struct st_context *st,
stObj->base.MinFilter == GL_LINEAR ||
stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
+ !stObj->base.GenerateMipmap &&
stImage->level == firstLevel) {
+ /* only alloc space for a single mipmap level */
lastLevel = firstLevel;
}
else {
+ /* alloc space for a full mipmap */
GLuint l2width = util_logbase2(width);
GLuint l2height = util_logbase2(height);
GLuint l2depth = util_logbase2(depth);
lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
}
- fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat);
+ fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat);
usage = default_usage(fmt);
@@ -411,14 +372,13 @@ compress_with_blit(GLcontext * ctx,
const GLuint dstImageOffsets[1] = {0};
struct st_texture_image *stImage = st_texture_image(texImage);
struct pipe_screen *screen = ctx->st->pipe->screen;
- const struct gl_texture_format *mesa_format;
+ gl_format mesa_format;
struct pipe_texture templ;
struct pipe_texture *src_tex;
struct pipe_surface *dst_surface;
struct pipe_transfer *tex_xfer;
void *map;
-
if (!stImage->pt) {
/* XXX: Can this happen? Should we assert? */
return GL_FALSE;
@@ -444,11 +404,10 @@ 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->MesaFormat);
- pf_get_block(templ.format, &templ.block);
- templ.width[0] = width;
- templ.height[0] = height;
- templ.depth[0] = 1;
+ templ.format = st_mesa_format_to_pipe_format(mesa_format);
+ 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);
@@ -464,15 +423,15 @@ compress_with_blit(GLcontext * ctx,
0, 0, width, height); /* x, y, w, h */
map = screen->transfer_map(screen, tex_xfer);
- mesa_format->StoreImage(ctx, 2, GL_RGBA, mesa_format,
- map, /* dest ptr */
- 0, 0, 0, /* dest x/y/z offset */
- tex_xfer->stride, /* dest row stride (bytes) */
- dstImageOffsets, /* image offsets (for 3D only) */
- width, height, 1, /* size */
- format, type, /* source format/type */
- pixels, /* source data */
- unpack); /* source data packing */
+ _mesa_texstore(ctx, 2, GL_RGBA, mesa_format,
+ map, /* dest ptr */
+ 0, 0, 0, /* dest x/y/z offset */
+ tex_xfer->stride, /* dest row stride (bytes) */
+ dstImageOffsets, /* image offsets (for 3D only) */
+ width, height, 1, /* size */
+ format, type, /* source format/type */
+ pixels, /* source data */
+ unpack); /* source data packing */
screen->transfer_unmap(screen, tex_xfer);
screen->tex_transfer_destroy(tex_xfer);
@@ -554,23 +513,14 @@ st_TexImage(GLcontext * ctx,
}
#endif
- /* choose the texture format */
- texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
- format, type);
-
_mesa_set_fetch_functions(texImage, dims);
- if (texImage->TexFormat->TexelBytes == 0) {
+ if (_mesa_is_format_compressed(texImage->TexFormat)) {
/* must be a compressed format */
texelBytes = 0;
- texImage->IsCompressed = GL_TRUE;
- texImage->CompressedSize =
- ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
- texImage->Height, texImage->Depth,
- texImage->TexFormat->MesaFormat);
}
else {
- texelBytes = texImage->TexFormat->TexelBytes;
+ texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
/* Minimum pitch of 32 bytes */
if (postConvWidth * texelBytes < 32) {
@@ -658,18 +608,23 @@ st_TexImage(GLcontext * ctx,
format, type,
pixels, unpack, "glTexImage");
}
- if (!pixels)
- return;
+
+ /* Note: we can't check for pixels==NULL until after we've allocated
+ * memory for the texture.
+ */
/* See if we can do texture compression with a blit/render.
*/
if (!compressed_src &&
!ctx->Mesa_DXTn &&
- is_compressed_mesa_format(texImage->TexFormat) &&
+ _mesa_is_format_compressed(texImage->TexFormat) &&
screen->is_format_supported(screen,
stImage->pt->format,
stImage->pt->target,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
+ if (!pixels)
+ goto done;
+
if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth,
format, type, pixels, unpack, texImage)) {
goto done;
@@ -692,10 +647,12 @@ st_TexImage(GLcontext * ctx,
}
else {
/* Allocate regular memory and store the image there temporarily. */
- if (texImage->IsCompressed) {
- sizeInBytes = texImage->CompressedSize;
- dstRowStride =
- _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+ if (_mesa_is_format_compressed(texImage->TexFormat)) {
+ sizeInBytes = _mesa_format_image_size(texImage->TexFormat,
+ texImage->Width,
+ texImage->Height,
+ texImage->Depth);
+ dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
assert(dims != 3);
}
else {
@@ -711,6 +668,9 @@ st_TexImage(GLcontext * ctx,
return;
}
+ if (!pixels)
+ goto done;
+
DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
width, height, depth, width * texelBytes, dstRowStride);
@@ -728,15 +688,15 @@ st_TexImage(GLcontext * ctx,
const GLubyte *src = (const GLubyte *) pixels;
for (i = 0; i < depth; i++) {
- if (!texImage->TexFormat->StoreImage(ctx, dims,
- texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- format, type, src, unpack)) {
+ if (!_mesa_texstore(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, src, unpack)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
}
@@ -753,9 +713,9 @@ st_TexImage(GLcontext * ctx,
}
}
+done:
_mesa_unmap_teximage_pbo(ctx, unpack);
-done:
if (stImage->pt && texImage->Data) {
st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
@@ -872,7 +832,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 * pf_get_blocksize(stImage->pt->format);
ubyte *map = screen->transfer_map(screen, tex_xfer);
GLuint row;
for (row = 0; row < height; row++) {
@@ -892,6 +852,9 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level,
GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width,
height, format, type, row, 0);
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback format translation\n", __FUNCTION__);
+
/* get float[4] rgba row from surface */
pipe_get_tile_rgba(tex_xfer, 0, row, width, 1, rgba);
@@ -951,7 +914,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 / pf_get_blocksize(stImage->pt->format);
}
else {
/* Otherwise, the image should actually be stored in
@@ -1057,7 +1020,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
/* See if we can do texture compression with a blit/render.
*/
if (!ctx->Mesa_DXTn &&
- is_compressed_mesa_format(texImage->TexFormat) &&
+ _mesa_is_format_compressed(texImage->TexFormat) &&
screen->is_format_supported(screen,
stImage->pt->format,
stImage->pt->target,
@@ -1092,21 +1055,21 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
- return;
+ goto done;
}
src = (const GLubyte *) pixels;
dstRowStride = stImage->transfer->stride;
for (i = 0; i < depth; i++) {
- if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- 0, 0, 0,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- format, type, src, packing)) {
+ if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, src, packing)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
}
@@ -1123,9 +1086,9 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
}
}
+done:
_mesa_unmap_teximage_pbo(ctx, packing);
-done:
if (stImage->pt) {
st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
@@ -1199,10 +1162,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);
@@ -1214,8 +1177,7 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
xoffset, yoffset,
width, height);
- block = stImage->pt->block;
- srcBlockStride = pf_get_stride(&block, width);
+ srcBlockStride = pf_get_stride(pformat, width);
dstBlockStride = stImage->transfer->stride;
} else {
assert(stImage->pt);
@@ -1229,16 +1191,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 % pf_get_blockwidth(pformat) == 0);
+ assert(yoffset % pf_get_blockheight(pformat) == 0);
+ assert(width % pf_get_blockwidth(pformat) == 0);
+ assert(height % pf_get_blockheight(pformat) == 0);
- for (y = 0; y < height; y += block.height) {
+ for (y = 0; y < height; y += pf_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 * pf_get_nblocksy(pformat, y);
+ char *dst = (char*)texImage->Data + dstBlockStride * pf_get_nblocksy(pformat, y);
+ memcpy(dst, src, pf_get_stride(pformat, width));
}
if (stImage->pt) {
@@ -1283,6 +1245,9 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
struct pipe_transfer *src_trans;
GLvoid *texDest;
enum pipe_transfer_usage transfer_usage;
+
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
assert(width <= MAX_WIDTH);
@@ -1297,7 +1262,8 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
srcX, srcY,
width, height);
- if (baseFormat == GL_DEPTH_COMPONENT &&
+ if ((baseFormat == GL_DEPTH_COMPONENT ||
+ baseFormat == GL_DEPTH_STENCIL) &&
pf_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
@@ -1310,7 +1276,7 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
destX, destY, width, height);
if (baseFormat == GL_DEPTH_COMPONENT ||
- baseFormat == GL_DEPTH24_STENCIL8) {
+ baseFormat == GL_DEPTH_STENCIL) {
const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
ctx->Pixel.DepthBias != 0.0F);
GLint row, yStep;
@@ -1362,16 +1328,16 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
* is actually RGBA but the user created the texture as GL_RGB we
* need to fill-in/override the alpha channel with 1.0.
*/
- texImage->TexFormat->StoreImage(ctx, dims,
- texImage->_BaseFormat,
- texImage->TexFormat,
- texDest,
- 0, 0, 0,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- GL_RGBA, GL_FLOAT, tempSrc, /* src */
- &unpack);
+ _mesa_texstore(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texDest,
+ 0, 0, 0,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ GL_RGBA, GL_FLOAT, tempSrc, /* src */
+ &unpack);
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
@@ -1390,8 +1356,8 @@ static unsigned
compatible_src_dst_formats(const struct gl_renderbuffer *src,
const struct gl_texture_image *dst)
{
- const GLenum srcFormat = src->_BaseFormat;
- const GLenum dstLogicalFormat = dst->_BaseFormat;
+ const GLenum srcFormat = _mesa_get_format_base_format(src->Format);
+ const GLenum dstLogicalFormat = _mesa_get_format_base_format(dst->TexFormat);
if (srcFormat == dstLogicalFormat) {
/* This is the same as matching_base_formats, which should
@@ -1408,6 +1374,12 @@ compatible_src_dst_formats(const struct gl_renderbuffer *src,
return TGSI_WRITEMASK_XYZ; /* A ==> 1.0 */
}
else {
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s failed for src %s, dst %s\n",
+ __FUNCTION__,
+ _mesa_lookup_enum_by_nr(srcFormat),
+ _mesa_lookup_enum_by_nr(dstLogicalFormat));
+
/* Otherwise fail.
*/
return 0;
@@ -1437,7 +1409,7 @@ st_copy_texsubimage(GLcontext *ctx,
struct gl_texture_image *texImage =
_mesa_select_tex_image(ctx, texObj, target, level);
struct st_texture_image *stImage = st_texture_image(texImage);
- const GLenum texBaseFormat = texImage->InternalFormat;
+ const GLenum texBaseFormat = texImage->_BaseFormat;
struct gl_framebuffer *fb = ctx->ReadBuffer;
struct st_renderbuffer *strb;
struct pipe_context *pipe = ctx->st->pipe;
@@ -1458,12 +1430,9 @@ st_copy_texsubimage(GLcontext *ctx,
/* determine if copying depth or color data */
if (texBaseFormat == GL_DEPTH_COMPONENT ||
- texBaseFormat == GL_DEPTH24_STENCIL8) {
+ texBaseFormat == GL_DEPTH_STENCIL) {
strb = st_renderbuffer(fb->_DepthBuffer);
}
- else if (texBaseFormat == GL_DEPTH_STENCIL_EXT) {
- strb = st_renderbuffer(fb->_StencilBuffer);
- }
else {
/* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
strb = st_renderbuffer(fb->_ColorReadBuffer);
@@ -1517,12 +1486,15 @@ st_copy_texsubimage(GLcontext *ctx,
* framebuffer's alpha values). We can't do that with the blit or
* textured-quad paths.
*/
- matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat);
+ matching_base_formats =
+ (_mesa_get_format_base_format(strb->Base.Format) ==
+ _mesa_get_format_base_format(texImage->TexFormat));
format_writemask = compatible_src_dst_formats(&strb->Base, texImage);
if (ctx->_ImageTransferState == 0x0) {
- if (matching_base_formats &&
+ if (pipe->surface_copy &&
+ matching_base_formats &&
src_format == dest_format &&
!do_flip)
{
@@ -1546,6 +1518,8 @@ st_copy_texsubimage(GLcontext *ctx,
use_fallback = GL_FALSE;
}
else if (format_writemask &&
+ texBaseFormat != GL_DEPTH_COMPONENT &&
+ texBaseFormat != GL_DEPTH_STENCIL &&
screen->is_format_supported(screen, src_format,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_SAMPLER,
@@ -1685,53 +1659,6 @@ st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
}
-/**
- * Compute which mipmap levels that really need to be sent to the hardware.
- * This depends on the base image size, GL_TEXTURE_MIN_LOD,
- * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
- */
-static void
-calculate_first_last_level(struct st_texture_object *stObj)
-{
- struct gl_texture_object *tObj = &stObj->base;
-
- /* These must be signed values. MinLod and MaxLod can be negative numbers,
- * and having firstLevel and lastLevel as signed prevents the need for
- * extra sign checks.
- */
- GLint firstLevel;
- GLint lastLevel;
-
- /* Yes, this looks overly complicated, but it's all needed.
- */
- switch (tObj->Target) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- case GL_TEXTURE_CUBE_MAP:
- if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
- /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
- */
- firstLevel = lastLevel = tObj->BaseLevel;
- }
- else {
- firstLevel = 0;
- lastLevel = MIN2(tObj->MaxLevel,
- (int) tObj->Image[0][tObj->BaseLevel]->WidthLog2);
- }
- break;
- case GL_TEXTURE_RECTANGLE_NV:
- case GL_TEXTURE_4D_SGIS:
- firstLevel = lastLevel = 0;
- break;
- default:
- return;
- }
-
- stObj->lastLevel = lastLevel;
-}
-
-
static void
copy_image_data_to_texture(struct st_context *st,
struct st_texture_object *stObj,
@@ -1750,8 +1677,6 @@ copy_image_data_to_texture(struct st_context *st,
pipe_texture_reference(&stImage->pt, NULL);
}
else if (stImage->base.Data) {
- assert(stImage->base.Data != NULL);
-
/* More straightforward upload.
*/
@@ -1765,10 +1690,10 @@ copy_image_data_to_texture(struct st_context *st,
dstLevel,
stImage->base.Data,
stImage->base.RowStride *
- stObj->pt->block.size,
+ pf_get_blocksize(stObj->pt->format),
stImage->base.RowStride *
stImage->base.Height *
- stObj->pt->block.size);
+ pf_get_blocksize(stObj->pt->format));
_mesa_align_free(stImage->base.Data);
stImage->base.Data = NULL;
}
@@ -1790,18 +1715,25 @@ st_finalize_texture(GLcontext *ctx,
{
struct st_texture_object *stObj = st_texture_object(tObj);
const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
- GLuint cpp, face;
+ GLuint blockSize, face;
struct st_texture_image *firstImage;
*needFlush = GL_FALSE;
- /* We know/require this is true by now:
- */
- assert(stObj->base._Complete);
+ if (stObj->base._Complete) {
+ /* The texture is complete and we know exactly how many mipmap levels
+ * are present/needed. This is conditional because we may be called
+ * from the st_generate_mipmap() function when the texture object is
+ * incomplete. In that case, we'll have set stObj->lastLevel before
+ * we get here.
+ */
+ if (stObj->base.MinFilter == GL_LINEAR ||
+ stObj->base.MinFilter == GL_NEAREST)
+ stObj->lastLevel = stObj->base.BaseLevel;
+ else
+ stObj->lastLevel = stObj->base._MaxLevel - stObj->base.BaseLevel;
+ }
- /* What levels must the texture include at a minimum?
- */
- calculate_first_last_level(stObj);
firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
/* If both firstImage and stObj point to a texture which can contain
@@ -1815,28 +1747,21 @@ st_finalize_texture(GLcontext *ctx,
pipe_texture_reference(&stObj->pt, firstImage->pt);
}
- /* FIXME: determine format block instead of cpp */
- if (firstImage->base.IsCompressed) {
- cpp = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
- }
- else {
- cpp = firstImage->base.TexFormat->TexelBytes;
- }
+ /* bytes per pixel block (blocks are usually 1x1) */
+ blockSize = _mesa_get_format_bytes(firstImage->base.TexFormat);
/* If we already have a gallium texture, check that it matches the texture
* object's format, target, size, num_levels, etc.
*/
if (stObj->pt) {
const enum pipe_format fmt =
- st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
+ st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
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 ||
- /* Nominal bytes per pixel: */
- stObj->pt->block.size / stObj->pt->block.width != cpp)
+ 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;
@@ -1847,7 +1772,7 @@ st_finalize_texture(GLcontext *ctx,
*/
if (!stObj->pt) {
const enum pipe_format fmt =
- st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat);
+ st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
GLuint usage = default_usage(fmt);
stObj->pt = st_texture_create(ctx->st,
@@ -1964,7 +1889,6 @@ st_init_texture_functions(struct dd_function_table *functions)
/* compressed texture functions */
functions->CompressedTexImage2D = st_CompressedTexImage2D;
functions->GetCompressedTexImage = st_GetCompressedTexImage;
- functions->CompressedTextureSize = _mesa_compressed_texture_size;
functions->NewTextureObject = st_NewTextureObject;
functions->NewTextureImage = st_NewTextureImage;
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 8514b6b375..d18a25ab51 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -36,6 +36,7 @@
#include "shader/shader_api.h"
#include "glapi/glapi.h"
#include "st_public.h"
+#include "st_debug.h"
#include "st_context.h"
#include "st_cb_accum.h"
#include "st_cb_bitmap.h"
@@ -50,7 +51,6 @@
#include "st_cb_drawtex.h"
#endif
#include "st_cb_fbo.h"
-#include "st_cb_get.h"
#if FEATURE_feedback
#include "st_cb_feedback.h"
#endif
@@ -113,6 +113,9 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
st->ctx = ctx;
st->pipe = pipe;
+ /* XXX: this is one-off, per-screen init: */
+ st_debug_init();
+
/* state tracker needs the VBO module */
_vbo_CreateContext(ctx);
@@ -327,12 +330,11 @@ void st_init_driver_functions(struct dd_function_table *functions)
st_init_rasterpos_functions(functions);
#endif
st_init_fbo_functions(functions);
- st_init_get_functions(functions);
#if FEATURE_feedback
st_init_feedback_functions(functions);
#endif
st_init_program_functions(functions);
-#if FEATURE_ARB_occlusion_query
+#if FEATURE_queryobj
st_init_query_functions(functions);
#endif
st_init_readpixels_functions(functions);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 18adb35e87..b760728658 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -127,6 +127,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 c7d26ce33c..6e699ca552 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -41,6 +41,32 @@
+#ifdef DEBUG
+int ST_DEBUG = 0;
+
+static const struct debug_named_value st_debug_flags[] = {
+ { "mesa", DEBUG_MESA },
+ { "tgsi", DEBUG_TGSI },
+ { "pipe", DEBUG_PIPE },
+ { "tex", DEBUG_TEX },
+ { "fallback", DEBUG_FALLBACK },
+ { "screen", DEBUG_SCREEN },
+ { "query", DEBUG_QUERY },
+ {NULL, 0}
+};
+#endif
+
+
+void
+st_debug_init(void)
+{
+#ifdef DEBUG
+ ST_DEBUG = debug_get_flags_option("ST_DEBUG", st_debug_flags, 0 );
+#endif
+}
+
+
+
/**
* Print current state. May be called from inside gdb to see currently
* bound vertex/fragment shaders and associated constants.
@@ -60,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);
@@ -68,3 +95,5 @@ st_print_current(void)
if (st->fp->Base.Base.Parameters)
_mesa_print_parameter_list(st->fp->Base.Base.Parameters);
}
+
+
diff --git a/src/mesa/state_tracker/st_debug.h b/src/mesa/state_tracker/st_debug.h
index 49d752e1b2..4a060d7759 100644
--- a/src/mesa/state_tracker/st_debug.h
+++ b/src/mesa/state_tracker/st_debug.h
@@ -29,8 +29,44 @@
#ifndef ST_DEBUG_H
#define ST_DEBUG_H
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+
extern void
st_print_current(void);
+#define DEBUG_MESA 0x1
+#define DEBUG_TGSI 0x2
+#define DEBUG_CONSTANTS 0x4
+#define DEBUG_PIPE 0x8
+#define DEBUG_TEX 0x10
+#define DEBUG_FALLBACK 0x20
+#define DEBUG_QUERY 0x40
+#define DEBUG_SCREEN 0x80
+
+#ifdef DEBUG
+extern int ST_DEBUG;
+#define DBSTR(x) x
+#else
+#define ST_DEBUG 0
+#define DBSTR(x) ""
+#endif
+
+void st_debug_init( void );
+
+static INLINE void
+ST_DBG( unsigned flag, const char *fmt, ... )
+{
+ if (ST_DEBUG & flag)
+ {
+ va_list args;
+
+ va_start( args, fmt );
+ debug_vprintf( fmt, args );
+ va_end( args );
+ }
+}
+
+
#endif /* ST_DEBUG_H */
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 503a5f34a3..e13ae57a0e 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -25,10 +25,20 @@
*
**************************************************************************/
- /*
- * Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
- */
+/*
+ * This file implements the st_draw_vbo() function which is called from
+ * Mesa's VBO module. All point/line/triangle rendering is done through
+ * this function whether the user called glBegin/End, glDrawArrays,
+ * glDrawElements, glEvalMesh, or glCalList, etc.
+ *
+ * We basically convert the VBO's vertex attribute/array information into
+ * Gallium vertex state, bind the vertex buffer objects and call
+ * pipe->draw_elements(), pipe->draw_range_elements() or pipe->draw_arrays().
+ *
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
#include "main/imports.h"
#include "main/image.h"
@@ -328,23 +338,29 @@ get_arrays_bounds(const struct st_vertex_program *vp,
const GLubyte **low, const GLubyte **high)
{
const GLubyte *low_addr = NULL;
+ const GLubyte *high_addr = NULL;
GLuint attr;
- GLint stride;
for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
+ const GLint stride = arrays[mesaAttr]->StrideB;
const GLubyte *start = arrays[mesaAttr]->Ptr;
- stride = arrays[mesaAttr]->StrideB;
+ const unsigned sz = (arrays[mesaAttr]->Size *
+ _mesa_sizeof_type(arrays[mesaAttr]->Type));
+ const GLubyte *end = start + (max_index * stride) + sz;
+
if (attr == 0) {
low_addr = start;
+ high_addr = end;
}
else {
low_addr = MIN2(low_addr, start);
+ high_addr = MAX2(high_addr, end);
}
}
*low = low_addr;
- *high = low_addr + (max_index + 1) * stride;
+ *high = high_addr;
}
@@ -557,7 +573,7 @@ st_draw_vbo(GLcontext *ctx,
/* must get these after state validation! */
vp = ctx->st->vp;
- vs = &ctx->st->vp->state;
+ vs = &ctx->st->vp_varient->state;
#if 0
if (MESA_VERBOSE & VERBOSE_GLSL) {
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index b2d682ef64..d793f820bc 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
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 3f835d38dd..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);
@@ -284,6 +288,7 @@ void st_init_extensions(struct st_context *st)
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
+ ctx->Extensions.S3_s3tc = GL_TRUE;
}
/* ycbcr support */
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index dcb90a3107..93125afe9e 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -99,10 +99,11 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
if (format == PIPE_FORMAT_A1R5G5B5_UNORM || format == PIPE_FORMAT_R5G6B5_UNORM) {
pinfo->datatype = GL_UNSIGNED_SHORT;
}
+ else if (format == PIPE_FORMAT_S8Z24_UNORM) {
+ pinfo->datatype = GL_UNSIGNED_INT_24_8;
+ }
else {
- GLuint size;
-
- size = format_max_bits( info );
+ const GLuint size = format_max_bits( info );
if (size == 8) {
if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
pinfo->datatype = GL_UNSIGNED_BYTE;
@@ -150,24 +151,10 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
pinfo->red_bits = 0;
}
- /* Base format */
- if (pinfo->depth_bits) {
- if (pinfo->stencil_bits) {
- pinfo->base_format = GL_DEPTH_STENCIL_EXT;
- }
- else {
- pinfo->base_format = GL_DEPTH_COMPONENT;
- }
- }
- else if (pinfo->stencil_bits) {
- pinfo->base_format = GL_STENCIL_INDEX;
- }
- else {
- pinfo->base_format = GL_RGBA;
- }
+ pinfo->mesa_format = st_pipe_format_to_mesa_format(format);
}
else if (pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR) {
- pinfo->base_format = GL_YCBCR_MESA;
+ pinfo->mesa_format = MESA_FORMAT_YCBCR;
pinfo->datatype = GL_UNSIGNED_SHORT;
pinfo->size = 2; /* two bytes per "texel" */
}
@@ -224,13 +211,15 @@ st_format_datatype(enum pipe_format format)
enum pipe_format
-st_mesa_format_to_pipe_format(GLuint mesaFormat)
+st_mesa_format_to_pipe_format(gl_format mesaFormat)
{
switch (mesaFormat) {
/* fix this */
case MESA_FORMAT_ARGB8888_REV:
case MESA_FORMAT_ARGB8888:
return PIPE_FORMAT_A8R8G8B8_UNORM;
+ case MESA_FORMAT_XRGB8888:
+ return PIPE_FORMAT_X8R8G8B8_UNORM;
case MESA_FORMAT_ARGB1555:
return PIPE_FORMAT_A1R5G5B5_UNORM;
case MESA_FORMAT_ARGB4444:
@@ -293,6 +282,88 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat)
}
}
+
+gl_format
+st_pipe_format_to_mesa_format(enum pipe_format pipeFormat)
+{
+ switch (pipeFormat) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ return MESA_FORMAT_ARGB8888;
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ return MESA_FORMAT_XRGB8888;
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ return MESA_FORMAT_ARGB1555;
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ return MESA_FORMAT_ARGB4444;
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ return MESA_FORMAT_RGB565;
+ case PIPE_FORMAT_A8L8_UNORM:
+ return MESA_FORMAT_AL88;
+ case PIPE_FORMAT_A8_UNORM:
+ return MESA_FORMAT_A8;
+ case PIPE_FORMAT_L8_UNORM:
+ return MESA_FORMAT_L8;
+ case PIPE_FORMAT_I8_UNORM:
+ return MESA_FORMAT_I8;
+ case PIPE_FORMAT_Z16_UNORM:
+ return MESA_FORMAT_Z16;
+ case PIPE_FORMAT_Z32_UNORM:
+ return MESA_FORMAT_Z32;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ return MESA_FORMAT_Z24_X8;
+ case PIPE_FORMAT_Z24S8_UNORM:
+ return MESA_FORMAT_Z24_S8;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ return MESA_FORMAT_X8_Z24;
+ case PIPE_FORMAT_S8Z24_UNORM:
+ return MESA_FORMAT_S8_Z24;
+ case PIPE_FORMAT_S8_UNORM:
+ return MESA_FORMAT_S8;
+
+ case PIPE_FORMAT_YCBCR:
+ return MESA_FORMAT_YCBCR;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return MESA_FORMAT_SIGNED_RGBA_16;
+
+#if FEATURE_texture_s3tc
+ case PIPE_FORMAT_DXT1_RGB:
+ return MESA_FORMAT_RGB_DXT1;
+ case PIPE_FORMAT_DXT1_RGBA:
+ return MESA_FORMAT_RGBA_DXT1;
+ case PIPE_FORMAT_DXT3_RGBA:
+ return MESA_FORMAT_RGBA_DXT3;
+ case PIPE_FORMAT_DXT5_RGBA:
+ return MESA_FORMAT_RGBA_DXT5;
+#if FEATURE_EXT_texture_sRGB
+ case PIPE_FORMAT_DXT1_SRGB:
+ return MESA_FORMAT_SRGB_DXT1;
+ case PIPE_FORMAT_DXT1_SRGBA:
+ return MESA_FORMAT_SRGBA_DXT1;
+ case PIPE_FORMAT_DXT3_SRGBA:
+ return MESA_FORMAT_SRGBA_DXT3;
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return MESA_FORMAT_SRGBA_DXT5;
+#endif
+#endif
+#if FEATURE_EXT_texture_sRGB
+ case PIPE_FORMAT_A8L8_SRGB:
+ return MESA_FORMAT_SLA8;
+ case PIPE_FORMAT_L8_SRGB:
+ return MESA_FORMAT_SL8;
+ case PIPE_FORMAT_R8G8B8_SRGB:
+ return MESA_FORMAT_SRGB8;
+ case PIPE_FORMAT_R8G8B8A8_SRGB:
+ return MESA_FORMAT_SRGBA8;
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ return MESA_FORMAT_SARGB8;
+#endif
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
/**
* Find an RGBA format supported by the context/winsys.
*/
@@ -318,6 +389,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
@@ -392,23 +490,23 @@ default_depth_format(struct pipe_screen *screen,
* or PIPE_TEXTURE_USAGE_SAMPLER
*/
enum pipe_format
-st_choose_format(struct pipe_context *pipe, GLenum internalFormat,
+st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
enum pipe_texture_target target, unsigned tex_usage)
{
- struct pipe_screen *screen = pipe->screen;
unsigned geom_flags = 0;
switch (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 );
@@ -430,7 +528,7 @@ st_choose_format(struct pipe_context *pipe, 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:
@@ -618,85 +716,90 @@ is_depth_or_stencil_format(GLenum internalFormat)
* Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
*/
enum pipe_format
-st_choose_renderbuffer_format(struct pipe_context *pipe, GLenum internalFormat)
+st_choose_renderbuffer_format(struct pipe_screen *screen,
+ GLenum internalFormat)
{
uint usage;
if (is_depth_or_stencil_format(internalFormat))
usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
else
usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- return st_choose_format(pipe, internalFormat, PIPE_TEXTURE_2D, usage);
+ return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, usage);
}
-static const struct gl_texture_format *
+static gl_format
translate_gallium_format_to_mesa_format(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
- return &_mesa_texformat_argb8888;
+ return MESA_FORMAT_ARGB8888;
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ return MESA_FORMAT_XRGB8888;
case PIPE_FORMAT_A1R5G5B5_UNORM:
- return &_mesa_texformat_argb1555;
+ return MESA_FORMAT_ARGB1555;
case PIPE_FORMAT_A4R4G4B4_UNORM:
- return &_mesa_texformat_argb4444;
+ return MESA_FORMAT_ARGB4444;
case PIPE_FORMAT_R5G6B5_UNORM:
- return &_mesa_texformat_rgb565;
+ return MESA_FORMAT_RGB565;
case PIPE_FORMAT_A8L8_UNORM:
- return &_mesa_texformat_al88;
+ return MESA_FORMAT_AL88;
case PIPE_FORMAT_A8_UNORM:
- return &_mesa_texformat_a8;
+ return MESA_FORMAT_A8;
case PIPE_FORMAT_L8_UNORM:
- return &_mesa_texformat_l8;
+ return MESA_FORMAT_L8;
case PIPE_FORMAT_I8_UNORM:
- return &_mesa_texformat_i8;
+ return MESA_FORMAT_I8;
case PIPE_FORMAT_Z16_UNORM:
- return &_mesa_texformat_z16;
+ return MESA_FORMAT_Z16;
case PIPE_FORMAT_Z32_UNORM:
- return &_mesa_texformat_z32;
+ return MESA_FORMAT_Z32;
case PIPE_FORMAT_Z24S8_UNORM:
- return &_mesa_texformat_z24_s8;
+ return MESA_FORMAT_Z24_S8;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ return MESA_FORMAT_X8_Z24;
case PIPE_FORMAT_S8Z24_UNORM:
- return &_mesa_texformat_s8_z24;
+ return MESA_FORMAT_S8_Z24;
case PIPE_FORMAT_YCBCR:
- return &_mesa_texformat_ycbcr;
+ return MESA_FORMAT_YCBCR;
case PIPE_FORMAT_YCBCR_REV:
- return &_mesa_texformat_ycbcr_rev;
+ return MESA_FORMAT_YCBCR_REV;
#if FEATURE_texture_s3tc
case PIPE_FORMAT_DXT1_RGB:
- return &_mesa_texformat_rgb_dxt1;
+ return MESA_FORMAT_RGB_DXT1;
case PIPE_FORMAT_DXT1_RGBA:
- return &_mesa_texformat_rgba_dxt1;
+ return MESA_FORMAT_RGBA_DXT1;
case PIPE_FORMAT_DXT3_RGBA:
- return &_mesa_texformat_rgba_dxt3;
+ return MESA_FORMAT_RGBA_DXT3;
case PIPE_FORMAT_DXT5_RGBA:
- return &_mesa_texformat_rgba_dxt5;
+ return MESA_FORMAT_RGBA_DXT5;
#if FEATURE_EXT_texture_sRGB
case PIPE_FORMAT_DXT1_SRGB:
- return &_mesa_texformat_srgb_dxt1;
+ return MESA_FORMAT_SRGB_DXT1;
case PIPE_FORMAT_DXT1_SRGBA:
- return &_mesa_texformat_srgba_dxt1;
+ return MESA_FORMAT_SRGBA_DXT1;
case PIPE_FORMAT_DXT3_SRGBA:
- return &_mesa_texformat_srgba_dxt3;
+ return MESA_FORMAT_SRGBA_DXT3;
case PIPE_FORMAT_DXT5_SRGBA:
- return &_mesa_texformat_srgba_dxt5;
+ return MESA_FORMAT_SRGBA_DXT5;
#endif
#endif
#if FEATURE_EXT_texture_sRGB
case PIPE_FORMAT_A8L8_SRGB:
- return &_mesa_texformat_sla8;
+ return MESA_FORMAT_SLA8;
case PIPE_FORMAT_L8_SRGB:
- return &_mesa_texformat_sl8;
+ return MESA_FORMAT_SL8;
case PIPE_FORMAT_R8G8B8_SRGB:
- return &_mesa_texformat_srgb8;
+ return MESA_FORMAT_SRGB8;
case PIPE_FORMAT_R8G8B8A8_SRGB:
- return &_mesa_texformat_srgba8;
+ return MESA_FORMAT_SRGBA8;
case PIPE_FORMAT_A8R8G8B8_SRGB:
- return &_mesa_texformat_sargb8;
+ return MESA_FORMAT_SARGB8;
#endif
/* XXX add additional cases */
default:
assert(0);
- return NULL;
+ return MESA_FORMAT_NONE;
}
}
@@ -704,7 +807,7 @@ translate_gallium_format_to_mesa_format(enum pipe_format format)
/**
* Called via ctx->Driver.chooseTextureFormat().
*/
-const struct gl_texture_format *
+gl_format
st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat,
GLenum format, GLenum type)
{
@@ -713,10 +816,10 @@ st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat,
(void) format;
(void) type;
- pFormat = st_choose_format(ctx->st->pipe, internalFormat, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_SAMPLER);
+ pFormat = st_choose_format(ctx->st->pipe->screen, internalFormat,
+ PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_SAMPLER);
if (pFormat == PIPE_FORMAT_NONE)
- return NULL;
+ return MESA_FORMAT_NONE;
return translate_gallium_format_to_mesa_format(pFormat);
}
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 9d9e02fe9b..7cddf5aa66 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -29,11 +29,12 @@
#ifndef ST_FORMAT_H
#define ST_FORMAT_H
+#include "main/formats.h"
struct pipe_format_info
{
enum pipe_format format;
- GLenum base_format;
+ gl_format mesa_format;
GLenum datatype;
GLubyte red_bits;
GLubyte green_bits;
@@ -60,18 +61,22 @@ st_format_datatype(enum pipe_format format);
extern enum pipe_format
-st_mesa_format_to_pipe_format(GLuint mesaFormat);
+st_mesa_format_to_pipe_format(gl_format mesaFormat);
+
+extern gl_format
+st_pipe_format_to_mesa_format(enum pipe_format pipeFormat);
extern enum pipe_format
-st_choose_format(struct pipe_context *pipe, GLenum internalFormat,
+st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
enum pipe_texture_target target, unsigned tex_usage);
extern enum pipe_format
-st_choose_renderbuffer_format(struct pipe_context *pipe, GLenum internalFormat);
+st_choose_renderbuffer_format(struct pipe_screen *screen,
+ GLenum internalFormat);
-extern const struct gl_texture_format *
+extern gl_format
st_ChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
GLenum format, GLenum type);
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index ca32b2e573..a5d1ae3b03 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -52,6 +52,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
struct st_framebuffer *stfb = ST_CALLOC_STRUCT(st_framebuffer);
if (stfb) {
int samples = st_get_msaa();
+ int i;
if (visual->sampleBuffers)
samples = visual->samples;
@@ -66,7 +67,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
else {
/* Only allocate front buffer right now if we're single buffered.
* If double-buffered, allocate front buffer on demand later.
- * See check_create_front_buffers().
+ * See check_create_front_buffers() and st_set_framebuffer_surface().
*/
struct gl_renderbuffer *rb
= st_new_renderbuffer_fb(colorFormat, samples, FALSE);
@@ -119,6 +120,12 @@ st_create_framebuffer( const __GLcontextModes *visual,
_mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
}
+ for (i = 0; i < visual->numAuxBuffers; i++) {
+ struct gl_renderbuffer *aux
+ = st_new_renderbuffer_fb(colorFormat, 0, FALSE);
+ _mesa_add_renderbuffer(&stfb->Base, BUFFER_AUX0 + i, aux);
+ }
+
stfb->Base.Initialized = GL_TRUE;
stfb->InitWidth = width;
stfb->InitHeight = height;
@@ -170,8 +177,20 @@ st_set_framebuffer_surface(struct st_framebuffer *stfb,
strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
- /* fail */
- if (!strb) return;
+ if (!strb) {
+ if (surfIndex == ST_SURFACE_FRONT_LEFT) {
+ /* Delayed creation when the window system supplies a fake front buffer */
+ struct st_renderbuffer *strb_back
+ = st_renderbuffer(stfb->Base.Attachment[ST_SURFACE_BACK_LEFT].Renderbuffer);
+ struct gl_renderbuffer *rb
+ = st_new_renderbuffer_fb(surf->format, strb_back->Base.NumSamples, FALSE);
+ _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
+ strb = st_renderbuffer(rb);
+ } else {
+ /* fail */
+ return;
+ }
+ }
/* replace the renderbuffer's surface/texture pointers */
pipe_surface_reference( &strb->surface, surf );
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 58f6933652..7700551830 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -27,6 +27,7 @@
#include "main/imports.h"
+#include "main/macros.h"
#include "main/mipmap.h"
#include "main/teximage.h"
#include "main/texformat.h"
@@ -37,10 +38,12 @@
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "util/u_gen_mipmap.h"
+#include "util/u_math.h"
#include "cso_cache/cso_cache.h"
#include "cso_cache/cso_context.h"
+#include "st_debug.h"
#include "st_context.h"
#include "st_draw.h"
#include "st_gen_mipmap.h"
@@ -112,6 +115,9 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
uint dstLevel;
GLenum datatype;
GLuint comps;
+
+ if (ST_DEBUG & DEBUG_FALLBACK)
+ debug_printf("%s: fallback processing\n", __FUNCTION__);
assert(target != GL_TEXTURE_3D); /* not done yet */
@@ -128,29 +134,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 / pf_get_blocksize(srcTrans->texture->format);
+ dstStride = dstTrans->stride / pf_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);
@@ -161,6 +171,43 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
}
+/**
+ * Compute the expected number of mipmap levels in the texture given
+ * the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/
+ * GL_TEXTURE_MAX_LEVEL settings. This will tell us how many mipmap
+ * level should be generated.
+ */
+static GLuint
+compute_num_levels(GLcontext *ctx,
+ struct gl_texture_object *texObj,
+ GLenum target)
+{
+ if (target == GL_TEXTURE_RECTANGLE_ARB) {
+ return 1;
+ }
+ else {
+ const GLuint maxLevels = texObj->MaxLevel - texObj->BaseLevel + 1;
+ const struct gl_texture_image *baseImage =
+ _mesa_get_tex_image(ctx, texObj, target, texObj->BaseLevel);
+ GLuint size, numLevels;
+
+ size = MAX2(baseImage->Width2, baseImage->Height2);
+ size = MAX2(size, baseImage->Depth2);
+
+ numLevels = 0;
+
+ while (size > 0) {
+ numLevels++;
+ size >>= 1;
+ }
+
+ numLevels = MIN2(numLevels, maxLevels);
+
+ return numLevels;
+ }
+}
+
+
void
st_generate_mipmap(GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj)
@@ -174,9 +221,49 @@ st_generate_mipmap(GLcontext *ctx, GLenum target,
if (!pt)
return;
- lastLevel = pt->last_level;
+ /* find expected last mipmap level */
+ lastLevel = compute_num_levels(ctx, texObj, target) - 1;
+
+ if (pt->last_level < lastLevel) {
+ /* The current gallium texture doesn't have space for all the
+ * mipmap levels we need to generate. So allocate a new texture.
+ */
+ struct st_texture_object *stObj = st_texture_object(texObj);
+ struct pipe_texture *oldTex = stObj->pt;
+ GLboolean needFlush;
+
+ /* create new texture with space for more levels */
+ stObj->pt = st_texture_create(st,
+ oldTex->target,
+ oldTex->format,
+ lastLevel,
+ oldTex->width0,
+ oldTex->height0,
+ oldTex->depth0,
+ oldTex->tex_usage);
+
+ /* The texture isn't in a "complete" state yet so set the expected
+ * lastLevel here, since it won't get done in st_finalize_texture().
+ */
+ stObj->lastLevel = lastLevel;
+
+ /* This will copy the old texture's base image into the new texture
+ * which we just allocated.
+ */
+ st_finalize_texture(ctx, st->pipe, texObj, &needFlush);
+
+ /* release the old tex (will likely be freed too) */
+ pipe_texture_reference(&oldTex, NULL);
+
+ pt = stObj->pt;
+ }
+
+ assert(lastLevel <= pt->last_level);
- if (!st_render_mipmap(st, target, pt, baseLevel, lastLevel)) {
+ /* Recall that the Mesa BaseLevel image is stored in the gallium
+ * texture's level[0] position. So pass baseLevel=0 here.
+ */
+ if (!st_render_mipmap(st, target, pt, 0, lastLevel)) {
fallback_generate_mipmap(ctx, target, texObj);
}
@@ -187,9 +274,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 04be57f8ff..1611d53e2f 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -151,7 +151,7 @@ dst_register( struct st_translate *t,
return t->address[index];
default:
- assert( 0 );
+ debug_assert( 0 );
return ureg_dst_undef();
}
}
@@ -173,8 +173,9 @@ src_register( struct st_translate *t,
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
+ case PROGRAM_ENV_PARAM:
case PROGRAM_UNIFORM:
- case PROGRAM_CONSTANT:
+ case PROGRAM_CONSTANT: /* ie, immediate */
return t->constants[index];
case PROGRAM_INPUT:
@@ -187,7 +188,7 @@ src_register( struct st_translate *t,
return ureg_src(t->address[index]);
default:
- assert( 0 );
+ debug_assert( 0 );
return ureg_src_undef();
}
}
@@ -216,7 +217,7 @@ translate_texture_target( GLuint textarget,
case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE;
case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT;
default:
- assert( 0 );
+ debug_assert( 0 );
return TGSI_TEXTURE_1D;
}
}
@@ -277,7 +278,7 @@ static struct ureg_src swizzle_4v( struct ureg_src src,
/**
- * Translate SWZ instructions into a single MAD. EG:
+ * Translate a SWZ instruction into a MOV, MUL or MAD instruction. EG:
*
* SWZ dst, src.x-y10
*
@@ -386,7 +387,7 @@ static void emit_swz( struct st_translate *t,
swizzle_4v( imm, add_swizzle ) );
}
else {
- assert(0);
+ debug_assert(0);
}
#undef IMM_ZERO
@@ -395,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 )
@@ -480,14 +498,6 @@ translate_opcode( unsigned op )
return TGSI_OPCODE_MOV;
case OPCODE_MUL:
return TGSI_OPCODE_MUL;
- case OPCODE_NOISE1:
- return TGSI_OPCODE_NOISE1;
- case OPCODE_NOISE2:
- return TGSI_OPCODE_NOISE2;
- case OPCODE_NOISE3:
- return TGSI_OPCODE_NOISE3;
- case OPCODE_NOISE4:
- return TGSI_OPCODE_NOISE4;
case OPCODE_NOP:
return TGSI_OPCODE_NOP;
case OPCODE_NRM3:
@@ -522,8 +532,6 @@ translate_opcode( unsigned op )
return TGSI_OPCODE_SSG;
case OPCODE_SUB:
return TGSI_OPCODE_SUB;
- case OPCODE_SWZ:
- return TGSI_OPCODE_SWZ;
case OPCODE_TEX:
return TGSI_OPCODE_TEX;
case OPCODE_TXB:
@@ -539,7 +547,7 @@ translate_opcode( unsigned op )
case OPCODE_END:
return TGSI_OPCODE_END;
default:
- assert( 0 );
+ debug_assert( 0 );
return TGSI_OPCODE_NOP;
}
}
@@ -578,7 +586,7 @@ compile_instruction(
case OPCODE_ELSE:
case OPCODE_ENDLOOP:
case OPCODE_IF:
- assert(num_dst == 0);
+ debug_assert(num_dst == 0);
ureg_label_insn( ureg,
translate_opcode( inst->Opcode ),
src, num_src,
@@ -615,6 +623,23 @@ compile_instruction(
src, num_src );
break;
+ case OPCODE_NOISE1:
+ case OPCODE_NOISE2:
+ case OPCODE_NOISE3:
+ case OPCODE_NOISE4:
+ /* At some point, a motivated person could add a better
+ * implementation of noise. Currently not even the nvidia
+ * binary drivers do anything more than this. In any case, the
+ * place to do this is in the GL state tracker, not the poor
+ * driver.
+ */
+ 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,
translate_opcode( inst->Opcode ),
@@ -670,6 +695,31 @@ 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);
+}
+
+
+/**
* Translate Mesa program to TGSI format.
* \param program the program to translate
* \param numInputs number of input registers used
@@ -698,12 +748,10 @@ st_translate_mesa_program(
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[] )
+ const ubyte outputSemanticIndex[] )
{
struct st_translate translate, *t;
struct ureg_program *ureg;
@@ -742,6 +790,10 @@ st_translate_mesa_program(
emit_inverted_wpos( t, program );
}
+ if (program->InputsRead & FRAG_BIT_FACE) {
+ emit_face_var( t, program );
+ }
+
/*
* Declare output attributes.
*/
@@ -761,7 +813,7 @@ st_translate_mesa_program(
outputSemanticIndex[i] );
break;
default:
- assert(0);
+ debug_assert(0);
return 0;
}
}
@@ -781,7 +833,7 @@ st_translate_mesa_program(
/* Declare address register.
*/
if (program->NumAddressRegs > 0) {
- assert( program->NumAddressRegs == 1 );
+ debug_assert( program->NumAddressRegs == 1 );
t->address[0] = ureg_DECL_address( ureg );
}
@@ -864,8 +916,19 @@ out:
if (!tokens) {
debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
_mesa_print_program(program);
- assert(0);
+ debug_assert(0);
}
return tokens;
}
+
+
+/**
+ * Tokens cannot be free with _mesa_free otherwise the builtin gallium
+ * malloc debugging will get confused.
+ */
+void
+st_free_tokens(const struct tgsi_token *tokens)
+{
+ FREE((void *)tokens);
+}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h
index 679d0ddd41..dc0362fe79 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.h
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h
@@ -49,12 +49,13 @@ st_translate_mesa_program(
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[] );
+ const ubyte outputSemanticIndex[] );
+
+void
+st_free_tokens(const struct tgsi_token *tokens);
#if defined __cplusplus
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 5f9d2a6dad..5c81a033f9 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -42,6 +42,7 @@
#include "draw/draw_context.h"
#include "tgsi/tgsi_dump.h"
+#include "st_debug.h"
#include "st_context.h"
#include "st_atom.h"
#include "st_program.h"
@@ -49,7 +50,37 @@
#include "cso_cache/cso_context.h"
-#define TGSI_DEBUG 0
+
+/**
+ * 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;
+}
+
+
/**
@@ -60,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 +108,56 @@ 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++;
}
}
-#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,98 +166,62 @@ 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];
}
}
+}
- 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) {
- _mesa_free((void *) 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;
- stvp->state.tokens =
+ vpv->state.tokens =
st_translate_mesa_program(st->ctx,
TGSI_PROCESSOR_VERTEX,
&stvp->Base.Base,
/* inputs */
- vs_num_inputs,
+ stvp->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 );
+ stvp->num_outputs,
+ stvp->result_to_output,
+ stvp->output_semantic_name,
+ stvp->output_semantic_index );
- stvp->num_inputs = vs_num_inputs;
- stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state);
+ vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state);
- if (0)
+ if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
_mesa_print_program(&stvp->Base.Base);
+ debug_printf("\n");
+ }
+
+ if (ST_DEBUG & DEBUG_TGSI) {
+ tgsi_dump( vpv->state.tokens, 0 );
+ debug_printf("\n");
+ }
- if (TGSI_DEBUG)
- tgsi_dump( stvp->state.tokens, 0 );
+ return vpv;
}
@@ -373,7 +244,6 @@ st_translate_fragment_program(struct st_context *st,
GLuint attr;
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
GLuint vslot = 0;
- GLuint num_generic = 0;
uint fs_num_inputs = 0;
@@ -381,13 +251,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;
@@ -430,14 +293,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:
@@ -446,19 +320,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];
}
}
@@ -467,7 +340,7 @@ st_translate_fragment_program(struct st_context *st,
*/
{
uint numColors = 0;
- GLbitfield outputsWritten = stfp->Base.Base.OutputsWritten;
+ GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
/* if z is written, emit that first */
if (outputsWritten & (1 << FRAG_RESULT_DEPTH)) {
@@ -496,8 +369,6 @@ st_translate_fragment_program(struct st_context *st,
break;
}
- output_flags[fs_num_outputs] = stfp->Base.Base.OutputFlags[attr];
-
fs_num_outputs++;
}
}
@@ -516,21 +387,23 @@ 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 );
stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
- if (0)
+ if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
_mesa_print_program(&stfp->Base.Base);
+ debug_printf("\n");
+ }
- if (TGSI_DEBUG)
+ if (ST_DEBUG & DEBUG_TGSI) {
tgsi_dump( stfp->state.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
+ debug_printf("\n");
+ }
}
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index e2e5eddef2..88aadbd751 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -64,41 +64,70 @@ 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
+{
+ char dummy; /* currently unused */
+};
+
+
+/**
+ * This represents a vertex program, especially translated to match
+ * the inputs of a particular fragment shader.
+ */
+struct st_vp_varient
+{
+ /* Parameters which generated this translated version of a vertex
+ * shader:
+ */
+ struct st_vp_varient_key key;
+
+ /** TGSI tokens -- why?
+ */
+ struct pipe_shader_state state;
+
+ /** Driver's compiled shader */
+ void *driver_shader;
+
+ /** For using our private draw module (glRasterPos) */
+ struct draw_vertex_shader *draw_shader;
+
+ /** Next in linked list */
+ struct st_vp_varient *next;
+};
+
+
+
+
/**
* Derived from Mesa gl_fragment_program:
*/
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 +172,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 bbc2830e69..3035d78b61 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -32,8 +32,9 @@
#include "st_cb_fbo.h"
#include "st_inlines.h"
#include "main/enums.h"
-#include "main/texobj.h"
+#include "main/texfetch.h"
#include "main/teximage.h"
+#include "main/texobj.h"
#include "main/texstore.h"
#undef Elements /* fix re-defined macro warning */
@@ -43,6 +44,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "util/u_rect.h"
+#include "util/u_math.h"
#define DBG if(0) printf
@@ -99,10 +101,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);
@@ -128,15 +129,15 @@ st_texture_match_image(const struct pipe_texture *pt,
/* Check if this image's format matches the established texture's format.
*/
- if (st_mesa_format_to_pipe_format(image->TexFormat->MesaFormat) != pt->format)
+ if (st_mesa_format_to_pipe_format(image->TexFormat) != pt->format)
return GL_FALSE;
/* 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;
@@ -240,8 +241,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,
@@ -264,7 +266,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;
@@ -274,15 +276,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);
@@ -300,9 +303,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;
@@ -312,13 +315,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
{
@@ -342,12 +345,21 @@ st_texture_image_copy(struct pipe_context *pipe,
src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i,
PIPE_BUFFER_USAGE_GPU_READ);
- pipe->surface_copy(pipe,
- dst_surface,
- 0, 0, /* destX, Y */
- src_surface,
- 0, 0, /* srcX, Y */
- width, height);
+ if (pipe->surface_copy) {
+ pipe->surface_copy(pipe,
+ dst_surface,
+ 0, 0, /* destX, Y */
+ src_surface,
+ 0, 0, /* srcX, Y */
+ width, height);
+ } else {
+ util_surface_copy(pipe, FALSE,
+ dst_surface,
+ 0, 0, /* destX, Y */
+ src_surface,
+ 0, 0, /* srcX, Y */
+ width, height);
+ }
pipe_surface_reference(&src_surface, NULL);
pipe_surface_reference(&dst_surface, NULL);
@@ -577,7 +589,6 @@ st_teximage_flush_before_map(struct st_context *st,
pipe->is_texture_referenced(pipe, pt, face, level);
if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
- usage == PIPE_TRANSFER_WRITE ||
- usage == PIPE_TRANSFER_READ_WRITE))
- st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ (usage & PIPE_TRANSFER_WRITE)))
+ st->pipe->flush(st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
}