summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2008-03-22 21:04:16 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2008-03-22 21:04:16 +0000
commit7b4d0a85263b0e208bb83e7ce6a01630e1dcb4af (patch)
treed2b1d770e2314a1f696d9d951d951cbfa41e8a09
parentff288d531c87670fde52986b1c30eef5fd2468d3 (diff)
parenta35c1ca3ad4361fee30d21ef13d8d37ae91aee66 (diff)
Merge branch 'gallium-0.1' into gallium-draw-optigallium-draw-opti
-rw-r--r--progs/tests/copypixrate.c63
-rw-r--r--progs/tests/mipmap_view.c25
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c209
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h53
-rw-r--r--src/gallium/auxiliary/draw/draw_aaline.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pstipple.c8
-rw-r--r--src/gallium/auxiliary/util/p_debug.c77
-rw-r--r--src/gallium/auxiliary/util/u_blit.c207
-rw-r--r--src/gallium/auxiliary/util/u_blit.h5
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c59
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.h16
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c192
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.h6
-rw-r--r--src/gallium/auxiliary/util/u_handle_table.c23
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c114
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.h12
-rw-r--r--src/gallium/drivers/cell/common.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c29
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_derived.c13
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c21
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.c247
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.h3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c3
-rw-r--r--src/gallium/drivers/cell/spu/Makefile1
-rw-r--r--src/gallium/drivers/cell/spu/spu_blend.c62
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c29
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h19
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c61
-rw-r--r--src/gallium/drivers/i915simple/i915_state_sampler.c6
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c3
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c3
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_setup.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_stipple.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c13
-rw-r--r--src/gallium/drivers/softpipe/sp_state_surface.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c23
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c1
-rw-r--r--src/gallium/include/pipe/p_context.h6
-rw-r--r--src/gallium/include/pipe/p_debug.h57
-rw-r--r--src/gallium/include/pipe/p_format.h72
-rw-r--r--src/gallium/include/pipe/p_screen.h1
-rw-r--r--src/gallium/include/pipe/p_state.h2
-rw-r--r--src/mesa/SConscript3
-rw-r--r--src/mesa/main/bufferobj.c141
-rw-r--r--src/mesa/main/bufferobj.h33
-rw-r--r--src/mesa/main/context.c4
-rw-r--r--src/mesa/main/drawpix.c62
-rw-r--r--src/mesa/main/teximage.c3
-rw-r--r--src/mesa/shader/program.c2
-rw-r--r--src/mesa/shader/shader_api.c6
-rw-r--r--src/mesa/sources1
-rw-r--r--src/mesa/state_tracker/st_atom_blend.c12
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c7
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c26
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c43
-rw-r--r--src/mesa/state_tracker/st_atom_shader.h6
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c10
-rw-r--r--src/mesa/state_tracker/st_atom_viewport.c26
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c527
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.h (renamed from src/gallium/drivers/cell/spu/spu_blend.h)16
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c28
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c256
-rw-r--r--src/mesa/state_tracker/st_cb_clear.h4
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c341
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.h4
-rw-r--r--src/mesa/state_tracker/st_cb_program.c57
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c17
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c26
-rw-r--r--src/mesa/state_tracker/st_context.c8
-rw-r--r--src/mesa/state_tracker/st_context.h13
-rw-r--r--src/mesa/state_tracker/st_debug.c3
-rw-r--r--src/mesa/state_tracker/st_draw.c6
-rw-r--r--src/mesa/state_tracker/st_extensions.c15
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c20
-rw-r--r--src/mesa/state_tracker/st_program.c10
-rw-r--r--src/mesa/state_tracker/st_texture.h2
-rw-r--r--src/mesa/swrast/s_bitmap.c32
-rw-r--r--src/mesa/swrast/s_drawpix.c29
-rw-r--r--src/mesa/swrast/s_readpix.c28
80 files changed, 2357 insertions, 1245 deletions
diff --git a/progs/tests/copypixrate.c b/progs/tests/copypixrate.c
index e9a42a1c8c..142315364c 100644
--- a/progs/tests/copypixrate.c
+++ b/progs/tests/copypixrate.c
@@ -73,6 +73,32 @@ Rand(int max)
}
+static void
+BlitOne(void)
+{
+ int x, y;
+
+ do {
+ x = Rand(WinWidth);
+ y = Rand(WinHeight);
+ } while (x <= ImgWidth && y <= ImgHeight);
+
+#ifdef GL_EXT_framebuffer_blit
+ if (UseBlit)
+ {
+ glBlitFramebufferEXT_func(0, 0, ImgWidth, ImgHeight,
+ x, y, x + ImgWidth, y + ImgHeight,
+ GL_COLOR_BUFFER_BIT, GL_LINEAR);
+ }
+ else
+#endif
+ {
+ glWindowPos2iARB(x, y);
+ glCopyPixels(0, 0, ImgWidth, ImgHeight, GL_COLOR);
+ }
+}
+
+
/**
* Measure glCopyPixels rate
*/
@@ -96,30 +122,14 @@ RunTest(void)
bpp = (r + g + b + a) / 8;
do {
- int x, y;
- x = Rand(WinWidth);
- y = Rand(WinHeight);
+ BlitOne();
- if (x > ImgWidth || y > ImgHeight) {
-#ifdef GL_EXT_framebuffer_blit
- if (UseBlit)
- {
- glBlitFramebufferEXT_func(0, 0, ImgWidth, ImgHeight,
- x, y, x + ImgWidth, y + ImgHeight,
- GL_COLOR_BUFFER_BIT, GL_LINEAR);
- }
- else
-#endif
- {
- glWindowPos2iARB(x, y);
- glCopyPixels(0, 0, ImgWidth, ImgHeight, GL_COLOR);
- }
- glFinish(); /* XXX OK? */
+ if (Buffer == GL_FRONT)
+ glFinish(); /* XXX to view progress */
- iters++;
+ iters++;
- t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
- }
+ t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
} while (t1 - t0 < 5.0);
glDisable(GL_ALPHA_TEST);
@@ -151,8 +161,10 @@ Draw(void)
else
glutSwapBuffers();
+#if 1
printf("exiting\n");
exit(0);
+#endif
}
@@ -175,9 +187,12 @@ Key(unsigned char key, int x, int y)
(void) x;
(void) y;
switch (key) {
- case 27:
- exit(0);
- break;
+ case 'b':
+ BlitOne();
+ break;
+ case 27:
+ exit(0);
+ break;
}
glutPostRedisplay();
}
diff --git a/progs/tests/mipmap_view.c b/progs/tests/mipmap_view.c
index d821f432f0..117e201718 100644
--- a/progs/tests/mipmap_view.c
+++ b/progs/tests/mipmap_view.c
@@ -55,17 +55,10 @@ Display(void)
for (bias = -1; bias < 11; bias++) {
- glRasterPos2f(x, y + TexHeight + 5);
- sprintf(str, "Texture LOD Bias = %d", bias);
- PrintString(str);
-
- glPushMatrix();
- glTranslatef(x, y, 0);
-
- glEnable(GL_TEXTURE_2D);
-
if (ScaleQuads) {
if (bias > 0) {
+ if (texWidth == 1 && texHeight == 1)
+ break;
texWidth = TexWidth >> bias;
texHeight = TexHeight >> bias;
if (texWidth < 1)
@@ -79,6 +72,20 @@ Display(void)
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
}
+ glRasterPos2f(x, y + TexHeight + 5);
+ if (ScaleQuads)
+ sprintf(str, "Texture Level %d: %d x %d",
+ (bias < 0 ? 0 : bias),
+ texWidth, texHeight);
+ else
+ sprintf(str, "Texture LOD Bias = %d", bias);
+ PrintString(str);
+
+ glPushMatrix();
+ glTranslatef(x, y, 0);
+
+ glEnable(GL_TEXTURE_2D);
+
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(1, 0); glVertex2f(texWidth, 0);
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 294ac82281..4a1a6cb79c 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -52,11 +52,27 @@ struct cso_context {
void *samplers[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
- void *blend;
- void *depth_stencil;
- void *rasterizer;
- void *fragment_shader;
- void *vertex_shader;
+ void *samplers_saved[PIPE_MAX_SAMPLERS];
+ unsigned nr_samplers_saved;
+
+ struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ uint nr_textures;
+
+ struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS];
+ uint nr_textures_saved;
+
+ /** Current and saved state.
+ * The saved state is used as a 1-deep stack.
+ */
+ void *blend, *blend_saved;
+ void *depth_stencil, *depth_stencil_saved;
+ void *rasterizer, *rasterizer_saved;
+ void *fragment_shader, *fragment_shader_saved;
+ void *vertex_shader, *vertex_shader_saved;
+
+ struct pipe_framebuffer_state fb, fb_saved;
+ struct pipe_viewport_state vp, vp_saved;
+ struct pipe_blend_color blend_color;
};
@@ -149,12 +165,23 @@ void cso_set_blend(struct cso_context *ctx,
}
}
-void cso_unset_blend(struct cso_context *ctx)
+void cso_save_blend(struct cso_context *ctx)
+{
+ assert(!ctx->blend_saved);
+ ctx->blend_saved = ctx->blend;
+}
+
+void cso_restore_blend(struct cso_context *ctx)
{
- ctx->blend = NULL;
+ if (ctx->blend != ctx->blend_saved) {
+ ctx->blend = ctx->blend_saved;
+ ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend_saved);
+ }
+ ctx->blend_saved = NULL;
}
+
void cso_single_sampler(struct cso_context *ctx,
unsigned idx,
const struct pipe_sampler_state *templ)
@@ -190,9 +217,11 @@ void cso_single_sampler_done( struct cso_context *ctx )
{
unsigned i;
- for (i = 0; i < 8; i++)
- if (ctx->samplers[i] == NULL)
+ /* find highest non-null sampler */
+ for (i = PIPE_MAX_SAMPLERS; i > 0; i--) {
+ if (ctx->samplers[i - 1] != NULL)
break;
+ }
ctx->nr_samplers = i;
@@ -226,15 +255,50 @@ void cso_set_samplers( struct cso_context *ctx,
cso_single_sampler_done( ctx );
}
-void cso_unset_samplers( struct cso_context *ctx )
+void cso_save_samplers(struct cso_context *ctx)
+{
+ ctx->nr_samplers_saved = ctx->nr_samplers;
+ memcpy(ctx->samplers_saved, ctx->samplers, sizeof(ctx->samplers));
+}
+
+void cso_restore_samplers(struct cso_context *ctx)
+{
+ cso_set_samplers(ctx, ctx->nr_samplers_saved,
+ (const struct pipe_sampler_state **) ctx->samplers_saved);
+}
+
+
+void cso_set_sampler_textures( struct cso_context *ctx,
+ uint count,
+ struct pipe_texture **textures )
{
uint i;
- for (i = 0; i < ctx->nr_samplers; i++)
- ctx->samplers[i] = NULL;
+
+ ctx->nr_textures = count;
+
+ for (i = 0; i < count; i++)
+ ctx->textures[i] = textures[i];
+ for ( ; i < PIPE_MAX_SAMPLERS; i++)
+ ctx->textures[i] = NULL;
+
+ ctx->pipe->set_sampler_textures(ctx->pipe, count, textures);
+}
+
+void cso_save_sampler_textures( struct cso_context *ctx )
+{
+ ctx->nr_textures_saved = ctx->nr_textures;
+ memcpy(ctx->textures_saved, ctx->textures, sizeof(ctx->textures));
+}
+
+void cso_restore_sampler_textures( struct cso_context *ctx )
+{
+ cso_set_sampler_textures(ctx, ctx->nr_textures_saved, ctx->textures_saved);
+ ctx->nr_textures_saved = 0;
}
+
void cso_set_depth_stencil_alpha(struct cso_context *ctx,
const struct pipe_depth_stencil_alpha_state *templ)
{
@@ -267,15 +331,25 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx,
}
}
-void cso_unset_depth_stencil_alpha(struct cso_context *ctx)
+void cso_save_depth_stencil_alpha(struct cso_context *ctx)
{
- ctx->depth_stencil = NULL;
+ assert(!ctx->depth_stencil_saved);
+ ctx->depth_stencil_saved = ctx->depth_stencil;
+}
+
+void cso_restore_depth_stencil_alpha(struct cso_context *ctx)
+{
+ if (ctx->depth_stencil != ctx->depth_stencil_saved) {
+ ctx->depth_stencil = ctx->depth_stencil_saved;
+ ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->depth_stencil_saved);
+ }
+ ctx->depth_stencil_saved = NULL;
}
void cso_set_rasterizer(struct cso_context *ctx,
- const struct pipe_rasterizer_state *templ)
+ const struct pipe_rasterizer_state *templ)
{
unsigned hash_key = cso_construct_key((void*)templ,
sizeof(struct pipe_rasterizer_state));
@@ -305,11 +379,20 @@ void cso_set_rasterizer(struct cso_context *ctx,
}
}
-void cso_unset_rasterizer(struct cso_context *ctx)
+void cso_save_rasterizer(struct cso_context *ctx)
{
- ctx->rasterizer = NULL;
+ assert(!ctx->rasterizer_saved);
+ ctx->rasterizer_saved = ctx->rasterizer;
}
+void cso_restore_rasterizer(struct cso_context *ctx)
+{
+ if (ctx->rasterizer != ctx->rasterizer_saved) {
+ ctx->rasterizer = ctx->rasterizer_saved;
+ ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rasterizer_saved);
+ }
+ ctx->rasterizer_saved = NULL;
+}
void cso_set_fragment_shader(struct cso_context *ctx,
@@ -343,12 +426,24 @@ void cso_set_fragment_shader(struct cso_context *ctx,
}
}
-void cso_unset_fragment_shader(struct cso_context *ctx)
+void cso_save_fragment_shader(struct cso_context *ctx)
{
- ctx->fragment_shader = NULL;
+ assert(!ctx->fragment_shader_saved);
+ ctx->fragment_shader_saved = ctx->fragment_shader;
+}
+
+void cso_restore_fragment_shader(struct cso_context *ctx)
+{
+ assert(ctx->fragment_shader_saved);
+ if (ctx->fragment_shader_saved != ctx->fragment_shader) {
+ ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved);
+ ctx->fragment_shader = ctx->fragment_shader_saved;
+ }
+ ctx->fragment_shader_saved = NULL;
}
+
void cso_set_vertex_shader(struct cso_context *ctx,
const struct pipe_shader_state *templ)
{
@@ -380,7 +475,79 @@ void cso_set_vertex_shader(struct cso_context *ctx,
}
}
-void cso_unset_vertex_shader(struct cso_context *ctx)
+void cso_save_vertex_shader(struct cso_context *ctx)
+{
+ assert(!ctx->vertex_shader_saved);
+ ctx->vertex_shader_saved = ctx->vertex_shader;
+}
+
+void cso_restore_vertex_shader(struct cso_context *ctx)
+{
+ assert(ctx->vertex_shader_saved);
+ if (ctx->vertex_shader_saved != ctx->vertex_shader) {
+ ctx->pipe->bind_fs_state(ctx->pipe, ctx->vertex_shader_saved);
+ ctx->vertex_shader = ctx->vertex_shader_saved;
+ }
+ ctx->vertex_shader_saved = NULL;
+}
+
+
+
+void cso_set_framebuffer(struct cso_context *ctx,
+ const struct pipe_framebuffer_state *fb)
+{
+ /* XXX this memcmp() fails to detect buffer size changes */
+ if (1/*memcmp(&ctx->fb, fb, sizeof(*fb))*/) {
+ ctx->fb = *fb;
+ ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
+ }
+}
+
+void cso_save_framebuffer(struct cso_context *ctx)
+{
+ ctx->fb_saved = ctx->fb;
+}
+
+void cso_restore_framebuffer(struct cso_context *ctx)
+{
+ if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) {
+ ctx->fb = ctx->fb_saved;
+ ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);
+ }
+}
+
+
+void cso_set_viewport(struct cso_context *ctx,
+ const struct pipe_viewport_state *vp)
+{
+ if (memcmp(&ctx->vp, vp, sizeof(*vp))) {
+ ctx->vp = *vp;
+ ctx->pipe->set_viewport_state(ctx->pipe, vp);
+ }
+}
+
+void cso_save_viewport(struct cso_context *ctx)
{
- ctx->vertex_shader = NULL;
+ ctx->vp_saved = ctx->vp;
+}
+
+
+void cso_restore_viewport(struct cso_context *ctx)
+{
+ if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) {
+ ctx->vp = ctx->vp_saved;
+ ctx->pipe->set_viewport_state(ctx->pipe, &ctx->vp);
+ }
+}
+
+
+
+
+void cso_set_blend_color(struct cso_context *ctx,
+ const struct pipe_blend_color *bc)
+{
+ if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) {
+ ctx->blend_color = *bc;
+ ctx->pipe->set_blend_color(ctx->pipe, bc);
+ }
}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 6aa619abf5..665e8d9911 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -41,27 +41,36 @@ struct cso_context;
struct cso_context *cso_create_context( struct pipe_context *pipe );
+void cso_destroy_context( struct cso_context *cso );
+
+
+
void cso_set_blend( struct cso_context *cso,
const struct pipe_blend_state *blend );
+void cso_save_blend(struct cso_context *cso);
+void cso_restore_blend(struct cso_context *cso);
+
-void cso_unset_blend(struct cso_context *cso);
void cso_set_depth_stencil_alpha( struct cso_context *cso,
const struct pipe_depth_stencil_alpha_state *dsa );
+void cso_save_depth_stencil_alpha(struct cso_context *cso);
+void cso_restore_depth_stencil_alpha(struct cso_context *cso);
+
-void cso_unset_depth_stencil_alpha( struct cso_context *cso );
void cso_set_rasterizer( struct cso_context *cso,
const struct pipe_rasterizer_state *rasterizer );
+void cso_save_rasterizer(struct cso_context *cso);
+void cso_restore_rasterizer(struct cso_context *cso);
+
-void cso_unset_rasterizer( struct cso_context *cso );
void cso_set_samplers( struct cso_context *cso,
unsigned count,
const struct pipe_sampler_state **states );
-
-void cso_unset_samplers( struct cso_context *cso );
-
+void cso_save_samplers(struct cso_context *cso);
+void cso_restore_samplers(struct cso_context *cso);
/* Alternate interface to support state trackers that like to modify
* samplers one at a time:
@@ -73,6 +82,15 @@ void cso_single_sampler( struct cso_context *cso,
void cso_single_sampler_done( struct cso_context *cso );
+
+void cso_set_sampler_textures( struct cso_context *cso,
+ uint count,
+ struct pipe_texture **textures );
+void cso_save_sampler_textures( struct cso_context *cso );
+void cso_restore_sampler_textures( struct cso_context *cso );
+
+
+
/* These aren't really sensible -- most of the time the api provides
* object semantics for shaders anyway, and the cases where it doesn't
* (eg mesa's internall-generated texenv programs), it will be up to
@@ -80,15 +98,32 @@ void cso_single_sampler_done( struct cso_context *cso );
*/
void cso_set_fragment_shader( struct cso_context *cso,
const struct pipe_shader_state *shader );
+void cso_save_fragment_shader(struct cso_context *cso);
+void cso_restore_fragment_shader(struct cso_context *cso);
+
-void cso_unset_fragment_shader( struct cso_context *cso );
void cso_set_vertex_shader( struct cso_context *cso,
const struct pipe_shader_state *shader );
+void cso_save_vertex_shader(struct cso_context *cso);
+void cso_restore_vertex_shader(struct cso_context *cso);
-void cso_unset_vertex_shader( struct cso_context *cso );
-void cso_destroy_context( struct cso_context *cso );
+
+void cso_set_framebuffer(struct cso_context *cso,
+ const struct pipe_framebuffer_state *fb);
+void cso_save_framebuffer(struct cso_context *cso);
+void cso_restore_framebuffer(struct cso_context *cso);
+
+
+void cso_set_viewport(struct cso_context *cso,
+ const struct pipe_viewport_state *vp);
+void cso_save_viewport(struct cso_context *cso);
+void cso_restore_viewport(struct cso_context *cso);
+
+
+void cso_set_blend_color(struct cso_context *cso,
+ const struct pipe_blend_color *bc);
#ifdef __cplusplus
diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c
index f2b983374e..6742f7f4b9 100644
--- a/src/gallium/auxiliary/draw/draw_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_aaline.c
@@ -410,6 +410,7 @@ aaline_create_texture(struct aaline_stage *aaline)
/* unmap */
pipe_surface_unmap(surface);
pipe_surface_reference(&surface, NULL);
+ pipe->texture_update(pipe, aaline->texture, 0, (1 << level));
}
}
@@ -664,7 +665,14 @@ aaline_reset_stipple_counter(struct draw_stage *stage)
static void
aaline_destroy(struct draw_stage *stage)
{
+ struct aaline_stage *aaline = aaline_stage(stage);
+
+ aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso);
+
+ pipe_texture_release(&aaline->texture);
+
draw_free_temp_verts( stage );
+
FREE( stage );
}
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 4cca965ac1..41da93cdf8 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -113,6 +113,8 @@ void draw_destroy( struct draw_context *draw )
draw->pipeline.aaline->destroy( draw->pipeline.aaline );
if (draw->pipeline.aapoint)
draw->pipeline.aapoint->destroy( draw->pipeline.aapoint );
+ if (draw->pipeline.pstipple)
+ draw->pipeline.pstipple->destroy( draw->pipeline.pstipple );
if (draw->pipeline.rasterize)
draw->pipeline.rasterize->destroy( draw->pipeline.rasterize );
tgsi_exec_machine_free_data(&draw->machine);
diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c
index 09d542002f..bd8d3a76ae 100644
--- a/src/gallium/auxiliary/draw/draw_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pstipple.c
@@ -374,7 +374,7 @@ pstip_update_texture(struct pstip_stage *pstip)
/* unmap */
pipe_surface_unmap(surface);
pipe_surface_reference(&surface, NULL);
- pipe->texture_update(pipe, pstip->texture);
+ pipe->texture_update(pipe, pstip->texture, 0, 0x1);
}
@@ -534,6 +534,12 @@ pstip_reset_stipple_counter(struct draw_stage *stage)
static void
pstip_destroy(struct draw_stage *stage)
{
+ struct pstip_stage *pstip = pstip_stage(stage);
+
+ pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso);
+
+ pipe_texture_release(&pstip->texture);
+
draw_free_temp_verts( stage );
FREE( stage );
}
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index bb84e8096d..c51e9e6a69 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -52,6 +52,9 @@ rpl_EngDebugPrint(const char *format, ...)
}
int rpl_vsnprintf(char *, size_t, const char *, va_list);
+int rpl_snprintf(char *str, size_t size, const char *format, ...);
+#define vsnprintf rpl_vsnprintf
+#define snprintf rpl_snprintf
#endif
@@ -82,6 +85,22 @@ void debug_printf(const char *format, ...)
}
+void debug_print_blob( const char *name,
+ const void *blob,
+ unsigned size )
+{
+ const unsigned *ublob = (const unsigned *)blob;
+ unsigned i;
+
+ debug_printf("%s (%d dwords%s)\n", name, size/4,
+ size%4 ? "... plus a few bytes" : "");
+
+ for (i = 0; i < size/4; i++) {
+ debug_printf("%d:\t%08x\n", i, ublob[i]);
+ }
+}
+
+
/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */
@@ -181,3 +200,61 @@ void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_lis
if(mask & what)
debug_vprintf(format, ap);
}
+
+
+const char *
+debug_dump_enum(const struct debug_named_value *names,
+ unsigned long value)
+{
+ static char rest[256];
+
+ while(names->name) {
+ if(names->value == value)
+ return names->name;
+ ++names;
+ }
+
+ snprintf(rest, sizeof(rest), "0x%08x", value);
+ return rest;
+}
+
+
+const char *
+debug_dump_flags(const struct debug_named_value *names,
+ unsigned long value)
+{
+ static char output[4096];
+ static char rest[256];
+ int first = 1;
+
+ output[0] = '\0';
+
+ while(names->name) {
+ if((names->value & value) == names->value) {
+ if (!first)
+ strncat(output, "|", sizeof(output));
+ else
+ first = 0;
+ strncat(output, names->name, sizeof(output));
+ value &= ~names->value;
+ }
+ ++names;
+ }
+
+ if (value) {
+ if (!first)
+ strncat(output, "|", sizeof(output));
+ else
+ first = 0;
+
+ snprintf(rest, sizeof(rest), "0x%08x", value);
+ strncat(output, rest, sizeof(output));
+ }
+
+ if(first)
+ return "0";
+
+ return output;
+}
+
+
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 4b4ab8185f..28a404fd01 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -45,19 +45,25 @@
#include "util/u_blit.h"
#include "util/u_simple_shaders.h"
+#include "cso_cache/cso_context.h"
+
struct blit_state
{
struct pipe_context *pipe;
+ struct cso_context *cso;
- void *blend;
- void *depthstencil;
- void *rasterizer;
- void *samplers[2]; /* one for linear, one for nearest sampling */
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state depthstencil;
+ struct pipe_rasterizer_state rasterizer;
+ struct pipe_sampler_state sampler;
/*struct pipe_viewport_state viewport;*/
struct pipe_sampler_state *vs;
struct pipe_sampler_state *fs;
+
+ struct pipe_buffer *vbuf; /**< quad vertices */
+ float vertices[4][2][4]; /**< vertex/texcoords for quad */
};
@@ -66,56 +72,45 @@ struct blit_state
* Intended to be created once and re-used for many blit() calls.
*/
struct blit_state *
-util_create_blit(struct pipe_context *pipe)
+util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
{
- struct pipe_blend_state blend;
- struct pipe_depth_stencil_alpha_state depthstencil;
- struct pipe_rasterizer_state rasterizer;
struct blit_state *ctx;
- struct pipe_sampler_state sampler;
+ uint i;
ctx = CALLOC_STRUCT(blit_state);
if (!ctx)
return NULL;
ctx->pipe = pipe;
+ ctx->cso = cso;
- /* we don't use blending, but need to set valid values */
- memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
- ctx->blend = pipe->create_blend_state(pipe, &blend);
+ /* disabled blending/masking */
+ memset(&ctx->blend, 0, sizeof(ctx->blend));
+ ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ ctx->blend.colormask = PIPE_MASK_RGBA;
- /* depth/stencil/alpha */
- memset(&depthstencil, 0, sizeof(depthstencil));
- ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil);
+ /* no-op depth/stencil/alpha */
+ memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
/* rasterizer */
- memset(&rasterizer, 0, sizeof(rasterizer));
- rasterizer.front_winding = PIPE_WINDING_CW;
- rasterizer.cull_mode = PIPE_WINDING_NONE;
- rasterizer.bypass_clipping = 1; /* bypasses viewport too */
- /*rasterizer.bypass_vs = 1;*/
- ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer);
+ memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
+ ctx->rasterizer.front_winding = PIPE_WINDING_CW;
+ ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
+ ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */
+ /*ctx->rasterizer.bypass_vs = 1;*/
/* samplers */
- memset(&sampler, 0, sizeof(sampler));
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
- sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
- sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
- sampler.normalized_coords = 1;
- ctx->samplers[0] = pipe->create_sampler_state(pipe, &sampler);
-
- sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
- sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
- ctx->samplers[1] = pipe->create_sampler_state(pipe, &sampler);
-
+ memset(&ctx->sampler, 0, sizeof(ctx->sampler));
+ ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ ctx->sampler.min_img_filter = 0; /* set later */
+ ctx->sampler.mag_img_filter = 0; /* set later */
+ ctx->sampler.normalized_coords = 1;
#if 0
/* viewport */
@@ -141,6 +136,24 @@ util_create_blit(struct pipe_context *pipe)
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(ctx->vertices));
+ if (!ctx->vbuf) {
+ FREE(ctx);
+ ctx->pipe->delete_fs_state(ctx->pipe, ctx->fs);
+ ctx->pipe->delete_vs_state(ctx->pipe, ctx->vs);
+ return NULL;
+ }
+
+ /* init vertex data that doesn't change */
+ for (i = 0; i < 4; i++) {
+ ctx->vertices[i][0][3] = 1.0f; /* w */
+ ctx->vertices[i][1][2] = 0.0f; /* r */
+ ctx->vertices[i][1][3] = 1.0f; /* q */
+ }
+
return ctx;
}
@@ -153,20 +166,59 @@ util_destroy_blit(struct blit_state *ctx)
{
struct pipe_context *pipe = ctx->pipe;
- pipe->delete_blend_state(pipe, ctx->blend);
- pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil);
- pipe->delete_rasterizer_state(pipe, ctx->rasterizer);
- pipe->delete_sampler_state(pipe, ctx->samplers[0]);
- pipe->delete_sampler_state(pipe, ctx->samplers[1]);
-
pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_fs_state(pipe, ctx->fs);
+ pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
+
FREE(ctx);
}
/**
+ * Setup vertex data for the textured quad we'll draw.
+ * Note: y=0=top
+ */
+static void
+setup_vertex_data(struct blit_state *ctx,
+ float x0, float y0, float x1, float y1, float z)
+{
+ void *buf;
+
+ ctx->vertices[0][0][0] = x0;
+ ctx->vertices[0][0][1] = y0;
+ ctx->vertices[0][0][2] = z;
+ ctx->vertices[0][1][0] = 0.0f; /*s*/
+ ctx->vertices[0][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[1][0][0] = x1;
+ ctx->vertices[1][0][1] = y0;
+ ctx->vertices[1][0][2] = z;
+ ctx->vertices[1][1][0] = 1.0f; /*s*/
+ ctx->vertices[1][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[2][0][0] = x1;
+ ctx->vertices[2][0][1] = y1;
+ ctx->vertices[2][0][2] = z;
+ ctx->vertices[2][1][0] = 1.0f;
+ ctx->vertices[2][1][1] = 1.0f;
+
+ ctx->vertices[3][0][0] = x0;
+ ctx->vertices[3][0][1] = y1;
+ ctx->vertices[3][0][2] = z;
+ ctx->vertices[3][1][0] = 0.0f;
+ ctx->vertices[3][1][1] = 1.0f;
+
+ buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
+
+ ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf);
+}
+
+
+/**
* Copy pixel block from src surface to dst surface.
* Overlapping regions are acceptable.
* XXX need some control over blitting Z and/or stencil.
@@ -236,17 +288,24 @@ util_blit_pixels(struct blit_state *ctx,
src, srcLeft, srcTop, /* src */
srcW, srcH); /* size */
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.num_cbufs = 1;
- fb.cbufs[0] = dst;
- pipe->set_framebuffer_state(pipe, &fb);
+ /* save state (restored below) */
+ cso_save_blend(ctx->cso);
+ cso_save_depth_stencil_alpha(ctx->cso);
+ cso_save_rasterizer(ctx->cso);
+ cso_save_samplers(ctx->cso);
+ cso_save_sampler_textures(ctx->cso);
+ cso_save_framebuffer(ctx->cso);
+
+ /* set misc state we care about */
+ cso_set_blend(ctx->cso, &ctx->blend);
+ cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
+ cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
/* sampler */
- if (filter == PIPE_TEX_MIPFILTER_NEAREST)
- pipe->bind_sampler_states(pipe, 1, &ctx->samplers[0]);
- else
- pipe->bind_sampler_states(pipe, 1, &ctx->samplers[1]);
+ ctx->sampler.min_img_filter = filter;
+ ctx->sampler.mag_img_filter = filter;
+ cso_single_sampler(ctx->cso, 0, &ctx->sampler);
+ cso_single_sampler_done(ctx->cso);
/* texture */
pipe->set_sampler_textures(pipe, 1, &tex);
@@ -255,22 +314,34 @@ util_blit_pixels(struct blit_state *ctx,
pipe->bind_fs_state(pipe, ctx->fs);
pipe->bind_vs_state(pipe, ctx->vs);
- /* misc state */
- pipe->bind_blend_state(pipe, ctx->blend);
- pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil);
- pipe->bind_rasterizer_state(pipe, ctx->rasterizer);
+ /* drawing dest */
+ memset(&fb, 0, sizeof(fb));
+ fb.width = dst->width;
+ fb.height = dst->height;
+ fb.num_cbufs = 1;
+ fb.cbufs[0] = dst;
+ cso_set_framebuffer(ctx->cso, &fb);
/* draw quad */
- util_draw_texquad(pipe, dstX0, dstY0, dstX1, dstY1, z);
-
- /* unbind */
- pipe->set_sampler_textures(pipe, 0, NULL);
- pipe->bind_sampler_states(pipe, 0, NULL);
-
- /* free stuff */
+ setup_vertex_data(ctx,
+ (float) dstX0, (float) dstY0,
+ (float) dstX1, (float) dstY1, z);
+
+ util_draw_vertex_buffer(ctx->pipe, ctx->vbuf,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
+
+ /* restore state we changed */
+ cso_restore_blend(ctx->cso);
+ cso_restore_depth_stencil_alpha(ctx->cso);
+ cso_restore_rasterizer(ctx->cso);
+ cso_restore_samplers(ctx->cso);
+ cso_restore_sampler_textures(ctx->cso);
+ cso_restore_framebuffer(ctx->cso);
+
+ /* free the texture */
pipe_surface_reference(&texSurf, NULL);
screen->texture_release(screen, &tex);
-
- /* Note: caller must restore pipe/gallium state at this time */
}
diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
index a349be99ad..61f1d9bb32 100644
--- a/src/gallium/auxiliary/util/u_blit.h
+++ b/src/gallium/auxiliary/util/u_blit.h
@@ -30,15 +30,16 @@
#define U_BLIT_H
+
struct pipe_context;
struct pipe_surface;
+struct cso_context;
struct blit_state;
-
extern struct blit_state *
-util_create_blit(struct pipe_context *pipe);
+util_create_blit(struct pipe_context *pipe, struct cso_context *cso);
extern void
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 79a69de633..37e8533609 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -34,15 +34,51 @@
/**
+ * Draw a simple vertex buffer / primitive.
+ * Limited to float[4] vertex attribs, tightly packed.
+ */
+void
+util_draw_vertex_buffer(struct pipe_context *pipe,
+ struct pipe_buffer *vbuf,
+ uint prim_type,
+ uint num_verts,
+ uint num_attribs)
+{
+ struct pipe_vertex_buffer vbuffer;
+ struct pipe_vertex_element velement;
+ uint i;
+
+ /* tell pipe about the vertex buffer */
+ vbuffer.buffer = vbuf;
+ vbuffer.pitch = num_attribs * 4 * sizeof(float); /* vertex size */
+ vbuffer.buffer_offset = 0;
+ pipe->set_vertex_buffer(pipe, 0, &vbuffer);
+
+ /* tell pipe about the vertex attributes */
+ for (i = 0; i < num_attribs; i++) {
+ velement.src_offset = i * 4 * sizeof(float);
+ velement.vertex_buffer_index = 0;
+ velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ velement.nr_components = 4;
+ pipe->set_vertex_element(pipe, i, &velement);
+ }
+
+ /* draw */
+ pipe->draw_arrays(pipe, prim_type, 0, num_verts);
+}
+
+
+
+/**
* Draw screen-aligned textured quad.
+ * Note: this function allocs/destroys a vertex buffer and isn't especially
+ * efficient.
*/
void
util_draw_texquad(struct pipe_context *pipe,
float x0, float y0, float x1, float y1, float z)
{
struct pipe_buffer *vbuf;
- struct pipe_vertex_buffer vbuffer;
- struct pipe_vertex_element velement;
uint numAttribs = 2, vertexBytes, i, j;
float *v;
@@ -89,24 +125,7 @@ util_draw_texquad(struct pipe_context *pipe,
pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
- /* tell pipe about the vertex buffer */
- vbuffer.buffer = vbuf;
- vbuffer.pitch = numAttribs * 4 * sizeof(float); /* vertex size */
- vbuffer.buffer_offset = 0;
- pipe->set_vertex_buffer(pipe, 0, &vbuffer);
-
- /* tell pipe about the vertex attributes */
- for (i = 0; i < numAttribs; i++) {
- velement.src_offset = i * 4 * sizeof(float);
- velement.vertex_buffer_index = 0;
- velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- velement.nr_components = 4;
- pipe->set_vertex_element(pipe, i, &velement);
- }
-
- /* draw */
- pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4);
+ util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
- /* XXX: do one-time */
pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
}
diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h
index a97f55d2ef..5b6539a99c 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.h
+++ b/src/gallium/auxiliary/util/u_draw_quad.h
@@ -29,9 +29,25 @@
#define U_DRAWQUAD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern void
+util_draw_vertex_buffer(struct pipe_context *pipe,
+ struct pipe_buffer *vbuf,
+ uint num_attribs, uint num_verts, uint prim_type);
+
+
extern void
util_draw_texquad(struct pipe_context *pipe,
float x0, float y0, float x1, float y1, float z);
+#ifdef __cplusplus
+}
+#endif
+
+
#endif
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index e18f8ab72a..cf02f00b1b 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -49,17 +49,24 @@
#include "tgsi/util/tgsi_dump.h"
#include "tgsi/util/tgsi_parse.h"
+#include "cso_cache/cso_context.h"
+
struct gen_mipmap_state
{
struct pipe_context *pipe;
+ struct cso_context *cso;
- void *blend;
- void *depthstencil;
- void *rasterizer;
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state depthstencil;
+ struct pipe_rasterizer_state rasterizer;
+ struct pipe_sampler_state sampler;
/*struct pipe_viewport_state viewport;*/
struct pipe_sampler_state *vs;
struct pipe_sampler_state *fs;
+
+ struct pipe_buffer *vbuf; /**< quad vertices */
+ float vertices[4][2][4]; /**< vertex/texcoords for quad */
};
@@ -675,39 +682,47 @@ fallback_gen_mipmap(struct gen_mipmap_state *ctx,
* generate a mipmap.
*/
struct gen_mipmap_state *
-util_create_gen_mipmap(struct pipe_context *pipe)
+util_create_gen_mipmap(struct pipe_context *pipe,
+ struct cso_context *cso)
{
- struct pipe_blend_state blend;
- struct pipe_depth_stencil_alpha_state depthstencil;
- struct pipe_rasterizer_state rasterizer;
struct gen_mipmap_state *ctx;
+ uint i;
ctx = CALLOC_STRUCT(gen_mipmap_state);
if (!ctx)
return NULL;
ctx->pipe = pipe;
+ ctx->cso = cso;
- /* we don't use blending, but need to set valid values */
- memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
- ctx->blend = pipe->create_blend_state(pipe, &blend);
+ /* disabled blending/masking */
+ memset(&ctx->blend, 0, sizeof(ctx->blend));
+ ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ ctx->blend.colormask = PIPE_MASK_RGBA;
- /* depth/stencil/alpha */
- memset(&depthstencil, 0, sizeof(depthstencil));
- ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil);
+ /* no-op depth/stencil/alpha */
+ memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
/* rasterizer */
- memset(&rasterizer, 0, sizeof(rasterizer));
- rasterizer.front_winding = PIPE_WINDING_CW;
- rasterizer.cull_mode = PIPE_WINDING_NONE;
- rasterizer.bypass_clipping = 1; /* bypasses viewport too */
- //rasterizer.bypass_vs = 1;
- ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer);
+ memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
+ ctx->rasterizer.front_winding = PIPE_WINDING_CW;
+ ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
+ ctx->rasterizer.bypass_clipping = 1; /* bypasses viewport too */
+ /*ctx->rasterizer.bypass_vs = 1;*/
+
+ /* sampler state */
+ memset(&ctx->sampler, 0, sizeof(ctx->sampler));
+ ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ ctx->sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
+ ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+ ctx->sampler.normalized_coords = 1;
+
#if 0
/* viewport */
@@ -733,10 +748,62 @@ util_create_gen_mipmap(struct pipe_context *pipe)
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->vbuf = pipe->winsys->buffer_create(pipe->winsys,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(ctx->vertices));
+ if (!ctx->vbuf) {
+ FREE(ctx);
+ return NULL;
+ }
+
+ /* vertex data that doesn't change */
+ for (i = 0; i < 4; i++) {
+ ctx->vertices[i][0][2] = 0.0f; /* z */
+ ctx->vertices[i][0][3] = 1.0f; /* w */
+ ctx->vertices[i][1][2] = 0.0f; /* r */
+ ctx->vertices[i][1][3] = 1.0f; /* q */
+ }
+
return ctx;
}
+static void
+set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
+{
+ void *buf;
+
+ ctx->vertices[0][0][0] = 0.0f; /*x*/
+ ctx->vertices[0][0][1] = 0.0f; /*y*/
+ ctx->vertices[0][1][0] = 0.0f; /*s*/
+ ctx->vertices[0][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[1][0][0] = width; /*x*/
+ ctx->vertices[1][0][1] = 0.0f; /*y*/
+ ctx->vertices[1][1][0] = 1.0f; /*s*/
+ ctx->vertices[1][1][1] = 0.0f; /*t*/
+
+ ctx->vertices[2][0][0] = width;
+ ctx->vertices[2][0][1] = height;
+ ctx->vertices[2][1][0] = 1.0f;
+ ctx->vertices[2][1][1] = 1.0f;
+
+ ctx->vertices[3][0][0] = 0.0f;
+ ctx->vertices[3][0][1] = height;
+ ctx->vertices[3][1][0] = 0.0f;
+ ctx->vertices[3][1][1] = 1.0f;
+
+ buf = ctx->pipe->winsys->buffer_map(ctx->pipe->winsys, ctx->vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
+
+ ctx->pipe->winsys->buffer_unmap(ctx->pipe->winsys, ctx->vbuf);
+}
+
+
+
/**
* Destroy a mipmap generation context
*/
@@ -745,12 +812,11 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
{
struct pipe_context *pipe = ctx->pipe;
- pipe->delete_blend_state(pipe, ctx->blend);
- pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil);
- pipe->delete_rasterizer_state(pipe, ctx->rasterizer);
pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_fs_state(pipe, ctx->fs);
+ pipe->winsys->buffer_destroy(pipe->winsys, ctx->vbuf);
+
FREE(ctx);
}
@@ -792,8 +858,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
- struct pipe_sampler_state sampler;
- void *sampler_cso;
uint dstLevel;
uint zslice = 0;
@@ -803,30 +867,29 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
return;
}
- /* init framebuffer state */
- memset(&fb, 0, sizeof(fb));
- fb.num_cbufs = 1;
-
- /* sampler state */
- memset(&sampler, 0, sizeof(sampler));
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
- sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
- sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
- sampler.normalized_coords = 1;
+ /* save state (restored below) */
+ cso_save_blend(ctx->cso);
+ cso_save_depth_stencil_alpha(ctx->cso);
+ cso_save_rasterizer(ctx->cso);
+ cso_save_samplers(ctx->cso);
+ cso_save_sampler_textures(ctx->cso);
+ cso_save_framebuffer(ctx->cso);
/* bind our state */
- pipe->bind_blend_state(pipe, ctx->blend);
- pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil);
- pipe->bind_rasterizer_state(pipe, ctx->rasterizer);
+ cso_set_blend(ctx->cso, &ctx->blend);
+ cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
+ cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
+
pipe->bind_vs_state(pipe, ctx->vs);
pipe->bind_fs_state(pipe, ctx->fs);
#if 0
pipe->set_viewport_state(pipe, &ctx->viewport);
#endif
+ /* init framebuffer state */
+ memset(&fb, 0, sizeof(fb));
+ fb.num_cbufs = 1;
+
/*
* XXX for small mipmap levels, it may be faster to use the software
* fallback path...
@@ -838,7 +901,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
* Setup framebuffer / dest surface
*/
fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
- pipe->set_framebuffer_state(pipe, &fb);
+ fb.width = pt->width[dstLevel];
+ fb.height = pt->height[dstLevel];
+ cso_set_framebuffer(ctx->cso, &fb);
/*
* Setup sampler state
@@ -847,11 +912,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
* has trouble with min clamping so we also set the lod_bias to
* try to work around that.
*/
- sampler.min_lod = sampler.max_lod = (float) srcLevel;
- sampler.lod_bias = (float) srcLevel;
- sampler_cso = pipe->create_sampler_state(pipe, &sampler);
- pipe->bind_sampler_states(pipe, 1, &sampler_cso);
-
+ ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
+ ctx->sampler.lod_bias = (float) srcLevel;
+ cso_single_sampler(ctx->cso, 0, &ctx->sampler);
+ cso_single_sampler_done(ctx->cso);
#if 0
simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
#endif
@@ -859,19 +923,25 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
pipe->set_sampler_textures(pipe, 1, &pt);
/* quad coords in window coords (bypassing clipping, viewport mapping) */
- util_draw_texquad(pipe,
- 0.0F, 0.0F, /* x0, y0 */
- (float) pt->width[dstLevel], /* x1 */
- (float) pt->height[dstLevel], /* y1 */
- 0.0F); /* z */
-
+ set_vertex_data(ctx,
+ (float) pt->width[dstLevel],
+ (float) pt->height[dstLevel]);
+ util_draw_vertex_buffer(ctx->pipe, ctx->vbuf,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
pipe->flush(pipe, PIPE_FLUSH_WAIT);
- /*pipe->texture_update(pipe, pt); not really needed */
-
- pipe->delete_sampler_state(pipe, sampler_cso);
+ /* need to signal that the texture has changed _after_ rendering to it */
+ pipe->texture_update(pipe, pt, face, (1 << dstLevel));
}
- /* Note: caller must restore pipe/gallium state at this time */
+ /* restore state we changed */
+ cso_restore_blend(ctx->cso);
+ cso_restore_depth_stencil_alpha(ctx->cso);
+ cso_restore_rasterizer(ctx->cso);
+ cso_restore_samplers(ctx->cso);
+ cso_restore_sampler_textures(ctx->cso);
+ cso_restore_framebuffer(ctx->cso);
}
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h
index 80496140a2..eeabf3bf07 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.h
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.h
@@ -31,11 +31,15 @@
#include "pipe/p_state.h"
+struct pipe_context;
+struct pipe_texture;
+struct cso_context;
+
struct gen_mipmap_state;
extern struct gen_mipmap_state *
-util_create_gen_mipmap(struct pipe_context *pipe);
+util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso);
extern void
diff --git a/src/gallium/auxiliary/util/u_handle_table.c b/src/gallium/auxiliary/util/u_handle_table.c
index 0bfb9e1b4a..2176a00959 100644
--- a/src/gallium/auxiliary/util/u_handle_table.c
+++ b/src/gallium/auxiliary/util/u_handle_table.c
@@ -170,9 +170,8 @@ handle_table_set(struct handle_table *ht,
unsigned index;
assert(ht);
- assert(handle > 0);
- assert(handle <= ht->size);
- if(!handle || handle > ht->size)
+ assert(handle);
+ if(!handle)
return 0;
assert(object);
@@ -185,7 +184,9 @@ handle_table_set(struct handle_table *ht,
if(!handle_table_resize(ht, index))
return 0;
- assert(!ht->objects[index]);
+ if(ht->objects[index] && ht->destroy)
+ ht->destroy(ht->objects[index]);
+
ht->objects[index] = object;
return handle;
@@ -199,13 +200,11 @@ handle_table_get(struct handle_table *ht,
void *object;
assert(ht);
- assert(handle > 0);
- assert(handle <= ht->size);
+ assert(handle);
if(!handle || handle > ht->size)
return NULL;
object = ht->objects[handle - 1];
- assert(object);
return object;
}
@@ -219,18 +218,14 @@ handle_table_remove(struct handle_table *ht,
unsigned index;
assert(ht);
- assert(handle > 0);
- assert(handle <= ht->size);
+ assert(handle);
if(!handle || handle > ht->size)
return;
index = handle - 1;
object = ht->objects[index];
- if(!object) {
- /* XXX: this warning may be noisy for legitimate use -- remove later */
- debug_warning("removing empty handle");
+ if(!object)
return;
- }
if(ht->destroy)
ht->destroy(object);
@@ -248,7 +243,7 @@ handle_table_get_next_handle(struct handle_table *ht,
unsigned index;
for(index = handle; index < ht->size; ++index) {
- if(!ht->objects[index])
+ if(ht->objects[index])
return index + 1;
}
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 88e2ab05bd..d230ddfbeb 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -68,7 +68,7 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
uint ti, i;
struct pipe_shader_state shader;
- tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0]));
+ tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
/* shader header
*/
@@ -84,16 +84,15 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/* declare inputs */
for (i = 0; i < num_attribs; i++) {
-
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
- /*
+
decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION;
- decl.Semantic.SemanticIndex = 0;
- */
+ decl.Semantic.SemanticName = semantic_names[i];
+ decl.Semantic.SemanticIndex = semantic_indexes[i];
+
decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.u.DeclarationRange.Last = i;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -102,19 +101,17 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/* declare outputs */
for (i = 0; i < num_attribs; i++) {
-
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_OUTPUT;
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = semantic_names[i];
decl.Semantic.SemanticIndex = semantic_indexes[i];
decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.u.DeclarationRange.Last = i;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
maxTokens - ti);
-
}
/* emit MOV instructions */
@@ -173,7 +170,7 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
uint ti;
struct pipe_shader_state shader;
- tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0]));
+ tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
/* shader header
*/
@@ -261,3 +258,98 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
return pipe->create_fs_state(pipe, &shader);
}
+
+
+
+
+/**
+ * Make simple fragment color pass-through shader.
+ */
+void *
+util_make_fragment_passthrough_shader(struct pipe_context *pipe)
+{
+ uint maxTokens = 40;
+ struct tgsi_token *tokens;
+ struct tgsi_header *header;
+ struct tgsi_processor *processor;
+ struct tgsi_full_declaration decl;
+ struct tgsi_full_instruction inst;
+ const uint procType = TGSI_PROCESSOR_FRAGMENT;
+ uint ti;
+ struct pipe_shader_state shader;
+
+ tokens = (struct tgsi_token *) MALLOC(maxTokens * sizeof(tokens[0]));
+
+ /* shader header
+ */
+ *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
+
+ header = (struct tgsi_header *) &tokens[1];
+ *header = tgsi_build_header();
+
+ processor = (struct tgsi_processor *) &tokens[2];
+ *processor = tgsi_build_processor( procType, header );
+
+ ti = 3;
+
+ /* declare input */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_INPUT;
+ decl.Declaration.Semantic = 1;
+ decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
+ decl.Semantic.SemanticIndex = 0;
+ decl.u.DeclarationRange.First =
+ decl.u.DeclarationRange.Last = 0;
+ ti += tgsi_build_full_declaration(&decl,
+ &tokens[ti],
+ header,
+ maxTokens - ti);
+
+ /* declare output */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_OUTPUT;
+ decl.Declaration.Semantic = 1;
+ decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
+ decl.Semantic.SemanticIndex = 0;
+ decl.u.DeclarationRange.First =
+ decl.u.DeclarationRange.Last = 0;
+ ti += tgsi_build_full_declaration(&decl,
+ &tokens[ti],
+ header,
+ maxTokens - ti);
+
+
+ /* MOVE out[0], in[0]; */
+ inst = tgsi_default_full_instruction();
+ inst.Instruction.Opcode = TGSI_OPCODE_MOV;
+ inst.Instruction.NumDstRegs = 1;
+ inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
+ inst.FullDstRegisters[0].DstRegister.Index = 0;
+ inst.Instruction.NumSrcRegs = 1;
+ inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+ inst.FullSrcRegisters[0].SrcRegister.Index = 0;
+ ti += tgsi_build_full_instruction(&inst,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
+
+ /* END instruction */
+ inst = tgsi_default_full_instruction();
+ inst.Instruction.Opcode = TGSI_OPCODE_END;
+ inst.Instruction.NumDstRegs = 0;
+ inst.Instruction.NumSrcRegs = 0;
+ ti += tgsi_build_full_instruction(&inst,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
+
+ assert(ti < maxTokens);
+
+#if 0 /*debug*/
+ tgsi_dump(tokens, 0);
+#endif
+
+ shader.tokens = tokens;
+ return pipe->create_fs_state(pipe, &shader);
+}
+
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index 3ef4f28801..ca219a092c 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -36,6 +36,11 @@
struct pipe_context;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
extern void *
util_make_vertex_passthrough_shader(struct pipe_context *pipe,
uint num_attribs,
@@ -47,6 +52,13 @@ extern void *
util_make_fragment_tex_shader(struct pipe_context *pipe);
+extern void *
+util_make_fragment_passthrough_shader(struct pipe_context *pipe);
+
+
+#ifdef __cplusplus
+}
#endif
+#endif
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index fe93fd8e1a..d59e4f7036 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -115,6 +115,16 @@ struct cell_command_depth_stencil_alpha_test {
/**
+ * Upload code to perform framebuffer blend operation
+ */
+struct cell_command_blend {
+ uint64_t base; /**< Effective address of code start. */
+ unsigned size; /**< Size in bytes of test code. */
+ unsigned read_fb; /**< Flag: should framebuffer be read? */
+};
+
+
+/**
* Tell SPUs about the framebuffer size, location
*/
struct cell_command_framebuffer
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index c880760e4b..00f4be7401 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -1,5 +1,5 @@
/**************************************************************************
- *
+ *
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
@@ -10,11 +10,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -22,7 +22,7 @@
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
/* Authors:
@@ -47,21 +47,20 @@ cell_create_blend_state(struct pipe_context *pipe,
struct cell_blend_state *cb = MALLOC(sizeof(struct cell_blend_state));
(void) memcpy(cb, blend, sizeof(*blend));
- cb->code.store = NULL;
+ cell_generate_alpha_blend(cb);
return cb;
}
static void
-cell_bind_blend_state(struct pipe_context *pipe, void *blend)
+cell_bind_blend_state(struct pipe_context *pipe, void *state)
{
struct cell_context *cell = cell_context(pipe);
draw_flush(cell->draw);
- cell->blend = (const struct cell_blend_state *)blend;
-
+ cell->blend = (struct cell_blend_state *) state;
cell->dirty |= CELL_NEW_BLEND;
}
@@ -70,7 +69,7 @@ static void
cell_delete_blend_state(struct pipe_context *pipe, void *blend)
{
struct cell_blend_state *cb = (struct cell_blend_state *) blend;
-
+
spe_release_func(& cb->code);
FREE(cb);
}
@@ -100,7 +99,7 @@ cell_create_depth_stencil_alpha_state(struct pipe_context *pipe,
MALLOC(sizeof(struct cell_depth_stencil_alpha_state));
(void) memcpy(cdsa, depth_stencil, sizeof(*depth_stencil));
- cdsa->code.store = NULL;
+ cell_generate_depth_stencil_test(cdsa);
return cdsa;
}
@@ -111,16 +110,11 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe,
void *depth_stencil)
{
struct cell_context *cell = cell_context(pipe);
- struct cell_depth_stencil_alpha_state *cdsa =
- (struct cell_depth_stencil_alpha_state *) depth_stencil;
draw_flush(cell->draw);
- if ((cdsa != NULL) && (cdsa->code.store == NULL)) {
- cell_generate_depth_stencil_test(cdsa);
- }
-
- cell->depth_stencil = cdsa;
+ cell->depth_stencil =
+ (struct cell_depth_stencil_alpha_state *) depth_stencil;
cell->dirty |= CELL_NEW_DEPTH_STENCIL;
}
@@ -357,4 +351,3 @@ cell_init_state_functions(struct cell_context *cell)
cell->pipe.set_scissor_state = cell_set_scissor_state;
cell->pipe.set_viewport_state = cell_set_viewport_state;
}
-
diff --git a/src/gallium/drivers/cell/ppu/cell_state_derived.c b/src/gallium/drivers/cell/ppu/cell_state_derived.c
index 5c240a55c0..5480534ad9 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_derived.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_derived.c
@@ -141,17 +141,8 @@ calculate_vertex_layout( struct cell_context *cell )
static void
compute_cliprect(struct cell_context *sp)
{
- unsigned surfWidth, surfHeight;
-
- if (sp->framebuffer.num_cbufs > 0) {
- surfWidth = sp->framebuffer.cbufs[0]->width;
- surfHeight = sp->framebuffer.cbufs[0]->height;
- }
- else {
- /* no surface? */
- surfWidth = sp->scissor.maxx;
- surfHeight = sp->scissor.maxy;
- }
+ uint surfWidth = sp->framebuffer.width;
+ uint surfHeight = sp->framebuffer.height;
if (sp->rasterizer->scissor) {
/* clip to scissor rect */
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 4d589bcdbf..5709b48f12 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -60,14 +60,25 @@ cell_emit_state(struct cell_context *cell)
fb->color_format = cbuf->format;
fb->depth_start = cell->zsbuf_map;
fb->depth_format = zbuf ? zbuf->format : PIPE_FORMAT_NONE;
- fb->width = cell->framebuffer.cbufs[0]->width;
- fb->height = cell->framebuffer.cbufs[0]->height;
+ fb->width = cell->framebuffer.width;
+ fb->height = cell->framebuffer.height;
}
if (cell->dirty & CELL_NEW_BLEND) {
- emit_state_cmd(cell, CELL_CMD_STATE_BLEND,
- cell->blend,
- sizeof(struct pipe_blend_state));
+ struct cell_command_blend blend;
+
+ if (cell->blend != NULL) {
+ blend.base = (intptr_t) cell->blend->code.store;
+ blend.size = (char *) cell->blend->code.csr
+ - (char *) cell->blend->code.store;
+ blend.read_fb = TRUE;
+ } else {
+ blend.base = 0;
+ blend.size = 0;
+ blend.read_fb = FALSE;
+ }
+
+ emit_state_cmd(cell, CELL_CMD_STATE_BLEND, &blend, sizeof(blend));
}
if (cell->dirty & CELL_NEW_DEPTH_STENCIL) {
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
index 9c47968459..c750b1d89d 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
@@ -72,8 +72,8 @@ emit_alpha_test(struct pipe_depth_stencil_alpha_state *dsa,
int tmp_a = spe_allocate_available_register(f);
int tmp_b = spe_allocate_available_register(f);
union {
- float f;
- unsigned u;
+ float f;
+ unsigned u;
} ref_val;
boolean complement = FALSE;
@@ -84,42 +84,42 @@ emit_alpha_test(struct pipe_depth_stencil_alpha_state *dsa,
switch (dsa->alpha.func) {
case PIPE_FUNC_NOTEQUAL:
- complement = TRUE;
- /* FALLTHROUGH */
+ complement = TRUE;
+ /* FALLTHROUGH */
case PIPE_FUNC_EQUAL:
- spe_fceq(f, tmp_a, ref, alphas);
- break;
+ spe_fceq(f, tmp_a, ref, alphas);
+ break;
case PIPE_FUNC_LEQUAL:
- complement = TRUE;
- /* FALLTHROUGH */
+ complement = TRUE;
+ /* FALLTHROUGH */
case PIPE_FUNC_GREATER:
- spe_fcgt(f, tmp_a, ref, alphas);
- break;
+ spe_fcgt(f, tmp_a, ref, alphas);
+ break;
case PIPE_FUNC_LESS:
- complement = TRUE;
- /* FALLTHROUGH */
+ complement = TRUE;
+ /* FALLTHROUGH */
case PIPE_FUNC_GEQUAL:
- spe_fcgt(f, tmp_a, ref, alphas);
- spe_fceq(f, tmp_b, ref, alphas);
- spe_or(f, tmp_a, tmp_b, tmp_a);
- break;
+ spe_fcgt(f, tmp_a, ref, alphas);
+ spe_fceq(f, tmp_b, ref, alphas);
+ spe_or(f, tmp_a, tmp_b, tmp_a);
+ break;
case PIPE_FUNC_ALWAYS:
case PIPE_FUNC_NEVER:
default:
- assert(0);
- break;
+ assert(0);
+ break;
}
if (complement) {
- spe_andc(f, mask, mask, tmp_a);
+ spe_andc(f, mask, mask, tmp_a);
} else {
- spe_and(f, mask, mask, tmp_a);
+ spe_and(f, mask, mask, tmp_a);
}
spe_release_register(f, ref);
@@ -588,19 +588,13 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa)
*/
static int
emit_alpha_factor_calculation(struct spe_function *f,
- unsigned factor, float const_alpha,
- int src_alpha, int dst_alpha)
+ unsigned factor,
+ int src_alpha, int dst_alpha, int const_alpha)
{
- union {
- float f;
- unsigned u;
- } alpha;
int factor_reg;
int tmp;
- alpha.f = const_alpha;
-
switch (factor) {
case PIPE_BLENDFACTOR_ONE:
factor_reg = -1;
@@ -621,13 +615,17 @@ emit_alpha_factor_calculation(struct spe_function *f,
break;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- const_alpha = 1.0 - const_alpha;
- /* FALLTHROUGH */
- case PIPE_BLENDFACTOR_CONST_ALPHA:
factor_reg = spe_allocate_available_register(f);
- spe_il(f, factor_reg, alpha.u & 0x0ffff);
- spe_ilh(f, factor_reg, alpha.u >> 16);
+ tmp = spe_allocate_available_register(f);
+ spe_il(f, tmp, 1);
+ spe_cuflt(f, tmp, tmp, 0);
+ spe_fs(f, factor_reg, tmp, const_alpha);
+ spe_release_register(f, tmp);
+ break;
+
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ factor_reg = const_alpha;
break;
case PIPE_BLENDFACTOR_ZERO:
@@ -669,29 +667,20 @@ emit_alpha_factor_calculation(struct spe_function *f,
/**
- * \note Emits a maximum of 5 instructions
+ * \note Emits a maximum of 6 instructions
*/
static void
emit_color_factor_calculation(struct spe_function *f,
unsigned sF, unsigned mask,
- const struct pipe_blend_color *blend_color,
const int *src,
const int *dst,
+ const int *const_color,
int *factor)
{
- union {
- float f[4];
- unsigned u[4];
- } color;
int tmp;
unsigned i;
- color.f[0] = blend_color->color[0];
- color.f[1] = blend_color->color[1];
- color.f[2] = blend_color->color[2];
- color.f[3] = blend_color->color[3];
-
factor[0] = -1;
factor[1] = -1;
factor[2] = -1;
@@ -748,29 +737,40 @@ emit_color_factor_calculation(struct spe_function *f,
break;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- color.f[0] = 1.0 - color.f[0];
- color.f[1] = 1.0 - color.f[1];
- color.f[2] = 1.0 - color.f[2];
- /* FALLTHROUGH */
- case PIPE_BLENDFACTOR_CONST_COLOR:
+ tmp = spe_allocate_available_register(f);
+ spe_il(f, tmp, 1);
+ spe_cuflt(f, tmp, tmp, 0);
+
for (i = 0; i < 3; i++) {
- factor[i] = spe_allocate_available_register(f);
+ factor[i] = spe_allocate_available_register(f);
+
+ spe_fs(f, factor[i], tmp, const_color[i]);
+ }
+ spe_release_register(f, tmp);
+ break;
- spe_il(f, factor[i], color.u[i] & 0x0ffff);
- spe_ilh(f, factor[i], color.u[i] >> 16);
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ for (i = 0; i < 3; i++) {
+ factor[i] = const_color[i];
}
break;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- color.f[3] = 1.0 - color.f[3];
- /* FALLTHROUGH */
- case PIPE_BLENDFACTOR_CONST_ALPHA:
factor[0] = spe_allocate_available_register(f);
factor[1] = factor[0];
factor[2] = factor[0];
- spe_il(f, factor[0], color.u[3] & 0x0ffff);
- spe_ilh(f, factor[0], color.u[3] >> 16);
+ tmp = spe_allocate_available_register(f);
+ spe_il(f, tmp, 1);
+ spe_cuflt(f, tmp, tmp, 0);
+ spe_fs(f, factor[0], tmp, const_color[3]);
+ spe_release_register(f, tmp);
+ break;
+
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ factor[0] = const_color[3];
+ factor[1] = factor[0];
+ factor[2] = factor[0];
break;
case PIPE_BLENDFACTOR_ZERO:
@@ -864,7 +864,11 @@ emit_blend_calculation(struct spe_function *f,
spe_il(f, src, 0);
} else if (dF == PIPE_BLENDFACTOR_ONE) {
spe_or(f, src, dst, dst);
+ } else {
+ spe_fm(f, src, dst, dst_factor);
}
+ } else if (dF == PIPE_BLENDFACTOR_ZERO) {
+ spe_fm(f, src, src, src_factor);
} else {
spe_fm(f, tmp, dst, dst_factor);
spe_fma(f, src, src, src_factor, tmp);
@@ -884,7 +888,11 @@ emit_blend_calculation(struct spe_function *f,
} else if (dF == PIPE_BLENDFACTOR_ONE) {
spe_il(f, tmp, 0);
spe_fs(f, src, tmp, dst);
+ } else {
+ spe_fm(f, src, dst, dst_factor);
}
+ } else if (dF == PIPE_BLENDFACTOR_ZERO) {
+ spe_fm(f, src, src, src_factor);
} else {
spe_fm(f, tmp, dst, dst_factor);
spe_fms(f, src, src, src_factor, tmp);
@@ -904,7 +912,11 @@ emit_blend_calculation(struct spe_function *f,
spe_il(f, src, 0);
} else if (dF == PIPE_BLENDFACTOR_ONE) {
spe_or(f, src, dst, dst);
+ } else {
+ spe_fm(f, src, dst, dst_factor);
}
+ } else if (dF == PIPE_BLENDFACTOR_ZERO) {
+ spe_fm(f, src, src, src_factor);
} else {
spe_fm(f, tmp, src, src_factor);
spe_fms(f, src, src, dst_factor, tmp);
@@ -913,12 +925,12 @@ emit_blend_calculation(struct spe_function *f,
case PIPE_BLEND_MIN:
spe_cgt(f, tmp, src, dst);
- spe_selb(f, src, dst, src, tmp);
+ spe_selb(f, src, src, dst, tmp);
break;
case PIPE_BLEND_MAX:
spe_cgt(f, tmp, src, dst);
- spe_selb(f, src, src, dst, tmp);
+ spe_selb(f, src, dst, src, tmp);
break;
default:
@@ -933,16 +945,15 @@ emit_blend_calculation(struct spe_function *f,
* Generate code to perform alpha blending on the SPE
*/
void
-cell_generate_alpha_blend(struct cell_blend_state *cb,
- const struct pipe_blend_color *blend_color)
+cell_generate_alpha_blend(struct cell_blend_state *cb)
{
struct pipe_blend_state *const b = &cb->base;
struct spe_function *const f = &cb->code;
/* This code generates a maximum of 3 (source alpha factor)
- * + 3 (destination alpha factor) + (3 * 5) (source color factor)
- * + (3 * 5) (destination color factor) + (4 * 2) (blend equation)
- * + 4 (fragment mask) + 1 (return) = 49 instlructions. Round up to 64 to
+ * + 3 (destination alpha factor) + (3 * 6) (source color factor)
+ * + (3 * 6) (destination color factor) + (4 * 2) (blend equation)
+ * + 4 (fragment mask) + 1 (return) = 55 instlructions. Round up to 64 to
* make it a happy power-of-two.
*/
spe_init_func(f, 4 * 64);
@@ -960,7 +971,13 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
spe_allocate_register(f, 9),
spe_allocate_register(f, 10),
};
- const int mask = spe_allocate_register(f, 11);
+ const int const_color[4] = {
+ spe_allocate_register(f, 11),
+ spe_allocate_register(f, 12),
+ spe_allocate_register(f, 13),
+ spe_allocate_register(f, 14),
+ };
+ const int mask = spe_allocate_register(f, 15);
unsigned func[4];
unsigned sF[4];
unsigned dF[4];
@@ -984,24 +1001,64 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
&& (b->alpha_func != PIPE_BLEND_MAX);
- sF[0] = b->rgb_src_factor;
- sF[1] = sF[0];
- sF[2] = sF[0];
- sF[3] = (b->alpha_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
- ? PIPE_BLENDFACTOR_ONE : b->alpha_src_factor;
+ if (b->blend_enable) {
+ sF[0] = b->rgb_src_factor;
+ sF[1] = sF[0];
+ sF[2] = sF[0];
+ switch (b->alpha_src_factor & 0x0f) {
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ sF[3] = PIPE_BLENDFACTOR_ONE;
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ sF[3] = b->alpha_src_factor + 1;
+ break;
+ default:
+ sF[3] = b->alpha_src_factor;
+ }
- dF[0] = b->rgb_dst_factor;
- dF[1] = dF[0];
- dF[2] = dF[0];
- dF[3] = b->rgb_dst_factor;
+ dF[0] = b->rgb_dst_factor;
+ dF[1] = dF[0];
+ dF[2] = dF[0];
+ switch (b->alpha_dst_factor & 0x0f) {
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ dF[3] = b->alpha_dst_factor + 1;
+ break;
+ default:
+ dF[3] = b->alpha_dst_factor;
+ }
+
+ func[0] = b->rgb_func;
+ func[1] = func[0];
+ func[2] = func[0];
+ func[3] = b->alpha_func;
+ } else {
+ sF[0] = PIPE_BLENDFACTOR_ONE;
+ sF[1] = PIPE_BLENDFACTOR_ONE;
+ sF[2] = PIPE_BLENDFACTOR_ONE;
+ sF[3] = PIPE_BLENDFACTOR_ONE;
+ dF[0] = PIPE_BLENDFACTOR_ZERO;
+ dF[1] = PIPE_BLENDFACTOR_ZERO;
+ dF[2] = PIPE_BLENDFACTOR_ZERO;
+ dF[3] = PIPE_BLENDFACTOR_ZERO;
+
+ func[0] = PIPE_BLEND_ADD;
+ func[1] = PIPE_BLEND_ADD;
+ func[2] = PIPE_BLEND_ADD;
+ func[3] = PIPE_BLEND_ADD;
+ }
/* If alpha writing is enabled and the alpha blend mode requires use of
* the alpha factor, calculate the alpha factor.
*/
if (((b->colormask & 8) != 0) && need_alpha_factor) {
- src_factor[3] = emit_alpha_factor_calculation(f, sF[3],
- blend_color->color[3],
+ src_factor[3] = emit_alpha_factor_calculation(f, sF[3], const_color[3],
frag[3], pixel[3]);
/* If the alpha destination blend factor is the same as the alpha source
@@ -1009,8 +1066,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
*/
dst_factor[3] = (dF[3] == sF[3])
? src_factor[3]
- : emit_alpha_factor_calculation(f, dF[3],
- blend_color->color[3],
+ : emit_alpha_factor_calculation(f, dF[3], const_color[3],
frag[3], pixel[3]);
}
@@ -1027,8 +1083,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
emit_color_factor_calculation(f,
b->rgb_src_factor,
b->colormask,
- blend_color,
- frag, pixel, src_factor);
+ frag, pixel, const_color, src_factor);
}
@@ -1048,17 +1103,11 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
emit_color_factor_calculation(f,
b->rgb_dst_factor,
b->colormask,
- blend_color,
- frag, pixel, dst_factor);
+ frag, pixel, const_color, dst_factor);
}
- func[0] = b->rgb_func;
- func[1] = func[0];
- func[2] = func[0];
- func[3] = b->alpha_func;
-
for (i = 0; i < 4; ++i) {
if ((b->colormask & (1U << i)) != 0) {
emit_blend_calculation(f,
@@ -1072,4 +1121,28 @@ cell_generate_alpha_blend(struct cell_blend_state *cb,
}
spe_bi(f, 0, 0, 0);
+
+#if 0
+ {
+ const uint32_t *p = f->store;
+
+ printf("# %u instructions\n", f->csr - f->store);
+ printf("# blend (%sabled)\n",
+ (cb->base.blend_enable) ? "en" : "dis");
+ printf("# RGB func / sf / df: %u %u %u\n",
+ cb->base.rgb_func,
+ cb->base.rgb_src_factor,
+ cb->base.rgb_dst_factor);
+ printf("# ALP func / sf / df: %u %u %u\n",
+ cb->base.alpha_func,
+ cb->base.alpha_src_factor,
+ cb->base.alpha_dst_factor);
+
+ printf("\t.text\n");
+ for (/* empty */; p < f->csr; p++) {
+ printf("\t.long\t0x%04x\n", *p);
+ }
+ fflush(stdout);
+ }
+#endif
}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
index 541c3b3be0..f699247f9e 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
@@ -29,7 +29,6 @@ extern void
cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa);
extern void
-cell_generate_alpha_blend(struct cell_blend_state *cb,
- const struct pipe_blend_color *blend_color);
+cell_generate_alpha_blend(struct cell_blend_state *cb);
#endif /* CELL_STATE_PER_FRAGMENT_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index e235421107..9c694e136d 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -134,7 +134,8 @@ cell_texture_release_screen(struct pipe_screen *screen,
static void
-cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture)
+cell_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
+ uint face, uint levelsMask)
{
/* XXX TO DO: re-tile the texture data ... */
diff --git a/src/gallium/drivers/cell/spu/Makefile b/src/gallium/drivers/cell/spu/Makefile
index 115ca8cd90..8e83610790 100644
--- a/src/gallium/drivers/cell/spu/Makefile
+++ b/src/gallium/drivers/cell/spu/Makefile
@@ -17,7 +17,6 @@ PROG_SPU_EMBED_O = $(PROG)_spu-embed.o
SOURCES = \
spu_main.c \
- spu_blend.c \
spu_dcache.c \
spu_per_fragment_op.c \
spu_render.c \
diff --git a/src/gallium/drivers/cell/spu/spu_blend.c b/src/gallium/drivers/cell/spu/spu_blend.c
deleted file mode 100644
index 23ec0eeb45..0000000000
--- a/src/gallium/drivers/cell/spu/spu_blend.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#include "spu_main.h"
-#include "spu_blend.h"
-#include "spu_colorpack.h"
-
-
-void
-blend_quad(uint itx, uint ity, vector float colors[4])
-{
- /* simple SRC_ALPHA, ONE_MINUS_SRC_ALPHA blending */
- vector float fbc00 = spu_unpack_color(spu.ctile.ui[ity][itx]);
- vector float fbc01 = spu_unpack_color(spu.ctile.ui[ity][itx+1]);
- vector float fbc10 = spu_unpack_color(spu.ctile.ui[ity+1][itx]);
- vector float fbc11 = spu_unpack_color(spu.ctile.ui[ity+1][itx+1]);
-
- vector float alpha00 = spu_splats(spu_extract(colors[0], 3));
- vector float alpha01 = spu_splats(spu_extract(colors[1], 3));
- vector float alpha10 = spu_splats(spu_extract(colors[2], 3));
- vector float alpha11 = spu_splats(spu_extract(colors[3], 3));
-
- vector float one_minus_alpha00 = spu_sub(spu_splats(1.0f), alpha00);
- vector float one_minus_alpha01 = spu_sub(spu_splats(1.0f), alpha01);
- vector float one_minus_alpha10 = spu_sub(spu_splats(1.0f), alpha10);
- vector float one_minus_alpha11 = spu_sub(spu_splats(1.0f), alpha11);
-
- colors[0] = spu_add(spu_mul(colors[0], alpha00),
- spu_mul(fbc00, one_minus_alpha00));
- colors[1] = spu_add(spu_mul(colors[1], alpha01),
- spu_mul(fbc01, one_minus_alpha01));
- colors[2] = spu_add(spu_mul(colors[2], alpha10),
- spu_mul(fbc10, one_minus_alpha10));
- colors[3] = spu_add(spu_mul(colors[3], alpha11),
- spu_mul(fbc11, one_minus_alpha11));
-}
-
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index 937962285d..0a490ab277 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -61,6 +61,10 @@ static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX]
static unsigned char depth_stencil_code_buffer[4 * 64]
ALIGN16_ATTRIB;
+static unsigned char fb_blend_code_buffer[4 * 64]
+ ALIGN16_ATTRIB;
+
+
/**
* Tell the PPU that this SPU has finished copying a buffer to
* local store and that it may be reused by the PPU.
@@ -246,14 +250,28 @@ cmd_state_framebuffer(const struct cell_command_framebuffer *cmd)
static void
-cmd_state_blend(const struct pipe_blend_state *state)
+cmd_state_blend(const struct cell_command_blend *state)
{
if (Debug)
printf("SPU %u: BLEND: enabled %d\n",
spu.init.id,
- state->blend_enable);
+ (state->size != 0));
- memcpy(&spu.blend, state, sizeof(*state));
+ ASSERT_ALIGN16(state->base);
+
+ if (state->size != 0) {
+ mfc_get(fb_blend_code_buffer,
+ (unsigned int) state->base, /* src */
+ ROUNDUP16(state->size),
+ TAG_BATCH_BUFFER,
+ 0, /* tid */
+ 0 /* rid */);
+ wait_on_mask(1 << TAG_BATCH_BUFFER);
+ spu.blend = (blend_func) fb_blend_code_buffer;
+ spu.read_fb = state->read_fb;
+ } else {
+ spu.read_fb = FALSE;
+ }
}
@@ -441,9 +459,8 @@ cmd_batch(uint opcode)
pos += 1;
break;
case CELL_CMD_STATE_BLEND:
- cmd_state_blend((struct pipe_blend_state *)
- &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct pipe_blend_state)) / 8);
+ cmd_state_blend((struct cell_command_blend *) &buffer[pos+1]);
+ pos += (1 + ROUNDUP8(sizeof(struct cell_command_blend)) / 8);
break;
case CELL_CMD_STATE_DEPTH_STENCIL:
cmd_state_depth_stencil((struct cell_command_depth_stencil_alpha_test *)
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index 444e218645..49f5d99674 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -67,6 +67,19 @@ typedef struct spu_frag_test_results (*frag_test_func)(qword frag_mask,
qword frag_alpha, qword facing);
+struct spu_blend_results {
+ qword r;
+ qword g;
+ qword b;
+ qword a;
+};
+
+typedef struct spu_blend_results (*blend_func)(
+ qword frag_r, qword frag_g, qword frag_b, qword frag_a,
+ qword pixel_r, qword pixel_g, qword pixel_b, qword pixel_a,
+ qword const_r, qword const_g, qword const_b, qword const_a,
+ qword frag_mask);
+
struct spu_framebuffer {
void *color_start; /**< addr of color surface in main memory */
void *depth_start; /**< addr of depth surface in main memory */
@@ -93,7 +106,11 @@ struct spu_global
boolean read_depth;
boolean read_stencil;
frag_test_func frag_test;
- struct pipe_blend_state blend;
+
+ boolean read_fb;
+ blend_func blend;
+ qword const_blend_color[4] ALIGN16_ATTRIB;
+
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct cell_command_texture texture;
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index 81823f2463..e6a1ce01df 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -29,10 +29,10 @@
* Triangle rendering within a tile.
*/
+#include <transpose_matrix4x4.h>
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "pipe/p_util.h"
-#include "spu_blend.h"
#include "spu_colorpack.h"
#include "spu_main.h"
#include "spu_texture.h"
@@ -261,6 +261,9 @@ do_depth_test(int x, int y, mask_t quadmask)
float4 zvals;
mask_t mask;
+ if (spu.fb.depth_format == PIPE_FORMAT_NONE)
+ return quadmask;
+
zvals.v = eval_z((float) x, (float) y);
mask = (mask_t) spu_do_depth_stencil(x - setup.cliprect_minx,
@@ -326,27 +329,47 @@ emit_quad( int x, int y, mask_t mask )
eval_coeff(1, (float) x, (float) y, colors);
}
-#if 1
- if (spu.blend.blend_enable)
- blend_quad(ix % TILE_SIZE, iy % TILE_SIZE, colors);
-#endif
- if (spu_extract(mask, 0))
- spu.ctile.ui[iy][ix] = spu_pack_color_shuffle(colors[0], shuffle);
- if (spu_extract(mask, 1))
- spu.ctile.ui[iy][ix+1] = spu_pack_color_shuffle(colors[1], shuffle);
- if (spu_extract(mask, 2))
- spu.ctile.ui[iy+1][ix] = spu_pack_color_shuffle(colors[2], shuffle);
- if (spu_extract(mask, 3))
- spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(colors[3], shuffle);
+ /* Read the current framebuffer values.
+ *
+ * Ignore read_fb for now. In the future we can use this to avoid
+ * reading the framebuffer if read_fb is false and the fragment mask is
+ * all 0xffffffff. This is the common case, so it is probably worth
+ * the effort. We'll have to profile to determine whether or not the
+ * extra conditional branches hurt overall performance.
+ */
+ vec_float4 aos_pix[4] = {
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+0]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+0][ix+1]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+0]),
+ spu_unpack_A8R8G8B8(spu.ctile.ui[iy+1][ix+1]),
+ };
-#if 0
- /* SIMD_Z with swizzled color buffer (someday) */
- vector unsigned int uicolors = *((vector unsigned int *) &colors);
- spu.ctile.ui4[iy/2][ix/2] = spu_sel(spu.ctile.ui4[iy/2][ix/2], uicolors, mask);
-#endif
- }
+ qword soa_pix[4];
+ qword soa_frag[4];
+ /* Convert pixel and fragment data from AoS to SoA format.
+ */
+ _transpose_matrix4x4((vec_float4 *) soa_pix, aos_pix);
+ _transpose_matrix4x4((vec_float4 *) soa_frag, colors);
+
+ const struct spu_blend_results result =
+ (*spu.blend)(soa_frag[0], soa_frag[1], soa_frag[2], soa_frag[3],
+ soa_pix[0], soa_pix[1], soa_pix[2], soa_pix[3],
+ spu.const_blend_color[0], spu.const_blend_color[1],
+ spu.const_blend_color[2], spu.const_blend_color[3],
+ (qword) mask);
+
+
+ /* Convert final pixel data from SoA to AoS format.
+ */
+ _transpose_matrix4x4(aos_pix, (const vec_float4 *) &result);
+
+ spu.ctile.ui[iy+0][ix+0] = spu_pack_color_shuffle(aos_pix[0], shuffle);
+ spu.ctile.ui[iy+0][ix+1] = spu_pack_color_shuffle(aos_pix[1], shuffle);
+ spu.ctile.ui[iy+1][ix+0] = spu_pack_color_shuffle(aos_pix[2], shuffle);
+ spu.ctile.ui[iy+1][ix+1] = spu_pack_color_shuffle(aos_pix[3], shuffle);
+ }
#endif
}
diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c
index 9dbb1b1b23..84f6529a3a 100644
--- a/src/gallium/drivers/i915simple/i915_state_sampler.c
+++ b/src/gallium/drivers/i915simple/i915_state_sampler.c
@@ -206,6 +206,12 @@ i915_update_texture(struct i915_context *i915, uint unit,
| format
| MS3_USE_FENCE_REGS);
+ /*
+ * XXX sampler->max_lod should be used to program the MAX_LOD field below.
+ * Also, when min_filter != mag_filter and there's just one mipmap level,
+ * set max_lod = 1 to make sure i915 chooses between min/mag filtering.
+ */
+
/* MS4 state */
state[1] =
((((pitch / 4) - 1) << MS4_PITCH_SHIFT)
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index ef5adff550..c39e747705 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -542,7 +542,8 @@ i915_texture_release_screen(struct pipe_screen *screen,
static void
-i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture)
+i915_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
+ uint face, uint levelsMask)
{
/* no-op? */
}
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c
index b24ac87c37..b580f98204 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -358,7 +358,8 @@ brw_texture_release_screen(struct pipe_screen *screen,
static void
-brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture)
+brw_texture_update(struct pipe_context *pipe, struct pipe_texture *texture,
+ uint face, uint levelsMask)
{
/* no-op? */
}
diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c
index 7aa9cf8e85..6a81e4d8cc 100644
--- a/src/gallium/drivers/softpipe/sp_prim_setup.c
+++ b/src/gallium/drivers/softpipe/sp_prim_setup.c
@@ -485,7 +485,7 @@ setup_fragcoord_coeff(struct setup_stage *setup, uint slot)
/*Y*/
if (setup->softpipe->rasterizer->origin_lower_left) {
/* y=0=bottom */
- const int winHeight = setup->softpipe->framebuffer.cbufs[0]->height;
+ const int winHeight = setup->softpipe->framebuffer.height;
setup->coef[slot].a0[1] = (float) (winHeight - 1);
setup->coef[slot].dady[1] = -1.0;
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c
index 8660432259..f1e9b80e09 100644
--- a/src/gallium/drivers/softpipe/sp_quad_stipple.c
+++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c
@@ -25,7 +25,7 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)
int y0, y1;
uint stipple0, stipple1;
if (softpipe->rasterizer->origin_lower_left) {
- y0 = softpipe->framebuffer.cbufs[0]->height - 1 - quad->y0;
+ y0 = softpipe->framebuffer.height - 1 - quad->y0;
y1 = y0 - 1;
}
else {
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 82cb31ece7..14abb20eeb 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -171,17 +171,8 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
static void
compute_cliprect(struct softpipe_context *sp)
{
- unsigned surfWidth, surfHeight;
-
- if (sp->framebuffer.num_cbufs > 0) {
- surfWidth = sp->framebuffer.cbufs[0]->width;
- surfHeight = sp->framebuffer.cbufs[0]->height;
- }
- else {
- /* no surface? */
- surfWidth = sp->scissor.maxx;
- surfHeight = sp->scissor.maxy;
- }
+ uint surfWidth = sp->framebuffer.width;
+ uint surfHeight = sp->framebuffer.height;
if (sp->rasterizer->scissor) {
/* clip to scissor rect */
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index 124b18b708..ba8c9eece7 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -101,9 +101,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
}
#endif
+ sp->framebuffer.width = fb->width;
+ sp->framebuffer.height = fb->height;
+
sp->dirty |= SP_NEW_FRAMEBUFFER;
}
-
-
-
-
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 64bf353aa4..256586ec88 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -81,8 +81,8 @@ softpipe_texture_layout(struct softpipe_texture * spt)
static struct pipe_texture *
-softpipe_texture_create_screen(struct pipe_screen *screen,
- const struct pipe_texture *templat)
+softpipe_texture_create(struct pipe_screen *screen,
+ const struct pipe_texture *templat)
{
struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
@@ -110,8 +110,8 @@ softpipe_texture_create_screen(struct pipe_screen *screen,
static void
-softpipe_texture_release_screen(struct pipe_screen *screen,
- struct pipe_texture **pt)
+softpipe_texture_release(struct pipe_screen *screen,
+ struct pipe_texture **pt)
{
if (!*pt)
return;
@@ -136,9 +136,9 @@ softpipe_texture_release_screen(struct pipe_screen *screen,
static struct pipe_surface *
-softpipe_get_tex_surface_screen(struct pipe_screen *screen,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice)
+softpipe_get_tex_surface(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice)
{
struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = softpipe_texture(pt);
@@ -174,7 +174,8 @@ softpipe_get_tex_surface_screen(struct pipe_screen *screen,
static void
softpipe_texture_update(struct pipe_context *pipe,
- struct pipe_texture *texture)
+ struct pipe_texture *texture,
+ uint face, uint levelsMask)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint unit;
@@ -196,7 +197,7 @@ softpipe_init_texture_funcs( struct softpipe_context *softpipe )
void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
- screen->texture_create = softpipe_texture_create_screen;
- screen->texture_release = softpipe_texture_release_screen;
- screen->get_tex_surface = softpipe_get_tex_surface_screen;
+ screen->texture_create = softpipe_texture_create;
+ screen->texture_release = softpipe_texture_release;
+ screen->get_tex_surface = softpipe_get_tex_surface;
}
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index 4caf2dd3fc..19f71887e7 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -156,6 +156,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
if (tc->surface_map) {
/*assert(tc->surface != ps);*/
pipe_surface_unmap(tc->surface);
+ tc->surface_map = NULL;
}
pipe_surface_reference(&tc->surface, ps);
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index b64948f0f3..a3824601be 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -192,12 +192,10 @@ struct pipe_context {
/**
* Called when texture data is changed.
- * Note: we could pass some hints about which mip levels or cube faces
- * have changed...
- * XXX this may go away - could pass a 'write' flag to get_tex_surface()
*/
void (*texture_update)(struct pipe_context *pipe,
- struct pipe_texture *texture);
+ struct pipe_texture *texture,
+ uint face, uint dirtyLevelsMask);
diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h
index f3dfa06216..14f8056924 100644
--- a/src/gallium/include/pipe/p_debug.h
+++ b/src/gallium/include/pipe/p_debug.h
@@ -73,6 +73,14 @@ extern "C" {
*/
void debug_printf(const char *format, ...);
+
+/* Dump a blob in hex to the same place that debug_printf sends its
+ * messages:
+ */
+void debug_print_blob( const char *name,
+ const void *blob,
+ unsigned size );
+
/**
* @sa debug_printf
*/
@@ -168,6 +176,55 @@ void debug_mask_vprintf(uint32_t uuid,
#endif
+/**
+ * Used by debug_dump_enum and debug_dump_flags to describe symbols.
+ */
+struct debug_named_value
+{
+ const char *name;
+ unsigned long value;
+};
+
+
+/**
+ * Some C pre-processor magic to simplify creating named values.
+ *
+ * Example:
+ * @code
+ * static const debug_named_value my_names[] = {
+ * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X),
+ * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y),
+ * DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z),
+ * DEBUG_NAMED_VALUE_END
+ * };
+ *
+ * ...
+ * debug_printf("%s = %s\n",
+ * name,
+ * debug_dump_enum(my_names, my_value));
+ * ...
+ * @endcode
+ */
+#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol}
+#define DEBUG_NAMED_VALUE_END {NULL, 0}
+
+
+/**
+ * Convert a enum value to a string.
+ */
+const char *
+debug_dump_enum(const struct debug_named_value *names,
+ unsigned long value);
+
+
+/**
+ * Convert binary flags value to a string.
+ */
+const char *
+debug_dump_flags(const struct debug_named_value *names,
+ unsigned long value);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index f90087b3c9..3238b152b6 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -38,16 +38,19 @@ extern "C" {
#endif
/**
- * The PIPE_FORMAT is a 32-bit wide bitfield that encodes all the information
- * needed to uniquely describe a pixel format.
+ * The pipe_format enum is a 32-bit wide bitfield that encodes all the
+ * information needed to uniquely describe a pixel format.
*/
/**
- * Possible format layouts -- occupy first 2 bits. The interpretation of
- * the remaining 30 bits depends on a particual format layout.
+ * Possible format layouts are encoded in the first 2 bits.
+ * The interpretation of the remaining 30 bits depends on a particular
+ * format layout.
*/
#define PIPE_FORMAT_LAYOUT_RGBAZS 0
#define PIPE_FORMAT_LAYOUT_YCBCR 1
+#define PIPE_FORMAT_LAYOUT_DXT 2 /**< XXX temporary? */
+
static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */
{
@@ -74,11 +77,13 @@ static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */
* Format types for RGBAZS layout.
*/
#define PIPE_FORMAT_TYPE_UNKNOWN 0
-#define PIPE_FORMAT_TYPE_FLOAT 1
-#define PIPE_FORMAT_TYPE_UNORM 2
-#define PIPE_FORMAT_TYPE_SNORM 3
-#define PIPE_FORMAT_TYPE_USCALED 4
-#define PIPE_FORMAT_TYPE_SSCALED 5
+#define PIPE_FORMAT_TYPE_FLOAT 1 /**< 16/32/64-bit/channel formats */
+#define PIPE_FORMAT_TYPE_UNORM 2 /**< uints, normalized to [0,1] */
+#define PIPE_FORMAT_TYPE_SNORM 3 /**< ints, normalized to [-1,1] */
+#define PIPE_FORMAT_TYPE_USCALED 4 /**< uints, not normalized */
+#define PIPE_FORMAT_TYPE_SSCALED 5 /**< ints, not normalized */
+#define PIPE_FORMAT_TYPE_SRGB 6 /**< sRGB colorspace */
+
/**
* Because the destination vector is assumed to be RGBA FLOAT, we
@@ -196,6 +201,20 @@ static INLINE uint pf_rev(pipe_format_ycbcr_t f)
return (f >> 2) & 0x1;
}
+
+/**
+ * Compresssed format layouts (this will probably change)
+ */
+#define _PIPE_FORMAT_DXT( LEVEL, RSIZE, GSIZE, BSIZE, ASIZE ) \
+ ((PIPE_FORMAT_LAYOUT_DXT << 0) | \
+ ((LEVEL) << 2) | \
+ ((RSIZE) << 5) | \
+ ((GSIZE) << 8) | \
+ ((BSIZE) << 11) | \
+ ((ASIZE) << 14) )
+
+
+
/**
* Texture/surface image formats (preliminary)
*/
@@ -281,11 +300,23 @@ enum pipe_format {
PIPE_FORMAT_R8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_R000, 1, 0, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
PIPE_FORMAT_R8G8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RG00, 1, 1, 0, 0, PIPE_FORMAT_TYPE_SSCALED ),
PIPE_FORMAT_R8G8B8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SSCALED ),
- PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED )
+ PIPE_FORMAT_R8G8B8A8_SSCALED = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SSCALED ),
+ /* sRGB formats */
+ PIPE_FORMAT_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRR1, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
+ PIPE_FORMAT_A8_L8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RRRG, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
+ PIPE_FORMAT_R8G8B8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGB0, 1, 1, 1, 0, PIPE_FORMAT_TYPE_SRGB ),
+ PIPE_FORMAT_R8G8B8A8_SRGB = _PIPE_FORMAT_RGBAZS_8 ( _PIPE_FORMAT_RGBA, 1, 1, 1, 1, PIPE_FORMAT_TYPE_SRGB ),
+
+ /* compressed formats */
+ PIPE_FORMAT_DXT1_RGB = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 0 ),
+ PIPE_FORMAT_DXT1_RGBA = _PIPE_FORMAT_DXT( 1, 8, 8, 8, 8 ),
+ PIPE_FORMAT_DXT3_RGBA = _PIPE_FORMAT_DXT( 3, 8, 8, 8, 8 ),
+ PIPE_FORMAT_DXT5_RGBA = _PIPE_FORMAT_DXT( 5, 8, 8, 8, 8 )
};
/**
+ * Unsigned 8-bit stencil format.
* XXX should remove this, but S8_UNORM is a poor name
*/
#define PIPE_FORMAT_U_S8 PIPE_FORMAT_S8_UNORM
@@ -294,11 +325,12 @@ enum pipe_format {
/**
* Builds pipe format name from format token.
*/
-static INLINE char *pf_sprint_name( char *str, uint format )
+static INLINE char *pf_sprint_name( char *str, enum pipe_format format )
{
strcpy( str, "PIPE_FORMAT_" );
switch (pf_layout( format )) {
- case PIPE_FORMAT_LAYOUT_RGBAZS: {
+ case PIPE_FORMAT_LAYOUT_RGBAZS:
+ {
pipe_format_rgbazs_t rgbazs = (pipe_format_rgbazs_t) format;
uint i;
uint scale = 1 << (pf_exp8( rgbazs ) * 3);
@@ -362,7 +394,8 @@ static INLINE char *pf_sprint_name( char *str, uint format )
}
}
break;
- case PIPE_FORMAT_LAYOUT_YCBCR: {
+ case PIPE_FORMAT_LAYOUT_YCBCR:
+ {
pipe_format_ycbcr_t ycbcr = (pipe_format_ycbcr_t) format;
strcat( str, "YCBCR" );
@@ -375,6 +408,10 @@ static INLINE char *pf_sprint_name( char *str, uint format )
return str;
}
+/**
+ * Return bits for a particular component.
+ * \param comp component index, starting at 0
+ */
static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp )
{
uint size;
@@ -397,6 +434,9 @@ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp )
return size << (pf_exp8(format) * 3);
}
+/**
+ * Return total bits needed for the pixel format.
+ */
static INLINE uint pf_get_bits( enum pipe_format format )
{
if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) {
@@ -417,7 +457,11 @@ static INLINE uint pf_get_bits( enum pipe_format format )
}
}
-static INLINE uint pf_get_size( enum pipe_format format ) {
+/**
+ * Return bytes per pixel for the given format.
+ */
+static INLINE uint pf_get_size( enum pipe_format format )
+{
assert(pf_get_bits(format) % 8 == 0);
return pf_get_bits(format) / 8;
}
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 6be9a82b68..35bd46d691 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -69,6 +69,7 @@ struct pipe_screen {
float (*get_paramf)( struct pipe_screen *, int param );
+ /**< type is one of PIPE_TEXTURE, PIPE_SURFACE */
boolean (*is_format_supported)( struct pipe_screen *,
enum pipe_format format,
uint type );
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 5791a10119..3e531c4da4 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -220,6 +220,8 @@ struct pipe_blend_color
struct pipe_framebuffer_state
{
+ unsigned width, height;
+
/** multiple colorbuffers for multiple render targets */
unsigned num_cbufs;
struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index 678e4ad0e8..b816a21b38 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -142,6 +142,8 @@ STATETRACKER_SOURCES = [
'state_tracker/st_atom_texture.c',
'state_tracker/st_atom_viewport.c',
'state_tracker/st_cb_accum.c',
+ 'state_tracker/st_cb_bitmap.c',
+ 'state_tracker/st_cb_blit.c',
'state_tracker/st_cb_bufferobjects.c',
'state_tracker/st_cb_clear.c',
'state_tracker/st_cb_flush.c',
@@ -154,7 +156,6 @@ STATETRACKER_SOURCES = [
'state_tracker/st_cb_readpixels.c',
'state_tracker/st_cb_strings.c',
'state_tracker/st_cb_texture.c',
- 'state_tracker/st_cache.c',
'state_tracker/st_context.c',
'state_tracker/st_debug.c',
'state_tracker/st_draw.c',
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 009055a6ab..e762eb3b63 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.1
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -470,6 +470,143 @@ _mesa_validate_pbo_access(GLuint dimensions,
/**
+ * If the source of glBitmap data is a PBO, check that we won't read out
+ * of buffer bounds, then map the buffer.
+ * If not sourcing from a PBO, just return the bitmap pointer.
+ * This is a helper function for (some) drivers.
+ * Return NULL if error.
+ * If non-null return, must call _mesa_unmap_bitmap_pbo() when done.
+ */
+const GLubyte *
+_mesa_map_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap)
+{
+ const GLubyte *buf;
+
+ if (unpack->BufferObj->Name) {
+ /* unpack from PBO */
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ unpack->BufferObj);
+ if (!buf)
+ return NULL;
+
+ buf = ADD_POINTERS(buf, bitmap);
+ }
+ else {
+ /* unpack from normal memory */
+ buf = bitmap;
+ }
+
+ return buf;
+}
+
+
+/**
+ * Counterpart to _mesa_map_bitmap_pbo()
+ * This is a helper function for (some) drivers.
+ */
+void
+_mesa_unmap_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack)
+{
+ if (unpack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+ }
+}
+
+
+/**
+ * \sa _mesa_map_bitmap_pbo
+ */
+const GLvoid *
+_mesa_map_drawpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+ const GLvoid *buf;
+
+ if (unpack->BufferObj->Name) {
+ /* unpack from PBO */
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB,
+ unpack->BufferObj);
+ if (!buf)
+ return NULL;
+
+ buf = ADD_POINTERS(buf, pixels);
+ }
+ else {
+ /* unpack from normal memory */
+ buf = pixels;
+ }
+
+ return buf;
+}
+
+
+/**
+ * \sa _mesa_unmap_bitmap_pbo
+ */
+void
+_mesa_unmap_drapix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack)
+{
+ if (unpack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+ }
+}
+
+
+/**
+ * If PBO is bound, map the buffer, return dest pointer in mapped buffer.
+ * Call _mesa_unmap_readpix_pbo() when finished
+ * \return NULL if error
+ */
+void *
+_mesa_map_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack,
+ GLvoid *dest)
+{
+ void *buf;
+
+ if (pack->BufferObj->Name) {
+ /* pack into PBO */
+ buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
+ GL_WRITE_ONLY_ARB,
+ pack->BufferObj);
+ if (!buf)
+ return NULL;
+
+ buf = ADD_POINTERS(buf, dest);
+ }
+ else {
+ /* pack to normal memory */
+ buf = dest;
+ }
+
+ return buf;
+}
+
+
+/**
+ * Counterpart to _mesa_map_readpix_pbo()
+ */
+void
+_mesa_unmap_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack)
+{
+ if (pack->BufferObj->Name) {
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj);
+ }
+}
+
+
+
+/**
* Return the gl_buffer_object for the given ID.
* Always return NULL for ID 0.
*/
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index f54f9e9ff0..46525f08ae 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 7.1
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -86,6 +86,35 @@ _mesa_validate_pbo_access(GLuint dimensions,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid *ptr);
+extern const GLubyte *
+_mesa_map_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap);
+
+extern void
+_mesa_unmap_bitmap_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack);
+
+extern const GLvoid *
+_mesa_map_drawpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels);
+
+extern void
+_mesa_unmap_drapix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack);
+
+
+extern void *
+_mesa_map_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack,
+ GLvoid *dest);
+
+extern void
+_mesa_unmap_readpix_pbo(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack);
+
+
extern void
_mesa_unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj );
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index a9f9bd9da4..d06644f65d 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -695,10 +695,10 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->Programs);
#endif
#if FEATURE_ARB_vertex_program
- _mesa_delete_program(ctx, ss->DefaultVertexProgram);
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultVertexProgram);
#endif
#if FEATURE_ARB_fragment_program
- _mesa_delete_program(ctx, ss->DefaultFragmentProgram);
+ ctx->Driver.DeleteProgram(ctx, ss->DefaultFragmentProgram);
#endif
#if FEATURE_ATI_fragment_shader
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index ae9c7e29a1..0f64f1c1c0 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,6 +24,7 @@
#include "glheader.h"
#include "imports.h"
+#include "bufferobj.h"
#include "context.h"
#include "drawpix.h"
#include "feedback.h"
@@ -183,6 +184,23 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
/* Round, to satisfy conformance tests (matches SGI's OpenGL) */
GLint x = IROUND(ctx->Current.RasterPos[0]);
GLint y = IROUND(ctx->Current.RasterPos[1]);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack from PBO */
+ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(invalid PBO access)");
+ return;
+ }
+ if (ctx->Unpack.BufferObj->Pointer) {
+ /* buffer is mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(PBO is mapped)");
+ return;
+ }
+ }
+
ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,
&ctx->Unpack, pixels);
}
@@ -303,6 +321,21 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
+ if (ctx->Pack.BufferObj->Name) {
+ if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(invalid PBO access)");
+ return;
+ }
+
+ if (ctx->Pack.BufferObj->Pointer) {
+ /* buffer is mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
+ return;
+ }
+ }
+
ctx->Driver.ReadPixels(ctx, x, y, width, height,
format, type, &ctx->Pack, pixels);
}
@@ -343,12 +376,27 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
}
if (ctx->RenderMode == GL_RENDER) {
- if (bitmap && width && height) {
- /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
- GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
- GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
- ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
+ /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
+ GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
+ GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack from PBO */
+ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
+ GL_COLOR_INDEX, GL_BITMAP,
+ (GLvoid *) bitmap)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBitmap(invalid PBO access)");
+ return;
+ }
+ if (ctx->Unpack.BufferObj->Pointer) {
+ /* buffer is mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
+ return;
+ }
}
+
+ ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
}
#if _HAVE_FULL_GL
else if (ctx->RenderMode == GL_FEEDBACK) {
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index f15e404527..384e145520 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2323,9 +2323,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
return;
}
- if (!pixels)
- return;
-
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 3869e31714..39c4ca1dd5 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -354,7 +354,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
clone->Format = prog->Format;
clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
if (!clone->Instructions) {
- _mesa_delete_program(ctx, clone);
+ ctx->Driver.DeleteProgram(ctx, clone);
return NULL;
}
_mesa_copy_instructions(clone->Instructions, prog->Instructions,
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 4470a87af0..4cb8bb8ed1 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -79,7 +79,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
/* to prevent a double-free in the next call */
shProg->VertexProgram->Base.Parameters = NULL;
}
- _mesa_delete_program(ctx, &shProg->VertexProgram->Base);
+ ctx->Driver.DeleteProgram(ctx, &shProg->VertexProgram->Base);
shProg->VertexProgram = NULL;
}
@@ -88,7 +88,7 @@ _mesa_clear_shader_program_data(GLcontext *ctx,
/* to prevent a double-free in the next call */
shProg->FragmentProgram->Base.Parameters = NULL;
}
- _mesa_delete_program(ctx, &shProg->FragmentProgram->Base);
+ ctx->Driver.DeleteProgram(ctx, &shProg->FragmentProgram->Base);
shProg->FragmentProgram = NULL;
}
@@ -246,7 +246,7 @@ _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
_mesa_free(sh->InfoLog);
for (i = 0; i < sh->NumPrograms; i++) {
assert(sh->Programs[i]);
- _mesa_delete_program(ctx, sh->Programs[i]);
+ ctx->Driver.DeleteProgram(ctx, sh->Programs[i]);
}
if (sh->Programs)
_mesa_free(sh->Programs);
diff --git a/src/mesa/sources b/src/mesa/sources
index 287af7121a..d109dce5bc 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -172,6 +172,7 @@ STATETRACKER_SOURCES = \
state_tracker/st_atom_texture.c \
state_tracker/st_atom_viewport.c \
state_tracker/st_cb_accum.c \
+ state_tracker/st_cb_bitmap.c \
state_tracker/st_cb_blit.c \
state_tracker/st_cb_bufferobjects.c \
state_tracker/st_cb_clear.c \
diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c
index 6c13fc8141..2a0e92245c 100644
--- a/src/mesa/state_tracker/st_atom_blend.c
+++ b/src/mesa/state_tracker/st_atom_blend.c
@@ -39,6 +39,7 @@
#include "pipe/p_defines.h"
#include "cso_cache/cso_context.h"
+#include "main/macros.h"
/**
* Convert GLenum blend tokens to pipe tokens.
@@ -213,13 +214,10 @@ update_blend( struct st_context *st )
cso_set_blend(st->cso_context, blend);
- if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) {
- /* state has changed */
- st->state.blend_color.color[0] = st->ctx->Color.BlendColor[0];
- st->state.blend_color.color[1] = st->ctx->Color.BlendColor[1];
- st->state.blend_color.color[2] = st->ctx->Color.BlendColor[2];
- st->state.blend_color.color[3] = st->ctx->Color.BlendColor[3];
- st->pipe->set_blend_color(st->pipe, (struct pipe_blend_color *) st->ctx->Color.BlendColor);
+ {
+ struct pipe_blend_color bc;
+ COPY_4FV(bc.color, st->ctx->Color.BlendColor);
+ cso_set_blend_color(st->cso_context, &bc);
}
}
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index 21416da2e0..cd7372902b 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -66,7 +66,8 @@ void st_upload_constants( struct st_context *st,
/* Update our own dependency flags. This works because this
* function will also be called whenever the program changes.
*/
- st->constants.tracked_state[id].dirty.mesa = params->StateFlags;
+ st->constants.tracked_state[id].dirty.mesa =
+ (params->StateFlags | _NEW_PROGRAM);
_mesa_load_state_parameters(st->ctx, params);
@@ -115,7 +116,7 @@ static void update_vs_constants(struct st_context *st )
const struct st_tracked_state st_update_vs_constants = {
.name = "st_update_vs_constants",
.dirty = {
- .mesa = 0,
+ .mesa = 0, /* set dynamically above */
.st = ST_NEW_VERTEX_PROGRAM,
},
.update = update_vs_constants
@@ -134,7 +135,7 @@ static void update_fs_constants(struct st_context *st )
const struct st_tracked_state st_update_fs_constants = {
.name = "st_update_fs_constants",
.dirty = {
- .mesa = 0,
+ .mesa = 0, /* set dynamically above */
.st = ST_NEW_FRAGMENT_PROGRAM,
},
.update = update_fs_constants
diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 3e58d49f1f..02573af8f0 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -35,6 +35,7 @@
#include "st_atom.h"
#include "st_cb_fbo.h"
#include "pipe/p_context.h"
+#include "cso_cache/cso_context.h"
/**
@@ -44,45 +45,42 @@
static void
update_framebuffer_state( struct st_context *st )
{
- struct pipe_framebuffer_state framebuffer;
+ struct pipe_framebuffer_state *framebuffer = &st->state.framebuffer;
struct gl_framebuffer *fb = st->ctx->DrawBuffer;
struct st_renderbuffer *strb;
GLuint i;
- memset(&framebuffer, 0, sizeof(framebuffer));
+ memset(framebuffer, 0, sizeof(*framebuffer));
+
+ framebuffer->width = fb->Width;
+ framebuffer->height = fb->Height;
/* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
* to determine which surfaces to draw to
*/
- framebuffer.num_cbufs = fb->_NumColorDrawBuffers[0];
- for (i = 0; i < framebuffer.num_cbufs; i++) {
+ framebuffer->num_cbufs = fb->_NumColorDrawBuffers[0];
+ for (i = 0; i < framebuffer->num_cbufs; i++) {
strb = st_renderbuffer(fb->_ColorDrawBuffers[0][i]);
assert(strb->surface);
- framebuffer.cbufs[i] = strb->surface;
+ framebuffer->cbufs[i] = strb->surface;
}
strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
if (strb) {
strb = st_renderbuffer(strb->Base.Wrapped);
assert(strb->surface);
- framebuffer.zsbuf = strb->surface;
+ framebuffer->zsbuf = strb->surface;
}
else {
strb = st_renderbuffer(fb->Attachment[BUFFER_STENCIL].Renderbuffer);
if (strb) {
strb = st_renderbuffer(strb->Base.Wrapped);
assert(strb->surface);
- framebuffer.zsbuf = strb->surface;
+ framebuffer->zsbuf = strb->surface;
}
}
- /* XXX: The memcmp is insufficient for eliminating redundant state changes,
- * but we should probably do more work here to that end.
- */
- if (1 /*memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0*/) {
- st->state.framebuffer = framebuffer;
- st->pipe->set_framebuffer_state( st->pipe, &framebuffer );
- }
+ cso_set_framebuffer(st->cso_context, framebuffer);
}
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 0726688493..ec39026eb3 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -78,34 +78,6 @@ struct translated_vertex_program
/**
- * Free data hanging off the st vert prog.
- */
-void
-st_remove_vertex_program(struct st_context *st, struct st_vertex_program *stvp)
-{
- /* no-op, for now? */
-}
-
-
-/**
- * Free data hanging off the st frag prog.
- */
-void
-st_remove_fragment_program(struct st_context *st,
- struct st_fragment_program *stfp)
-{
- struct translated_vertex_program *xvp, *next;
-
- for (xvp = stfp->vertex_programs; xvp; xvp = next) {
- next = xvp->next;
- /* XXX free xvp->vs */
- free(xvp);
- }
-}
-
-
-
-/**
* Given a vertex program output attribute, return the corresponding
* fragment program input attribute.
* \return -1 for vertex outputs that have no corresponding fragment input
@@ -265,6 +237,21 @@ find_translated_vp(struct st_context *st,
}
+void
+st_free_translated_vertex_programs(struct st_context *st,
+ struct translated_vertex_program *xvp)
+{
+ struct translated_vertex_program *next;
+
+ while (xvp) {
+ next = xvp->next;
+ free(xvp);
+ xvp = next;
+ }
+}
+
+
+
static void
update_linkage( struct st_context *st )
{
diff --git a/src/mesa/state_tracker/st_atom_shader.h b/src/mesa/state_tracker/st_atom_shader.h
index f3124d87c0..8403bc66c9 100644
--- a/src/mesa/state_tracker/st_atom_shader.h
+++ b/src/mesa/state_tracker/st_atom_shader.h
@@ -31,10 +31,8 @@
extern void
-st_remove_vertex_program(struct st_context *, struct st_vertex_program *);
-
-extern void
-st_remove_fragment_program(struct st_context *, struct st_fragment_program *);
+st_free_translated_vertex_programs(struct st_context *st,
+ struct translated_vertex_program *xvp);
#endif /* ST_ATOM_SHADER_H */
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index e53a897637..9aef30f456 100644
--- a/src/mesa/state_tracker/st_atom_texture.c
+++ b/src/mesa/state_tracker/st_atom_texture.c
@@ -64,7 +64,10 @@ update_textures(struct st_context *st)
GLboolean flush, retval;
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
- /* XXX retval indicates whether there's a texture border */
+ if (!retval) {
+ /* out of mem */
+ continue;
+ }
st->state.num_textures = unit + 1;
}
@@ -76,11 +79,6 @@ update_textures(struct st_context *st)
pt = st_get_stobj_texture(stObj);
pipe_texture_reference(&st->state.sampler_texture[unit], pt);
-
- if (stObj && stObj->dirtyData) {
- st->pipe->texture_update(st->pipe, pt);
- stObj->dirtyData = GL_FALSE;
- }
}
st->pipe->set_sampler_textures(st->pipe, st->state.num_textures,
diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c
index 147aa3c51a..eb3f62cfbe 100644
--- a/src/mesa/state_tracker/st_atom_viewport.c
+++ b/src/mesa/state_tracker/st_atom_viewport.c
@@ -29,9 +29,9 @@
#include "context.h"
#include "colormac.h"
#include "st_context.h"
-#include "pipe/p_context.h"
#include "st_atom.h"
-
+#include "pipe/p_context.h"
+#include "cso_cache/cso_context.h"
/**
* Update the viewport transformation matrix. Depends on:
@@ -65,22 +65,18 @@ update_viewport( struct st_context *st )
GLfloat half_width = ctx->Viewport.Width / 2.0;
GLfloat half_height = ctx->Viewport.Height / 2.0;
GLfloat half_depth = (ctx->Viewport.Far - ctx->Viewport.Near) / 2.0;
- struct pipe_viewport_state vp;
- vp.scale[0] = half_width;
- vp.scale[1] = half_height * yScale;
- vp.scale[2] = half_depth;
- vp.scale[3] = 1.0;
+ st->state.viewport.scale[0] = half_width;
+ st->state.viewport.scale[1] = half_height * yScale;
+ st->state.viewport.scale[2] = half_depth;
+ st->state.viewport.scale[3] = 1.0;
- vp.translate[0] = half_width + x;
- vp.translate[1] = (half_height + y) * yScale + yBias;
- vp.translate[2] = half_depth + z;
- vp.translate[3] = 0.0;
+ st->state.viewport.translate[0] = half_width + x;
+ st->state.viewport.translate[1] = (half_height + y) * yScale + yBias;
+ st->state.viewport.translate[2] = half_depth + z;
+ st->state.viewport.translate[3] = 0.0;
- if (memcmp(&vp, &st->state.viewport, sizeof(vp)) != 0) {
- st->state.viewport = vp;
- st->pipe->set_viewport_state(st->pipe, &vp);
- }
+ cso_set_viewport(st->cso_context, &st->state.viewport);
}
}
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
new file mode 100644
index 0000000000..acc22d4323
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -0,0 +1,527 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Brian Paul
+ */
+
+#include "main/imports.h"
+#include "main/image.h"
+#include "main/bufferobj.h"
+#include "main/macros.h"
+#include "main/texformat.h"
+#include "shader/program.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+
+#include "st_context.h"
+#include "st_atom.h"
+#include "st_atom_constbuf.h"
+#include "st_program.h"
+#include "st_cb_bitmap.h"
+#include "st_mesa_to_tgsi.h"
+#include "st_texture.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_winsys.h"
+#include "util/p_tile.h"
+#include "util/u_draw_quad.h"
+#include "util/u_simple_shaders.h"
+#include "shader/prog_instruction.h"
+#include "cso_cache/cso_context.h"
+
+
+
+/**
+ * Make fragment program for glBitmap:
+ * Sample the texture and kill the fragment if the bit is 0.
+ * This program will be combined with the user's fragment program.
+ */
+static struct st_fragment_program *
+make_bitmap_fragment_program(GLcontext *ctx)
+{
+ struct st_fragment_program *stfp;
+ struct gl_program *p;
+ GLuint ic = 0;
+
+ p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+ if (!p)
+ return NULL;
+
+ p->NumInstructions = 5;
+
+ p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
+ if (!p->Instructions) {
+ ctx->Driver.DeleteProgram(ctx, p);
+ return NULL;
+ }
+ _mesa_init_instructions(p->Instructions, p->NumInstructions);
+
+ /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
+ p->Instructions[ic].Opcode = OPCODE_TEX;
+ p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
+ p->Instructions[ic].DstReg.Index = 0;
+ p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
+ p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
+ p->Instructions[ic].TexSrcUnit = 0;
+ p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
+ ic++;
+
+ /* SWZ tmp0.x, tmp0.x, 1111; # tmp0.x = 1.0 */
+ p->Instructions[ic].Opcode = OPCODE_SWZ;
+ p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
+ p->Instructions[ic].DstReg.Index = 0;
+ p->Instructions[ic].DstReg.WriteMask = WRITEMASK_X;
+ p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
+ p->Instructions[ic].SrcReg[0].Index = 0;
+ p->Instructions[ic].SrcReg[0].Swizzle
+ = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE );
+ ic++;
+
+ /* SUB tmp0, tmp0.wwww, tmp0.xxxx; # tmp0.w -= 1 */
+ p->Instructions[ic].Opcode = OPCODE_SUB;
+ p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
+ p->Instructions[ic].DstReg.Index = 0;
+ p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
+ p->Instructions[ic].SrcReg[0].Index = 0;
+ p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_WWWW;
+ p->Instructions[ic].SrcReg[1].File = PROGRAM_TEMPORARY;
+ p->Instructions[ic].SrcReg[1].Index = 0;
+ p->Instructions[ic].SrcReg[1].Swizzle = SWIZZLE_XXXX; /* 1.0 */
+ ic++;
+
+ /* KIL if tmp0 < 0 */
+ p->Instructions[ic].Opcode = OPCODE_KIL;
+ p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
+ p->Instructions[ic].SrcReg[0].Index = 0;
+ ic++;
+
+ /* END; */
+ p->Instructions[ic++].Opcode = OPCODE_END;
+
+ assert(ic == p->NumInstructions);
+
+ p->InputsRead = FRAG_BIT_TEX0;
+ p->OutputsWritten = 0x0;
+
+ stfp = (struct st_fragment_program *) p;
+ stfp->Base.UsesKill = GL_TRUE;
+ st_translate_fragment_program(ctx->st, stfp, NULL);
+
+ return stfp;
+}
+
+
+/**
+ * Combine basic bitmap fragment program with the user-defined program.
+ */
+static struct st_fragment_program *
+combined_bitmap_fragment_program(GLcontext *ctx)
+{
+ struct st_context *st = ctx->st;
+ struct st_fragment_program *stfp;
+
+ if (!st->bitmap.program) {
+ /* create the basic bitmap fragment program */
+ st->bitmap.program = make_bitmap_fragment_program(ctx);
+ }
+
+ if (st->bitmap.user_prog_sn == st->fp->serialNo) {
+ /* re-use */
+ stfp = st->bitmap.combined_prog;
+ }
+ else {
+ /* Concatenate the bitmap program with the current user-defined program.
+ */
+ stfp = (struct st_fragment_program *)
+ _mesa_combine_programs(ctx,
+ &st->bitmap.program->Base.Base,
+ &st->fp->Base.Base);
+
+#if 0
+ {
+ struct gl_program *p = &stfp->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, NULL);
+
+ /* save new program, update serial numbers */
+ st->bitmap.user_prog_sn = st->fp->serialNo;
+ st->bitmap.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 glBitmap.
+ */
+ st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
+
+ return stfp;
+}
+
+
+/**
+ * Create a texture which represents a bitmap image.
+ */
+static struct pipe_texture *
+make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap)
+{
+ struct pipe_context *pipe = ctx->st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_surface *surface;
+ uint format = 0, cpp, comp;
+ ubyte *dest;
+ struct pipe_texture *pt;
+ int row, col;
+
+ /* find a texture format we know */
+ if (screen->is_format_supported( screen, PIPE_FORMAT_U_I8, PIPE_TEXTURE )) {
+ format = PIPE_FORMAT_U_I8;
+ cpp = 1;
+ comp = 0;
+ }
+ else if (screen->is_format_supported( screen, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_TEXTURE )) {
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ cpp = 4;
+ comp = 3; /* alpha channel */ /*XXX little-endian dependency */
+ }
+ else {
+ /* XXX support more formats */
+ assert( 0 );
+ }
+
+ /* PBO source... */
+ bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
+ if (!bitmap) {
+ return NULL;
+ }
+
+ /**
+ * Create texture to hold bitmap pattern.
+ */
+ pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, width, height,
+ 1, 0);
+ if (!pt) {
+ _mesa_unmap_bitmap_pbo(ctx, unpack);
+ return NULL;
+ }
+
+ surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
+
+ /* map texture surface */
+ dest = pipe_surface_map(surface);
+
+ /* Put image into texture surface.
+ * Note that the image is actually going to be upside down in
+ * the texture. We deal with that with texcoords.
+ */
+
+ for (row = 0; row < height; row++) {
+ const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
+ bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
+ ubyte *destRow = dest + row * surface->pitch * cpp;
+
+ if (unpack->LsbFirst) {
+ /* Lsb first */
+ GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+
+ /* set texel to 255 if bit is set */
+ destRow[comp] = (*src & mask) ? 255 : 0;
+ destRow += cpp;
+
+ if (mask == 128U) {
+ src++;
+ mask = 1U;
+ }
+ else {
+ mask = mask << 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 1)
+ src++;
+ }
+ else {
+ /* Msb first */
+ GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+
+ /* set texel to 255 if bit is set */
+ destRow[comp] =(*src & mask) ? 255 : 0;
+ destRow += cpp;
+
+ if (mask == 1U) {
+ src++;
+ mask = 128U;
+ }
+ else {
+ mask = mask >> 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 128)
+ src++;
+ }
+
+ } /* row */
+
+ _mesa_unmap_bitmap_pbo(ctx, unpack);
+
+ /* Release surface */
+ pipe_surface_unmap(surface);
+ pipe_surface_reference(&surface, NULL);
+ pipe->texture_update(pipe, pt, 0, 0x1);
+
+ pt->format = format;
+
+ return pt;
+}
+
+
+static void
+setup_bitmap_vertex_data(struct st_context *st,
+ int x, int y, int width, int height,
+ float z, const float color[4])
+{
+ struct pipe_context *pipe = st->pipe;
+ const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
+ const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
+ const GLfloat x0 = x;
+ const GLfloat x1 = x + width;
+ const GLfloat y0 = invert ? (fb->Height - y - height) : y;
+ const GLfloat y1 = invert ? (y0 + height) : y + height;
+ const GLfloat bias = st->bitmap_texcoord_bias;
+ const GLfloat xBias = bias / (x1-x0);
+ const GLfloat yBias = bias / (y1-y0);
+ const GLfloat sLeft = 0.0 + xBias, sRight = 1.0 + xBias;
+ const GLfloat tTop = 1.0 - yBias, tBot = 1.0 - tTop - yBias;
+ GLuint i;
+ void *buf;
+
+ if (!st->bitmap.vbuf) {
+ st->bitmap.vbuf = pipe->winsys->buffer_create(pipe->winsys, 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(st->bitmap.vertices));
+ }
+
+ /* positions, texcoords */
+ st->bitmap.vertices[0][0][0] = x0;
+ st->bitmap.vertices[0][0][1] = y0;
+ st->bitmap.vertices[0][2][0] = sLeft;
+ st->bitmap.vertices[0][2][1] = tTop;
+
+ st->bitmap.vertices[1][0][0] = x1;
+ st->bitmap.vertices[1][0][1] = y0;
+ st->bitmap.vertices[1][2][0] = sRight;
+ st->bitmap.vertices[1][2][1] = tTop;
+
+ st->bitmap.vertices[2][0][0] = x1;
+ st->bitmap.vertices[2][0][1] = y1;
+ st->bitmap.vertices[2][2][0] = sRight;
+ st->bitmap.vertices[2][2][1] = tBot;
+
+ st->bitmap.vertices[3][0][0] = x0;
+ st->bitmap.vertices[3][0][1] = y1;
+ st->bitmap.vertices[3][2][0] = sLeft;
+ st->bitmap.vertices[3][2][1] = tBot;
+
+ /* same for all verts: */
+ for (i = 0; i < 4; i++) {
+ st->bitmap.vertices[i][0][2] = z;
+ st->bitmap.vertices[i][0][3] = 1.0;
+ st->bitmap.vertices[i][1][0] = color[0];
+ st->bitmap.vertices[i][1][1] = color[1];
+ st->bitmap.vertices[i][1][2] = color[2];
+ st->bitmap.vertices[i][1][3] = color[3];
+ st->bitmap.vertices[i][2][2] = 0.0; /*R*/
+ st->bitmap.vertices[i][2][3] = 1.0; /*Q*/
+ }
+
+ /* put vertex data into vbuf */
+ buf = pipe->winsys->buffer_map(pipe->winsys, st->bitmap.vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ memcpy(buf, st->bitmap.vertices, sizeof(st->bitmap.vertices));
+ pipe->winsys->buffer_unmap(pipe->winsys, st->bitmap.vbuf);
+}
+
+
+
+/**
+ * Render a glBitmap by drawing a textured quad
+ */
+static void
+draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
+ GLsizei width, GLsizei height,
+ struct pipe_texture *pt,
+ struct st_fragment_program *stfp)
+{
+ struct st_context *st = ctx->st;
+ struct pipe_context *pipe = ctx->st->pipe;
+ struct cso_context *cso = ctx->st->cso_context;
+ GLuint maxSize;
+
+ /* limit checks */
+ /* XXX if DrawPixels image is larger than max texture size, break
+ * it up into chunks.
+ */
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ assert(width <= maxSize);
+ assert(height <= maxSize);
+
+ cso_save_rasterizer(cso);
+ //cso_save_viewport(cso);
+
+ /* rasterizer state: just scissor */
+ {
+ struct pipe_rasterizer_state rasterizer;
+ memset(&rasterizer, 0, sizeof(rasterizer));
+ if (ctx->Scissor.Enabled)
+ rasterizer.scissor = 1;
+ rasterizer.bypass_clipping = 1;
+
+ cso_set_rasterizer(cso, &rasterizer);
+ }
+
+ /* fragment shader state: TEX lookup program */
+ pipe->bind_fs_state(pipe, stfp->driver_shader);
+
+ /* vertex shader state: position + texcoord pass-through */
+ pipe->bind_vs_state(pipe, st->bitmap.vs);
+
+ /* sampler / texture state */
+ {
+ struct pipe_sampler_state sampler;
+ memset(&sampler, 0, sizeof(sampler));
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
+ sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+ sampler.normalized_coords = 1;
+
+ cso_single_sampler(cso, 0, &sampler);
+ cso_single_sampler_done(cso);
+
+ pipe->set_sampler_textures(pipe, 1, &pt);
+ }
+
+ /* draw textured quad */
+ setup_bitmap_vertex_data(st, x, y, width, height,
+ ctx->Current.RasterPos[2],
+ ctx->Current.RasterColor);
+
+ util_draw_vertex_buffer(pipe, st->bitmap.vbuf,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 3); /* attribs/vert */
+
+
+ /* restore state */
+ cso_restore_rasterizer(cso);
+ cso_restore_samplers(cso);
+ //cso_restore_viewport(cso);
+ /* shaders don't go through cso yet */
+ pipe->bind_fs_state(pipe, st->fp->driver_shader);
+ pipe->bind_vs_state(pipe, st->vp->driver_shader);
+
+ pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
+ ctx->st->state.sampler_texture);
+}
+
+
+
+static void
+st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
+{
+ struct st_fragment_program *stfp;
+ struct st_context *st = ctx->st;
+ struct pipe_texture *pt;
+
+ stfp = combined_bitmap_fragment_program(ctx);
+
+ if (!st->bitmap.vs) {
+ /* create pass-through vertex shader now */
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_COLOR,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indexes[] = { 0, 0, 0 };
+ st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3,
+ semantic_names,
+ semantic_indexes);
+ }
+
+ st_validate_state(st);
+
+ pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
+ if (pt) {
+ draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
+ width, height,
+ pt, stfp);
+ pipe_texture_reference(&pt, NULL);
+ }
+}
+
+
+
+void st_init_bitmap_functions(struct dd_function_table *functions)
+{
+ functions->Bitmap = st_Bitmap;
+}
+
+
+void
+st_destroy_bitmap(struct st_context *st)
+{
+ struct pipe_context *pipe = st->pipe;
+
+ /* XXX free frag shader state */
+
+ if (st->bitmap.vs) {
+ pipe->delete_vs_state(pipe, st->bitmap.vs);
+ st->bitmap.vs = NULL;
+ }
+ if (st->bitmap.vbuf) {
+ pipe->winsys->buffer_destroy(pipe->winsys, st->bitmap.vbuf);
+ st->bitmap.vbuf = NULL;
+ }
+}
+
diff --git a/src/gallium/drivers/cell/spu/spu_blend.h b/src/mesa/state_tracker/st_cb_bitmap.h
index 2b594b578b..ac19e0ebb1 100644
--- a/src/gallium/drivers/cell/spu/spu_blend.h
+++ b/src/mesa/state_tracker/st_cb_bitmap.h
@@ -1,8 +1,8 @@
/**************************************************************************
*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -26,12 +26,16 @@
**************************************************************************/
-#ifndef SPU_BLEND_H
-#define SPU_BLEND_H
+#ifndef ST_CB_BITMAP_H
+#define ST_CB_BITMAP_H
+
+
+extern void
+st_init_bitmap_functions(struct dd_function_table *functions);
extern void
-blend_quad(uint itx, uint ity, vector float colors[4]);
+st_destroy_bitmap(struct st_context *st);
-#endif /* SPU_BLEND_H */
+#endif /* ST_CB_BITMAP_H */
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index dfa79c975c..63211d8b66 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -52,7 +52,7 @@
void
st_init_blit(struct st_context *st)
{
- st->blit = util_create_blit(st->pipe);
+ st->blit = util_create_blit(st->pipe, st->cso_context);
}
@@ -85,11 +85,14 @@ st_BlitFramebuffer(GLcontext *ctx,
struct pipe_surface *srcSurf = srcRb->surface;
struct pipe_surface *dstSurf = dstRb->surface;
- srcY0 = srcRb->Base.Height - srcY0;
- srcY1 = srcRb->Base.Height - srcY1;
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+ /* invert Y */
+ srcY0 = srcRb->Base.Height - srcY0;
+ srcY1 = srcRb->Base.Height - srcY1;
- dstY0 = dstRb->Base.Height - dstY0;
- dstY1 = dstRb->Base.Height - dstY1;
+ dstY0 = dstRb->Base.Height - dstY0;
+ dstY1 = dstRb->Base.Height - dstY1;
+ }
util_blit_pixels(st->blit,
srcSurf, srcX0, srcY0, srcX1, srcY1,
@@ -98,22 +101,9 @@ st_BlitFramebuffer(GLcontext *ctx,
}
-#if 0
- /* XXX is this sufficient? */
- st_invalidate_state(ctx, _NEW_COLOR | _NEW_TEXTURE);
-#else
- /* need to "unset" cso state because we went behind the back of the cso
- * tracker. Without unset, the _set_ calls would be no-ops.
- */
- cso_unset_blend(st->cso_context);
- cso_unset_depth_stencil_alpha(st->cso_context);
- cso_unset_rasterizer(st->cso_context);
- cso_set_blend(st->cso_context, &st->state.blend);
- cso_set_depth_stencil_alpha(st->cso_context, &st->state.depth_stencil);
- cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
+ /* shaders don't go through CSO yet */
pipe->bind_fs_state(pipe, st->fp->driver_shader);
pipe->bind_vs_state(pipe, st->vp->driver_shader);
-#endif
}
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 693cddedf7..5ca15df602 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -49,14 +49,37 @@
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
#include "util/u_pack_color.h"
+#include "util/u_simple_shaders.h"
+#include "util/u_draw_quad.h"
#include "cso_cache/cso_context.h"
/* XXX for testing draw module vertex passthrough: */
+/* XXX this hack is broken now */
#define TEST_DRAW_PASSTHROUGH 0
+void
+st_destroy_clear(struct st_context *st)
+{
+ struct pipe_context *pipe = st->pipe;
+
+ if (st->clear.fs) {
+ pipe->delete_fs_state(pipe, st->clear.fs);
+ st->clear.fs = NULL;
+ }
+ if (st->clear.vs) {
+ pipe->delete_vs_state(pipe, st->clear.vs);
+ st->clear.vs = NULL;
+ }
+ if (st->clear.vbuf) {
+ pipe->winsys->buffer_destroy(pipe->winsys, st->clear.vbuf);
+ st->clear.vbuf = NULL;
+ }
+}
+
+
static GLboolean
is_depth_stencil_format(enum pipe_format pipeFormat)
{
@@ -72,104 +95,6 @@ is_depth_stencil_format(enum pipe_format pipeFormat)
/**
- * Create a simple fragment shader that just passes through the fragment color.
- */
-static struct st_fragment_program *
-make_frag_shader(struct st_context *st)
-{
- GLcontext *ctx = st->ctx;
- struct st_fragment_program *stfp;
- struct gl_program *p;
- GLuint interpMode[16];
- GLuint i;
-
- /* XXX temporary */
- for (i = 0; i < 16; i++)
- interpMode[i] = TGSI_INTERPOLATE_LINEAR;
-
- p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
- if (!p)
- return NULL;
-
- p->NumInstructions = 2;
- p->Instructions = _mesa_alloc_instructions(2);
- if (!p->Instructions) {
- ctx->Driver.DeleteProgram(ctx, p);
- return NULL;
- }
- _mesa_init_instructions(p->Instructions, 2);
- /* MOV result.color, fragment.color; */
- p->Instructions[0].Opcode = OPCODE_MOV;
- p->Instructions[0].DstReg.File = PROGRAM_OUTPUT;
- p->Instructions[0].DstReg.Index = FRAG_RESULT_COLR;
- p->Instructions[0].SrcReg[0].File = PROGRAM_INPUT;
- p->Instructions[0].SrcReg[0].Index = FRAG_ATTRIB_COL0;
- /* END; */
- p->Instructions[1].Opcode = OPCODE_END;
-
- p->InputsRead = FRAG_BIT_COL0;
- p->OutputsWritten = (1 << FRAG_RESULT_COLR);
-
- stfp = (struct st_fragment_program *) p;
- st_translate_fragment_program(st, stfp, NULL);
-
- return stfp;
-}
-
-
-/**
- * Create a simple vertex shader that just passes through the
- * vertex position and color.
- */
-static struct st_vertex_program *
-make_vertex_shader(struct st_context *st)
-{
- GLcontext *ctx = st->ctx;
- struct st_vertex_program *stvp;
- struct gl_program *p;
-
- p = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
- if (!p)
- return NULL;
-
- p->NumInstructions = 3;
- p->Instructions = _mesa_alloc_instructions(3);
- if (!p->Instructions) {
- ctx->Driver.DeleteProgram(ctx, p);
- return NULL;
- }
- _mesa_init_instructions(p->Instructions, 3);
- /* MOV result.pos, vertex.pos; */
- p->Instructions[0].Opcode = OPCODE_MOV;
- p->Instructions[0].DstReg.File = PROGRAM_OUTPUT;
- p->Instructions[0].DstReg.Index = VERT_RESULT_HPOS;
- p->Instructions[0].SrcReg[0].File = PROGRAM_INPUT;
- p->Instructions[0].SrcReg[0].Index = VERT_ATTRIB_POS;
- /* MOV result.color, vertex.color; */
- p->Instructions[1].Opcode = OPCODE_MOV;
- p->Instructions[1].DstReg.File = PROGRAM_OUTPUT;
- p->Instructions[1].DstReg.Index = VERT_RESULT_COL0;
- p->Instructions[1].SrcReg[0].File = PROGRAM_INPUT;
- p->Instructions[1].SrcReg[0].Index = VERT_ATTRIB_COLOR0;
- /* END; */
- p->Instructions[2].Opcode = OPCODE_END;
-
- p->InputsRead = VERT_BIT_POS | VERT_BIT_COLOR0;
- p->OutputsWritten = ((1 << VERT_RESULT_COL0) |
- (1 << VERT_RESULT_HPOS));
-
- stvp = (struct st_vertex_program *) p;
- st_translate_vertex_program(st, stvp, NULL);
-#if 0
- assert(stvp->cso);
-#endif
-
- return stvp;
-}
-
-
-
-/**
* Draw a screen-aligned quadrilateral.
* Coords are window coords with y=0=bottom. These coords will be transformed
* by the vertex shader and viewport transform (which will flip Y if needed).
@@ -179,45 +104,51 @@ draw_quad(GLcontext *ctx,
float x0, float y0, float x1, float y1, GLfloat z,
const GLfloat color[4])
{
- GLfloat verts[4][2][4]; /* four verts, two attribs, XYZW */
+ struct st_context *st = ctx->st;
+ struct pipe_context *pipe = st->pipe;
GLuint i;
+ void *buf;
-#if TEST_DRAW_PASSTHROUGH
- /* invert Y coords (may be off by one pixel) */
- y0 = ctx->DrawBuffer->Height - y0;
- y1 = ctx->DrawBuffer->Height - y1;
-#endif
+ if (!st->clear.vbuf) {
+ st->clear.vbuf = pipe->winsys->buffer_create(pipe->winsys, 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ sizeof(st->clear.vertices));
+ }
/* positions */
- verts[0][0][0] = x0;
- verts[0][0][1] = y0;
+ st->clear.vertices[0][0][0] = x0;
+ st->clear.vertices[0][0][1] = y0;
- verts[1][0][0] = x1;
- verts[1][0][1] = y0;
+ st->clear.vertices[1][0][0] = x1;
+ st->clear.vertices[1][0][1] = y0;
- verts[2][0][0] = x1;
- verts[2][0][1] = y1;
+ st->clear.vertices[2][0][0] = x1;
+ st->clear.vertices[2][0][1] = y1;
- verts[3][0][0] = x0;
- verts[3][0][1] = y1;
+ st->clear.vertices[3][0][0] = x0;
+ st->clear.vertices[3][0][1] = y1;
/* same for all verts: */
for (i = 0; i < 4; i++) {
- verts[i][0][2] = z;
- verts[i][0][3] = 1.0;
- verts[i][1][0] = color[0];
- verts[i][1][1] = color[1];
- verts[i][1][2] = color[2];
- verts[i][1][3] = color[3];
+ st->clear.vertices[i][0][2] = z;
+ st->clear.vertices[i][0][3] = 1.0;
+ st->clear.vertices[i][1][0] = color[0];
+ st->clear.vertices[i][1][1] = color[1];
+ st->clear.vertices[i][1][2] = color[2];
+ st->clear.vertices[i][1][3] = color[3];
}
- st_draw_vertices(ctx, PIPE_PRIM_POLYGON, 4, (float *) verts, 2,
-#if TEST_DRAW_PASSTHROUGH
- GL_TRUE
-#else
- GL_FALSE
-#endif
- );
+ /* put vertex data into vbuf */
+ buf = pipe->winsys->buffer_map(pipe->winsys, st->clear.vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ memcpy(buf, st->clear.vertices, sizeof(st->clear.vertices));
+ pipe->winsys->buffer_unmap(pipe->winsys, st->clear.vbuf);
+
+ /* draw */
+ util_draw_vertex_buffer(pipe, st->clear.vbuf,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
}
@@ -234,9 +165,17 @@ clear_with_quad(GLcontext *ctx,
struct st_context *st = ctx->st;
struct pipe_context *pipe = st->pipe;
const GLfloat x0 = ctx->DrawBuffer->_Xmin;
- const GLfloat y0 = ctx->DrawBuffer->_Ymin;
const GLfloat x1 = ctx->DrawBuffer->_Xmax;
- const GLfloat y1 = ctx->DrawBuffer->_Ymax;
+ GLfloat y0, y1;
+
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+ y0 = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymax;
+ y1 = ctx->DrawBuffer->Height - ctx->DrawBuffer->_Ymin;
+ }
+ else {
+ y0 = ctx->DrawBuffer->_Ymin;
+ y1 = ctx->DrawBuffer->_Ymax;
+ }
/*
printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
@@ -247,10 +186,19 @@ clear_with_quad(GLcontext *ctx,
x1, y1);
*/
+ cso_save_blend(st->cso_context);
+ cso_save_depth_stencil_alpha(st->cso_context);
+ cso_save_rasterizer(st->cso_context);
+ cso_save_viewport(st->cso_context);
+
/* blend state: RGBA masking */
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
+ blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
if (color) {
if (ctx->Color.ColorMask[0])
blend.colormask |= PIPE_MASK_R;
@@ -290,42 +238,35 @@ clear_with_quad(GLcontext *ctx,
cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
}
- /* rasterizer state: nothing */
+ /* rasterizer state: bypass clipping */
{
struct pipe_rasterizer_state raster;
memset(&raster, 0, sizeof(raster));
-#if 0
- /* don't do per-pixel scissor; we'll just draw a PIPE_PRIM_QUAD
- * that matches the scissor bounds.
- */
- if (ctx->Scissor.Enabled)
- raster.scissor = 1;
-#endif
-#if TEST_DRAW_PASSTHROUGH
raster.bypass_clipping = 1;
+#if TEST_DRAW_PASSTHROUGH
raster.bypass_vs = 1;
#endif
cso_set_rasterizer(st->cso_context, &raster);
}
/* fragment shader state: color pass-through program */
- {
- static struct st_fragment_program *stfp = NULL;
- if (!stfp) {
- stfp = make_frag_shader(st);
- }
- pipe->bind_fs_state(pipe, stfp->driver_shader);
+ if (!st->clear.fs) {
+ st->clear.fs = util_make_fragment_passthrough_shader(pipe);
}
+ pipe->bind_fs_state(pipe, st->clear.fs);
+
#if !TEST_DRAW_PASSTHROUGH
/* vertex shader state: color/position pass-through */
- {
- static struct st_vertex_program *stvp = NULL;
- if (!stvp) {
- stvp = make_vertex_shader(st);
- }
- pipe->bind_vs_state(pipe, stvp->driver_shader);
+ if (!st->clear.vs) {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_COLOR };
+ const uint semantic_indexes[] = { 0, 0 };
+ st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2,
+ semantic_names,
+ semantic_indexes);
}
+ pipe->bind_vs_state(pipe, st->clear.vs);
#endif
#if !TEST_DRAW_PASSTHROUGH
@@ -342,28 +283,21 @@ clear_with_quad(GLcontext *ctx,
vp.translate[1] = 0.5 * height;
vp.translate[2] = 0.0;
vp.translate[3] = 0.0;
- pipe->set_viewport_state(pipe, &vp);
+ cso_set_viewport(st->cso_context, &vp);
}
#endif
/* draw quad matching scissor rect (XXX verify coord round-off) */
draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
-#if 0
- /* Can't depend on old state objects still existing -- may have
- * been deleted to make room in the hash, etc. (Should get
- * fixed...)
- */
- st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
-#else
/* Restore pipe state */
- cso_set_blend(st->cso_context, &st->state.blend);
- cso_set_depth_stencil_alpha(st->cso_context, &st->state.depth_stencil);
- cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
+ cso_restore_blend(st->cso_context);
+ cso_restore_depth_stencil_alpha(st->cso_context);
+ cso_restore_rasterizer(st->cso_context);
+ cso_restore_viewport(st->cso_context);
+ /* these don't go through cso yet */
pipe->bind_fs_state(pipe, st->fp->driver_shader);
pipe->bind_vs_state(pipe, st->vp->driver_shader);
-#endif
- pipe->set_viewport_state(pipe, &st->state.viewport);
}
diff --git a/src/mesa/state_tracker/st_cb_clear.h b/src/mesa/state_tracker/st_cb_clear.h
index c715e56bd5..dfa4033faa 100644
--- a/src/mesa/state_tracker/st_cb_clear.h
+++ b/src/mesa/state_tracker/st_cb_clear.h
@@ -31,6 +31,10 @@
extern void
+st_destroy_clear(struct st_context *st);
+
+
+extern void
st_init_clear_functions(struct dd_function_table *functions);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 18ec9645c4..2ebaf8a2c3 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -32,6 +32,7 @@
#include "main/imports.h"
#include "main/image.h"
+#include "main/bufferobj.h"
#include "main/macros.h"
#include "main/texformat.h"
#include "shader/program.h"
@@ -56,6 +57,7 @@
#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "util/p_tile.h"
+#include "util/u_draw_quad.h"
#include "shader/prog_instruction.h"
#include "cso_cache/cso_context.h"
@@ -85,140 +87,6 @@ is_passthrough_program(const struct gl_fragment_program *prog)
}
-/**
- * Make fragment program for glBitmap:
- * Sample the texture and kill the fragment if the bit is 0.
- * This program will be combined with the user's fragment program.
- */
-static struct st_fragment_program *
-make_bitmap_fragment_program(GLcontext *ctx)
-{
- struct st_fragment_program *stfp;
- struct gl_program *p;
- GLuint ic = 0;
-
- p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
- if (!p)
- return NULL;
-
- p->NumInstructions = 5;
-
- p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
- if (!p->Instructions) {
- ctx->Driver.DeleteProgram(ctx, p);
- return NULL;
- }
- _mesa_init_instructions(p->Instructions, p->NumInstructions);
-
- /* TEX tmp0, fragment.texcoord[0], texture[0], 2D; */
- p->Instructions[ic].Opcode = OPCODE_TEX;
- p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
- p->Instructions[ic].DstReg.Index = 0;
- p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
- p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
- p->Instructions[ic].TexSrcUnit = 0;
- p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
- ic++;
-
- /* SWZ tmp0.x, tmp0.x, 1111; # tmp0.x = 1.0 */
- p->Instructions[ic].Opcode = OPCODE_SWZ;
- p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
- p->Instructions[ic].DstReg.Index = 0;
- p->Instructions[ic].DstReg.WriteMask = WRITEMASK_X;
- p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
- p->Instructions[ic].SrcReg[0].Index = 0;
- p->Instructions[ic].SrcReg[0].Swizzle
- = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE );
- ic++;
-
- /* SUB tmp0, tmp0.wwww, tmp0.xxxx; # tmp0.w -= 1 */
- p->Instructions[ic].Opcode = OPCODE_SUB;
- p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY;
- p->Instructions[ic].DstReg.Index = 0;
- p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
- p->Instructions[ic].SrcReg[0].Index = 0;
- p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_WWWW;
- p->Instructions[ic].SrcReg[1].File = PROGRAM_TEMPORARY;
- p->Instructions[ic].SrcReg[1].Index = 0;
- p->Instructions[ic].SrcReg[1].Swizzle = SWIZZLE_XXXX; /* 1.0 */
- ic++;
-
- /* KIL if tmp0 < 0 */
- p->Instructions[ic].Opcode = OPCODE_KIL;
- p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY;
- p->Instructions[ic].SrcReg[0].Index = 0;
- ic++;
-
- /* END; */
- p->Instructions[ic++].Opcode = OPCODE_END;
-
- assert(ic == p->NumInstructions);
-
- p->InputsRead = FRAG_BIT_TEX0;
- p->OutputsWritten = 0x0;
-
- stfp = (struct st_fragment_program *) p;
- stfp->Base.UsesKill = GL_TRUE;
- st_translate_fragment_program(ctx->st, stfp, NULL);
-
- return stfp;
-}
-
-
-/**
- * Combine basic bitmap fragment program with the user-defined program.
- */
-static struct st_fragment_program *
-combined_bitmap_fragment_program(GLcontext *ctx)
-{
- struct st_context *st = ctx->st;
- struct st_fragment_program *stfp;
-
- if (!st->bitmap.program) {
- /* create the basic bitmap fragment program */
- st->bitmap.program = make_bitmap_fragment_program(ctx);
- }
-
- if (st->bitmap.user_prog_sn == st->fp->serialNo) {
- /* re-use */
- stfp = st->bitmap.combined_prog;
- }
- else {
- /* Concatenate the bitmap program with the current user-defined program.
- */
- stfp = (struct st_fragment_program *)
- _mesa_combine_programs(ctx,
- &st->bitmap.program->Base.Base,
- &st->fp->Base.Base);
-
-#if 0
- {
- struct gl_program *p = &stfp->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, NULL);
-
- /* save new program, update serial numbers */
- st->bitmap.user_prog_sn = st->fp->serialNo;
- st->bitmap.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 glBitmap.
- */
- st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
-
- return stfp;
-}
-
-
/**
* Make fragment shader for glDraw/CopyPixels. This shader is made
@@ -351,7 +219,7 @@ make_fragment_shader_z(struct st_context *st)
* Create a simple vertex shader that just passes through the
* vertex position and texcoord (and optionally, color).
*/
-struct st_vertex_program *
+static struct st_vertex_program *
st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor)
{
/* only make programs once and re-use */
@@ -467,16 +335,15 @@ make_texture(struct st_context *st,
assert(pipeFormat);
cpp = st_sizeof_format(pipeFormat);
+ pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ if (!pixels)
+ return NULL;
+
pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height,
1, 0);
- if (!pt)
+ if (!pt) {
+ _mesa_unmap_drapix_pbo(ctx, unpack);
return NULL;
-
- if (unpack->BufferObj && unpack->BufferObj->Name) {
- /*
- pt->region = buffer_object_region(unpack->BufferObj);
- */
- printf("st_DrawPixels (sourcing from PBO not implemented yet)\n");
}
{
@@ -513,12 +380,16 @@ make_texture(struct st_context *st,
/* unmap */
pipe_surface_unmap(surface);
pipe_surface_reference(&surface, NULL);
+ pipe->texture_update(pipe, pt, 0, 0x1);
+
assert(success);
/* restore */
ctx->_ImageTransferState = imageTransferStateSave;
}
+ _mesa_unmap_drapix_pbo(ctx, unpack);
+
return pt;
}
@@ -650,14 +521,17 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
assert(width <= maxSize);
assert(height <= maxSize);
- /* setup state: just scissor */
+ cso_save_rasterizer(cso);
+ cso_save_viewport(cso);
+
+ /* rasterizer state: just scissor */
{
- struct pipe_rasterizer_state setup;
- memset(&setup, 0, sizeof(setup));
+ struct pipe_rasterizer_state rasterizer;
+ memset(&rasterizer, 0, sizeof(rasterizer));
if (ctx->Scissor.Enabled)
- setup.scissor = 1;
+ rasterizer.scissor = 1;
- cso_set_rasterizer(cso, &setup);
+ cso_set_rasterizer(cso, &rasterizer);
}
/* fragment shader state: TEX lookup program */
@@ -696,7 +570,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
vp.translate[1] = 0.5 * height;
vp.translate[2] = 0.0;
vp.translate[3] = 0.0;
- pipe->set_viewport_state(pipe, &vp);
+ cso_set_viewport(cso, &vp);
}
/* texture state: */
@@ -719,26 +593,18 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
else
draw_quad(ctx, x0, y0, z, x1, y1, invertTex);
- /* restore GL state */
- pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
- ctx->st->state.sampler_texture);
-
- pipe->set_viewport_state(pipe, &ctx->st->state.viewport);
-
-#if 0
- /* Can't depend on old state objects still existing -- may have
- * been deleted to make room in the hash, etc. (Should get
- * fixed...)
- */
- st_invalidate_state(ctx, _NEW_COLOR | _NEW_TEXTURE);
-#else
/* restore state */
+ cso_restore_rasterizer(cso);
+ cso_restore_viewport(cso);
+ /* shaders don't go through cso yet */
pipe->bind_fs_state(pipe, st->fp->driver_shader);
pipe->bind_vs_state(pipe, st->vp->driver_shader);
+
cso_set_rasterizer(cso, &st->state.rasterizer);
cso_set_samplers(cso, PIPE_MAX_SAMPLERS,
(const struct pipe_sampler_state **) st->state.sampler_list);
-#endif
+ pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
+ ctx->st->state.sampler_texture);
}
@@ -972,9 +838,9 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
bufferFormat = ps->format;
- if (any_fragment_ops(st) ||
+ if (1/*any_fragment_ops(st) ||
any_pixel_transfer_ops(st) ||
- !compatible_formats(format, type, ps->format)) {
+ !compatible_formats(format, type, ps->format)*/) {
/* textured quad */
struct pipe_texture *pt
= make_texture(ctx->st, width, height, format, type, unpack, pixels);
@@ -993,152 +859,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
-/**
- * Create a texture which represents a bitmap image.
- */
-static struct pipe_texture *
-make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
- const struct gl_pixelstore_attrib *unpack,
- const GLubyte *bitmap)
-{
- struct pipe_context *pipe = ctx->st->pipe;
- struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *surface;
- uint format = 0, cpp, comp;
- ubyte *dest;
- struct pipe_texture *pt;
- int row, col;
-
- /* find a texture format we know */
- if (screen->is_format_supported( screen, PIPE_FORMAT_U_I8, PIPE_TEXTURE )) {
- format = PIPE_FORMAT_U_I8;
- cpp = 1;
- comp = 0;
- }
- else if (screen->is_format_supported( screen, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_TEXTURE )) {
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
- cpp = 4;
- comp = 3; /* alpha channel */ /*XXX little-endian dependency */
- }
- else {
- /* XXX support more formats */
- assert( 0 );
- }
-
- /**
- * Create a texture.
- */
- pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, format, 0, width, height,
- 1, 0);
- if (!pt)
- return NULL;
-
- if (unpack->BufferObj && unpack->BufferObj->Name) {
- /*
- pt->region = buffer_object_region(unpack->BufferObj);
- */
- printf("st_Bitmap (sourcing from PBO not implemented yet)\n");
- }
-
- surface = screen->get_tex_surface(screen, pt, 0, 0, 0);
-
- /* map texture surface */
- dest = pipe_surface_map(surface);
-
- /* Put image into texture surface.
- * Note that the image is actually going to be upside down in
- * the texture. We deal with that with texcoords.
- */
-
- for (row = 0; row < height; row++) {
- const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
- bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
- ubyte *destRow = dest + row * surface->pitch * cpp;
-
- if (unpack->LsbFirst) {
- /* Lsb first */
- GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
- for (col = 0; col < width; col++) {
-
- /* set texel to 255 if bit is set */
- destRow[comp] = (*src & mask) ? 255 : 0;
- destRow += cpp;
-
- if (mask == 128U) {
- src++;
- mask = 1U;
- }
- else {
- mask = mask << 1;
- }
- }
-
- /* get ready for next row */
- if (mask != 1)
- src++;
- }
- else {
- /* Msb first */
- GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
- for (col = 0; col < width; col++) {
-
- /* set texel to 255 if bit is set */
- destRow[comp] =(*src & mask) ? 255 : 0;
- destRow += cpp;
-
- if (mask == 1U) {
- src++;
- mask = 128U;
- }
- else {
- mask = mask >> 1;
- }
- }
-
- /* get ready for next row */
- if (mask != 128)
- src++;
- }
-
- } /* row */
-
- /* Release surface */
- pipe_surface_unmap(surface);
- pipe_surface_reference(&surface, NULL);
-
- pt->format = format;
-
- return pt;
-}
-
-
-
-static void
-st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
- const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap )
-{
- struct st_fragment_program *stfp;
- struct st_vertex_program *stvp;
- struct st_context *st = ctx->st;
- struct pipe_texture *pt;
-
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
- stfp = combined_bitmap_fragment_program(ctx);
-
- st_validate_state(st);
-
- pt = make_bitmap_texture(ctx, width, height, unpack, bitmap);
- if (pt) {
- draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
- width, height, 1.0, 1.0,
- pt, stvp, stfp,
- ctx->Current.RasterColor, GL_FALSE);
-
- pipe_texture_reference(&pt, NULL);
- }
-}
-
-
static void
copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
@@ -1339,5 +1059,4 @@ void st_init_drawpixels_functions(struct dd_function_table *functions)
{
functions->DrawPixels = st_DrawPixels;
functions->CopyPixels = st_CopyPixels;
- functions->Bitmap = st_Bitmap;
}
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.h b/src/mesa/state_tracker/st_cb_drawpixels.h
index b8b906f06b..71ba487020 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.h
+++ b/src/mesa/state_tracker/st_cb_drawpixels.h
@@ -30,10 +30,6 @@
#define ST_CB_DRAWPIXELS_H
-extern struct st_vertex_program *
-st_make_passthrough_vertex_shader(struct st_context *st, GLboolean passColor);
-
-
extern void st_init_drawpixels_functions(struct dd_function_table *functions);
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 0a62e20e0c..a739fcd336 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -126,19 +126,39 @@ static void st_delete_program( GLcontext *ctx,
struct gl_program *prog )
{
struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
switch( prog->Target ) {
case GL_VERTEX_PROGRAM_ARB:
{
struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
- st_remove_vertex_program(st, stvp);
+
+ if (stvp->driver_shader) {
+ pipe->delete_vs_state(pipe, stvp->driver_shader);
+ stvp->driver_shader = NULL;
+ }
+
+ if (stvp->state.tokens) {
+ FREE((void *) stvp->state.tokens);
+ stvp->state.tokens = NULL;
+ }
}
break;
case GL_FRAGMENT_PROGRAM_ARB:
{
- struct st_fragment_program *stfp
- = (struct st_fragment_program *) prog;
- st_remove_fragment_program(st, stfp);
+ struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
+
+ if (stfp->driver_shader) {
+ pipe->delete_fs_state(pipe, stfp->driver_shader);
+ stfp->driver_shader = NULL;
+ }
+
+ if (stfp->state.tokens) {
+ FREE((void *) stfp->state.tokens);
+ stfp->state.tokens = NULL;
+ }
+
+ st_free_translated_vertex_programs(st, stfp->vertex_programs);
}
break;
default:
@@ -162,27 +182,25 @@ static void st_program_string_notify( GLcontext *ctx,
struct gl_program *prog )
{
struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
if (target == GL_FRAGMENT_PROGRAM_ARB) {
struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
stfp->serialNo++;
-#if 0
- if (stfp->cso) {
- /* free the TGSI code */
- // cso_delete(stfp->vs);
- stfp->cso = NULL;
+ if (stfp->driver_shader) {
+ pipe->delete_fs_state(pipe, stfp->driver_shader);
+ stfp->driver_shader = NULL;
}
-#endif
-
- stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
if (stfp->state.tokens) {
FREE((void *) stfp->state.tokens);
stfp->state.tokens = NULL;
}
+ stfp->param_state = stfp->Base.Base.Parameters->StateFlags;
+
if (st->fp == stfp)
st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
}
@@ -191,26 +209,23 @@ static void st_program_string_notify( GLcontext *ctx,
stvp->serialNo++;
-#if 0
- if (stvp->cso) {
- /* free the CSO data */
- st->pipe->delete_vs_state(st->pipe, stvp->cso->data);
- FREE((void *) stvp->cso);
- stvp->cso = NULL;
+ if (stvp->driver_shader) {
+ pipe->delete_vs_state(pipe, stvp->driver_shader);
+ stvp->driver_shader = NULL;
}
-#endif
+
if (stvp->draw_shader) {
draw_delete_vertex_shader(st->draw, stvp->draw_shader);
stvp->draw_shader = NULL;
}
- stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
-
if (stvp->state.tokens) {
FREE((void *) stvp->state.tokens);
stvp->state.tokens = NULL;
}
+ stvp->param_state = stvp->Base.Base.Parameters->StateFlags;
+
if (st->vp == stvp)
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index c89c74229e..4cf9adcd28 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -34,6 +34,7 @@
#include "main/imports.h"
+#include "main/bufferobj.h"
#include "main/context.h"
#include "main/image.h"
@@ -126,7 +127,6 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
-
/**
* Do glReadPixels by getting rows from the framebuffer surface with
* get_tile(). Convert to requested format/type with Mesa image routines.
@@ -155,18 +155,13 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
+ dest = _mesa_map_readpix_pbo(ctx, &clippedPacking, dest);
+ if (!dest)
+ return;
+
/* make sure rendering has completed */
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE);
- if (pack->BufferObj && pack->BufferObj->Name) {
- /* reading into a PBO */
-
- }
- else {
- /* reading into user memory/buffer */
-
- }
-
if (format == GL_STENCIL_INDEX) {
st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest);
return;
@@ -285,6 +280,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
}
}
+
+ _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index d4731c7737..a6c1a35355 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -476,6 +476,7 @@ st_TexImage(GLcontext * ctx,
struct gl_texture_image *texImage,
GLsizei imageSize, int compressed)
{
+ struct pipe_context *pipe = ctx->st->pipe;
struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLint postConvWidth, postConvHeight;
@@ -563,7 +564,8 @@ st_TexImage(GLcontext * ctx,
if (!stObj->pt) {
guess_and_alloc_texture(ctx->st, stObj, stImage);
if (!stObj->pt) {
- DBG("guess_and_alloc_texture: failed\n");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return;
}
}
@@ -690,8 +692,8 @@ st_TexImage(GLcontext * ctx,
texImage->Data = NULL;
}
- /* flag data as dirty */
- stObj->dirtyData = GL_TRUE;
+ if (stObj->pt)
+ pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
ctx->Driver.GenerateMipmap(ctx, target, texObj);
@@ -866,6 +868,7 @@ st_TexSubimage(GLcontext * ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
+ struct pipe_context *pipe = ctx->st->pipe;
struct st_texture_object *stObj = st_texture_object(texObj);
struct st_texture_image *stImage = st_texture_image(texImage);
GLuint dstRowStride;
@@ -924,8 +927,7 @@ st_TexSubimage(GLcontext * ctx,
texImage->Data = NULL;
}
- /* flag data as dirty */
- stObj->dirtyData = GL_TRUE;
+ pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
}
@@ -1179,8 +1181,7 @@ do_copy_texsubimage(GLcontext *ctx,
pipe_surface_reference(&dest_surface, NULL);
- /* flag data as dirty */
- stObj->dirtyData = GL_TRUE;
+ pipe->texture_update(pipe, stObj->pt, stImage->face, (1 << level));
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
ctx->Driver.GenerateMipmap(ctx, target, texObj);
@@ -1379,7 +1380,7 @@ copy_image_data_to_texture(struct st_context *st,
/**
* Called during state validation. When this function is finished,
* the texture object should be ready for rendering.
- * \return GL_FALSE if a texture border is present, GL_TRUE otherwise
+ * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
*/
GLboolean
st_finalize_texture(GLcontext *ctx,
@@ -1405,6 +1406,7 @@ st_finalize_texture(GLcontext *ctx,
calculate_first_last_level(stObj);
firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
+#if 0
/* Fallback case:
*/
if (firstImage->base.Border) {
@@ -1413,7 +1415,7 @@ st_finalize_texture(GLcontext *ctx,
}
return GL_FALSE;
}
-
+#endif
/* If both firstImage and stObj point to a texture which can contain
* all active images, favour firstImage. Note that because of the
@@ -1466,6 +1468,10 @@ st_finalize_texture(GLcontext *ctx,
firstImage->base.Height,
firstImage->base.Depth,
comp_byte);
+ if (!stObj->pt) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ return GL_FALSE;
+ }
}
/* Pull in any images not in the object's texture:
@@ -1481,11 +1487,11 @@ st_finalize_texture(GLcontext *ctx,
if (stImage && stObj->pt != stImage->pt) {
copy_image_data_to_texture(ctx->st, stObj, level, stImage);
*needFlush = GL_TRUE;
+ pipe->texture_update(pipe, stObj->pt, face, (1 << level));
}
}
}
-
return GL_TRUE;
}
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index e1fc885e0e..d9e8722976 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -35,8 +35,9 @@
#include "st_public.h"
#include "st_context.h"
#include "st_cb_accum.h"
-#include "st_cb_bufferobjects.h"
+#include "st_cb_bitmap.h"
#include "st_cb_blit.h"
+#include "st_cb_bufferobjects.h"
#include "st_cb_clear.h"
#include "st_cb_drawpixels.h"
#include "st_cb_fbo.h"
@@ -154,7 +155,9 @@ static void st_destroy_context_priv( struct st_context *st )
st_destroy_atoms( st );
st_destroy_draw( st );
st_destroy_generate_mipmap(st);
+ st_destroy_bitmap(st);
st_destroy_blit(st);
+ st_destroy_clear(st);
_vbo_DestroyContext(st->ctx);
@@ -220,8 +223,9 @@ void st_init_driver_functions(struct dd_function_table *functions)
_mesa_init_glsl_driver_functions(functions);
st_init_accum_functions(functions);
- st_init_bufferobject_functions(functions);
+ st_init_bitmap_functions(functions);
st_init_blit_functions(functions);
+ st_init_bufferobject_functions(functions);
st_init_clear_functions(functions);
st_init_drawpixels_functions(functions);
st_init_fbo_functions(functions);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 63150dbeaf..2d37086799 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -82,7 +82,6 @@ struct st_context
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state *sampler_list[PIPE_MAX_SAMPLERS];
- struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
struct pipe_constant_buffer constants[2];
struct pipe_framebuffer_state framebuffer;
@@ -143,12 +142,24 @@ struct st_context
GLuint combined_prog_sn;
} pixel_xfer;
+ /** for glBitmap */
struct {
struct st_fragment_program *program; /**< bitmap tex/kil program */
GLuint user_prog_sn; /**< user fragment program serial no. */
struct st_fragment_program *combined_prog;
+ void *vs;
+ float vertices[4][3][4]; /**< vertex pos + color + texcoord */
+ struct pipe_buffer *vbuf;
} bitmap;
+ /** for glClear */
+ struct {
+ void *vs;
+ void *fs;
+ float vertices[4][2][4]; /**< vertex pos + color */
+ struct pipe_buffer *vbuf;
+ } clear;
+
struct gen_mipmap_state *gen_mipmap;
struct blit_state *blit;
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 8b9b91aa34..23ecfff0aa 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -50,9 +50,10 @@ st_print_current(void)
{
GET_CURRENT_CONTEXT(ctx);
struct st_context *st = ctx->st;
- int i;
#if 0
+ int i;
+
printf("Vertex Transform Inputs:\n");
for (i = 0; i < st->vp->state.num_inputs; i++) {
printf(" Slot %d: VERT_ATTRIB_%d\n", i, st->vp->index_to_input[i]);
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 5ebd0bbcce..20af90df7d 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -223,7 +223,7 @@ st_draw_vbo(GLcontext *ctx,
/* loop over TGSI shader inputs to determine vertex buffer
* and attribute info
*/
- for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) {
+ for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
struct pipe_vertex_element velement;
@@ -333,7 +333,7 @@ st_draw_vbo(GLcontext *ctx,
}
/* unreference buffers (frees wrapped user-space buffer objects) */
- for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) {
+ for (attr = 0; attr < vp->num_inputs; attr++) {
pipe_buffer_reference(winsys, &vbuffer[attr].buffer, NULL);
assert(!vbuffer[attr].buffer);
pipe->set_vertex_buffer(pipe, attr, &vbuffer[attr]);
@@ -502,7 +502,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
/* loop over TGSI shader inputs to determine vertex buffer
* and attribute info
*/
- for (attr = 0; attr < /*vs*/vp->num_inputs; attr++) {
+ for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj;
struct pipe_vertex_element velement;
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 0962b5f74c..7fab4d041d 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -155,7 +155,6 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.EXT_texture_env_combine = GL_TRUE;
ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE;
ctx->Extensions.EXT_texture_lod_bias = GL_TRUE;
- ctx->Extensions.EXT_texture_sRGB = GL_TRUE; /* XXX temp */
ctx->Extensions.NV_blend_square = GL_TRUE;
ctx->Extensions.NV_texgen_reflection = GL_TRUE;
@@ -190,10 +189,6 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.ATI_separate_stencil = GL_TRUE;
}
- if (screen->get_param(screen, PIPE_CAP_S3TC)) {
- ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
- }
-
if (screen->get_param(screen, PIPE_CAP_ANISOTROPIC_FILTER)) {
ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE;
}
@@ -214,4 +209,14 @@ void st_init_extensions(struct st_context *st)
/*ctx->Extensions.ARB_shadow_ambient = GL_TRUE;*/
}
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R8G8B8A8_SRGB,
+ PIPE_TEXTURE)) {
+ ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
+ }
+
+ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
+ PIPE_TEXTURE)) {
+ ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
+ }
+
}
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 6c3afca1ba..61e1d9621c 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -59,7 +59,7 @@
void
st_init_generate_mipmap(struct st_context *st)
{
- st->gen_mipmap = util_create_gen_mipmap(st->pipe);
+ st->gen_mipmap = util_create_gen_mipmap(st->pipe, st->cso_context);
}
@@ -94,19 +94,11 @@ st_render_mipmap(struct st_context *st,
util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel);
- /* restore pipe state */
-#if 0
- cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
- cso_set_samplers(st->cso_context, st->state.samplers_list);
- pipe->bind_fs_state(pipe, st->fp->shader_program);
- pipe->bind_vs_state(pipe, st->vp->shader_program);
- pipe->set_sampler_textures(pipe, st->state.num_textures,
- st->state.sampler_texture);
- pipe->set_viewport_state(pipe, &st->state.viewport);
-#else
- /* XXX is this sufficient? */
- st_invalidate_state(st->ctx, _NEW_COLOR | _NEW_TEXTURE);
-#endif
+ /* shaders don't go through CSO yet */
+ if (st->fp)
+ pipe->bind_fs_state(pipe, st->fp->driver_shader);
+ if (st->vp)
+ pipe->bind_vs_state(pipe, st->vp->driver_shader);
return TRUE;
}
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index d9d11ee0e8..101a6a48af 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -260,6 +260,16 @@ st_translate_vertex_program(struct st_context *st,
outputMapping = defaultOutputMapping;
}
+ /* free old shader state, if any */
+ if (stvp->state.tokens) {
+ FREE((void *) stvp->state.tokens);
+ stvp->state.tokens = NULL;
+ }
+ if (stvp->driver_shader) {
+ pipe->delete_vs_state(pipe, stvp->driver_shader);
+ stvp->driver_shader = NULL;
+ }
+
/* XXX: fix static allocation of tokens:
*/
num_tokens = tgsi_translate_mesa_program( TGSI_PROCESSOR_VERTEX,
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index 78f5f451ed..7abccb3a69 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -71,8 +71,6 @@ struct st_texture_object
GLboolean imageOverride;
GLint depthOverride;
GLuint pitchOverride;
-
- GLboolean dirtyData;
};
diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c
index 1e7f6c18e6..f3dda12e25 100644
--- a/src/mesa/swrast/s_bitmap.c
+++ b/src/mesa/swrast/s_bitmap.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.2
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -57,25 +57,9 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
ASSERT(ctx->RenderMode == GL_RENDER);
- if (unpack->BufferObj->Name) {
- /* unpack from PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
- GL_COLOR_INDEX, GL_BITMAP,
- (GLvoid *) bitmap)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- unpack->BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
- return;
- }
- bitmap = ADD_POINTERS(buf, bitmap);
- }
+ bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
+ if (!bitmap)
+ return;
RENDER_START(swrast,ctx);
@@ -150,11 +134,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
RENDER_FINISH(swrast,ctx);
- if (unpack->BufferObj->Name) {
- /* done with PBO so unmap it now */
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- unpack->BufferObj);
- }
+ _mesa_unmap_bitmap_pbo(ctx, unpack);
}
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index 0cf425e1c6..fb04d9f746 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -812,7 +812,6 @@ draw_depth_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
}
-
/**
* Execute software-based glDrawPixels.
* By time we get here, all error checking will have been done.
@@ -835,25 +834,9 @@ _swrast_DrawPixels( GLcontext *ctx,
if (swrast->NewState)
_swrast_validate_derived( ctx );
- if (unpack->BufferObj->Name) {
- /* unpack from PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glDrawPixels(invalid PBO access)");
- goto end;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- unpack->BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)");
- goto end;
- }
- pixels = ADD_POINTERS(buf, pixels);
- }
+ pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ if (!pixels)
+ return;
switch (format) {
case GL_STENCIL_INDEX:
@@ -894,11 +877,7 @@ end:
RENDER_FINISH(swrast,ctx);
- if (unpack->BufferObj->Name) {
- /* done with PBO so unmap it now */
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- unpack->BufferObj);
- }
+ _mesa_unmap_drapix_pbo(ctx, unpack);
}
diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index fe9a70f4ea..2f155d0b70 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -572,25 +572,9 @@ _swrast_ReadPixels( GLcontext *ctx,
goto end;
}
- if (clippedPacking.BufferObj->Name) {
- /* pack into PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, &clippedPacking, width, height, 1,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(invalid PBO access)");
- goto end;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- clippedPacking.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
- goto end;
- }
- pixels = ADD_POINTERS(buf, pixels);
- }
+ pixels = _mesa_map_readpix_pbo(ctx, &clippedPacking, pixels);
+ if (!pixels)
+ return;
switch (format) {
case GL_COLOR_INDEX:
@@ -632,9 +616,5 @@ _swrast_ReadPixels( GLcontext *ctx,
end:
RENDER_FINISH(swrast, ctx);
- if (clippedPacking.BufferObj->Name) {
- /* done with PBO so unmap it now */
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- clippedPacking.BufferObj);
- }
+ _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
}