summaryrefslogtreecommitdiff
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/sources1
-rw-r--r--src/mesa/state_tracker/st_atom_framebuffer.c3
-rw-r--r--src/mesa/state_tracker/st_atom_texture.c5
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c524
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.h41
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c13
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c221
-rw-r--r--src/mesa/state_tracker/st_cb_clear.h4
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c295
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.h4
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c13
-rw-r--r--src/mesa/state_tracker/st_context.c8
-rw-r--r--src/mesa/state_tracker/st_context.h12
-rw-r--r--src/mesa/state_tracker/st_debug.c3
14 files changed, 701 insertions, 446 deletions
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_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c
index 43259c3ecb..02573af8f0 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -52,6 +52,9 @@ update_framebuffer_state( struct st_context *st )
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
*/
diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
index 2a711e513d..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;
}
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..33256196bb
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -0,0 +1,524 @@
+/**************************************************************************
+ *
+ * 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/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 );
+ }
+
+ /**
+ * 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);
+ 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/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h
new file mode 100644
index 0000000000..ac19e0ebb1
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_bitmap.h
@@ -0,0 +1,41 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+
+#ifndef ST_CB_BITMAP_H
+#define ST_CB_BITMAP_H
+
+
+extern void
+st_init_bitmap_functions(struct dd_function_table *functions);
+
+
+extern void
+st_destroy_bitmap(struct st_context *st);
+
+
+#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 64314a5078..63211d8b66 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -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;
-
- dstY0 = dstRb->Base.Height - dstY0;
- dstY1 = dstRb->Base.Height - dstY1;
+ 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;
+ }
util_blit_pixels(st->blit,
srcSurf, srcX0, srcY0, srcX1, srcY1,
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index c23938dc68..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__,
@@ -299,35 +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 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
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 99d5e3e848..b4cd93cd54 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -56,6 +56,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 +86,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 +218,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 */
@@ -655,14 +522,14 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
cso_save_rasterizer(cso);
cso_save_viewport(cso);
- /* setup state: just scissor */
+ /* 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 */
@@ -990,153 +857,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);
- pipe->texture_update(pipe, pt, 0, 0x1);
-
- 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,
@@ -1337,5 +1057,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_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 306b27c423..a6c1a35355 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -564,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;
}
}
@@ -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:
@@ -1486,7 +1492,6 @@ st_finalize_texture(GLcontext *ctx,
}
}
-
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 ca8307c4ba..2d37086799 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -142,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]);