diff options
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r-- | src/mesa/state_tracker/st_cb_bitmap.c | 148 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_drawpixels.c | 14 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_cb_flush.c | 2 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 2 |
4 files changed, 89 insertions, 77 deletions
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index ec56b25f7ce..975a55d6dc0 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -60,6 +60,19 @@ /** + * glBitmaps are drawn as textured quads. The user's bitmap pattern + * is stored in a texture image. An alpha8 texture format is used. + * The fragment shader samples a bit (texel) from the texture, then + * discards the fragment if the bit is off. + * + * Note that we actually store the inverse image of the bitmap to + * simplify the fragment program. An "on" bit gets stored as texel=0x0 + * and an "off" bit is stored as texel=0xff. Then we kill the + * fragment if the negated texel value is less than zero. + */ + + +/** * The bitmap cache attempts to accumulate multiple glBitmap calls in a * buffer which is then rendered en mass upon a flush, state change, etc. * A wide, short buffer is used to target the common case of a series @@ -102,7 +115,7 @@ make_bitmap_fragment_program(GLcontext *ctx) if (!p) return NULL; - p->NumInstructions = 5; + p->NumInstructions = 3; p->Instructions = _mesa_alloc_instructions(p->NumInstructions); if (!p->Instructions) { @@ -121,33 +134,11 @@ make_bitmap_fragment_program(GLcontext *ctx) 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 */ + /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */ p->Instructions[ic].Opcode = OPCODE_KIL; p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; p->Instructions[ic].SrcReg[0].Index = 0; + p->Instructions[ic].SrcReg[0].NegateBase = NEGATE_XYZW; ic++; /* END; */ @@ -289,7 +280,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, for (col = 0; col < width; col++) { /* set texel to 255 if bit is set */ - destRow[comp] = (*src & mask) ? 255 : 0; + destRow[comp] = (*src & mask) ? 0x0 : 0xff; destRow += cpp; if (mask == 128U) { @@ -311,7 +302,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, for (col = 0; col < width; col++) { /* set texel to 255 if bit is set */ - destRow[comp] =(*src & mask) ? 255 : 0; + destRow[comp] =(*src & mask) ? 0x0 : 0xff; destRow += cpp; if (mask == 1U) { @@ -350,16 +341,21 @@ setup_bitmap_vertex_data(struct st_context *st, { 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 fb_width = fb->Width; + const GLfloat fb_height = fb->Height; const GLfloat x0 = x; const GLfloat x1 = x + width; - const GLfloat y0 = invert ? ((int) fb->Height - y - height) : y; - const GLfloat y1 = invert ? (y0 + height) : y + height; + const GLfloat y0 = y; + const GLfloat y1 = 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; + const GLfloat tTop = yBias, tBot = 1.0 - tTop - yBias; + const GLfloat clip_x0 = x0 / fb_width * 2.0 - 1.0; + const GLfloat clip_y0 = y0 / fb_height * 2.0 - 1.0; + const GLfloat clip_x1 = x1 / fb_width * 2.0 - 1.0; + const GLfloat clip_y1 = y1 / fb_height * 2.0 - 1.0; GLuint i; void *buf; @@ -369,24 +365,26 @@ setup_bitmap_vertex_data(struct st_context *st, sizeof(st->bitmap.vertices)); } - /* positions, texcoords */ - st->bitmap.vertices[0][0][0] = x0; - st->bitmap.vertices[0][0][1] = y0; + /* Positions are in clip coords since we need to do clipping in case + * the bitmap quad goes beyond the window bounds. + */ + st->bitmap.vertices[0][0][0] = clip_x0; + st->bitmap.vertices[0][0][1] = clip_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][0][0] = clip_x1; + st->bitmap.vertices[1][0][1] = clip_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][0][0] = clip_x1; + st->bitmap.vertices[2][0][1] = clip_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][0][0] = clip_x0; + st->bitmap.vertices[3][0][1] = clip_y1; st->bitmap.vertices[3][2][0] = sLeft; st->bitmap.vertices[3][2][1] = tBot; @@ -437,17 +435,12 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_rasterizer(cso); cso_save_samplers(cso); + cso_save_sampler_textures(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); - } + st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled; + cso_set_rasterizer(cso, &st->bitmap.rasterizer); /* fragment shader state: TEX lookup program */ pipe->bind_fs_state(pipe, stfp->driver_shader); @@ -456,21 +449,26 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, pipe->bind_vs_state(pipe, st->bitmap.vs); /* sampler / texture state */ + cso_single_sampler(cso, 0, &st->bitmap.sampler); + cso_single_sampler_done(cso); + pipe->set_sampler_textures(pipe, 1, &pt); + + /* viewport state: viewport matching window dims */ { - 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); + const struct gl_framebuffer *fb = st->ctx->DrawBuffer; + const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); + const float width = fb->Width; + const float height = fb->Height; + struct pipe_viewport_state vp; + vp.scale[0] = 0.5 * width; + vp.scale[1] = height * (invert ? -0.5 : 0.5); + vp.scale[2] = 1.0; + vp.scale[3] = 1.0; + vp.translate[0] = 0.5 * width; + vp.translate[1] = 0.5 * height; + vp.translate[2] = 0.0; + vp.translate[3] = 0.0; + cso_set_viewport(cso, &vp); } /* draw textured quad */ @@ -487,18 +485,18 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, /* restore state */ cso_restore_rasterizer(cso); cso_restore_samplers(cso); + cso_restore_sampler_textures(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 reset_cache(struct st_context *st) { - memset(st->bitmap.cache->buffer, 0, sizeof(st->bitmap.cache->buffer)); + memset(st->bitmap.cache->buffer, 0xff, sizeof(st->bitmap.cache->buffer)); st->bitmap.cache->empty = GL_TRUE; st->bitmap.cache->xmin = 1000000; @@ -635,7 +633,7 @@ accum_bitmap(struct st_context *st, /* XXX try to combine this code with code in make_bitmap_texture() */ #define SET_PIXEL(COL, ROW) \ - cache->buffer[py + (ROW)][px + (COL)] = 0xff; + cache->buffer[py + (ROW)][px + (COL)] = 0x0; for (row = 0; row < height; row++) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, @@ -742,6 +740,22 @@ st_init_bitmap_functions(struct dd_function_table *functions) void st_init_bitmap(struct st_context *st) { + struct pipe_sampler_state *sampler = &st->bitmap.sampler; + + /* init sampler state once */ + 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; + + /* init baseline rasterizer state once */ + memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer)); + st->bitmap.rasterizer.bypass_vs = 1; + init_bitmap_cache(st); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 43cc21d1fb4..c181575f158 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -530,14 +530,13 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_rasterizer(cso); cso_save_viewport(cso); cso_save_samplers(cso); + cso_save_sampler_textures(cso); /* rasterizer state: just scissor */ { struct pipe_rasterizer_state rasterizer; memset(&rasterizer, 0, sizeof(rasterizer)); - if (ctx->Scissor.Enabled) - rasterizer.scissor = 1; - + rasterizer.scissor = ctx->Scissor.Enabled; cso_set_rasterizer(cso, &rasterizer); } @@ -581,9 +580,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* texture state: */ - { - pipe->set_sampler_textures(pipe, 1, &pt); - } + pipe->set_sampler_textures(pipe, 1, &pt); /* Compute window coords (y=0=bottom) with pixel zoom. * Recall that these coords are transformed by the current @@ -604,12 +601,11 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_restore_rasterizer(cso); cso_restore_viewport(cso); cso_restore_samplers(cso); + cso_restore_sampler_textures(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); } diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index e321b401e2d..1de3676bda6 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -105,7 +105,7 @@ static void st_glFlush(GLcontext *ctx) void st_finish( struct st_context *st ) { - struct pipe_fence_handle *fence; + struct pipe_fence_handle *fence = NULL; st_gl_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 85e3d47e1aa..44705bc89a3 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -148,6 +148,8 @@ struct st_context struct st_fragment_program *program; /**< bitmap tex/kil program */ GLuint user_prog_sn; /**< user fragment program serial no. */ struct st_fragment_program *combined_prog; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; struct pipe_shader_state vert_shader; void *vs; float vertices[4][3][4]; /**< vertex pos + color + texcoord */ |