diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/sources | 1 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_framebuffer.c | 3 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_atom_texture.c | 5 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_bitmap.c | 524 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_bitmap.h | 41 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_blit.c | 13 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_clear.c | 221 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_clear.h | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 295 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.h | 4 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 13 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 8 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 12 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_debug.c | 3 |
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]); |