summaryrefslogtreecommitdiffstats
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.c4
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c32
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c18
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c4
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c12
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c145
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c25
-rw-r--r--src/mesa/state_tracker/st_cb_accum.h6
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c147
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.h9
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c33
-rw-r--r--src/mesa/state_tracker/st_cb_blit.h1
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c42
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c8
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c246
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.h11
-rw-r--r--src/mesa/state_tracker/st_cb_drawtex.c3
-rw-r--r--src/mesa/state_tracker/st_cb_drawtex.h1
-rw-r--r--src/mesa/state_tracker/st_cb_eglimage.c1
-rw-r--r--src/mesa/state_tracker/st_cb_eglimage.h1
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c39
-rw-r--r--src/mesa/state_tracker/st_cb_feedback.c1
-rw-r--r--src/mesa/state_tracker/st_cb_feedback.h1
-rw-r--r--src/mesa/state_tracker/st_cb_program.c112
-rw-r--r--src/mesa/state_tracker/st_cb_program.h5
-rw-r--r--src/mesa/state_tracker/st_cb_queryobj.c3
-rw-r--r--src/mesa/state_tracker/st_cb_queryobj.h1
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c1
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.h1
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c17
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.h4
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c90
-rw-r--r--src/mesa/state_tracker/st_cb_texture.h3
-rw-r--r--src/mesa/state_tracker/st_cb_xformfb.c1
-rw-r--r--src/mesa/state_tracker/st_cb_xformfb.h1
-rw-r--r--src/mesa/state_tracker/st_context.c11
-rw-r--r--src/mesa/state_tracker/st_context.h21
-rw-r--r--src/mesa/state_tracker/st_debug.c4
-rw-r--r--src/mesa/state_tracker/st_draw.c13
-rw-r--r--src/mesa/state_tracker/st_draw.h3
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c30
-rw-r--r--src/mesa/state_tracker/st_extensions.c5
-rw-r--r--src/mesa/state_tracker/st_format.c131
-rw-r--r--src/mesa/state_tracker/st_format.h3
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c41
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.h4
-rw-r--r--src/mesa/state_tracker/st_manager.c30
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c43
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.h16
-rw-r--r--src/mesa/state_tracker/st_program.c827
-rw-r--r--src/mesa/state_tracker/st_program.h139
-rw-r--r--src/mesa/state_tracker/st_texture.c54
52 files changed, 1523 insertions, 881 deletions
diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c
index e29ab46ef99..bf160fe1080 100644
--- a/src/mesa/state_tracker/st_atom.c
+++ b/src/mesa/state_tracker/st_atom.c
@@ -147,7 +147,11 @@ void st_validate_state( struct st_context *st )
/*printf("%s %x/%x\n", __FUNCTION__, state->mesa, state->st);*/
+#ifdef NDEBUG
+ if (0) {
+#else
if (1) {
+#endif
/* Debug version which enforces various sanity checks on the
* state flags which are generated and checked to help ensure
* state atoms are ordered correctly in the list.
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 8d1dc792bc8..05667a74305 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -56,7 +56,6 @@ void st_upload_constants( struct st_context *st,
unsigned shader_type)
{
struct pipe_context *pipe = st->pipe;
- struct pipe_resource **cbuf = &st->state.constants[shader_type];
assert(shader_type == PIPE_SHADER_VERTEX ||
shader_type == PIPE_SHADER_FRAGMENT ||
@@ -64,17 +63,24 @@ void st_upload_constants( struct st_context *st,
/* update constants */
if (params && params->NumParameters) {
+ struct pipe_resource *cbuf;
const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
+ /* Update the constants which come from fixed-function state, such as
+ * transformation matrices, fog factors, etc. The rest of the values in
+ * the parameters list are explicitly set by the user with glUniform,
+ * glProgramParameter(), etc.
+ */
_mesa_load_state_parameters(st->ctx, params);
/* We always need to get a new buffer, to keep the drivers simple and
* avoid gratuitous rendering synchronization.
+ * Let's use a user buffer to avoid an unnecessary copy.
*/
- pipe_resource_reference(cbuf, NULL );
- *cbuf = pipe_buffer_create(pipe->screen,
- PIPE_BIND_CONSTANT_BUFFER,
- paramBytes );
+ cbuf = pipe_user_buffer_create(pipe->screen,
+ params->ParameterValues,
+ paramBytes,
+ PIPE_BIND_CONSTANT_BUFFER);
if (ST_DEBUG & DEBUG_CONSTANTS) {
debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
@@ -83,17 +89,15 @@ void st_upload_constants( struct st_context *st,
_mesa_print_parameter_list(params);
}
- /* load Mesa constants into the constant buffer */
- pipe_buffer_write(st->pipe, *cbuf,
- 0, paramBytes,
- params->ParameterValues);
+ st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf);
+ pipe_resource_reference(&cbuf, NULL);
- st->pipe->set_constant_buffer(st->pipe, shader_type, 0, *cbuf);
+ st->state.constants[shader_type].ptr = params->ParameterValues;
+ st->state.constants[shader_type].size = paramBytes;
}
- else if (*cbuf) {
- st->constants.tracked_state[shader_type].dirty.mesa = 0x0;
-
- pipe_resource_reference(cbuf, NULL);
+ else if (st->state.constants[shader_type].ptr) {
+ st->state.constants[shader_type].ptr = NULL;
+ st->state.constants[shader_type].size = 0;
st->pipe->set_constant_buffer(st->pipe, shader_type, 0, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 036bc60049a..2843b7b1764 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -51,7 +51,7 @@ static void
update_renderbuffer_surface(struct st_context *st,
struct st_renderbuffer *strb)
{
- struct pipe_screen *screen = st->pipe->screen;
+ struct pipe_context *pipe = st->pipe;
struct pipe_resource *resource = strb->rtt->pt;
int rtt_width = strb->Base.Width;
int rtt_height = strb->Base.Height;
@@ -65,15 +65,19 @@ update_renderbuffer_surface(struct st_context *st,
for (level = 0; level <= resource->last_level; level++) {
if (u_minify(resource->width0, level) == rtt_width &&
u_minify(resource->height0, level) == rtt_height) {
+ struct pipe_surface surf_tmpl;
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = resource->format;
+ surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+ surf_tmpl.u.tex.level = level;
+ surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
+ surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
pipe_surface_reference(&strb->surface, NULL);
- strb->surface = screen->get_tex_surface(screen,
- resource,
- strb->rtt_face,
- level,
- strb->rtt_slice,
- PIPE_BIND_RENDER_TARGET);
+ strb->surface = pipe->create_surface(pipe,
+ resource,
+ &surf_tmpl);
#if 0
printf("-- alloc new surface %d x %d into tex %p\n",
strb->surface->width, strb->surface->height,
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index 6be03376d01..378b30e57cc 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -122,8 +122,8 @@ load_color_map_texture(struct gl_context *ctx, struct pipe_resource *pt)
uint i, j;
transfer = pipe_get_transfer(st_context(ctx)->pipe,
- pt, 0, 0, 0, PIPE_TRANSFER_WRITE,
- 0, 0, texSize, texSize);
+ pt, 0, 0, PIPE_TRANSFER_WRITE,
+ 0, 0, texSize, texSize);
dest = (uint *) pipe_transfer_map(pipe, transfer);
/* Pack four 1D maps into a 2D texture:
diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c
index f147d768084..b67068df373 100644
--- a/src/mesa/state_tracker/st_atom_sampler.c
+++ b/src/mesa/state_tracker/st_atom_sampler.c
@@ -121,6 +121,18 @@ static void
xlate_border_color(const GLfloat *colorIn, GLenum baseFormat, GLfloat *colorOut)
{
switch (baseFormat) {
+ case GL_RED:
+ colorOut[0] = colorIn[0];
+ colorOut[1] = 0.0F;
+ colorOut[2] = 0.0F;
+ colorOut[3] = 1.0F;
+ break;
+ case GL_RG:
+ colorOut[0] = colorIn[0];
+ colorOut[1] = colorIn[1];
+ colorOut[2] = 0.0F;
+ colorOut[3] = 1.0F;
+ break;
case GL_RGB:
colorOut[0] = colorIn[0];
colorOut[1] = colorIn[1];
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 05442ef91b5..c311d043931 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -50,99 +50,6 @@
#include "st_program.h"
-
-/**
- * Translate fragment program if needed.
- */
-static void
-translate_fp(struct st_context *st,
- struct st_fragment_program *stfp)
-{
- if (!stfp->tgsi.tokens) {
- assert(stfp->Base.Base.NumInstructions > 0);
-
- st_translate_fragment_program(st, stfp);
- }
-}
-
-/*
- * Translate geometry program if needed.
- */
-static void
-translate_gp(struct st_context *st,
- struct st_geometry_program *stgp)
-{
- if (!stgp->tgsi.tokens) {
- assert(stgp->Base.Base.NumInstructions > 1);
-
- st_translate_geometry_program(st, stgp);
- }
-}
-
-/**
- * Find a translated vertex program that corresponds to stvp and
- * has outputs matched to stfp's inputs.
- * This performs vertex and fragment translation (to TGSI) when needed.
- */
-static struct st_vp_varient *
-find_translated_vp(struct st_context *st,
- struct st_vertex_program *stvp )
-{
- struct st_vp_varient *vpv;
- struct st_vp_varient_key key;
-
- /* Nothing in our key yet. This will change:
- */
- memset(&key, 0, sizeof key);
-
- /* When this is true, we will add an extra input to the vertex
- * shader translation (for edgeflags), an extra output with
- * edgeflag semantics, and extend the vertex shader to pass through
- * the input to the output. We'll need to use similar logic to set
- * up the extra vertex_element input for edgeflags.
- * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
- */
- key.passthrough_edgeflags = (st->vertdata_edgeflags && (
- st->ctx->Polygon.FrontMode != GL_FILL ||
- st->ctx->Polygon.BackMode != GL_FILL));
-
-
- /* Do we need to throw away old translations after a change in the
- * GL program string?
- */
- if (stvp->serialNo != stvp->lastSerialNo) {
- /* These may have changed if the program string changed.
- */
- st_prepare_vertex_program( st, stvp );
-
- /* We are now up-to-date:
- */
- stvp->lastSerialNo = stvp->serialNo;
- }
-
- /* See if we've got a translated vertex program whose outputs match
- * the fragment program's inputs.
- */
- for (vpv = stvp->varients; vpv; vpv = vpv->next) {
- if (memcmp(&vpv->key, &key, sizeof key) == 0) {
- break;
- }
- }
-
- /* 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 vpv;
-}
-
-
/**
* Return pointer to a pass-through fragment shader.
* This shader is used when a texture is missing/incomplete.
@@ -167,12 +74,16 @@ static void
update_fp( struct st_context *st )
{
struct st_fragment_program *stfp;
+ struct st_fp_variant_key key;
assert(st->ctx->FragmentProgram._Current);
stfp = st_fragment_program(st->ctx->FragmentProgram._Current);
assert(stfp->Base.Base.Target == GL_FRAGMENT_PROGRAM_ARB);
- translate_fp(st, stfp);
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+
+ st->fp_variant = st_get_fp_variant(st, stfp, &key);
st_reference_fragprog(st, &st->fp, stfp);
@@ -182,7 +93,8 @@ update_fp( struct st_context *st )
cso_set_fragment_shader_handle(st->cso_context, fs);
}
else {
- cso_set_fragment_shader_handle(st->cso_context, stfp->driver_shader);
+ cso_set_fragment_shader_handle(st->cso_context,
+ st->fp_variant->driver_shader);
}
}
@@ -206,6 +118,7 @@ static void
update_vp( struct st_context *st )
{
struct st_vertex_program *stvp;
+ struct st_vp_variant_key key;
/* find active shader and params -- Should be covered by
* ST_NEW_VERTEX_PROGRAM
@@ -214,12 +127,26 @@ update_vp( struct st_context *st )
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);
+ memset(&key, 0, sizeof key);
+ key.st = st; /* variants are per-context */
+
+ /* When this is true, we will add an extra input to the vertex
+ * shader translation (for edgeflags), an extra output with
+ * edgeflag semantics, and extend the vertex shader to pass through
+ * the input to the output. We'll need to use similar logic to set
+ * up the extra vertex_element input for edgeflags.
+ * _NEW_POLYGON, ST_NEW_EDGEFLAGS_DATA
+ */
+ key.passthrough_edgeflags = (st->vertdata_edgeflags && (
+ st->ctx->Polygon.FrontMode != GL_FILL ||
+ st->ctx->Polygon.BackMode != GL_FILL));
+
+ st->vp_variant = st_get_vp_variant(st, stvp, &key);
st_reference_vertprog(st, &st->vp, stvp);
cso_set_vertex_shader_handle(st->cso_context,
- st->vp_varient->driver_shader);
+ st->vp_variant->driver_shader);
st->vertex_result_to_slot = stvp->result_to_output;
}
@@ -231,14 +158,16 @@ const struct st_tracked_state st_update_vp = {
_NEW_POLYGON, /* mesa */
ST_NEW_VERTEX_PROGRAM | ST_NEW_EDGEFLAGS_DATA /* st */
},
- update_vp /* update */
+ update_vp /* update */
};
+
+
static void
update_gp( struct st_context *st )
{
-
struct st_geometry_program *stgp;
+ struct st_gp_variant_key key;
if (!st->ctx->GeometryProgram._Current) {
cso_set_geometry_shader_handle(st->cso_context, NULL);
@@ -248,18 +177,22 @@ update_gp( struct st_context *st )
stgp = st_geometry_program(st->ctx->GeometryProgram._Current);
assert(stgp->Base.Base.Target == MESA_GEOMETRY_PROGRAM);
- translate_gp(st, stgp);
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+
+ st->gp_variant = st_get_gp_variant(st, stgp, &key);
st_reference_geomprog(st, &st->gp, stgp);
- cso_set_geometry_shader_handle(st->cso_context, stgp->driver_shader);
+ cso_set_geometry_shader_handle(st->cso_context,
+ st->gp_variant->driver_shader);
}
const struct st_tracked_state st_update_gp = {
- "st_update_gp", /* name */
- { /* dirty */
- 0, /* mesa */
- ST_NEW_GEOMETRY_PROGRAM /* st */
+ "st_update_gp", /* name */
+ { /* dirty */
+ 0, /* mesa */
+ ST_NEW_GEOMETRY_PROGRAM /* st */
},
- update_gp /* update */
+ update_gp /* update */
};
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 6c5caf42e35..35921f4f614 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -33,6 +33,7 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "st_debug.h"
#include "st_context.h"
@@ -138,10 +139,10 @@ accum_accum(struct st_context *st, GLfloat value,
debug_printf("%s: fallback processing\n", __FUNCTION__);
color_trans = pipe_get_transfer(st->pipe,
- color_strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_READ, xpos, ypos,
- width, height);
+ color_strb->texture,
+ 0, 0,
+ PIPE_TRANSFER_READ, xpos, ypos,
+ width, height);
buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
@@ -187,9 +188,9 @@ accum_load(struct st_context *st, GLfloat value,
debug_printf("%s: fallback processing\n", __FUNCTION__);
color_trans = pipe_get_transfer(st->pipe, color_strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_READ, xpos, ypos,
- width, height);
+ 0, 0,
+ PIPE_TRANSFER_READ, xpos, ypos,
+ width, height);
buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
@@ -241,12 +242,12 @@ accum_return(struct gl_context *ctx, GLfloat value,
usage = PIPE_TRANSFER_READ_WRITE;
else
usage = PIPE_TRANSFER_WRITE;
-
+
color_trans = pipe_get_transfer(st_context(ctx)->pipe,
- color_strb->texture, 0, 0, 0,
- usage,
- xpos, ypos,
- width, height);
+ color_strb->texture, 0, 0,
+ usage,
+ xpos, ypos,
+ width, height);
if (usage & PIPE_TRANSFER_READ)
pipe_get_tile_rgba(pipe, color_trans, 0, 0, width, height, buf);
diff --git a/src/mesa/state_tracker/st_cb_accum.h b/src/mesa/state_tracker/st_cb_accum.h
index b8c9c350031..050a21483e4 100644
--- a/src/mesa/state_tracker/st_cb_accum.h
+++ b/src/mesa/state_tracker/st_cb_accum.h
@@ -30,7 +30,11 @@
#define ST_CB_ACCUM_H
-#include "main/mtypes.h"
+#include "main/mfeatures.h"
+
+struct dd_function_table;
+struct gl_context;
+struct gl_renderbuffer;
#if FEATURE_accum
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 3c0ee6c2883..e23fe86daeb 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -34,6 +34,7 @@
#include "main/image.h"
#include "main/bufferobj.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "program/program.h"
#include "program/prog_print.h"
@@ -185,48 +186,47 @@ find_free_bit(uint bitfield)
/**
* Combine basic bitmap fragment program with the user-defined program.
+ * \param st current context
+ * \param fpIn the incoming fragment program
+ * \param fpOut the new fragment program which does fragment culling
+ * \param bitmap_sampler sampler number for the bitmap texture
*/
-static struct st_fragment_program *
-combined_bitmap_fragment_program(struct gl_context *ctx)
+void
+st_make_bitmap_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut,
+ GLuint *bitmap_sampler)
{
- struct st_context *st = st_context(ctx);
- struct st_fragment_program *stfp = st->fp;
-
- if (!stfp->bitmap_program) {
- /*
- * Generate new program which is the user-defined program prefixed
- * with the bitmap sampler/kill instructions.
- */
- struct st_fragment_program *bitmap_prog;
- uint sampler;
-
- sampler = find_free_bit(st->fp->Base.Base.SamplersUsed);
- bitmap_prog = make_bitmap_fragment_program(ctx, sampler);
+ struct st_fragment_program *bitmap_prog;
+ struct gl_program *newProg;
+ uint sampler;
- stfp->bitmap_program = (struct st_fragment_program *)
- _mesa_combine_programs(ctx,
- &bitmap_prog->Base.Base, &stfp->Base.Base);
- stfp->bitmap_program->bitmap_sampler = sampler;
+ /*
+ * Generate new program which is the user-defined program prefixed
+ * with the bitmap sampler/kill instructions.
+ */
+ sampler = find_free_bit(fpIn->Base.SamplersUsed);
+ bitmap_prog = make_bitmap_fragment_program(st->ctx, sampler);
- /* done with this after combining */
- st_reference_fragprog(st, &bitmap_prog, NULL);
+ newProg = _mesa_combine_programs(st->ctx,
+ &bitmap_prog->Base.Base,
+ &fpIn->Base);
+ /* done with this after combining */
+ st_reference_fragprog(st, &bitmap_prog, NULL);
#if 0
- {
- struct gl_program *p = &stfp->bitmap_program->Base.Base;
- printf("Combined bitmap program:\n");
- _mesa_print_program(p);
- printf("InputsRead: 0x%x\n", p->InputsRead);
- printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
- _mesa_print_parameter_list(p->Parameters);
- }
-#endif
-
- /* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp->bitmap_program);
+ {
+ printf("Combined bitmap program:\n");
+ _mesa_print_program(newProg);
+ printf("InputsRead: 0x%x\n", newProg->InputsRead);
+ printf("OutputsWritten: 0x%x\n", newProg->OutputsWritten);
+ _mesa_print_parameter_list(newProg->Parameters);
}
+#endif
- return stfp->bitmap_program;
+ /* return results */
+ *fpOut = (struct gl_fragment_program *) newProg;
+ *bitmap_sampler = sampler;
}
@@ -283,9 +283,9 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
return NULL;
}
- transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0, width, height);
+ transfer = pipe_get_transfer(st->pipe, pt, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, width, height);
dest = pipe_transfer_map(pipe, transfer);
@@ -349,7 +349,8 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized,
if (!st->bitmap.vbuf) {
st->bitmap.vbuf = pipe_buffer_create(pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
- max_slots * sizeof(st->bitmap.vertices));
+ max_slots *
+ sizeof(st->bitmap.vertices));
}
/* Positions are in clip coords since we need to do clipping in case
@@ -389,10 +390,11 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized,
/* put vertex data into vbuf */
pipe_buffer_write_nooverlap(st->pipe,
- st->bitmap.vbuf,
- st->bitmap.vbuf_slot * sizeof st->bitmap.vertices,
- sizeof st->bitmap.vertices,
- st->bitmap.vertices);
+ st->bitmap.vbuf,
+ st->bitmap.vbuf_slot
+ * sizeof(st->bitmap.vertices),
+ sizeof st->bitmap.vertices,
+ st->bitmap.vertices);
return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices;
}
@@ -411,11 +413,16 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct cso_context *cso = st->cso_context;
- struct st_fragment_program *stfp;
+ struct st_fp_variant *fpv;
+ struct st_fp_variant_key key;
GLuint maxSize;
GLuint offset;
- stfp = combined_bitmap_fragment_program(ctx);
+ memset(&key, 0, sizeof(key));
+ key.st = st;
+ key.bitmap = GL_TRUE;
+
+ fpv = st_get_fp_variant(st, st->fp, &key);
/* As an optimization, Mesa's fragment programs will sometimes get the
* primary color from a statevar/constant rather than a varying variable.
@@ -428,7 +435,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
GLfloat colorSave[4];
COPY_4V(colorSave, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color);
- st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
+ st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
COPY_4V(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], colorSave);
}
@@ -437,7 +444,8 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
/* XXX if the bitmap is larger than the max texture size, break
* it up into chunks.
*/
- maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen,
+ PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
assert(width <= (GLsizei)maxSize);
assert(height <= (GLsizei)maxSize);
@@ -454,7 +462,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_set_rasterizer(cso, &st->bitmap.rasterizer);
/* fragment shader state: TEX lookup program */
- cso_set_fragment_shader_handle(cso, stfp->driver_shader);
+ cso_set_fragment_shader_handle(cso, fpv->driver_shader);
/* vertex shader state: position + texcoord pass-through */
cso_set_vertex_shader_handle(cso, st->bitmap.vs);
@@ -462,21 +470,22 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
/* user samplers, plus our bitmap sampler */
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_samplers);
+ uint num = MAX2(fpv->bitmap_sampler + 1, st->state.num_samplers);
uint i;
for (i = 0; i < st->state.num_samplers; i++) {
samplers[i] = &st->state.samplers[i];
}
- samplers[stfp->bitmap_sampler] = &st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
+ samplers[fpv->bitmap_sampler] =
+ &st->bitmap.samplers[sv->texture->target != PIPE_TEXTURE_RECT];
cso_set_samplers(cso, num, (const struct pipe_sampler_state **) samplers);
}
/* user textures, plus the bitmap texture */
{
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
- uint num = MAX2(stfp->bitmap_sampler + 1, st->state.num_textures);
+ uint num = MAX2(fpv->bitmap_sampler + 1, st->state.num_textures);
memcpy(sampler_views, st->state.sampler_views, sizeof(sampler_views));
- sampler_views[stfp->bitmap_sampler] = sv;
+ sampler_views[fpv->bitmap_sampler] = sv;
cso_set_fragment_sampler_views(cso, num, sampler_views);
}
@@ -504,7 +513,9 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
z = z * 2.0 - 1.0;
/* draw textured quad */
- offset = setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT, x, y, width, height, z, color);
+ offset = setup_bitmap_vertex_data(st,
+ sv->texture->target != PIPE_TEXTURE_RECT,
+ x, y, width, height, z, color);
util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
@@ -573,6 +584,9 @@ print_cache(const struct bitmap_cache *cache)
}
+/**
+ * Create gallium pipe_transfer object for the bitmap cache.
+ */
static void
create_cache_trans(struct st_context *st)
{
@@ -585,10 +599,10 @@ create_cache_trans(struct st_context *st)
/* Map the texture transfer.
* Subsequent glBitmap calls will write into the texture image.
*/
- cache->trans = pipe_get_transfer(st->pipe, cache->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, 0, 0,
- BITMAP_CACHE_WIDTH,
- BITMAP_CACHE_HEIGHT);
+ cache->trans = pipe_get_transfer(st->pipe, cache->texture, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ BITMAP_CACHE_WIDTH,
+ BITMAP_CACHE_HEIGHT);
cache->buffer = pipe_transfer_map(pipe, cache->trans);
/* init image to all 0xff */
@@ -651,7 +665,9 @@ st_flush_bitmap_cache(struct st_context *st)
}
}
-/* Flush bitmap cache and release vertex buffer.
+
+/**
+ * Flush bitmap cache and release vertex buffer.
*/
void
st_flush_bitmap( struct st_context *st )
@@ -737,7 +753,8 @@ accum_bitmap(struct st_context *st,
* Called via ctx->Driver.Bitmap()
*/
static void
-st_Bitmap(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
+st_Bitmap(struct gl_context *ctx, GLint x, GLint y,
+ GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
{
struct st_context *st = st_context(ctx);
@@ -764,7 +781,8 @@ st_Bitmap(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei heigh
pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
if (pt) {
- struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt);
+ struct pipe_sampler_view *sv =
+ st_create_texture_sampler_view(st->pipe, pt);
assert(pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT);
@@ -814,15 +832,18 @@ st_init_bitmap(struct st_context *st)
st->bitmap.rasterizer.gl_rasterization_rules = 1;
/* find a usable texture format */
- if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, PIPE_TEXTURE_2D, 0,
+ if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM,
+ PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, 0)) {
st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM;
}
- else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM, PIPE_TEXTURE_2D, 0,
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM,
+ PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, 0)) {
st->bitmap.tex_format = PIPE_FORMAT_A8_UNORM;
}
- else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, PIPE_TEXTURE_2D, 0,
+ else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM,
+ PIPE_TEXTURE_2D, 0,
PIPE_BIND_SAMPLER_VIEW, 0)) {
st->bitmap.tex_format = PIPE_FORMAT_L8_UNORM;
}
@@ -845,8 +866,6 @@ st_destroy_bitmap(struct st_context *st)
struct pipe_context *pipe = st->pipe;
struct bitmap_cache *cache = st->bitmap.cache;
-
-
if (st->bitmap.vs) {
cso_delete_vertex_shader(st->cso_context, st->bitmap.vs);
st->bitmap.vs = NULL;
diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h
index d04b2b67795..ed141580376 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.h
+++ b/src/mesa/state_tracker/st_cb_bitmap.h
@@ -31,9 +31,12 @@
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
struct st_context;
+struct gl_fragment_program;
+struct st_fragment_program;
#if FEATURE_drawpix
@@ -47,6 +50,12 @@ extern void
st_destroy_bitmap(struct st_context *st);
extern void
+st_make_bitmap_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut,
+ GLuint *bitmap_sampler);
+
+extern void
st_flush_bitmap_cache(struct st_context *st);
/* Flush bitmap cache and release vertex buffer. Needed at end of
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index af41835326a..6d02a7dccd4 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -33,6 +33,7 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "st_context.h"
#include "st_texture.h"
@@ -40,7 +41,6 @@
#include "st_cb_fbo.h"
#include "util/u_blit.h"
-#include "util/u_inlines.h"
void
@@ -115,17 +115,14 @@ st_BlitFramebuffer(struct gl_context *ctx,
st_texture_object(srcAtt->Texture);
struct st_renderbuffer *dstRb =
st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
- struct pipe_subresource srcSub;
struct pipe_surface *dstSurf = dstRb->surface;
if (!srcObj->pt)
return;
- srcSub.face = srcAtt->CubeMapFace;
- srcSub.level = srcAtt->TextureLevel;
-
- util_blit_pixels(st->blit, srcObj->pt, srcSub,
- srcX0, srcY0, srcX1, srcY1, srcAtt->Zoffset,
+ util_blit_pixels(st->blit, srcObj->pt, srcAtt->TextureLevel,
+ srcX0, srcY0, srcX1, srcY1,
+ srcAtt->Zoffset + srcAtt->CubeMapFace,
dstSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
}
@@ -136,14 +133,11 @@ st_BlitFramebuffer(struct gl_context *ctx,
st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
struct pipe_surface *srcSurf = srcRb->surface;
struct pipe_surface *dstSurf = dstRb->surface;
- struct pipe_subresource srcSub;
-
- srcSub.face = srcSurf->face;
- srcSub.level = srcSurf->level;
util_blit_pixels(st->blit,
- srcRb->texture, srcSub, srcX0, srcY0, srcX1, srcY1,
- srcSurf->zslice,
+ srcRb->texture, srcSurf->u.tex.level,
+ srcX0, srcY0, srcX1, srcY1,
+ srcSurf->u.tex.first_layer,
dstSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
}
@@ -176,11 +170,11 @@ st_BlitFramebuffer(struct gl_context *ctx,
/* Blitting depth and stencil values between combined
* depth/stencil buffers. This is the ideal case for such buffers.
*/
- util_blit_pixels(st->blit, srcDepthRb->texture,
- u_subresource(srcDepthRb->surface->face,
- srcDepthRb->surface->level),
+ util_blit_pixels(st->blit,
+ srcDepthRb->texture,
+ srcDepthRb->surface->u.tex.level,
srcX0, srcY0, srcX1, srcY1,
- srcDepthRb->surface->zslice,
+ srcDepthRb->surface->u.tex.first_layer,
dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
}
@@ -189,10 +183,9 @@ st_BlitFramebuffer(struct gl_context *ctx,
if (mask & GL_DEPTH_BUFFER_BIT) {
util_blit_pixels(st->blit, srcDepthRb->texture,
- u_subresource(srcDepthRb->surface->face,
- srcDepthRb->surface->level),
+ srcDepthRb->surface->u.tex.level,
srcX0, srcY0, srcX1, srcY1,
- srcDepthRb->surface->zslice,
+ srcDepthRb->surface->u.tex.first_layer,
dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
0.0, pFilter);
}
diff --git a/src/mesa/state_tracker/st_cb_blit.h b/src/mesa/state_tracker/st_cb_blit.h
index c230652cefc..c6d9a367955 100644
--- a/src/mesa/state_tracker/st_cb_blit.h
+++ b/src/mesa/state_tracker/st_cb_blit.h
@@ -30,6 +30,7 @@
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
struct st_context;
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 27540c36ce7..d4d9af4ada3 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -211,6 +211,13 @@ st_bufferobj_data(struct gl_context *ctx,
/**
+ * Dummy data whose's pointer is used for zero size buffers or ranges.
+ */
+static long st_bufferobj_zero_length = 0;
+
+
+
+/**
* Called via glMapBufferARB().
*/
static void *
@@ -233,10 +240,16 @@ st_bufferobj_map(struct gl_context *ctx, GLenum target, GLenum access,
break;
}
- obj->Pointer = pipe_buffer_map(st_context(ctx)->pipe,
- st_obj->buffer,
- flags,
- &st_obj->transfer);
+ /* Handle zero-size buffers here rather than in drivers */
+ if (obj->Size == 0) {
+ obj->Pointer = &st_bufferobj_zero_length;
+ }
+ else {
+ obj->Pointer = pipe_buffer_map(st_context(ctx)->pipe,
+ st_obj->buffer,
+ flags,
+ &st_obj->transfer);
+ }
if (obj->Pointer) {
obj->Offset = 0;
@@ -247,13 +260,6 @@ st_bufferobj_map(struct gl_context *ctx, GLenum target, GLenum access,
/**
- * Dummy data whose's pointer is used for zero length ranges.
- */
-static long
-st_bufferobj_zero_length_range = 0;
-
-
-/**
* Called via glMapBufferRange().
*/
static void *
@@ -273,6 +279,12 @@ st_bufferobj_map_range(struct gl_context *ctx, GLenum target,
if (access & GL_MAP_FLUSH_EXPLICIT_BIT)
flags |= PIPE_TRANSFER_FLUSH_EXPLICIT;
+
+ if (access & GL_MAP_INVALIDATE_RANGE_BIT)
+ flags |= PIPE_TRANSFER_DISCARD;
+
+ if (access & GL_MAP_INVALIDATE_BUFFER_BIT)
+ flags |= PIPE_TRANSFER_DISCARD;
if (access & GL_MAP_UNSYNCHRONIZED_BIT)
flags |= PIPE_TRANSFER_UNSYNCHRONIZED;
@@ -293,7 +305,7 @@ st_bufferobj_map_range(struct gl_context *ctx, GLenum target,
* length range from the pipe driver.
*/
if (!length) {
- obj->Pointer = &st_bufferobj_zero_length_range;
+ obj->Pointer = &st_bufferobj_zero_length;
}
else {
obj->Pointer = pipe_buffer_map_range(pipe,
@@ -348,7 +360,7 @@ st_bufferobj_unmap(struct gl_context *ctx, GLenum target, struct gl_buffer_objec
struct st_buffer_object *st_obj = st_buffer_object(obj);
if (obj->Length)
- pipe_buffer_unmap(pipe, st_obj->buffer, st_obj->transfer);
+ pipe_buffer_unmap(pipe, st_obj->transfer);
st_obj->transfer = NULL;
obj->Pointer = NULL;
@@ -397,8 +409,8 @@ st_copy_buffer_subdata(struct gl_context *ctx,
if (srcPtr && dstPtr)
memcpy(dstPtr + writeOffset, srcPtr + readOffset, size);
- pipe_buffer_unmap(pipe, srcObj->buffer, src_transfer);
- pipe_buffer_unmap(pipe, dstObj->buffer, dst_transfer);
+ pipe_buffer_unmap(pipe, src_transfer);
+ pipe_buffer_unmap(pipe, dst_transfer);
}
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index bd1dd78b23c..6571bf237fb 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -470,13 +470,9 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
if (mask & (1 << b)) {
struct gl_renderbuffer *rb
= ctx->DrawBuffer->Attachment[b].Renderbuffer;
- struct st_renderbuffer *strb;
+ struct st_renderbuffer *strb = st_renderbuffer(rb);
- assert(rb);
-
- strb = st_renderbuffer(rb);
-
- if (!strb->surface)
+ if (!strb || !strb->surface)
continue;
if (check_clear_color_with_quad( ctx, rb ))
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index d80c068ea81..d128ff98f02 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -34,6 +34,8 @@
#include "main/image.h"
#include "main/bufferobj.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
+#include "main/mtypes.h"
#include "main/pack.h"
#include "main/texformat.h"
#include "main/texstore.h"
@@ -94,88 +96,61 @@ is_passthrough_program(const struct gl_fragment_program *prog)
/**
* Make fragment shader for glDraw/CopyPixels. This shader is made
* by combining the pixel transfer shader with the user-defined shader.
- * \return pointer to Gallium driver fragment shader
+ * \param fpIn the current/incoming fragment program
+ * \param fpOut returns the combined fragment program
*/
-static void *
-combined_drawpix_fragment_program(struct gl_context *ctx)
+void
+st_make_drawpix_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut)
{
- struct st_context *st = st_context(ctx);
- struct st_fragment_program *stfp;
+ struct gl_program *newProg;
- if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn
- && st->fp->serialNo == st->pixel_xfer.user_prog_sn) {
- /* the pixel tranfer program has not changed and the user-defined
- * program has not changed, so re-use the combined program.
- */
- stfp = st->pixel_xfer.combined_prog;
+ if (is_passthrough_program(fpIn)) {
+ newProg = (struct gl_program *) _mesa_clone_fragment_program(st->ctx,
+ &st->pixel_xfer.program->Base);
}
else {
- /* Concatenate the pixel transfer program with the current user-
- * defined program.
- */
- if (is_passthrough_program(&st->fp->Base)) {
- stfp = (struct st_fragment_program *)
- _mesa_clone_fragment_program(ctx, &st->pixel_xfer.program->Base);
- }
- else {
#if 0
- printf("Base program:\n");
- _mesa_print_program(&st->fp->Base.Base);
- printf("DrawPix program:\n");
- _mesa_print_program(&st->pixel_xfer.program->Base.Base);
+ /* debug */
+ printf("Base program:\n");
+ _mesa_print_program(&fpIn->Base);
+ printf("DrawPix program:\n");
+ _mesa_print_program(&st->pixel_xfer.program->Base.Base);
#endif
- stfp = (struct st_fragment_program *)
- _mesa_combine_programs(ctx,
- &st->pixel_xfer.program->Base.Base,
- &st->fp->Base.Base);
- }
+ newProg = _mesa_combine_programs(st->ctx,
+ &st->pixel_xfer.program->Base.Base,
+ &fpIn->Base);
+ }
#if 0
- {
- struct gl_program *p = &stfp->Base.Base;
- printf("Combined DrawPixels program:\n");
- _mesa_print_program(p);
- printf("InputsRead: 0x%x\n", p->InputsRead);
- printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
- _mesa_print_parameter_list(p->Parameters);
- }
+ /* debug */
+ printf("Combined DrawPixels program:\n");
+ _mesa_print_program(newProg);
+ printf("InputsRead: 0x%x\n", newProg->InputsRead);
+ printf("OutputsWritten: 0x%x\n", newProg->OutputsWritten);
+ _mesa_print_parameter_list(newProg->Parameters);
#endif
- /* translate to TGSI tokens */
- st_translate_fragment_program(st, stfp);
-
- /* save new program, update serial numbers */
- st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo;
- st->pixel_xfer.user_prog_sn = st->fp->serialNo;
- st->pixel_xfer.combined_prog_sn = stfp->serialNo;
- /* can't reference new program directly, already have a reference on it */
- st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
- st->pixel_xfer.combined_prog = stfp;
- }
-
- /* Ideally we'd have updated the pipe constants during the normal
- * st/atom mechanism. But we can't since this is specific to glDrawPixels.
- */
- st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
-
- return stfp->driver_shader;
+ *fpOut = (struct gl_fragment_program *) newProg;
}
/**
- * Create fragment shader that does a TEX() instruction to get a Z and/or
+ * Create fragment program that does a TEX() instruction to get a Z and/or
* stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
* Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
* Pass fragment color through as-is.
- * \return pointer to the Gallium driver fragment shader
+ * \return pointer to the gl_fragment program
*/
-static void *
-make_fragment_shader_z_stencil(struct st_context *st, GLboolean write_depth,
- GLboolean write_stencil)
+struct gl_fragment_program *
+st_make_drawpix_z_stencil_program(struct st_context *st,
+ GLboolean write_depth,
+ GLboolean write_stencil)
{
struct gl_context *ctx = st->ctx;
struct gl_program *p;
- struct st_fragment_program *stp;
+ struct gl_fragment_program *fp;
GLuint ic = 0;
const GLuint shaderIndex = write_depth * 2 + write_stencil;
@@ -183,7 +158,7 @@ make_fragment_shader_z_stencil(struct st_context *st, GLboolean write_depth,
if (st->drawpix.shaders[shaderIndex]) {
/* already have the proper shader */
- return st->drawpix.shaders[shaderIndex]->driver_shader;
+ return st->drawpix.shaders[shaderIndex];
}
/*
@@ -245,18 +220,15 @@ make_fragment_shader_z_stencil(struct st_context *st, GLboolean write_depth,
if (write_stencil)
p->SamplersUsed |= 1 << 1;
- stp = st_fragment_program((struct gl_fragment_program *) p);
+ fp = (struct gl_fragment_program *) p;
/* save the new shader */
- st->drawpix.shaders[shaderIndex] = stp;
+ st->drawpix.shaders[shaderIndex] = fp;
- st_translate_fragment_program(st, stp);
-
- return stp->driver_shader;
+ return fp;
}
-
/**
* Create a simple vertex shader that just passes through the
* vertex position and texcoord (and optionally, color).
@@ -427,9 +399,9 @@ make_texture(struct st_context *st,
/* we'll do pixel transfer in a fragment shader */
ctx->_ImageTransferState = 0x0;
- transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 0,
- PIPE_TRANSFER_WRITE, 0, 0,
- width, height);
+ transfer = pipe_get_transfer(st->pipe, pt, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ width, height);
/* map texture transfer */
dest = pipe_transfer_map(pipe, transfer);
@@ -763,9 +735,9 @@ draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
else
usage = PIPE_TRANSFER_WRITE;
- pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0, 0,
- usage, x, y,
- width, height);
+ pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0,
+ usage, x, y,
+ width, height);
stmap = pipe_transfer_map(pipe, pt);
@@ -873,6 +845,61 @@ draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
/**
+ * Get fragment program variant for a glDrawPixels or glCopyPixels
+ * command for RGBA data.
+ */
+static struct st_fp_variant *
+get_color_fp_variant(struct st_context *st)
+{
+ struct gl_context *ctx = st->ctx;
+ struct st_fp_variant_key key;
+ struct st_fp_variant *fpv;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st;
+ key.drawpixels = 1;
+ key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 ||
+ ctx->Pixel.RedScale != 1.0 ||
+ ctx->Pixel.GreenBias != 0.0 ||
+ ctx->Pixel.GreenScale != 1.0 ||
+ ctx->Pixel.BlueBias != 0.0 ||
+ ctx->Pixel.BlueScale != 1.0 ||
+ ctx->Pixel.AlphaBias != 0.0 ||
+ ctx->Pixel.AlphaScale != 1.0);
+ key.pixelMaps = ctx->Pixel.MapColorFlag;
+
+ fpv = st_get_fp_variant(st, st->fp, &key);
+
+ return fpv;
+}
+
+
+/**
+ * Get fragment program variant for a glDrawPixels or glCopyPixels
+ * command for depth/stencil data.
+ */
+static struct st_fp_variant *
+get_depth_stencil_fp_variant(struct st_context *st, GLboolean write_depth,
+ GLboolean write_stencil)
+{
+ struct st_fp_variant_key key;
+ struct st_fp_variant *fpv;
+
+ memset(&key, 0, sizeof(key));
+
+ key.st = st;
+ key.drawpixels = 1;
+ key.drawpixels_z = write_depth;
+ key.drawpixels_stencil = write_stencil;
+
+ fpv = st_get_fp_variant(st, st->fp, &key);
+
+ return fpv;
+}
+
+
+/**
* Called via ctx->Driver.DrawPixels()
*/
static void
@@ -889,6 +916,7 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
struct pipe_sampler_view *sv[2];
int num_sampler_view = 1;
enum pipe_format stencil_format = PIPE_FORMAT_NONE;
+ struct st_fp_variant *fpv;
if (format == GL_DEPTH_STENCIL)
write_stencil = write_depth = GL_TRUE;
@@ -921,14 +949,25 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
st_validate_state(st);
+ /*
+ * Get vertex/fragment shaders
+ */
if (write_depth || write_stencil) {
- driver_fp = make_fragment_shader_z_stencil(st, write_depth, write_stencil);
+ fpv = get_depth_stencil_fp_variant(st, write_depth, write_stencil);
+
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
+
color = ctx->Current.RasterColor;
}
else {
- driver_fp = combined_drawpix_fragment_program(ctx);
+ fpv = get_color_fp_variant(st);
+
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
+
color = NULL;
if (st->pixel_xfer.pixelmap_enabled) {
sv[1] = st->pixel_xfer.pixelmap_sampler_view;
@@ -936,6 +975,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
}
}
+ /* update fragment program constants */
+ st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
+
/* draw with textured quad */
{
struct pipe_resource *pt
@@ -1025,15 +1067,15 @@ copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
usage = PIPE_TRANSFER_READ_WRITE;
else
usage = PIPE_TRANSFER_WRITE;
-
+
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
dsty = rbDraw->Base.Height - dsty - height;
}
ptDraw = pipe_get_transfer(st_context(ctx)->pipe,
- rbDraw->texture, 0, 0, 0,
- usage, dstx, dsty,
- width, height);
+ rbDraw->texture, 0, 0,
+ usage, dstx, dsty,
+ width, height);
assert(util_format_get_blockwidth(ptDraw->resource->format) == 1);
assert(util_format_get_blockheight(ptDraw->resource->format) == 1);
@@ -1116,6 +1158,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
GLint readX, readY, readW, readH;
GLuint sample_count;
struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
+ struct st_fp_variant *fpv;
st_validate_state(st);
@@ -1125,11 +1168,18 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
return;
}
+ /*
+ * Get vertex/fragment shaders
+ */
if (type == GL_COLOR) {
rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
- driver_fp = combined_drawpix_fragment_program(ctx);
+
+ fpv = get_color_fp_variant(st);
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
+
if (st->pixel_xfer.pixelmap_enabled) {
sv[1] = st->pixel_xfer.pixelmap_sampler_view;
num_sampler_view++;
@@ -1139,10 +1189,17 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
assert(type == GL_DEPTH);
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- driver_fp = make_fragment_shader_z_stencil(st, GL_TRUE, GL_FALSE);
+
+ fpv = get_depth_stencil_fp_variant(st, GL_TRUE, GL_FALSE);
+ driver_fp = fpv->driver_shader;
+
driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
}
+ /* update fragment program constants */
+ st_upload_constants(st, fpv->parameters, PIPE_SHADER_FRAGMENT);
+
+
if (rbRead->Base.Wrapped)
rbRead = st_renderbuffer(rbRead->Base.Wrapped);
@@ -1209,27 +1266,24 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
/* Make temporary texture which is a copy of the src region.
*/
if (srcFormat == texFormat) {
- struct pipe_subresource srcsub, dstsub;
- srcsub.face = 0;
- srcsub.level = 0;
- dstsub.face = 0;
- dstsub.level = 0;
- /* copy source framebuffer surface into mipmap/texture */
+ struct pipe_box src_box;
+ u_box_2d(readX, readY, readW, readH, &src_box);
+ /* copy source framebuffer surface into mipmap/texture */
pipe->resource_copy_region(pipe,
pt, /* dest tex */
- dstsub,
+ 0,
pack.SkipPixels, pack.SkipRows, 0, /* dest pos */
rbRead->texture, /* src tex */
- srcsub,
- readX, readY, 0, readW, readH); /* src region */
+ 0,
+ &src_box);
}
else {
/* CPU-based fallback/conversion */
struct pipe_transfer *ptRead =
- pipe_get_transfer(st->pipe, rbRead->texture, 0, 0, 0,
- PIPE_TRANSFER_READ,
- readX, readY, readW, readH);
+ pipe_get_transfer(st->pipe, rbRead->texture, 0, 0,
+ PIPE_TRANSFER_READ,
+ readX, readY, readW, readH);
struct pipe_transfer *ptTex;
enum pipe_transfer_usage transfer_usage;
@@ -1241,8 +1295,8 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
else
transfer_usage = PIPE_TRANSFER_WRITE;
- ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, 0, transfer_usage,
- 0, 0, width, height);
+ ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage,
+ 0, 0, width, height);
/* copy image from ptRead surface to ptTex surface */
if (type == GL_COLOR) {
@@ -1297,7 +1351,7 @@ st_destroy_drawpix(struct st_context *st)
for (i = 0; i < Elements(st->drawpix.shaders); i++) {
if (st->drawpix.shaders[i])
- st_reference_fragprog(st, &st->drawpix.shaders[i], NULL);
+ _mesa_reference_fragprog(st->ctx, &st->drawpix.shaders[i], NULL);
}
st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.h b/src/mesa/state_tracker/st_cb_drawpixels.h
index 575f169e08e..44d7f5ed1e7 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.h
+++ b/src/mesa/state_tracker/st_cb_drawpixels.h
@@ -31,6 +31,7 @@
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
struct st_context;
@@ -42,6 +43,16 @@ extern void st_init_drawpixels_functions(struct dd_function_table *functions);
extern void
st_destroy_drawpix(struct st_context *st);
+extern void
+st_make_drawpix_fragment_program(struct st_context *st,
+ struct gl_fragment_program *fpIn,
+ struct gl_fragment_program **fpOut);
+
+extern struct gl_fragment_program *
+st_make_drawpix_z_stencil_program(struct st_context *st,
+ GLboolean write_depth,
+ GLboolean write_stencil);
+
#else
static INLINE void
diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c
index 6cad7d3216e..b540a79331b 100644
--- a/src/mesa/state_tracker/st_cb_drawtex.c
+++ b/src/mesa/state_tracker/st_cb_drawtex.c
@@ -15,6 +15,7 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "program/program.h"
#include "program/prog_print.h"
@@ -220,7 +221,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
}
}
- pipe_buffer_unmap(pipe, vbuffer, vbuffer_transfer);
+ pipe_buffer_unmap(pipe, vbuffer_transfer);
#undef SET_ATTRIB
}
diff --git a/src/mesa/state_tracker/st_cb_drawtex.h b/src/mesa/state_tracker/st_cb_drawtex.h
index d21262f8977..455da04e674 100644
--- a/src/mesa/state_tracker/st_cb_drawtex.h
+++ b/src/mesa/state_tracker/st_cb_drawtex.h
@@ -11,6 +11,7 @@
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
struct st_context;
diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c
index c4b84de790c..dfde821fc19 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.c
+++ b/src/mesa/state_tracker/st_cb_eglimage.c
@@ -26,6 +26,7 @@
* Chia-I Wu <[email protected]>
*/
+#include "main/mfeatures.h"
#include "main/texobj.h"
#include "main/texfetch.h"
#include "main/teximage.h"
diff --git a/src/mesa/state_tracker/st_cb_eglimage.h b/src/mesa/state_tracker/st_cb_eglimage.h
index b6e44d5aff5..48567ed9da5 100644
--- a/src/mesa/state_tracker/st_cb_eglimage.h
+++ b/src/mesa/state_tracker/st_cb_eglimage.h
@@ -30,6 +30,7 @@
#define ST_CB_EGLIMAGE_H
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 9425f07aee6..0c7641f8623 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -38,6 +38,7 @@
#include "main/fbobject.h"
#include "main/framebuffer.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "main/renderbuffer.h"
#include "pipe/p_context.h"
@@ -52,6 +53,7 @@
#include "util/u_format.h"
#include "util/u_inlines.h"
+#include "util/u_surface.h"
/**
@@ -60,19 +62,23 @@
* during window resize.
*/
static GLboolean
-st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
+st_renderbuffer_alloc_storage(struct gl_context * ctx,
+ struct gl_renderbuffer *rb,
GLenum internalFormat,
GLuint width, GLuint height)
{
struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = st->pipe->screen;
struct st_renderbuffer *strb = st_renderbuffer(rb);
enum pipe_format format;
+ struct pipe_surface surf_tmpl;
if (strb->format != PIPE_FORMAT_NONE)
format = strb->format;
else
- format = st_choose_renderbuffer_format(screen, internalFormat, rb->NumSamples);
+ format = st_choose_renderbuffer_format(screen, internalFormat,
+ rb->NumSamples);
/* init renderbuffer fields */
strb->Base.Width = width;
@@ -113,6 +119,7 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *r
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
+ template.array_size = 1;
template.last_level = 0;
template.nr_samples = rb->NumSamples;
if (util_format_is_depth_or_stencil(format)) {
@@ -120,7 +127,7 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *r
}
else {
template.bind = (PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_RENDER_TARGET);
+ PIPE_BIND_RENDER_TARGET);
}
strb->texture = screen->resource_create(screen, &template);
@@ -128,10 +135,11 @@ st_renderbuffer_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *r
if (!strb->texture)
return FALSE;
- strb->surface = screen->get_tex_surface(screen,
- strb->texture,
- 0, 0, 0,
- template.bind);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, strb->texture, template.bind);
+ strb->surface = pipe->create_surface(pipe,
+ strb->texture,
+ &surf_tmpl);
if (strb->surface) {
assert(strb->surface->texture);
assert(strb->surface->format);
@@ -327,12 +335,12 @@ st_render_texture(struct gl_context *ctx,
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *strb;
struct gl_renderbuffer *rb;
struct pipe_resource *pt = st_get_texobj_resource(att->Texture);
struct st_texture_object *stObj;
const struct gl_texture_image *texImage;
+ struct pipe_surface surf_tmpl;
/* When would this fail? Perhaps assert? */
if (!pt)
@@ -381,12 +389,15 @@ st_render_texture(struct gl_context *ctx,
assert(strb->rtt_level <= strb->texture->last_level);
/* new surface for rendering into the texture */
- strb->surface = screen->get_tex_surface(screen,
- strb->texture,
- strb->rtt_face,
- strb->rtt_level,
- strb->rtt_slice,
- PIPE_BIND_RENDER_TARGET);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = strb->texture->format;
+ surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+ surf_tmpl.u.tex.level = strb->rtt_level;
+ surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
+ surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
+ strb->surface = pipe->create_surface(pipe,
+ strb->texture,
+ &surf_tmpl);
strb->format = pt->format;
diff --git a/src/mesa/state_tracker/st_cb_feedback.c b/src/mesa/state_tracker/st_cb_feedback.c
index 5c01856f033..9b85a39bedd 100644
--- a/src/mesa/state_tracker/st_cb_feedback.c
+++ b/src/mesa/state_tracker/st_cb_feedback.c
@@ -40,6 +40,7 @@
#include "main/imports.h"
#include "main/context.h"
#include "main/feedback.h"
+#include "main/mfeatures.h"
#include "vbo/vbo.h"
diff --git a/src/mesa/state_tracker/st_cb_feedback.h b/src/mesa/state_tracker/st_cb_feedback.h
index f2342f58238..02e34e40271 100644
--- a/src/mesa/state_tracker/st_cb_feedback.h
+++ b/src/mesa/state_tracker/st_cb_feedback.h
@@ -31,6 +31,7 @@
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 4d83fcc6ccb..32694975d17 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -46,16 +46,13 @@
#include "st_cb_program.h"
-static GLuint SerialNo = 1;
-
/**
* Called via ctx->Driver.BindProgram() to bind an ARB vertex or
* fragment program.
*/
-static void st_bind_program( struct gl_context *ctx,
- GLenum target,
- struct gl_program *prog )
+static void
+st_bind_program(struct gl_context *ctx, GLenum target, struct gl_program *prog)
{
struct st_context *st = st_context(ctx);
@@ -77,7 +74,8 @@ static void st_bind_program( struct gl_context *ctx,
* Called via ctx->Driver.UseProgram() to bind a linked GLSL program
* (vertex shader + fragment shader).
*/
-static void st_use_program( struct gl_context *ctx, struct gl_shader_program *shProg)
+static void
+st_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
{
struct st_context *st = st_context(ctx);
@@ -87,48 +85,28 @@ static void st_use_program( struct gl_context *ctx, struct gl_shader_program *sh
}
-
/**
* Called via ctx->Driver.NewProgram() to allocate a new vertex or
* fragment program.
*/
-static struct gl_program *st_new_program( struct gl_context *ctx,
- GLenum target,
- GLuint id )
+static struct gl_program *
+st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
{
switch (target) {
case GL_VERTEX_PROGRAM_ARB: {
struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program);
-
- prog->serialNo = SerialNo++;
-
- return _mesa_init_vertex_program( ctx,
- &prog->Base,
- target,
- id );
+ return _mesa_init_vertex_program(ctx, &prog->Base, target, id);
}
case GL_FRAGMENT_PROGRAM_ARB:
case GL_FRAGMENT_PROGRAM_NV: {
struct st_fragment_program *prog = ST_CALLOC_STRUCT(st_fragment_program);
-
- prog->serialNo = SerialNo++;
-
- return _mesa_init_fragment_program( ctx,
- &prog->Base,
- target,
- id );
+ return _mesa_init_fragment_program(ctx, &prog->Base, target, id);
}
case MESA_GEOMETRY_PROGRAM: {
struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
-
- prog->serialNo = SerialNo++;
-
- return _mesa_init_geometry_program( ctx,
- &prog->Base,
- target,
- id );
+ return _mesa_init_geometry_program(ctx, &prog->Base, target, id);
}
default:
@@ -138,7 +116,10 @@ static struct gl_program *st_new_program( struct gl_context *ctx,
}
-void
+/**
+ * Called via ctx->Driver.DeleteProgram()
+ */
+static void
st_delete_program(struct gl_context *ctx, struct gl_program *prog)
{
struct st_context *st = st_context(ctx);
@@ -147,17 +128,15 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
case GL_VERTEX_PROGRAM_ARB:
{
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
- st_vp_release_varients( st, stvp );
+ st_release_vp_variants( st, stvp );
}
break;
case MESA_GEOMETRY_PROGRAM:
{
- struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
+ struct st_geometry_program *stgp =
+ (struct st_geometry_program *) prog;
- if (stgp->driver_shader) {
- cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
- stgp->driver_shader = NULL;
- }
+ st_release_gp_variants(st, stgp);
if (stgp->tgsi.tokens) {
st_free_tokens((void *) stgp->tgsi.tokens);
@@ -167,23 +146,15 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
break;
case GL_FRAGMENT_PROGRAM_ARB:
{
- struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
+ struct st_fragment_program *stfp =
+ (struct st_fragment_program *) prog;
- if (stfp->driver_shader) {
- cso_delete_fragment_shader(st->cso_context, stfp->driver_shader);
- stfp->driver_shader = NULL;
- }
+ st_release_fp_variants(st, stfp);
if (stfp->tgsi.tokens) {
st_free_tokens(stfp->tgsi.tokens);
stfp->tgsi.tokens = NULL;
}
-
- if (stfp->bitmap_program) {
- struct gl_program *prg = &stfp->bitmap_program->Base.Base;
- _mesa_reference_program(ctx, &prg, NULL);
- stfp->bitmap_program = NULL;
- }
}
break;
default:
@@ -195,15 +166,25 @@ st_delete_program(struct gl_context *ctx, struct gl_program *prog)
}
-static GLboolean st_is_program_native( struct gl_context *ctx,
- GLenum target,
- struct gl_program *prog )
+/**
+ * Called via ctx->Driver.IsProgramNative()
+ */
+static GLboolean
+st_is_program_native(struct gl_context *ctx,
+ GLenum target,
+ struct gl_program *prog)
{
return GL_TRUE;
}
-static GLboolean st_program_string_notify( struct gl_context *ctx,
+/**
+ * Called via ctx->Driver.ProgramStringNotify()
+ * Called when the program's text/code is changed. We have to free
+ * all shader variants and corresponding gallium shaders when this happens.
+ */
+static GLboolean
+st_program_string_notify( struct gl_context *ctx,
GLenum target,
struct gl_program *prog )
{
@@ -212,12 +193,7 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
if (target == GL_FRAGMENT_PROGRAM_ARB) {
struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
- stfp->serialNo++;
-
- if (stfp->driver_shader) {
- cso_delete_fragment_shader(st->cso_context, stfp->driver_shader);
- stfp->driver_shader = NULL;
- }
+ st_release_fp_variants(st, stfp);
if (stfp->tgsi.tokens) {
st_free_tokens(stfp->tgsi.tokens);
@@ -230,12 +206,7 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
else if (target == MESA_GEOMETRY_PROGRAM) {
struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
- stgp->serialNo++;
-
- if (stgp->driver_shader) {
- cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
- stgp->driver_shader = NULL;
- }
+ st_release_gp_variants(st, stgp);
if (stgp->tgsi.tokens) {
st_free_tokens((void *) stgp->tgsi.tokens);
@@ -248,9 +219,7 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
else if (target == GL_VERTEX_PROGRAM_ARB) {
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
- stvp->serialNo++;
-
- st_vp_release_varients( st, stvp );
+ st_release_vp_variants( st, stvp );
if (st->vp == stvp)
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
@@ -261,8 +230,11 @@ static GLboolean st_program_string_notify( struct gl_context *ctx,
}
-
-void st_init_program_functions(struct dd_function_table *functions)
+/**
+ * Plug in the program and shader-related device driver functions.
+ */
+void
+st_init_program_functions(struct dd_function_table *functions)
{
functions->BindProgram = st_bind_program;
functions->UseProgram = st_use_program;
diff --git a/src/mesa/state_tracker/st_cb_program.h b/src/mesa/state_tracker/st_cb_program.h
index 004afb6d812..091a4439c48 100644
--- a/src/mesa/state_tracker/st_cb_program.h
+++ b/src/mesa/state_tracker/st_cb_program.h
@@ -29,15 +29,10 @@
#define ST_CB_PROGRAM_H
-#include "main/mtypes.h"
-
struct dd_function_table;
extern void
st_init_program_functions(struct dd_function_table *functions);
-extern void
-st_delete_program(struct gl_context *ctx, struct gl_program *prog);
-
#endif
diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c
index aa31b3710b5..d0ac253bcec 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.c
+++ b/src/mesa/state_tracker/st_cb_queryobj.c
@@ -35,6 +35,7 @@
#include "main/imports.h"
#include "main/context.h"
+#include "main/mfeatures.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -84,6 +85,8 @@ st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q)
/* convert GL query type to Gallium query type */
switch (q->Target) {
+ case GL_ANY_SAMPLES_PASSED:
+ /* fall-through */
case GL_SAMPLES_PASSED_ARB:
type = PIPE_QUERY_OCCLUSION_COUNTER;
break;
diff --git a/src/mesa/state_tracker/st_cb_queryobj.h b/src/mesa/state_tracker/st_cb_queryobj.h
index 017471b0b06..03f0be8372b 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.h
+++ b/src/mesa/state_tracker/st_cb_queryobj.h
@@ -29,6 +29,7 @@
#define ST_CB_QUERYOBJ_H
+#include "main/mfeatures.h"
#include "main/mtypes.h"
/**
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index 15a4f602d1d..32d465c5cce 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -38,6 +38,7 @@
#include "main/imports.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "main/feedback.h"
#include "st_context.h"
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.h b/src/mesa/state_tracker/st_cb_rasterpos.h
index 2dc109bb184..b61411bd20c 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.h
+++ b/src/mesa/state_tracker/st_cb_rasterpos.h
@@ -30,6 +30,7 @@
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index bcd46ac9d54..0507be74578 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -80,7 +80,7 @@ st_read_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
/* Create a read transfer from the renderbuffer's texture */
pt = pipe_get_transfer(pipe, strb->texture,
- 0, 0, 0, /* face, level, zslice */
+ 0, 0,
PIPE_TRANSFER_READ,
x, y, width, height);
@@ -236,7 +236,7 @@ st_fast_readpixels(struct gl_context *ctx, struct st_renderbuffer *strb,
}
trans = pipe_get_transfer(pipe, strb->texture,
- 0, 0, 0, /* face, level, zslice */
+ 0, 0,
PIPE_TRANSFER_READ,
x, y, width, height);
if (!trans) {
@@ -328,7 +328,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- GLfloat temp[MAX_WIDTH][4];
+ GLfloat (*temp)[4];
const GLbitfield transferOps = ctx->_ImageTransferState;
GLsizei i, j;
GLint yStep, dfStride;
@@ -381,6 +381,13 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
return;
}
+ /* allocate temp pixel row buffer */
+ temp = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+ if (!temp) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
+ return;
+ }
+
if (format == GL_RGBA && type == GL_FLOAT) {
/* write tile(row) directly into user's buffer */
df = (GLfloat *) _mesa_image_address2d(&clippedPacking, dest, width,
@@ -400,7 +407,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
/* Create a read transfer from the renderbuffer's texture */
trans = pipe_get_transfer(pipe, strb->texture,
- 0, 0, 0, /* face, level, zslice */
+ 0, 0,
PIPE_TRANSFER_READ,
x, y, width, height);
@@ -533,6 +540,8 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei h
}
}
+ free(temp);
+
pipe->transfer_destroy(pipe, trans);
_mesa_unmap_pbo_dest(ctx, &clippedPacking);
diff --git a/src/mesa/state_tracker/st_cb_readpixels.h b/src/mesa/state_tracker/st_cb_readpixels.h
index 83c9b659e3d..9622ae6feea 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.h
+++ b/src/mesa/state_tracker/st_cb_readpixels.h
@@ -29,9 +29,11 @@
#ifndef ST_CB_READPIXELS_H
#define ST_CB_READPIXELS_H
-#include "main/mtypes.h"
+#include "main/glheader.h"
struct dd_function_table;
+struct gl_context;
+struct gl_pixelstore_attrib;
extern struct st_renderbuffer *
st_get_color_read_renderbuffer(struct gl_context *ctx);
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 15e69e1fa07..09a10ba5819 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -63,7 +63,7 @@
#include "util/u_surface.h"
#include "util/u_sampler.h"
#include "util/u_math.h"
-
+#include "util/u_box.h"
#define DBG if (0) printf
@@ -431,7 +431,7 @@ compress_with_blit(struct gl_context * ctx,
struct pipe_resource *src_tex;
struct pipe_sampler_view view_templ;
struct pipe_sampler_view *src_view;
- struct pipe_surface *dst_surface;
+ struct pipe_surface *dst_surface, surf_tmpl;
struct pipe_transfer *tex_xfer;
void *map;
@@ -441,9 +441,13 @@ compress_with_blit(struct gl_context * ctx,
}
/* get destination surface (in the compressed texture) */
- dst_surface = screen->get_tex_surface(screen, stImage->pt,
- stImage->face, stImage->level, 0,
- 0 /* flags */);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = stImage->pt->format;
+ surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+ surf_tmpl.u.tex.level = stImage->level;
+ surf_tmpl.u.tex.first_layer = stImage->face;
+ surf_tmpl.u.tex.last_layer = stImage->face;
+ dst_surface = pipe->create_surface(pipe, stImage->pt, &surf_tmpl);
if (!dst_surface) {
/* can't render into this format (or other problem) */
return GL_FALSE;
@@ -464,6 +468,7 @@ compress_with_blit(struct gl_context * ctx,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.last_level = 0;
templ.usage = PIPE_USAGE_DEFAULT;
templ.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -475,9 +480,9 @@ compress_with_blit(struct gl_context * ctx,
/* Put user's tex data into the temporary texture
*/
tex_xfer = pipe_get_transfer(st_context(ctx)->pipe, src_tex,
- 0, 0, 0, /* face, level are zero */
- PIPE_TRANSFER_WRITE,
- 0, 0, width, height); /* x, y, w, h */
+ 0, 0, /* layer, level are zero */
+ PIPE_TRANSFER_WRITE,
+ 0, 0, width, height); /* x, y, w, h */
map = pipe_transfer_map(pipe, tex_xfer);
_mesa_texstore(ctx, 2, GL_RGBA, mesa_format,
@@ -857,7 +862,6 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
{
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
- struct pipe_screen *screen = pipe->screen;
struct st_texture_image *stImage = st_texture_image(texImage);
struct st_texture_object *stObj = st_texture_object(texObj);
struct pipe_sampler_view *src_view =
@@ -871,7 +875,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
PIPE_BIND_TRANSFER_READ);
/* create temp / dest surface */
- if (!util_create_rgba_surface(screen, width, height, bind,
+ if (!util_create_rgba_surface(pipe, width, height, bind,
&dst_texture, &dst_surface)) {
_mesa_problem(ctx, "util_create_rgba_surface() failed "
"in decompress_with_blit()");
@@ -891,9 +895,9 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
/* map the dst_surface so we can read from it */
tex_xfer = pipe_get_transfer(st_context(ctx)->pipe,
- dst_texture, 0, 0, 0,
- PIPE_TRANSFER_READ,
- 0, 0, width, height);
+ dst_texture, 0, 0,
+ PIPE_TRANSFER_READ,
+ 0, 0, width, height);
pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
@@ -1310,7 +1314,7 @@ fallback_copy_texsubimage(struct gl_context *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__);
@@ -1321,11 +1325,11 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
}
src_trans = pipe_get_transfer(st_context(ctx)->pipe,
- strb->texture,
- 0, 0, 0,
- PIPE_TRANSFER_READ,
- srcX, srcY,
- width, height);
+ strb->texture,
+ 0, 0,
+ PIPE_TRANSFER_READ,
+ srcX, srcY,
+ width, height);
if ((baseFormat == GL_DEPTH_COMPONENT ||
baseFormat == GL_DEPTH_STENCIL) &&
@@ -1334,7 +1338,8 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
else
transfer_usage = PIPE_TRANSFER_WRITE;
- texDest = st_texture_image_map(st, stImage, 0, transfer_usage,
+ /* XXX this used to ignore destZ param */
+ texDest = st_texture_image_map(st, stImage, destZ, transfer_usage,
destX, destY, width, height);
if (baseFormat == GL_DEPTH_COMPONENT ||
@@ -1523,6 +1528,9 @@ st_copy_texsubimage(struct gl_context *ctx,
if (texBaseFormat == GL_DEPTH_COMPONENT ||
texBaseFormat == GL_DEPTH_STENCIL) {
strb = st_renderbuffer(fb->_DepthBuffer);
+ if (strb->Base.Wrapped) {
+ strb = st_renderbuffer(strb->Base.Wrapped);
+ }
}
else {
/* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */
@@ -1592,27 +1600,23 @@ st_copy_texsubimage(struct gl_context *ctx,
if (matching_base_formats &&
src_format == dest_format &&
- !do_flip)
+ !do_flip)
{
/* use surface_copy() / blit */
- struct pipe_subresource subdst, subsrc;
- subdst.face = stImage->face;
- subdst.level = stImage->level;
- subsrc.face = strb->surface->face;
- subsrc.level = strb->surface->level;
+ struct pipe_box src_box;
+ u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer,
+ width, height, &src_box);
/* for resource_copy_region(), y=0=top, always */
pipe->resource_copy_region(pipe,
/* dest */
stImage->pt,
- subdst,
- destX, destY, destZ,
+ stImage->level,
+ destX, destY, destZ + stImage->face,
/* src */
strb->texture,
- subsrc,
- srcX, srcY, strb->surface->zslice,
- /* size */
- width, height);
+ strb->surface->u.tex.level,
+ &src_box);
use_fallback = GL_FALSE;
}
else if (format_writemask &&
@@ -1628,12 +1632,16 @@ st_copy_texsubimage(struct gl_context *ctx,
0)) {
/* draw textured quad to do the copy */
GLint srcY0, srcY1;
- struct pipe_subresource subsrc;
+ struct pipe_surface surf_tmpl;
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = stImage->pt->format;
+ surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
+ surf_tmpl.u.tex.level = stImage->level;
+ surf_tmpl.u.tex.first_layer = stImage->face + destZ;
+ surf_tmpl.u.tex.last_layer = stImage->face + destZ;
- dest_surface = screen->get_tex_surface(screen, stImage->pt,
- stImage->face, stImage->level,
- destZ,
- PIPE_BIND_RENDER_TARGET);
+ dest_surface = pipe->create_surface(pipe, stImage->pt,
+ &surf_tmpl);
if (do_flip) {
srcY1 = strb->Base.Height - srcY - height;
@@ -1643,15 +1651,13 @@ st_copy_texsubimage(struct gl_context *ctx,
srcY0 = srcY;
srcY1 = srcY0 + height;
}
- subsrc.face = strb->surface->face;
- subsrc.level = strb->surface->level;
util_blit_pixels_writemask(st->blit,
strb->texture,
- subsrc,
+ strb->surface->u.tex.level,
srcX, srcY0,
srcX + width, srcY1,
- strb->surface->zslice,
+ strb->surface->u.tex.first_layer,
dest_surface,
destX, destY,
destX + width, destY + height,
@@ -1853,7 +1859,7 @@ st_finalize_texture(struct gl_context *ctx,
*/
if (firstImage->pt &&
firstImage->pt != stObj->pt &&
- firstImage->pt->last_level >= stObj->lastLevel) {
+ (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
pipe_resource_reference(&stObj->pt, firstImage->pt);
pipe_sampler_view_reference(&stObj->sampler_view, NULL);
}
diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h
index 60987055eb1..f1502bda788 100644
--- a/src/mesa/state_tracker/st_cb_texture.h
+++ b/src/mesa/state_tracker/st_cb_texture.h
@@ -31,9 +31,10 @@
#include "main/glheader.h"
-#include "main/mtypes.h"
struct dd_function_table;
+struct gl_context;
+struct gl_texture_object;
struct pipe_context;
struct st_context;
diff --git a/src/mesa/state_tracker/st_cb_xformfb.c b/src/mesa/state_tracker/st_cb_xformfb.c
index 838a0a4a934..e415b186aa7 100644
--- a/src/mesa/state_tracker/st_cb_xformfb.c
+++ b/src/mesa/state_tracker/st_cb_xformfb.c
@@ -35,6 +35,7 @@
#include "main/imports.h"
#include "main/context.h"
+#include "main/mfeatures.h"
#include "main/transformfeedback.h"
#include "st_cb_xformfb.h"
diff --git a/src/mesa/state_tracker/st_cb_xformfb.h b/src/mesa/state_tracker/st_cb_xformfb.h
index 574cf481e18..1215ebea871 100644
--- a/src/mesa/state_tracker/st_cb_xformfb.h
+++ b/src/mesa/state_tracker/st_cb_xformfb.h
@@ -30,6 +30,7 @@
#include "main/compiler.h"
+#include "main/mfeatures.h"
struct dd_function_table;
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index d6628b1bff0..c7f3949bf9e 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -207,12 +207,6 @@ static void st_destroy_context_priv( struct st_context *st )
pipe_sampler_view_reference(&st->state.sampler_views[i], NULL);
}
- for (i = 0; i < Elements(st->state.constants); i++) {
- if (st->state.constants[i]) {
- pipe_resource_reference(&st->state.constants[i], NULL);
- }
- }
-
if (st->default_texture) {
st->ctx->Driver.DeleteTexture(st->ctx, st->default_texture);
st->default_texture = NULL;
@@ -244,14 +238,15 @@ void st_destroy_context( struct st_context *st )
pipe->set_index_buffer(pipe, NULL);
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, NULL);
- pipe_resource_reference(&st->state.constants[PIPE_SHADER_VERTEX], NULL);
+ pipe->set_constant_buffer(pipe, i, 0, NULL);
}
_mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache);
_vbo_DestroyContext(st->ctx);
+ st_destroy_program_variants(st);
+
_mesa_free_context_data(ctx);
st_destroy_context_priv(st);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index d342c0cff1e..64a8f790e22 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -1,4 +1,3 @@
-//struct dd_function_table;
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
@@ -93,7 +92,10 @@ struct st_context
struct pipe_sampler_state samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state *sampler_list[PIPE_MAX_SAMPLERS];
struct pipe_clip_state clip;
- struct pipe_resource *constants[PIPE_SHADER_TYPES];
+ struct {
+ void *ptr;
+ unsigned size;
+ } constants[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_scissor_state scissor;
@@ -106,15 +108,6 @@ struct st_context
GLuint poly_stipple[32]; /**< In OpenGL's bottom-to-top order */
} state;
- struct {
- struct st_tracked_state tracked_state[PIPE_SHADER_TYPES];
- } constants;
-
- /* XXX unused: */
- struct {
- struct gl_fragment_program *fragment_program;
- } cb;
-
char vendor[100];
char renderer[100];
@@ -130,7 +123,9 @@ struct st_context
struct st_fragment_program *fp; /**< Currently bound fragment program */
struct st_geometry_program *gp; /**< Currently bound geometry program */
- struct st_vp_varient *vp_varient;
+ struct st_vp_variant *vp_variant;
+ struct st_fp_variant *fp_variant;
+ struct st_gp_variant *gp_variant;
struct gl_texture_object *default_texture;
@@ -160,7 +155,7 @@ struct st_context
/** for glDraw/CopyPixels */
struct {
- struct st_fragment_program *shaders[4];
+ struct gl_fragment_program *shaders[4];
void *vert_shaders[2]; /**< ureg shaders */
} drawpix;
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index df32491d044..e1e373d07d4 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -89,8 +89,8 @@ st_print_current(void)
}
#endif
- if (st->vp->varients)
- tgsi_dump( st->vp->varients[0].tgsi.tokens, 0 );
+ if (st->vp->variants)
+ tgsi_dump( st->vp->variants[0].tgsi.tokens, 0 );
if (st->vp->Base.Base.Parameters)
_mesa_print_parameter_list(st->vp->Base.Base.Parameters);
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 61a0e1b0877..db70daacc48 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -43,6 +43,7 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "program/prog_uniform.h"
#include "vbo/vbo.h"
@@ -241,7 +242,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
*/
static GLboolean
is_interleaved_arrays(const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLboolean *userSpace)
{
@@ -297,7 +298,7 @@ is_interleaved_arrays(const struct st_vertex_program *vp,
*/
static void
get_arrays_bounds(const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
const GLubyte **low, const GLubyte **high)
@@ -343,7 +344,7 @@ get_arrays_bounds(const struct st_vertex_program *vp,
static void
setup_interleaved_attribs(struct gl_context *ctx,
const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
GLboolean userSpace,
@@ -409,7 +410,7 @@ setup_interleaved_attribs(struct gl_context *ctx,
static void
setup_non_interleaved_attribs(struct gl_context *ctx,
const struct st_vertex_program *vp,
- const struct st_vp_varient *vpv,
+ const struct st_vp_variant *vpv,
const struct gl_client_array **arrays,
GLuint max_index,
GLboolean *userSpace,
@@ -617,7 +618,7 @@ st_draw_vbo(struct gl_context *ctx,
struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
const struct st_vertex_program *vp;
- const struct st_vp_varient *vpv;
+ const struct st_vp_variant *vpv;
struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS];
GLuint attr;
struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
@@ -650,7 +651,7 @@ st_draw_vbo(struct gl_context *ctx,
/* must get these after state validation! */
vp = st->vp;
- vpv = st->vp_varient;
+ vpv = st->vp_variant;
#if 0
if (MESA_VERBOSE & VERBOSE_GLSL) {
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
index 2e4c468cff5..5d3c278228f 100644
--- a/src/mesa/state_tracker/st_draw.h
+++ b/src/mesa/state_tracker/st_draw.h
@@ -36,10 +36,11 @@
#include "main/compiler.h"
#include "main/glheader.h"
-#include "main/mtypes.h"
struct _mesa_index_buffer;
struct _mesa_prim;
+struct gl_client_array;
+struct gl_context;
struct st_context;
void st_init_draw( struct st_context *st );
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 7f392fc4916..4e76a050701 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -28,6 +28,7 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "vbo/vbo.h"
@@ -109,9 +110,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
struct pipe_index_buffer ibuffer;
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
struct pipe_transfer *ib_transfer = NULL;
- struct pipe_transfer *cb_transfer;
GLuint attr, i;
- ubyte *mapped_constants;
const void *mapped_indices = NULL;
assert(draw);
@@ -123,10 +122,10 @@ st_feedback_draw_vbo(struct gl_context *ctx,
/* must get these after state validation! */
vp = st->vp;
- vs = &st->vp_varient->tgsi;
+ vs = &st->vp_variant->tgsi;
- if (!st->vp_varient->draw_shader) {
- st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs);
+ if (!st->vp_variant->draw_shader) {
+ st->vp_variant->draw_shader = draw_create_vertex_shader(draw, vs);
}
/*
@@ -139,7 +138,7 @@ st_feedback_draw_vbo(struct gl_context *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, NULL);
- draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
+ draw_bind_vertex_shader(draw, st->vp_variant->draw_shader);
set_feedback_vertex_format(ctx);
/* loop over TGSI shader inputs to determine vertex buffer
@@ -242,14 +241,10 @@ st_feedback_draw_vbo(struct gl_context *ctx,
draw_set_mapped_index_buffer(draw, mapped_indices);
}
- /* map constant buffers */
- mapped_constants = pipe_buffer_map(pipe,
- st->state.constants[PIPE_SHADER_VERTEX],
- PIPE_TRANSFER_READ,
- &cb_transfer);
+ /* set the constant buffer */
draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX, 0,
- mapped_constants,
- st->state.constants[PIPE_SHADER_VERTEX]->width0);
+ st->state.constants[PIPE_SHADER_VERTEX].ptr,
+ st->state.constants[PIPE_SHADER_VERTEX].size);
/* draw here */
@@ -258,17 +253,12 @@ st_feedback_draw_vbo(struct gl_context *ctx,
}
- /* unmap constant buffers */
- pipe_buffer_unmap(pipe, st->state.constants[PIPE_SHADER_VERTEX],
- cb_transfer);
-
/*
* unmap vertex/index buffers
*/
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (draw->pt.vertex_buffer[i].buffer) {
- pipe_buffer_unmap(pipe, draw->pt.vertex_buffer[i].buffer,
- vb_transfer[i]);
+ pipe_buffer_unmap(pipe, vb_transfer[i]);
pipe_resource_reference(&draw->pt.vertex_buffer[i].buffer, NULL);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
@@ -279,7 +269,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
draw_set_index_buffer(draw, NULL);
if (ib_transfer)
- pipe_buffer_unmap(pipe, ibuffer.buffer, ib_transfer);
+ pipe_buffer_unmap(pipe, ib_transfer);
pipe_resource_reference(&ibuffer.buffer, NULL);
}
}
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 37a0aa2bc9f..df4f5cf8b5c 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -29,6 +29,7 @@
#include "main/imports.h"
#include "main/context.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -224,6 +225,7 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
ctx->Extensions.ARB_fragment_program = GL_TRUE;
+ ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
ctx->Extensions.ARB_multisample = GL_TRUE;
ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; /* XXX temp */
@@ -343,6 +345,7 @@ void st_init_extensions(struct st_context *st)
if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
ctx->Extensions.ARB_occlusion_query = GL_TRUE;
+ ctx->Extensions.ARB_occlusion_query2 = GL_TRUE;
}
if (screen->get_param(screen, PIPE_CAP_TIMER_QUERY)) {
ctx->Extensions.EXT_timer_query = GL_TRUE;
@@ -442,7 +445,9 @@ void st_init_extensions(struct st_context *st)
#endif
if (screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) {
+#if 0 /* XXX re-enable when GLSL compiler again supports geometry shaders */
ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
+#endif
}
if (screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 955d821a657..2e0a664dd01 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -37,6 +37,7 @@
#include "main/texstore.h"
#include "main/image.h"
#include "main/macros.h"
+#include "main/mfeatures.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -146,14 +147,28 @@ st_mesa_format_to_pipe_format(gl_format mesaFormat)
return PIPE_FORMAT_B4G4R4A4_UNORM;
case MESA_FORMAT_RGB565:
return PIPE_FORMAT_B5G6R5_UNORM;
+ case MESA_FORMAT_RGB332:
+ return PIPE_FORMAT_B2G3R3_UNORM;
+ case MESA_FORMAT_ARGB2101010:
+ return PIPE_FORMAT_B10G10R10A2_UNORM;
+ case MESA_FORMAT_AL44:
+ return PIPE_FORMAT_L4A4_UNORM;
case MESA_FORMAT_AL88:
return PIPE_FORMAT_L8A8_UNORM;
+ case MESA_FORMAT_AL1616:
+ return PIPE_FORMAT_L16A16_UNORM;
case MESA_FORMAT_A8:
return PIPE_FORMAT_A8_UNORM;
+ case MESA_FORMAT_A16:
+ return PIPE_FORMAT_A16_UNORM;
case MESA_FORMAT_L8:
return PIPE_FORMAT_L8_UNORM;
+ case MESA_FORMAT_L16:
+ return PIPE_FORMAT_L16_UNORM;
case MESA_FORMAT_I8:
return PIPE_FORMAT_I8_UNORM;
+ case MESA_FORMAT_I16:
+ return PIPE_FORMAT_I16_UNORM;
case MESA_FORMAT_Z16:
return PIPE_FORMAT_Z16_UNORM;
case MESA_FORMAT_Z32:
@@ -261,14 +276,28 @@ st_pipe_format_to_mesa_format(enum pipe_format format)
return MESA_FORMAT_ARGB4444;
case PIPE_FORMAT_B5G6R5_UNORM:
return MESA_FORMAT_RGB565;
+ case PIPE_FORMAT_B2G3R3_UNORM:
+ return MESA_FORMAT_RGB332;
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ return MESA_FORMAT_ARGB2101010;
+ case PIPE_FORMAT_L4A4_UNORM:
+ return MESA_FORMAT_AL44;
case PIPE_FORMAT_L8A8_UNORM:
return MESA_FORMAT_AL88;
+ case PIPE_FORMAT_L16A16_UNORM:
+ return MESA_FORMAT_AL1616;
case PIPE_FORMAT_A8_UNORM:
return MESA_FORMAT_A8;
+ case PIPE_FORMAT_A16_UNORM:
+ return MESA_FORMAT_A16;
case PIPE_FORMAT_L8_UNORM:
return MESA_FORMAT_L8;
+ case PIPE_FORMAT_L16_UNORM:
+ return MESA_FORMAT_L16;
case PIPE_FORMAT_I8_UNORM:
return MESA_FORMAT_I8;
+ case PIPE_FORMAT_I16_UNORM:
+ return MESA_FORMAT_I16;
case PIPE_FORMAT_S8_USCALED:
return MESA_FORMAT_S8;
@@ -469,17 +498,27 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
unsigned geom_flags = 0; /* we don't care about POT vs. NPOT here, yet */
switch (internalFormat) {
+ case GL_RGB10:
+ case GL_RGB10_A2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B10G10R10A2_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B10G10R10A2_UNORM;
+ /* Pass through. */
case 4:
case GL_RGBA:
case GL_RGBA8:
- case GL_RGB10_A2:
return default_rgba_format( screen, target, sample_count, bindings,
geom_flags );
case 3:
case GL_RGB:
+ case GL_RGB8:
return default_rgb_format( screen, target, sample_count, bindings,
geom_flags );
+
+ case GL_RGB12:
+ case GL_RGB16:
case GL_RGBA12:
case GL_RGBA16:
if (screen->is_format_supported( screen, PIPE_FORMAT_R16G16B16A16_UNORM,
@@ -506,16 +545,14 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return default_rgba_format( screen, target, sample_count, bindings,
geom_flags );
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return default_rgb_format( screen, target, sample_count, bindings,
- geom_flags );
-
+ case GL_R3_G3_B2:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_B2G3R3_UNORM,
+ target, sample_count, bindings,
+ geom_flags ))
+ return PIPE_FORMAT_B2G3R3_UNORM;
+ /* Pass through. */
case GL_RGB5:
case GL_RGB4:
- case GL_R3_G3_B2:
if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM,
target, sample_count, bindings,
geom_flags ))
@@ -527,11 +564,15 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return default_rgba_format( screen, target, sample_count, bindings,
geom_flags );
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_A16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_A16_UNORM;
+ /* Pass through. */
case GL_ALPHA:
case GL_ALPHA4:
case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
case GL_COMPRESSED_ALPHA:
if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target,
sample_count, bindings, geom_flags ))
@@ -539,12 +580,16 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return default_rgba_format( screen, target, sample_count, bindings,
geom_flags );
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L16_UNORM;
+ /* Pass through. */
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE4:
case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target,
sample_count, bindings, geom_flags ))
@@ -552,14 +597,17 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return default_rgba_format( screen, target, sample_count, bindings,
geom_flags );
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L16A16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L16A16_UNORM;
+ /* Pass through. */
case 2:
case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
case GL_LUMINANCE6_ALPHA2:
case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
case GL_COMPRESSED_LUMINANCE_ALPHA:
if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
sample_count, bindings, geom_flags ))
@@ -567,11 +615,25 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return default_rgba_format( screen, target, sample_count, bindings,
geom_flags );
+ case GL_LUMINANCE4_ALPHA4:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L4A4_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L4A4_UNORM;
+ if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_L8A8_UNORM;
+ return default_rgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ if (screen->is_format_supported( screen, PIPE_FORMAT_I16_UNORM, target,
+ sample_count, bindings, geom_flags ))
+ return PIPE_FORMAT_I16_UNORM;
+ /* Pass through. */
case GL_INTENSITY:
case GL_INTENSITY4:
case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
case GL_COMPRESSED_INTENSITY:
if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target,
sample_count, bindings, geom_flags ))
@@ -680,10 +742,10 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
case GL_DEPTH_COMPONENT:
{
static const enum pipe_format formats[] = {
- PIPE_FORMAT_Z16_UNORM,
PIPE_FORMAT_Z32_UNORM,
PIPE_FORMAT_Z24_UNORM_S8_USCALED,
- PIPE_FORMAT_S8_USCALED_Z24_UNORM
+ PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+ PIPE_FORMAT_Z16_UNORM
};
return find_supported_format(screen, formats, Elements(formats),
target, sample_count, bindings, geom_flags);
@@ -717,18 +779,30 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
case GL_SRGB_EXT:
case GL_SRGB8_EXT:
- case GL_COMPRESSED_SRGB_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_EXT:
case GL_SRGB_ALPHA_EXT:
case GL_SRGB8_ALPHA8_EXT:
return default_srgba_format( screen, target, sample_count, bindings,
geom_flags );
+
+ case GL_COMPRESSED_SRGB_EXT:
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
- return PIPE_FORMAT_DXT1_SRGB;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_SRGB, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_DXT1_SRGB;
+ return default_srgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
return PIPE_FORMAT_DXT1_SRGBA;
+
+ case GL_COMPRESSED_SRGB_ALPHA_EXT:
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
- return PIPE_FORMAT_DXT3_SRGBA;
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_SRGBA, target,
+ sample_count, bindings, geom_flags))
+ return PIPE_FORMAT_DXT3_SRGBA;
+ return default_srgba_format( screen, target, sample_count, bindings,
+ geom_flags );
+
case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
return PIPE_FORMAT_DXT5_SRGBA;
@@ -955,8 +1029,13 @@ gl_format
st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat,
GLenum format, GLenum type)
{
+ boolean want_renderable =
+ internalFormat == 3 || internalFormat == 4 ||
+ internalFormat == GL_RGB || internalFormat == GL_RGBA ||
+ internalFormat == GL_RGB8 || internalFormat == GL_RGBA8;
+
return st_ChooseTextureFormat_renderable(ctx, internalFormat,
- format, type, GL_TRUE);
+ format, type, want_renderable);
}
/**
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 43fa59b1006..fe195c1069b 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -31,11 +31,12 @@
#define ST_FORMAT_H
#include "main/formats.h"
-#include "main/mtypes.h"
+#include "main/glheader.h"
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
+struct gl_context;
struct pipe_screen;
extern GLenum
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 1fc4f40488f..c5f6008a222 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -79,11 +79,15 @@ st_render_mipmap(struct st_context *st,
const uint face = _mesa_tex_target_to_face(target);
assert(psv->texture == stObj->pt);
- assert(target != GL_TEXTURE_3D); /* not done yet */
+#if 0
+ assert(target != GL_TEXTURE_3D); /* implemented but untested */
+#endif
/* check if we can render in the texture's format */
- if (!screen->is_format_supported(screen, psv->format, psv->texture->target, 0,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ /* XXX should probably kill this and always use util_gen_mipmap
+ since this implements a sw fallback as well */
+ if (!screen->is_format_supported(screen, psv->format, psv->texture->target,
+ 0, PIPE_BIND_RENDER_TARGET, 0)) {
return FALSE;
}
@@ -161,12 +165,12 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
struct pipe_resource *pt = st_get_texobj_resource(texObj);
const uint baseLevel = texObj->BaseLevel;
const uint lastLevel = pt->last_level;
- const uint face = _mesa_tex_target_to_face(target), zslice = 0;
+ const uint face = _mesa_tex_target_to_face(target);
uint dstLevel;
GLenum datatype;
GLuint comps;
GLboolean compressed;
-
+
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
@@ -198,16 +202,15 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
ubyte *dstData;
int srcStride, dstStride;
- srcTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, face,
- srcLevel, zslice,
- PIPE_TRANSFER_READ, 0, 0,
- srcWidth, srcHeight);
-
+ srcTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, srcLevel,
+ face,
+ PIPE_TRANSFER_READ, 0, 0,
+ srcWidth, srcHeight);
- dstTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, face,
- dstLevel, zslice,
- PIPE_TRANSFER_WRITE, 0, 0,
- dstWidth, dstHeight);
+ dstTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, dstLevel,
+ face,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ dstWidth, dstHeight);
srcData = (ubyte *) pipe_transfer_map(pipe, srcTrans);
dstData = (ubyte *) pipe_transfer_map(pipe, dstTrans);
@@ -215,6 +218,8 @@ fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
srcStride = srcTrans->stride / util_format_get_blocksize(srcTrans->resource->format);
dstStride = dstTrans->stride / util_format_get_blocksize(dstTrans->resource->format);
+ /* this cannot work correctly for 3d since it does
+ not respect layerStride. */
if (compressed) {
const enum pipe_format format = pt->format;
const uint bw = util_format_get_blockwidth(format);
@@ -365,6 +370,12 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
pt = stObj->pt;
}
+ else {
+ /* Make sure that the base texture image data is present in the
+ * texture buffer.
+ */
+ st_finalize_texture(ctx, st->pipe, texObj);
+ }
assert(pt->last_level >= lastLevel);
@@ -372,6 +383,8 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
* use the software fallback.
*/
if (!st_render_mipmap(st, target, stObj, baseLevel, lastLevel)) {
+ /* since the util code actually also has a fallback, should
+ probably make it never fail and kill this */
fallback_generate_mipmap(ctx, target, texObj);
}
diff --git a/src/mesa/state_tracker/st_gen_mipmap.h b/src/mesa/state_tracker/st_gen_mipmap.h
index 3ba091da151..815c6a51638 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.h
+++ b/src/mesa/state_tracker/st_gen_mipmap.h
@@ -30,8 +30,10 @@
#define ST_GEN_MIPMAP_H
-#include "main/mtypes.h"
+#include "main/glheader.h"
+struct gl_context;
+struct gl_texture_object;
struct st_context;
extern void
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 05733e818ea..179e5dc8392 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -34,9 +34,11 @@
#include "util/u_pointer.h"
#include "util/u_inlines.h"
#include "util/u_atomic.h"
+#include "util/u_surface.h"
#include "main/mtypes.h"
#include "main/context.h"
+#include "main/mfeatures.h"
#include "main/texobj.h"
#include "main/teximage.h"
#include "main/texstate.h"
@@ -142,7 +144,7 @@ buffer_index_to_attachment(gl_buffer_index index)
static void
st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
{
- struct pipe_screen *screen = st->pipe->screen;
+ struct pipe_context *pipe = st->pipe;
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
uint width, height;
unsigned i;
@@ -160,7 +162,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
for (i = 0; i < stfb->num_statts; i++) {
struct st_renderbuffer *strb;
- struct pipe_surface *ps;
+ struct pipe_surface *ps, surf_tmpl;
gl_buffer_index idx;
if (!textures[i])
@@ -179,8 +181,10 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
continue;
}
- ps = screen->get_tex_surface(screen, textures[i], 0, 0, 0,
- PIPE_BIND_RENDER_TARGET);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ u_surface_default_template(&surf_tmpl, textures[i],
+ PIPE_BIND_RENDER_TARGET);
+ ps = pipe->create_surface(pipe, textures[i], &surf_tmpl);
if (ps) {
pipe_surface_reference(&strb->surface, ps);
pipe_resource_reference(&strb->texture, ps->texture);
@@ -510,7 +514,8 @@ st_context_flush(struct st_context_iface *stctxi, unsigned flags,
}
static boolean
-st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type target,
+st_context_teximage(struct st_context_iface *stctxi,
+ enum st_texture_type target,
int level, enum pipe_format internal_format,
struct pipe_resource *tex, boolean mipmap)
{
@@ -813,6 +818,7 @@ st_manager_flush_frontbuffer(struct st_context *st)
/**
* Return the surface of an EGLImage.
+ * FIXME: I think this should operate on resources, not surfaces
*/
struct pipe_surface *
st_manager_get_egl_image_surface(struct st_context *st,
@@ -821,7 +827,7 @@ st_manager_get_egl_image_surface(struct st_context *st,
struct st_manager *smapi =
(struct st_manager *) st->iface.st_context_private;
struct st_egl_image stimg;
- struct pipe_surface *ps;
+ struct pipe_surface *ps, surf_tmpl;
if (!smapi || !smapi->get_egl_image)
return NULL;
@@ -830,8 +836,13 @@ st_manager_get_egl_image_surface(struct st_context *st,
if (!smapi->get_egl_image(smapi, eglimg, &stimg))
return NULL;
- ps = smapi->screen->get_tex_surface(smapi->screen,
- stimg.texture, stimg.face, stimg.level, stimg.zslice, usage);
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = stimg.texture->format;
+ surf_tmpl.usage = usage;
+ surf_tmpl.u.tex.level = stimg.level;
+ surf_tmpl.u.tex.first_layer = stimg.layer;
+ surf_tmpl.u.tex.last_layer = stimg.layer;
+ ps = st->pipe->create_surface(st->pipe, stimg.texture, &surf_tmpl);
pipe_resource_reference(&stimg.texture, NULL);
return ps;
@@ -856,7 +867,8 @@ st_manager_validate_framebuffers(struct st_context *st)
* Add a color renderbuffer on demand.
*/
boolean
-st_manager_add_color_renderbuffer(struct st_context *st, struct gl_framebuffer *fb,
+st_manager_add_color_renderbuffer(struct st_context *st,
+ struct gl_framebuffer *fb,
gl_buffer_index idx)
{
struct st_framebuffer *stfb = st_ws_framebuffer(fb);
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 96c8aeb6e8d..42f1c2017f8 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -772,10 +772,13 @@ emit_adjusted_wpos( struct st_translate *t,
/**
* Emit the TGSI instructions for inverting the WPOS y coordinate.
+ * This code is unavoidable because it also depends on whether
+ * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM).
*/
static void
-emit_inverted_wpos( struct st_translate *t,
- const struct gl_program *program )
+emit_wpos_inversion( struct st_translate *t,
+ const struct gl_program *program,
+ boolean invert)
{
struct ureg_program *ureg = t->ureg;
@@ -783,17 +786,17 @@ emit_inverted_wpos( struct st_translate *t,
* Need to replace instances of INPUT[WPOS] with temp T
* where T = INPUT[WPOS] by y is inverted.
*/
- static const gl_state_index winSizeState[STATE_LENGTH]
- = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 };
+ static const gl_state_index wposTransformState[STATE_LENGTH]
+ = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 0, 0, 0 };
/* XXX: note we are modifying the incoming shader here! Need to
* do this before emitting the constant decls below, or this
* will be missed:
*/
- unsigned winHeightConst = _mesa_add_state_reference(program->Parameters,
- winSizeState);
+ unsigned wposTransConst = _mesa_add_state_reference(program->Parameters,
+ wposTransformState);
- struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst );
+ struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst );
struct ureg_dst wpos_temp;
struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
@@ -806,12 +809,23 @@ emit_inverted_wpos( struct st_translate *t,
ureg_MOV( ureg, wpos_temp, wpos_input );
}
- /* SUB wpos_temp.y, winsize_const, wpos_input
- */
- ureg_SUB( ureg,
- ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
- winsize,
- wpos_input);
+ if (invert) {
+ /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy
+ */
+ ureg_MAD( ureg,
+ ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+ wpos_input,
+ ureg_scalar(wpostrans, 0),
+ ureg_scalar(wpostrans, 1));
+ } else {
+ /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww
+ */
+ ureg_MAD( ureg,
+ ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+ wpos_input,
+ ureg_scalar(wpostrans, 2),
+ ureg_scalar(wpostrans, 3));
+ }
/* Use wpos_temp as position input from here on:
*/
@@ -873,8 +887,7 @@ emit_wpos(struct st_context *st,
/* we invert after adjustment so that we avoid the MOV to temporary,
* and reuse the adjustment ADD instead */
- if (invert)
- emit_inverted_wpos(t, program);
+ emit_wpos_inversion(t, program, invert);
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h
index 9bfd4960b60..0615e52ef62 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.h
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h
@@ -29,18 +29,20 @@
#ifndef ST_MESA_TO_TGSI_H
#define ST_MESA_TO_TGSI_H
-#include "main/mtypes.h"
-
-#include "pipe/p_compiler.h"
-
-struct ureg_program;
-
#if defined __cplusplus
extern "C" {
#endif
-struct tgsi_token;
+#include "main/glheader.h"
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_defines.h"
+
+struct gl_context;
struct gl_program;
+struct tgsi_token;
+struct ureg_program;
+
enum pipe_error
st_translate_mesa_program(
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 76799287fe1..7b32b46838a 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -32,7 +32,10 @@
#include "main/imports.h"
+#include "main/hash.h"
+#include "main/mfeatures.h"
#include "main/mtypes.h"
+#include "program/prog_parameter.h"
#include "program/prog_print.h"
#include "program/programopt.h"
@@ -44,6 +47,8 @@
#include "tgsi/tgsi_ureg.h"
#include "st_debug.h"
+#include "st_cb_bitmap.h"
+#include "st_cb_drawpixels.h"
#include "st_context.h"
#include "st_program.h"
#include "st_mesa_to_tgsi.h"
@@ -52,34 +57,109 @@
/**
+ * Delete a vertex program variant. Note the caller must unlink
+ * the variant from the linked list.
+ */
+static void
+delete_vp_variant(struct st_context *st, struct st_vp_variant *vpv)
+{
+ if (vpv->driver_shader)
+ cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
+
+#if FEATURE_feedback || FEATURE_rastpos
+ if (vpv->draw_shader)
+ draw_delete_vertex_shader( st->draw, vpv->draw_shader );
+#endif
+
+ if (vpv->tgsi.tokens)
+ st_free_tokens(vpv->tgsi.tokens);
+
+ FREE( vpv );
+}
+
+
+
+/**
* Clean out any old compilations:
*/
void
-st_vp_release_varients( struct st_context *st,
+st_release_vp_variants( struct st_context *st,
struct st_vertex_program *stvp )
{
- struct st_vp_varient *vpv;
+ struct st_vp_variant *vpv;
- for (vpv = stvp->varients; vpv; ) {
- struct st_vp_varient *next = vpv->next;
+ for (vpv = stvp->variants; vpv; ) {
+ struct st_vp_variant *next = vpv->next;
+ delete_vp_variant(st, vpv);
+ vpv = next;
+ }
- if (vpv->driver_shader)
- cso_delete_vertex_shader(st->cso_context, vpv->driver_shader);
-
-#if FEATURE_feedback || FEATURE_rastpos
- if (vpv->draw_shader)
- draw_delete_vertex_shader( st->draw, vpv->draw_shader );
-#endif
+ stvp->variants = NULL;
+}
+
+
+
+/**
+ * Delete a fragment program variant. Note the caller must unlink
+ * the variant from the linked list.
+ */
+static void
+delete_fp_variant(struct st_context *st, struct st_fp_variant *fpv)
+{
+ if (fpv->driver_shader)
+ cso_delete_fragment_shader(st->cso_context, fpv->driver_shader);
- if (vpv->tgsi.tokens)
- st_free_tokens(vpv->tgsi.tokens);
+ FREE(fpv);
+}
+
+
+/**
+ * Free all variants of a fragment program.
+ */
+void
+st_release_fp_variants(struct st_context *st, struct st_fragment_program *stfp)
+{
+ struct st_fp_variant *fpv;
+
+ for (fpv = stfp->variants; fpv; ) {
+ struct st_fp_variant *next = fpv->next;
+ delete_fp_variant(st, fpv);
+ fpv = next;
+ }
+
+ stfp->variants = NULL;
+}
+
+
+/**
+ * Delete a geometry program variant. Note the caller must unlink
+ * the variant from the linked list.
+ */
+static void
+delete_gp_variant(struct st_context *st, struct st_gp_variant *gpv)
+{
+ if (gpv->driver_shader)
+ cso_delete_geometry_shader(st->cso_context, gpv->driver_shader);
- FREE( vpv );
+ FREE(gpv);
+}
- vpv = next;
+
+/**
+ * Free all variants of a geometry program.
+ */
+void
+st_release_gp_variants(struct st_context *st, struct st_geometry_program *stgp)
+{
+ struct st_gp_variant *gpv;
+
+ for (gpv = stgp->variants; gpv; ) {
+ struct st_gp_variant *next = gpv->next;
+ delete_gp_variant(st, gpv);
+ gpv = next;
}
- stvp->varients = NULL;
+ stgp->variants = NULL;
}
@@ -92,7 +172,7 @@ st_vp_release_varients( struct st_context *st,
* \param tokensOut destination for TGSI tokens
* \return pointer to cached pipe_shader object.
*/
-void
+static void
st_prepare_vertex_program(struct st_context *st,
struct st_vertex_program *stvp)
{
@@ -196,17 +276,22 @@ st_prepare_vertex_program(struct st_context *st,
}
-struct st_vp_varient *
+/**
+ * Translate a vertex program to create a new variant.
+ */
+static struct st_vp_variant *
st_translate_vertex_program(struct st_context *st,
struct st_vertex_program *stvp,
- const struct st_vp_varient_key *key)
+ const struct st_vp_variant_key *key)
{
- struct st_vp_varient *vpv = CALLOC_STRUCT(st_vp_varient);
+ struct st_vp_variant *vpv = CALLOC_STRUCT(st_vp_variant);
struct pipe_context *pipe = st->pipe;
struct ureg_program *ureg;
enum pipe_error error;
unsigned num_outputs;
+ st_prepare_vertex_program( st, stvp );
+
_mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_OUTPUT);
_mesa_remove_output_reads(&stvp->Base.Base, PROGRAM_VARYING);
@@ -216,6 +301,8 @@ st_translate_vertex_program(struct st_context *st,
return NULL;
}
+ vpv->key = *key;
+
vpv->num_inputs = stvp->num_inputs;
num_outputs = stvp->num_outputs;
if (key->passthrough_edgeflags) {
@@ -229,23 +316,22 @@ st_translate_vertex_program(struct st_context *st,
debug_printf("\n");
}
- error =
- st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_VERTEX,
- ureg,
- &stvp->Base.Base,
- /* inputs */
- vpv->num_inputs,
- stvp->input_to_index,
- NULL, /* input semantic name */
- NULL, /* input semantic index */
- NULL,
- /* outputs */
- num_outputs,
- stvp->result_to_output,
- stvp->output_semantic_name,
- stvp->output_semantic_index,
- key->passthrough_edgeflags );
+ error = st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_VERTEX,
+ ureg,
+ &stvp->Base.Base,
+ /* inputs */
+ vpv->num_inputs,
+ stvp->input_to_index,
+ NULL, /* input semantic name */
+ NULL, /* input semantic index */
+ NULL,
+ /* outputs */
+ num_outputs,
+ stvp->result_to_output,
+ stvp->output_semantic_name,
+ stvp->output_semantic_index,
+ key->passthrough_edgeflags );
if (error)
goto fail;
@@ -275,201 +361,317 @@ fail:
}
+/**
+ * Find/create a vertex program variant.
+ */
+struct st_vp_variant *
+st_get_vp_variant(struct st_context *st,
+ struct st_vertex_program *stvp,
+ const struct st_vp_variant_key *key)
+{
+ struct st_vp_variant *vpv;
+
+ /* Search for existing variant */
+ for (vpv = stvp->variants; vpv; vpv = vpv->next) {
+ if (memcmp(&vpv->key, key, sizeof(*key)) == 0) {
+ break;
+ }
+ }
+
+ if (!vpv) {
+ /* create now */
+ vpv = st_translate_vertex_program(st, stvp, key);
+ if (vpv) {
+ /* insert into list */
+ vpv->next = stvp->variants;
+ stvp->variants = vpv;
+ }
+ }
+
+ return vpv;
+}
+
/**
- * Translate a Mesa fragment shader into a TGSI shader.
- * \return pointer to cached pipe_shader object.
+ * Translate a Mesa fragment shader into a TGSI shader using extra info in
+ * the key.
+ * \return new fragment program variant
*/
-void
+static struct st_fp_variant *
st_translate_fragment_program(struct st_context *st,
- struct st_fragment_program *stfp )
+ struct st_fragment_program *stfp,
+ const struct st_fp_variant_key *key)
{
struct pipe_context *pipe = st->pipe;
- GLuint outputMapping[FRAG_RESULT_MAX];
- GLuint inputMapping[FRAG_ATTRIB_MAX];
- GLuint interpMode[PIPE_MAX_SHADER_INPUTS]; /* XXX size? */
- GLuint attr;
- enum pipe_error error;
- const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
- struct ureg_program *ureg;
+ struct st_fp_variant *variant = CALLOC_STRUCT(st_fp_variant);
- ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
- ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
- uint fs_num_inputs = 0;
+ if (!variant)
+ return NULL;
- ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
- ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
- uint fs_num_outputs = 0;
+ assert(!(key->bitmap && key->drawpixels));
- _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
+#if FEATURE_drawpix
+ if (key->bitmap) {
+ /* glBitmap drawing */
+ struct gl_fragment_program *fp;
- /*
- * Convert Mesa program inputs to TGSI input register semantics.
- */
- for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
- if (inputsRead & (1 << attr)) {
- const GLuint slot = fs_num_inputs++;
+ st_make_bitmap_fragment_program(st, &stfp->Base,
+ &fp, &variant->bitmap_sampler);
- inputMapping[attr] = slot;
+ variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
+ stfp = st_fragment_program(fp);
+ }
+ else if (key->drawpixels) {
+ /* glDrawPixels drawing */
+ struct gl_fragment_program *fp;
- switch (attr) {
- case FRAG_ATTRIB_WPOS:
- input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- break;
- case FRAG_ATTRIB_COL0:
- input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- break;
- case FRAG_ATTRIB_COL1:
- input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
- input_semantic_index[slot] = 1;
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- break;
- case FRAG_ATTRIB_FOGC:
- input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- break;
- case FRAG_ATTRIB_FACE:
- input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
- input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
- 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_PNTC:
- case FRAG_ATTRIB_TEX0:
- case FRAG_ATTRIB_TEX1:
- case FRAG_ATTRIB_TEX2:
- case FRAG_ATTRIB_TEX3:
- case FRAG_ATTRIB_TEX4:
- case FRAG_ATTRIB_TEX5:
- case FRAG_ATTRIB_TEX6:
- case FRAG_ATTRIB_TEX7:
- case FRAG_ATTRIB_VAR0:
- default:
- /* Actually, let's try and zero-base this just for
- * readability of the generated TGSI.
- */
- assert(attr >= FRAG_ATTRIB_TEX0);
- input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
- input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- if (attr == FRAG_ATTRIB_PNTC)
- interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
- else
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- break;
- }
+ if (key->drawpixels_z || key->drawpixels_stencil) {
+ fp = st_make_drawpix_z_stencil_program(st, key->drawpixels_z,
+ key->drawpixels_stencil);
}
else {
- inputMapping[attr] = -1;
+ /* RGBA */
+ st_make_drawpix_fragment_program(st, &stfp->Base, &fp);
+ variant->parameters = _mesa_clone_parameter_list(fp->Base.Parameters);
}
+ stfp = st_fragment_program(fp);
}
+#endif
- /*
- * Semantics and mapping for outputs
- */
- {
- uint numColors = 0;
- GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
-
- /* if z is written, emit that first */
- if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
- fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
- fs_output_semantic_index[fs_num_outputs] = 0;
- outputMapping[FRAG_RESULT_DEPTH] = fs_num_outputs;
- fs_num_outputs++;
- outputsWritten &= ~(1 << FRAG_RESULT_DEPTH);
- }
+ if (!stfp->tgsi.tokens) {
+ /* need to translate Mesa instructions to TGSI now */
+ GLuint outputMapping[FRAG_RESULT_MAX];
+ GLuint inputMapping[FRAG_ATTRIB_MAX];
+ GLuint interpMode[PIPE_MAX_SHADER_INPUTS]; /* XXX size? */
+ GLuint attr;
+ enum pipe_error error;
+ const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
+ struct ureg_program *ureg;
+ GLboolean write_all = GL_FALSE;
- if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
- fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_STENCIL;
- fs_output_semantic_index[fs_num_outputs] = 0;
- outputMapping[FRAG_RESULT_STENCIL] = fs_num_outputs;
- fs_num_outputs++;
- outputsWritten &= ~(1 << FRAG_RESULT_STENCIL);
- }
+ ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
+ ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
+ uint fs_num_inputs = 0;
+
+ ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
+ ubyte fs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
+ uint fs_num_outputs = 0;
+
+
+ _mesa_remove_output_reads(&stfp->Base.Base, PROGRAM_OUTPUT);
+
+ /*
+ * Convert Mesa program inputs to TGSI input register semantics.
+ */
+ for (attr = 0; attr < FRAG_ATTRIB_MAX; attr++) {
+ if (inputsRead & (1 << attr)) {
+ const GLuint slot = fs_num_inputs++;
+
+ inputMapping[attr] = slot;
- /* handle remaning outputs (color) */
- for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
- if (outputsWritten & BITFIELD64_BIT(attr)) {
switch (attr) {
- case FRAG_RESULT_DEPTH:
- case FRAG_RESULT_STENCIL:
- /* handled above */
- assert(0);
+ case FRAG_ATTRIB_WPOS:
+ input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ break;
+ case FRAG_ATTRIB_COL0:
+ input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ break;
+ case FRAG_ATTRIB_COL1:
+ input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+ input_semantic_index[slot] = 1;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ break;
+ case FRAG_ATTRIB_FOGC:
+ input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
+ case FRAG_ATTRIB_FACE:
+ input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
+ 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_PNTC:
+ case FRAG_ATTRIB_TEX0:
+ case FRAG_ATTRIB_TEX1:
+ case FRAG_ATTRIB_TEX2:
+ case FRAG_ATTRIB_TEX3:
+ case FRAG_ATTRIB_TEX4:
+ case FRAG_ATTRIB_TEX5:
+ case FRAG_ATTRIB_TEX6:
+ case FRAG_ATTRIB_TEX7:
+ case FRAG_ATTRIB_VAR0:
default:
- assert(attr == FRAG_RESULT_COLOR ||
- (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
- fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
- fs_output_semantic_index[fs_num_outputs] = numColors;
- outputMapping[attr] = fs_num_outputs;
- numColors++;
+ /* Actually, let's try and zero-base this just for
+ * readability of the generated TGSI.
+ */
+ assert(attr >= FRAG_ATTRIB_TEX0);
+ input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
+ input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ if (attr == FRAG_ATTRIB_PNTC)
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ else
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
}
+ }
+ else {
+ inputMapping[attr] = -1;
+ }
+ }
+
+ /*
+ * Semantics and mapping for outputs
+ */
+ {
+ uint numColors = 0;
+ GLbitfield64 outputsWritten = stfp->Base.Base.OutputsWritten;
+
+ /* if z is written, emit that first */
+ if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+ fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_POSITION;
+ fs_output_semantic_index[fs_num_outputs] = 0;
+ outputMapping[FRAG_RESULT_DEPTH] = fs_num_outputs;
+ fs_num_outputs++;
+ outputsWritten &= ~(1 << FRAG_RESULT_DEPTH);
+ }
+ if (outputsWritten & BITFIELD64_BIT(FRAG_RESULT_STENCIL)) {
+ fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_STENCIL;
+ fs_output_semantic_index[fs_num_outputs] = 0;
+ outputMapping[FRAG_RESULT_STENCIL] = fs_num_outputs;
fs_num_outputs++;
+ outputsWritten &= ~(1 << FRAG_RESULT_STENCIL);
+ }
+
+ /* handle remaning outputs (color) */
+ for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
+ if (outputsWritten & BITFIELD64_BIT(attr)) {
+ switch (attr) {
+ case FRAG_RESULT_DEPTH:
+ case FRAG_RESULT_STENCIL:
+ /* handled above */
+ assert(0);
+ break;
+ case FRAG_RESULT_COLOR:
+ write_all = GL_TRUE; /* fallthrough */
+ default:
+ assert(attr == FRAG_RESULT_COLOR ||
+ (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
+ fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
+ fs_output_semantic_index[fs_num_outputs] = numColors;
+ outputMapping[attr] = fs_num_outputs;
+ numColors++;
+ break;
+ }
+
+ fs_num_outputs++;
+ }
}
}
- }
- ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
- if (ureg == NULL)
- return;
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
- if (ST_DEBUG & DEBUG_MESA) {
- _mesa_print_program(&stfp->Base.Base);
- _mesa_print_program_parameters(st->ctx, &stfp->Base.Base);
- debug_printf("\n");
+ if (ST_DEBUG & DEBUG_MESA) {
+ _mesa_print_program(&stfp->Base.Base);
+ _mesa_print_program_parameters(st->ctx, &stfp->Base.Base);
+ debug_printf("\n");
+ }
+ if (write_all == GL_TRUE)
+ ureg_property_fs_color0_writes_all_cbufs(ureg, 1);
+
+ error = st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_FRAGMENT,
+ ureg,
+ &stfp->Base.Base,
+ /* inputs */
+ fs_num_inputs,
+ inputMapping,
+ input_semantic_name,
+ input_semantic_index,
+ interpMode,
+ /* outputs */
+ fs_num_outputs,
+ outputMapping,
+ fs_output_semantic_name,
+ fs_output_semantic_index, FALSE );
+
+ stfp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
+ ureg_destroy( ureg );
}
- error =
- st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_FRAGMENT,
- ureg,
- &stfp->Base.Base,
- /* inputs */
- fs_num_inputs,
- inputMapping,
- input_semantic_name,
- input_semantic_index,
- interpMode,
- /* outputs */
- fs_num_outputs,
- outputMapping,
- fs_output_semantic_name,
- fs_output_semantic_index, FALSE );
-
- stfp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
- ureg_destroy( ureg );
- stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->tgsi);
+ /* fill in variant */
+ variant->driver_shader = pipe->create_fs_state(pipe, &stfp->tgsi);
+ variant->key = *key;
if (ST_DEBUG & DEBUG_TGSI) {
tgsi_dump( stfp->tgsi.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
debug_printf("\n");
}
+
+ return variant;
}
-void
+
+/**
+ * Translate fragment program if needed.
+ */
+struct st_fp_variant *
+st_get_fp_variant(struct st_context *st,
+ struct st_fragment_program *stfp,
+ const struct st_fp_variant_key *key)
+{
+ struct st_fp_variant *fpv;
+
+ /* Search for existing variant */
+ for (fpv = stfp->variants; fpv; fpv = fpv->next) {
+ if (memcmp(&fpv->key, key, sizeof(*key)) == 0) {
+ break;
+ }
+ }
+
+ if (!fpv) {
+ /* create new */
+ fpv = st_translate_fragment_program(st, stfp, key);
+ if (fpv) {
+ /* insert into list */
+ fpv->next = stfp->variants;
+ stfp->variants = fpv;
+ }
+ }
+
+ return fpv;
+}
+
+
+/**
+ * Translate a geometry program to create a new variant.
+ */
+static struct st_gp_variant *
st_translate_geometry_program(struct st_context *st,
- struct st_geometry_program *stgp)
+ struct st_geometry_program *stgp,
+ const struct st_gp_variant_key *key)
{
GLuint inputMapping[GEOM_ATTRIB_MAX];
GLuint outputMapping[GEOM_RESULT_MAX];
@@ -492,12 +694,19 @@ st_translate_geometry_program(struct st_context *st,
GLuint maxSlot = 0;
struct ureg_program *ureg;
+ struct st_gp_variant *gpv;
+
+ gpv = CALLOC_STRUCT(st_gp_variant);
+ if (!gpv)
+ return NULL;
+
_mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT);
_mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_VARYING);
ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
if (ureg == NULL) {
- return;
+ FREE(gpv);
+ return NULL;
}
/* which vertex output goes to the first geometry input */
@@ -527,7 +736,7 @@ st_translate_geometry_program(struct st_context *st,
} else
++gs_builtin_inputs;
-#if 1
+#if 0
debug_printf("input map at %d = %d\n",
slot + gs_array_offset, stgp->input_map[slot + gs_array_offset]);
#endif
@@ -669,37 +878,35 @@ st_translate_geometry_program(struct st_context *st,
st_free_tokens(stgp->tgsi.tokens);
stgp->tgsi.tokens = NULL;
}
- if (stgp->driver_shader) {
- cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
- stgp->driver_shader = NULL;
- }
ureg_property_gs_input_prim(ureg, stgp->Base.InputType);
ureg_property_gs_output_prim(ureg, stgp->Base.OutputType);
ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut);
- error = st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_GEOMETRY,
- ureg,
- &stgp->Base.Base,
- /* inputs */
- gs_num_inputs,
- inputMapping,
- stgp->input_semantic_name,
- stgp->input_semantic_index,
- NULL,
- /* outputs */
- gs_num_outputs,
- outputMapping,
- gs_output_semantic_name,
- gs_output_semantic_index,
- FALSE);
-
+ error = st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_GEOMETRY,
+ ureg,
+ &stgp->Base.Base,
+ /* inputs */
+ gs_num_inputs,
+ inputMapping,
+ stgp->input_semantic_name,
+ stgp->input_semantic_index,
+ NULL,
+ /* outputs */
+ gs_num_outputs,
+ outputMapping,
+ gs_output_semantic_name,
+ gs_output_semantic_index,
+ FALSE);
stgp->num_inputs = gs_num_inputs;
stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
ureg_destroy( ureg );
- stgp->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
+
+ /* fill in new variant */
+ gpv->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
+ gpv->key = *key;
if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
_mesa_print_program(&stgp->Base.Base);
@@ -710,8 +917,44 @@ st_translate_geometry_program(struct st_context *st,
tgsi_dump(stgp->tgsi.tokens, 0);
debug_printf("\n");
}
+
+ return gpv;
}
+
+/**
+ * Get/create geometry program variant.
+ */
+struct st_gp_variant *
+st_get_gp_variant(struct st_context *st,
+ struct st_geometry_program *stgp,
+ const struct st_gp_variant_key *key)
+{
+ struct st_gp_variant *gpv;
+
+ /* Search for existing variant */
+ for (gpv = stgp->variants; gpv; gpv = gpv->next) {
+ if (memcmp(&gpv->key, key, sizeof(*key)) == 0) {
+ break;
+ }
+ }
+
+ if (!gpv) {
+ /* create new */
+ gpv = st_translate_geometry_program(st, stgp, key);
+ if (gpv) {
+ /* insert into list */
+ gpv->next = stgp->variants;
+ stgp->variants = gpv;
+ }
+ }
+
+ return gpv;
+}
+
+
+
+
/**
* Debug- print current shader text
*/
@@ -757,3 +1000,155 @@ st_print_shaders(struct gl_context *ctx)
}
}
}
+
+
+/**
+ * Vert/Geom/Frag programs have per-context variants. Free all the
+ * variants attached to the given program which match the given context.
+ */
+static void
+destroy_program_variants(struct st_context *st, struct gl_program *program)
+{
+ if (!program)
+ return;
+
+ switch (program->Target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ {
+ struct st_vertex_program *stvp = (struct st_vertex_program *) program;
+ struct st_vp_variant *vpv, **prevPtr = &stvp->variants;
+
+ for (vpv = stvp->variants; vpv; ) {
+ struct st_vp_variant *next = vpv->next;
+ if (vpv->key.st == st) {
+ /* unlink from list */
+ *prevPtr = next;
+ /* destroy this variant */
+ delete_vp_variant(st, vpv);
+ }
+ else {
+ prevPtr = &vpv->next;
+ }
+ vpv = next;
+ }
+ }
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ {
+ struct st_fragment_program *stfp =
+ (struct st_fragment_program *) program;
+ struct st_fp_variant *fpv, **prevPtr = &stfp->variants;
+
+ for (fpv = stfp->variants; fpv; ) {
+ struct st_fp_variant *next = fpv->next;
+ if (fpv->key.st == st) {
+ /* unlink from list */
+ *prevPtr = next;
+ /* destroy this variant */
+ delete_fp_variant(st, fpv);
+ }
+ else {
+ prevPtr = &fpv->next;
+ }
+ fpv = next;
+ }
+ }
+ break;
+ case MESA_GEOMETRY_PROGRAM:
+ {
+ struct st_geometry_program *stgp =
+ (struct st_geometry_program *) program;
+ struct st_gp_variant *gpv, **prevPtr = &stgp->variants;
+
+ for (gpv = stgp->variants; gpv; ) {
+ struct st_gp_variant *next = gpv->next;
+ if (gpv->key.st == st) {
+ /* unlink from list */
+ *prevPtr = next;
+ /* destroy this variant */
+ delete_gp_variant(st, gpv);
+ }
+ else {
+ prevPtr = &gpv->next;
+ }
+ gpv = next;
+ }
+ }
+ break;
+ default:
+ _mesa_problem(NULL, "Unexpected program target in "
+ "destroy_program_variants_cb()");
+ }
+}
+
+
+/**
+ * Callback for _mesa_HashWalk. Free all the shader's program variants
+ * which match the given context.
+ */
+static void
+destroy_shader_program_variants_cb(GLuint key, void *data, void *userData)
+{
+ struct st_context *st = (struct st_context *) userData;
+ struct gl_shader *shader = (struct gl_shader *) data;
+
+ switch (shader->Type) {
+ case GL_SHADER_PROGRAM_MESA:
+ {
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+ GLuint i;
+
+ for (i = 0; i < shProg->NumShaders; i++) {
+ destroy_program_variants(st, shProg->Shaders[i]->Program);
+ }
+
+ destroy_program_variants(st, (struct gl_program *)
+ shProg->VertexProgram);
+ destroy_program_variants(st, (struct gl_program *)
+ shProg->FragmentProgram);
+ destroy_program_variants(st, (struct gl_program *)
+ shProg->GeometryProgram);
+ }
+ break;
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ case GL_GEOMETRY_SHADER:
+ {
+ destroy_program_variants(st, shader->Program);
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
+/**
+ * Callback for _mesa_HashWalk. Free all the program variants which match
+ * the given context.
+ */
+static void
+destroy_program_variants_cb(GLuint key, void *data, void *userData)
+{
+ struct st_context *st = (struct st_context *) userData;
+ struct gl_program *program = (struct gl_program *) data;
+ destroy_program_variants(st, program);
+}
+
+
+/**
+ * Walk over all shaders and programs to delete any variants which
+ * belong to the given context.
+ * This is called during context tear-down.
+ */
+void
+st_destroy_program_variants(struct st_context *st)
+{
+ /* ARB vert/frag program */
+ _mesa_HashWalk(st->ctx->Shared->Programs,
+ destroy_program_variants_cb, st);
+
+ /* GLSL vert/frag/geom shaders */
+ _mesa_HashWalk(st->ctx->Shared->ShaderObjects,
+ destroy_shader_program_variants_cb, st);
+}
diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h
index 72dbc715fe1..c4244df939e 100644
--- a/src/mesa/state_tracker/st_program.h
+++ b/src/mesa/state_tracker/st_program.h
@@ -40,26 +40,61 @@
#include "st_context.h"
+/** Fragment program variant key */
+struct st_fp_variant_key
+{
+ struct st_context *st; /**< variants are per-context */
+
+ /** for glBitmap */
+ GLuint bitmap:1; /**< glBitmap variant? */
+
+ /** for glDrawPixels */
+ GLuint drawpixels:1; /**< glDrawPixels variant */
+ GLuint scaleAndBias:1; /**< glDrawPixels w/ scale and/or bias? */
+ GLuint pixelMaps:1; /**< glDrawPixels w/ pixel lookup map? */
+ GLuint drawpixels_z:1; /**< glDrawPixels(GL_DEPTH) */
+ GLuint drawpixels_stencil:1; /**< glDrawPixels(GL_STENCIL) */
+};
+
+
+/**
+ * Variant of a fragment program.
+ */
+struct st_fp_variant
+{
+ /** Parameters which generated this version of fragment program */
+ struct st_fp_variant_key key;
+
+ /** Driver's compiled shader */
+ void *driver_shader;
+
+ /** For glBitmap variants */
+ struct gl_program_parameter_list *parameters;
+ uint bitmap_sampler;
+
+ /** next in linked list */
+ struct st_fp_variant *next;
+};
+
+
/**
* Derived from Mesa gl_fragment_program:
*/
struct st_fragment_program
{
struct gl_fragment_program Base;
- GLuint serialNo;
struct pipe_shader_state tgsi;
- void *driver_shader;
- /** Program prefixed with glBitmap prologue */
- struct st_fragment_program *bitmap_program;
- uint bitmap_sampler;
+ struct st_fp_variant *variants;
};
-struct st_vp_varient_key
+/** Vertex program variant key */
+struct st_vp_variant_key
{
+ struct st_context *st; /**< variants are per-context */
boolean passthrough_edgeflags;
};
@@ -68,12 +103,12 @@ struct st_vp_varient_key
* This represents a vertex program, especially translated to match
* the inputs of a particular fragment shader.
*/
-struct st_vp_varient
+struct st_vp_variant
{
/* Parameters which generated this translated version of a vertex
* shader:
*/
- struct st_vp_varient_key key;
+ struct st_vp_variant_key key;
/**
* TGSI tokens (to later generate a 'draw' module shader for
@@ -88,9 +123,9 @@ struct st_vp_varient
struct draw_vertex_shader *draw_shader;
/** Next in linked list */
- struct st_vp_varient *next;
+ struct st_vp_variant *next;
- /** similar to that in st_vertex_program, but with information about edgeflags too */
+ /** similar to that in st_vertex_program, but with edgeflags info too */
GLuint num_inputs;
};
@@ -101,7 +136,6 @@ struct st_vp_varient
struct st_vertex_program
{
struct gl_vertex_program Base; /**< The Mesa vertex program */
- GLuint serialNo, lastSerialNo;
/** maps a Mesa VERT_ATTRIB_x to a packed TGSI input index */
GLuint input_to_index[VERT_ATTRIB_MAX];
@@ -115,18 +149,41 @@ struct st_vertex_program
ubyte output_semantic_index[VERT_RESULT_MAX];
GLuint num_outputs;
- /** List of translated varients of this vertex program.
+ /** List of translated variants of this vertex program.
*/
- struct st_vp_varient *varients;
+ struct st_vp_variant *variants;
+};
+
+
+
+/** Geometry program variant key */
+struct st_gp_variant_key
+{
+ struct st_context *st; /**< variants are per-context */
+ /* no other fields yet */
+};
+
+
+/**
+ * Geometry program variant.
+ */
+struct st_gp_variant
+{
+ /* Parameters which generated this translated version of a vertex */
+ struct st_gp_variant_key key;
+
+ void *driver_shader;
+
+ struct st_gp_variant *next;
};
+
/**
* Derived from Mesa gl_geometry_program:
*/
struct st_geometry_program
{
struct gl_geometry_program Base; /**< The Mesa geometry program */
- GLuint serialNo;
/** map GP input back to VP output */
GLuint input_map[PIPE_MAX_SHADER_INPUTS];
@@ -145,9 +202,12 @@ struct st_geometry_program
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
struct pipe_shader_state tgsi;
- void *driver_shader;
+
+ struct st_gp_variant *variants;
};
+
+
static INLINE struct st_fragment_program *
st_fragment_program( struct gl_fragment_program *fp )
{
@@ -162,9 +222,9 @@ st_vertex_program( struct gl_vertex_program *vp )
}
static INLINE struct st_geometry_program *
-st_geometry_program( struct gl_geometry_program *vp )
+st_geometry_program( struct gl_geometry_program *gp )
{
- return (struct st_geometry_program *)vp;
+ return (struct st_geometry_program *)gp;
}
static INLINE void
@@ -198,32 +258,43 @@ st_reference_fragprog(struct st_context *st,
}
-extern void
-st_translate_fragment_program(struct st_context *st,
- struct st_fragment_program *fp);
+extern struct st_vp_variant *
+st_get_vp_variant(struct st_context *st,
+ struct st_vertex_program *stvp,
+ const struct st_vp_variant_key *key);
+
+
+extern struct st_fp_variant *
+st_get_fp_variant(struct st_context *st,
+ struct st_fragment_program *stfp,
+ const struct st_fp_variant_key *key);
+
+
+extern struct st_gp_variant *
+st_get_gp_variant(struct st_context *st,
+ struct st_geometry_program *stgp,
+ const struct st_gp_variant_key *key);
+
+
extern void
-st_translate_geometry_program(struct st_context *st,
- struct st_geometry_program *stgp);
+st_release_vp_variants( struct st_context *st,
+ struct st_vertex_program *stvp );
-/* 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);
+st_release_fp_variants( struct st_context *st,
+ struct st_fragment_program *stfp );
-extern struct st_vp_varient *
-st_translate_vertex_program(struct st_context *st,
- struct st_vertex_program *stvp,
- const struct st_vp_varient_key *key);
+extern void
+st_release_gp_variants(struct st_context *st,
+ struct st_geometry_program *stgp);
-void
-st_vp_release_varients( struct st_context *st,
- struct st_vertex_program *stvp );
extern void
st_print_shaders(struct gl_context *ctx);
+extern void
+st_destroy_program_variants(struct st_context *st);
+
#endif
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index c6cf2ba061b..155ea39f18c 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -84,6 +84,7 @@ st_texture_create(struct st_context *st,
pt.width0 = width0;
pt.height0 = height0;
pt.depth0 = depth0;
+ pt.array_size = (target == PIPE_TEXTURE_CUBE ? 6 : 1);
pt.usage = PIPE_USAGE_DEFAULT;
pt.bind = bind;
pt.flags = 0;
@@ -136,7 +137,7 @@ st_texture_match_image(const struct pipe_resource *pt,
*/
GLubyte *
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
- GLuint zoffset, enum pipe_transfer_usage usage,
+ GLuint zoffset, enum pipe_transfer_usage usage,
GLuint x, GLuint y, GLuint w, GLuint h)
{
struct pipe_context *pipe = st->pipe;
@@ -144,9 +145,9 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
DBG("%s \n", __FUNCTION__);
- stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->face,
- stImage->level, zoffset,
- usage, x, y, w, h);
+ stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->level,
+ stImage->face + zoffset,
+ usage, x, y, w, h);
if (stImage->transfer)
return pipe_transfer_map(pipe, stImage->transfer);
@@ -219,10 +220,10 @@ st_texture_image_data(struct st_context *st,
DBG("%s\n", __FUNCTION__);
for (i = 0; i < depth; i++) {
- dst_transfer = pipe_get_transfer(st->pipe, dst, face, level, i,
- PIPE_TRANSFER_WRITE, 0, 0,
- u_minify(dst->width0, level),
- u_minify(dst->height0, level));
+ dst_transfer = pipe_get_transfer(st->pipe, dst, level, face + i,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ u_minify(dst->width0, level),
+ u_minify(dst->height0, level));
st_surface_data(pipe, dst_transfer,
0, 0, /* dstx, dsty */
@@ -230,7 +231,7 @@ st_texture_image_data(struct st_context *st,
src_row_stride,
0, 0, /* source x, y */
u_minify(dst->width0, level),
- u_minify(dst->height0, level)); /* width, height */
+ u_minify(dst->height0, level)); /* width, height */
pipe->transfer_destroy(pipe, dst_transfer);
@@ -245,14 +246,10 @@ st_texture_image_data(struct st_context *st,
static void
print_center_pixel(struct pipe_context *pipe, struct pipe_resource *src)
{
- struct pipe_subresource rect;
struct pipe_transfer *xfer;
struct pipe_box region;
ubyte *map;
- rect.face = 0;
- rect.level = 0;
-
region.x = src->width0 / 2;
region.y = src->height0 / 2;
region.z = 0;
@@ -260,7 +257,7 @@ print_center_pixel(struct pipe_context *pipe, struct pipe_resource *src)
region.height = 1;
region.depth = 1;
- xfer = pipe->get_transfer(pipe, src, rect, PIPE_TRANSFER_READ, &region);
+ xfer = pipe->get_transfer(pipe, src, 0, PIPE_TRANSFER_READ, &region);
map = pipe->transfer_map(pipe, xfer);
printf("center pixel: %d %d %d %d\n", map[0], map[1], map[2], map[3]);
@@ -282,22 +279,26 @@ st_texture_image_copy(struct pipe_context *pipe,
struct pipe_resource *src, GLuint srcLevel,
GLuint face)
{
- GLuint width = u_minify(dst->width0, dstLevel);
- GLuint height = u_minify(dst->height0, dstLevel);
- GLuint depth = u_minify(dst->depth0, dstLevel);
- struct pipe_subresource dstsub, srcsub;
+ GLuint width = u_minify(dst->width0, dstLevel);
+ GLuint height = u_minify(dst->height0, dstLevel);
+ GLuint depth = u_minify(dst->depth0, dstLevel);
+ struct pipe_box src_box;
GLuint i;
assert(u_minify(src->width0, srcLevel) == width);
assert(u_minify(src->height0, srcLevel) == height);
assert(u_minify(src->depth0, srcLevel) == depth);
- dstsub.face = face;
- dstsub.level = dstLevel;
- srcsub.face = face;
- srcsub.level = srcLevel;
+ src_box.x = 0;
+ src_box.y = 0;
+ src_box.width = width;
+ src_box.height = height;
+ src_box.depth = 1;
/* Loop over 3D image slices */
- for (i = 0; i < depth; i++) {
+ /* could (and probably should) use "true" 3d box here -
+ but drivers can't quite handle it yet */
+ for (i = face; i < face + depth; i++) {
+ src_box.z = i;
if (0) {
print_center_pixel(pipe, src);
@@ -305,12 +306,11 @@ st_texture_image_copy(struct pipe_context *pipe,
pipe->resource_copy_region(pipe,
dst,
- dstsub,
+ dstLevel,
0, 0, i,/* destX, Y, Z */
src,
- srcsub,
- 0, 0, i,/* srcX, Y, Z */
- width, height);
+ srcLevel,
+ &src_box);
}
}