diff options
Diffstat (limited to 'src/mesa/pipe/softpipe')
31 files changed, 4240 insertions, 0 deletions
diff --git a/src/mesa/pipe/softpipe/Makefile b/src/mesa/pipe/softpipe/Makefile new file mode 100644 index 0000000000..12a8bd0409 --- /dev/null +++ b/src/mesa/pipe/softpipe/Makefile @@ -0,0 +1,3 @@ +default: + cd ../.. ; make + diff --git a/src/mesa/pipe/softpipe/sp_clear.c b/src/mesa/pipe/softpipe/sp_clear.c new file mode 100644 index 0000000000..e83bc053ef --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_clear.c @@ -0,0 +1,71 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* Author: + * Brian Paul + */ + + +#include "sp_clear.h" +#include "sp_context.h" +#include "sp_surface.h" +#include "colormac.h" + + +void +softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth, + GLboolean stencil, GLboolean accum) +{ + const struct softpipe_context *softpipe = softpipe_context(pipe); + const GLint x = softpipe->scissor.minx; + const GLint y = softpipe->scissor.miny; + const GLint w = softpipe->scissor.maxx - x; + const GLint h = softpipe->scissor.maxy - y; + + if (color) { + GLuint i; + GLubyte clr[4]; + + UNCLAMPED_FLOAT_TO_UBYTE(clr[0], softpipe->clear_color.color[0]); + UNCLAMPED_FLOAT_TO_UBYTE(clr[1], softpipe->clear_color.color[1]); + UNCLAMPED_FLOAT_TO_UBYTE(clr[2], softpipe->clear_color.color[2]); + UNCLAMPED_FLOAT_TO_UBYTE(clr[3], softpipe->clear_color.color[3]); + + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { + struct pipe_surface *ps = softpipe->framebuffer.cbufs[i]; + struct softpipe_surface *sps = softpipe_surface(ps); + GLint j; + for (j = 0; j < h; j++) { + sps->write_mono_row_ub(sps, w, x, y + j, clr); + } + } + } + + if (depth) { + } + +} diff --git a/src/mesa/pipe/softpipe/sp_clear.h b/src/mesa/pipe/softpipe/sp_clear.h new file mode 100644 index 0000000000..f9db99dd32 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_clear.h @@ -0,0 +1,43 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* Author: + * Brian Paul + */ + +#ifndef SP_CLEAR_H +#define SP_CLEAR_H + +#include "pipe/p_state.h" +struct pipe_context; + +extern void +softpipe_clear(struct pipe_context *pipe, GLboolean color, GLboolean depth, + GLboolean stencil, GLboolean accum); + + +#endif /* SP_CLEAR_H */ diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c new file mode 100644 index 0000000000..3bb04a6835 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_context.c @@ -0,0 +1,126 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/* Author: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "main/imports.h" +#include "main/macros.h" +#include "pipe/draw/draw_context.h" +#include "sp_context.h" +#include "sp_clear.h" +#include "sp_state.h" +#include "sp_prim_setup.h" + + +static void softpipe_destroy( struct pipe_context *pipe ) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + + draw_destroy( softpipe->draw ); + + free( softpipe ); +} + + +static void softpipe_draw_vb( struct pipe_context *pipe, + struct vertex_buffer *VB ) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + + if (softpipe->dirty) + softpipe_update_derived( softpipe ); + + draw_vb( softpipe->draw, VB ); +} + + +static void softpipe_reset_occlusion_counter(struct pipe_context *pipe) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + softpipe->occlusion_counter = 0; +} + +/* XXX pipe param should be const */ +static GLuint softpipe_get_occlusion_counter(struct pipe_context *pipe) +{ + struct softpipe_context *softpipe = softpipe_context( pipe ); + return softpipe->occlusion_counter; +} + + +struct pipe_context *softpipe_create( void ) +{ + struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); + + softpipe->pipe.destroy = softpipe_destroy; + softpipe->pipe.set_alpha_test_state = softpipe_set_alpha_test_state; + softpipe->pipe.set_blend_color = softpipe_set_blend_color; + softpipe->pipe.set_blend_state = softpipe_set_blend_state; + softpipe->pipe.set_clip_state = softpipe_set_clip_state; + softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state; + softpipe->pipe.set_depth_state = softpipe_set_depth_test_state; + softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; + softpipe->pipe.set_fs_state = softpipe_set_fs_state; + softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; + softpipe->pipe.set_sampler_state = softpipe_set_sampler_state; + softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; + softpipe->pipe.set_setup_state = softpipe_set_setup_state; + softpipe->pipe.set_stencil_state = softpipe_set_stencil_state; + softpipe->pipe.set_texture_state = softpipe_set_texture_state; + softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; + softpipe->pipe.draw_vb = softpipe_draw_vb; + softpipe->pipe.clear = softpipe_clear; + softpipe->pipe.reset_occlusion_counter = softpipe_reset_occlusion_counter; + softpipe->pipe.get_occlusion_counter = softpipe_get_occlusion_counter; + + softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe); + softpipe->quad.shade = sp_quad_shade_stage(softpipe); + softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe); + softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); + softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe); + softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe); + softpipe->quad.coverage = sp_quad_coverage_stage(softpipe); + softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe); + softpipe->quad.blend = sp_quad_blend_stage(softpipe); + softpipe->quad.colormask = sp_quad_colormask_stage(softpipe); + softpipe->quad.output = sp_quad_output_stage(softpipe); + + /* + * Create drawing context and plug our rendering stage into it. + */ + softpipe->draw = draw_create(); + draw_set_setup_stage(softpipe->draw, sp_draw_render_stage(softpipe)); + + /* + * XXX we could plug GL selection/feedback into the drawing pipeline + * by specifying a different setup/render stage. + */ + + return &softpipe->pipe; +} diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h new file mode 100644 index 0000000000..ef1a06ccaf --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -0,0 +1,153 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SP_CONTEXT_H +#define SP_CONTEXT_H + +#include "glheader.h" + +#include "pipe/p_state.h" +#include "pipe/p_context.h" + +#include "sp_quad.h" + + +struct softpipe_surface; +struct draw_context; +struct draw_stage; + + +enum interp_mode { + INTERP_CONSTANT, + INTERP_LINEAR, + INTERP_PERSPECTIVE +}; + + +#define SP_NEW_VIEWPORT 0x1 +#define SP_NEW_SETUP 0x2 +#define SP_NEW_FS 0x4 +#define SP_NEW_BLEND 0x8 +#define SP_NEW_CLIP 0x10 +#define SP_NEW_SCISSOR 0x20 +#define SP_NEW_STIPPLE 0x40 +#define SP_NEW_FRAMEBUFFER 0x80 +#define SP_NEW_ALPHA_TEST 0x100 +#define SP_NEW_DEPTH_TEST 0x200 +#define SP_NEW_SAMPLER 0x400 +#define SP_NEW_TEXTURE 0x800 +#define SP_NEW_STENCIL 0x1000 + + +struct softpipe_context { + struct pipe_context pipe; /**< base class */ + + /* The most recent drawing state as set by the driver: + */ + struct pipe_alpha_test_state alpha_test; + struct pipe_blend_state blend; + struct pipe_blend_color blend_color; + struct pipe_clear_color_state clear_color; + struct pipe_clip_state clip; + struct pipe_depth_state depth_test; + struct pipe_framebuffer_state framebuffer; + struct pipe_fs_state fs; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; + struct pipe_setup_state setup; + struct pipe_stencil_state stencil; + struct pipe_texture_object *texture[PIPE_MAX_SAMPLERS]; + struct pipe_viewport_state viewport; + GLuint dirty; + + /* Setup derived state. TODO: this should be passed in the program + * tokens as parameters to DECL instructions. + * + * For now we just set colors to CONST on flatshade, textures to + * perspective always and everything else to linear. + */ + enum interp_mode interp[PIPE_ATTRIB_MAX]; + + + /* FS + setup derived state: + */ + + /** Map fragment program attribute to quad/coef array slot */ + GLuint fp_attr_to_slot[PIPE_ATTRIB_MAX]; + /** Map vertex format attribute to a vertex attribute slot */ + GLuint vf_attr_to_slot[PIPE_ATTRIB_MAX]; + GLuint nr_attrs; + GLuint nr_frag_attrs; /**< number of active fragment attribs */ + GLbitfield attr_mask; /**< bitfield of VF_ATTRIB_ indexes/bits */ + + GLboolean need_z; /**< produce quad/fragment Z values? */ + GLboolean need_w; /**< produce quad/fragment W values? */ + + /* Stipple derived state: + */ + GLubyte stipple_masks[16][16]; + + GLuint occlusion_counter; + + /** Software quad rendering pipeline */ + struct { + struct quad_stage *polygon_stipple; + struct quad_stage *shade; + struct quad_stage *alpha_test; + struct quad_stage *stencil_test; + struct quad_stage *depth_test; + struct quad_stage *occlusion; + struct quad_stage *coverage; + struct quad_stage *bufloop; + struct quad_stage *blend; + struct quad_stage *colormask; + struct quad_stage *output; + + struct quad_stage *first; /**< points to one of the above stages */ + } quad; + + /** The primitive drawing context */ + struct draw_context *draw; + + struct pipe_surface *cbuf; /**< current color buffer (one of cbufs) */ +}; + + + + +static INLINE struct softpipe_context * +softpipe_context( struct pipe_context *pipe ) +{ + return (struct softpipe_context *)pipe; +} + + +#endif /* SP_CONTEXT_H */ diff --git a/src/mesa/pipe/softpipe/sp_headers.h b/src/mesa/pipe/softpipe/sp_headers.h new file mode 100644 index 0000000000..68a84621f2 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_headers.h @@ -0,0 +1,95 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SP_HEADERS_H +#define SP_HEADERS_H + + +#define PRIM_POINT 1 +#define PRIM_LINE 2 +#define PRIM_TRI 3 + + +/* The rasterizer generates 2x2 quads of fragment and feeds them to + * the current fp_machine (see below). + */ +#define QUAD_BOTTOM_LEFT 0 +#define QUAD_BOTTOM_RIGHT 1 +#define QUAD_TOP_LEFT 2 +#define QUAD_TOP_RIGHT 3 +#define QUAD_SIZE (2*2) + +#define MASK_BOTTOM_LEFT 0x1 +#define MASK_BOTTOM_RIGHT 0x2 +#define MASK_TOP_LEFT 0x4 +#define MASK_TOP_RIGHT 0x8 +#define MASK_ALL 0xf + + +#define NUM_CHANNELS 4 /* avoid confusion between 4 pixels and 4 channels */ + + +struct setup_coefficient { + GLfloat a0[NUM_CHANNELS]; /* in an xyzw layout */ + GLfloat dadx[NUM_CHANNELS]; + GLfloat dady[NUM_CHANNELS]; +}; + + + +/** + * Encodes everything we need to know about a 2x2 pixel block. Uses + * "Channel-Serial" or "SoA" layout. + */ +struct quad_header { + GLint x0; + GLint y0; + GLuint mask:4; + GLuint facing:1; /**< Front (0) or back (1) facing? */ + GLuint prim:2; /**< PRIM_POINT, LINE, TRI */ + + struct { + GLfloat color[4][QUAD_SIZE]; /* rrrr, gggg, bbbb, aaaa */ + GLfloat depth[QUAD_SIZE]; + } outputs; + + GLfloat coverage[QUAD_SIZE]; /** fragment coverage for antialiasing */ + + const struct setup_coefficient *coef; + + const enum interp_mode *interp; /* XXX: this information should be + * encoded in fragment program DECL + * statements. */ + + GLuint nr_attrs; +}; + + +#endif /* SP_HEADERS_H */ diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c new file mode 100644 index 0000000000..6420fc8809 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -0,0 +1,1005 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * \brief Primitive rasterization/rendering (points, lines, triangles) + * + * \author Keith Whitwell <keith@tungstengraphics.com> + * \author Brian Paul + */ + + +#include "imports.h" +#include "macros.h" + +#include "sp_context.h" +#include "sp_headers.h" +#include "pipe/draw/draw_private.h" +#include "sp_quad.h" +#include "sp_prim_setup.h" + + + +/** + * Emit/render a quad. + * This passes the quad to the first stage of per-fragment operations. + */ +static INLINE void +quad_emit(struct softpipe_context *sp, struct quad_header *quad) +{ + sp->quad.first->run(sp->quad.first, quad); +} + + +/** + * Triangle edge info + */ +struct edge { + GLfloat dx; /* X(v1) - X(v0), used only during setup */ + GLfloat dy; /* Y(v1) - Y(v0), used only during setup */ + GLfloat dxdy; /* dx/dy */ + GLfloat sx; /* first sample point x coord */ + GLfloat sy; + GLint lines; /* number of lines on this edge */ +}; + + +/** + * Triangle setup info (derived from draw_stage). + * Also used for line drawing (taking some liberties). + */ +struct setup_stage { + struct draw_stage stage; /**< This must be first (base class) */ + + /*XXX NEW */ + struct softpipe_context *softpipe; + + /* Vertices are just an array of floats making up each attribute in + * turn. Currently fixed at 4 floats, but should change in time. + * Codegen will help cope with this. + */ + const struct vertex_header *vmax; + const struct vertex_header *vmid; + const struct vertex_header *vmin; + const struct vertex_header *vprovoke; + + struct edge ebot; + struct edge etop; + struct edge emaj; + + GLfloat oneoverarea; + + struct setup_coefficient coef[FRAG_ATTRIB_MAX]; + struct quad_header quad; + + struct { + GLint left[2]; /**< [0] = row0, [1] = row1 */ + GLint right[2]; + GLint y; + GLuint y_flags; + GLuint mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */ + } span; +}; + + + +/** + * Basically a cast wrapper. + */ +static inline struct setup_stage *setup_stage( struct draw_stage *stage ) +{ + return (struct setup_stage *)stage; +} + + +/** + * Given an X or Y coordinate, return the block/quad coordinate that it + * belongs to. + */ +static inline GLint block( GLint x ) +{ + return x & ~1; +} + + + +/** + * Run shader on a quad/block. + */ +static void run_shader_block( struct setup_stage *setup, + GLint x, GLint y, GLuint mask ) +{ + setup->quad.x0 = x; + setup->quad.y0 = y; + setup->quad.mask = mask; + + quad_emit(setup->softpipe, &setup->quad); +} + + +/** + * Compute mask which indicates which pixels in the 2x2 quad are actually inside + * the triangle's bounds. + * + * this is pretty nasty... may need to rework flush_spans again to + * fix it, if possible. + */ +static GLuint calculate_mask( struct setup_stage *setup, + GLint x ) +{ + GLuint mask = 0; + + if (x >= setup->span.left[0] && x < setup->span.right[0]) + mask |= MASK_BOTTOM_LEFT; + + if (x >= setup->span.left[1] && x < setup->span.right[1]) + mask |= MASK_TOP_LEFT; + + if (x+1 >= setup->span.left[0] && x+1 < setup->span.right[0]) + mask |= MASK_BOTTOM_RIGHT; + + if (x+1 >= setup->span.left[1] && x+1 < setup->span.right[1]) + mask |= MASK_TOP_RIGHT; + + return mask; +} + + +/** + * Render a horizontal span of quads + */ +static void flush_spans( struct setup_stage *setup ) +{ + GLint minleft, maxright; + GLint x; + + switch (setup->span.y_flags) { + case 3: + minleft = MIN2(setup->span.left[0], setup->span.left[1]); + maxright = MAX2(setup->span.right[0], setup->span.right[1]); + break; + + case 1: + minleft = setup->span.left[0]; + maxright = setup->span.right[0]; + break; + + case 2: + minleft = setup->span.left[1]; + maxright = setup->span.right[1]; + break; + + default: + return; + } + + + for (x = block(minleft); x <= block(maxright); ) + { + run_shader_block( setup, x, + setup->span.y, + calculate_mask( setup, x ) ); + x += 2; + } + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; +} + + +static GLboolean setup_sort_vertices( struct setup_stage *setup, + const struct prim_header *prim ) +{ + const struct vertex_header *v0 = prim->v[0]; + const struct vertex_header *v1 = prim->v[1]; + const struct vertex_header *v2 = prim->v[2]; + + setup->vprovoke = v2; + + /* determine bottom to top order of vertices */ + { + GLfloat y0 = v0->data[0][1]; + GLfloat y1 = v1->data[0][1]; + GLfloat y2 = v2->data[0][1]; + if (y0 <= y1) { + if (y1 <= y2) { + /* y0<=y1<=y2 */ + setup->vmin = v0; + setup->vmid = v1; + setup->vmax = v2; + } + else if (y2 <= y0) { + /* y2<=y0<=y1 */ + setup->vmin = v2; + setup->vmid = v0; + setup->vmax = v1; + } + else { + /* y0<=y2<=y1 */ + setup->vmin = v0; + setup->vmid = v2; + setup->vmax = v1; + } + } + else { + if (y0 <= y2) { + /* y1<=y0<=y2 */ + setup->vmin = v1; + setup->vmid = v0; + setup->vmax = v2; + } + else if (y2 <= y1) { + /* y2<=y1<=y0 */ + setup->vmin = v2; + setup->vmid = v1; + setup->vmax = v0; + } + else { + /* y1<=y2<=y0 */ + setup->vmin = v1; + setup->vmid = v2; + setup->vmax = v0; + } + } + } + + setup->ebot.dx = setup->vmid->data[0][0] - setup->vmin->data[0][0]; + setup->ebot.dy = setup->vmid->data[0][1] - setup->vmin->data[0][1]; + setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0]; + setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1]; + setup->etop.dx = setup->vmax->data[0][0] - setup->vmid->data[0][0]; + setup->etop.dy = setup->vmax->data[0][1] - setup->vmid->data[0][1]; + + /* + * Compute triangle's area. Use 1/area to compute partial + * derivatives of attributes later. + * + * The area will be the same as prim->det, but the sign may be + * different depending on how the vertices get sorted above. + * + * To determine whether the primitive is front or back facing we + * use the prim->det value because its sign is correct. + */ + { + const GLfloat area = (setup->emaj.dx * setup->ebot.dy - + setup->ebot.dx * setup->emaj.dy); + + setup->oneoverarea = 1.0 / area; + /* + _mesa_printf("%s one-over-area %f area %f det %f\n", + __FUNCTION__, setup->oneoverarea, area, prim->det ); + */ + } + + /* We need to know if this is a front or back-facing triangle for: + * - the GLSL gl_FrontFacing fragment attribute (bool) + * - two-sided stencil test + */ + setup->quad.facing = (prim->det > 0.0) ^ (setup->softpipe->setup.front_winding == PIPE_WINDING_CW); + + return GL_TRUE; +} + + +/** + * Compute a0 for a constant-valued coefficient (GL_FLAT shading). + * The value value comes from vertex->data[slot][i]. + * The result will be put into setup->coef[slot].a0[i]. + * \param slot which attribute slot + * \param i which component of the slot (0..3) + */ +static void const_coeff( struct setup_stage *setup, + GLuint slot, + GLuint i ) +{ + assert(slot < FRAG_ATTRIB_MAX); + assert(i <= 3); + + setup->coef[slot].dadx[i] = 0; + setup->coef[slot].dady[i] = 0; + + /* need provoking vertex info! + */ + setup->coef[slot].a0[i] = setup->vprovoke->data[slot][i]; +} + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a triangle. + */ +static void tri_linear_coeff( struct setup_stage *setup, + GLuint slot, + GLuint i) +{ + GLfloat botda = setup->vmid->data[slot][i] - setup->vmin->data[slot][i]; + GLfloat majda = setup->vmax->data[slot][i] - setup->vmin->data[slot][i]; + GLfloat a = setup->ebot.dy * majda - botda * setup->emaj.dy; + GLfloat b = setup->emaj.dx * botda - majda * setup->ebot.dx; + + assert(slot < FRAG_ATTRIB_MAX); + assert(i <= 3); + + setup->coef[slot].dadx[i] = a * setup->oneoverarea; + setup->coef[slot].dady[i] = b * setup->oneoverarea; + + /* calculate a0 as the value which would be sampled for the + * fragment at (0,0), taking into account that we want to sample at + * pixel centers, in other words (0.5, 0.5). + * + * this is neat but unfortunately not a good way to do things for + * triangles with very large values of dadx or dady as it will + * result in the subtraction and re-addition from a0 of a very + * large number, which means we'll end up loosing a lot of the + * fractional bits and precision from a0. the way to fix this is + * to define a0 as the sample at a pixel center somewhere near vmin + * instead - i'll switch to this later. + */ + setup->coef[slot].a0[i] = (setup->vmin->data[slot][i] - + (setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5) + + setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5))); + + /* + _mesa_printf("attr[%d].%c: %f dx:%f dy:%f\n", + slot, "xyzw"[i], + setup->coef[slot].a0[i], + setup->coef[slot].dadx[i], + setup->coef[slot].dady[i]); + */ +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a triangle. + */ +static void tri_persp_coeff( struct setup_stage *setup, + GLuint slot, + GLuint i ) +{ + /* premultiply by 1/w: + */ + GLfloat mina = setup->vmin->data[slot][i] * setup->vmin->data[0][3]; + GLfloat mida = setup->vmid->data[slot][i] * setup->vmid->data[0][3]; + GLfloat maxa = setup->vmax->data[slot][i] * setup->vmax->data[0][3]; + + GLfloat botda = mida - mina; + GLfloat majda = maxa - mina; + GLfloat a = setup->ebot.dy * majda - botda * setup->emaj.dy; + GLfloat b = setup->emaj.dx * botda - majda * setup->ebot.dx; + + assert(slot < FRAG_ATTRIB_MAX); + assert(i <= 3); + + setup->coef[slot].dadx[i] = a * setup->oneoverarea; + setup->coef[slot].dady[i] = b * setup->oneoverarea; + setup->coef[slot].a0[i] = (mina - + (setup->coef[slot].dadx[i] * (setup->vmin->data[0][0] - 0.5) + + setup->coef[slot].dady[i] * (setup->vmin->data[0][1] - 0.5))); +} + + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized. + */ +static void setup_tri_coefficients( struct setup_stage *setup ) +{ + const enum interp_mode *interp = setup->softpipe->interp; + GLuint slot, j; + + /* z and w are done by linear interpolation: + */ + tri_linear_coeff(setup, 0, 2); + tri_linear_coeff(setup, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (slot = 1; slot < setup->quad.nr_attrs; slot++) { + switch (interp[slot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, slot, j); + break; + + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + tri_linear_coeff(setup, slot, j); + break; + + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + tri_persp_coeff(setup, slot, j); + break; + } + } +} + + + +static void setup_tri_edges( struct setup_stage *setup ) +{ + GLfloat vmin_x = setup->vmin->data[0][0] + 0.5; + GLfloat vmid_x = setup->vmid->data[0][0] + 0.5; + + GLfloat vmin_y = setup->vmin->data[0][1] - 0.5; + GLfloat vmid_y = setup->vmid->data[0][1] - 0.5; + GLfloat vmax_y = setup->vmax->data[0][1] - 0.5; + + setup->emaj.sy = ceilf(vmin_y); + setup->emaj.lines = (GLint) ceilf(vmax_y - setup->emaj.sy); + setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy; + setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy; + + setup->etop.sy = ceilf(vmid_y); + setup->etop.lines = (GLint) ceilf(vmax_y - setup->etop.sy); + setup->etop.dxdy = setup->etop.dx / setup->etop.dy; + setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy; + + setup->ebot.sy = ceilf(vmin_y); + setup->ebot.lines = (GLint) ceilf(vmid_y - setup->ebot.sy); + setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy; + setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy; +} + + +/** + * Render the upper or lower half of a triangle. + * Scissoring is applied here too. + */ +static void subtriangle( struct setup_stage *setup, + struct edge *eleft, + struct edge *eright, + GLuint lines ) +{ + GLint y, start_y, finish_y; + GLint sy = (GLint)eleft->sy; + + assert((GLint)eleft->sy == (GLint) eright->sy); + assert((GLint)eleft->sy >= 0); /* catch bug in x64? */ + + /* scissor y: + */ + if (setup->softpipe->setup.scissor) { + start_y = sy; + finish_y = start_y + lines; + + if (start_y < setup->softpipe->scissor.miny) + start_y = setup->softpipe->scissor.miny; + + if (finish_y > setup->softpipe->scissor.maxy) + finish_y = setup->softpipe->scissor.maxy; + + start_y -= sy; + finish_y -= sy; + } + else { + start_y = 0; + finish_y = lines; + } + + /* + _mesa_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y); + */ + + for (y = start_y; y < finish_y; y++) { + + /* avoid accumulating adds as floats don't have the precision to + * accurately iterate large triangle edges that way. luckily we + * can just multiply these days. + * + * this is all drowned out by the attribute interpolation anyway. + */ + GLint left = (GLint)(eleft->sx + y * eleft->dxdy); + GLint right = (GLint)(eright->sx + y * eright->dxdy); + + /* scissor x: + */ + if (setup->softpipe->setup.scissor) { + if (left < setup->softpipe->scissor.minx) + left = setup->softpipe->scissor.minx; + + if (right > setup->softpipe->scissor.maxx) + right = setup->softpipe->scissor.maxx; + } + + if (left < right) { + GLint _y = sy+y; + if (block(_y) != setup->span.y) { + flush_spans(setup); + setup->span.y = block(_y); + } + + setup->span.left[_y&1] = left; + setup->span.right[_y&1] = right; + setup->span.y_flags |= 1<<(_y&1); + } + } + + + /* save the values so that emaj can be restarted: + */ + eleft->sx += lines * eleft->dxdy; + eright->sx += lines * eright->dxdy; + eleft->sy += lines; + eright->sy += lines; +} + + +/** + * Do setup for triangle rasterization, then render the triangle. + */ +static void setup_tri( struct draw_stage *stage, + struct prim_header *prim ) +{ + struct setup_stage *setup = setup_stage( stage ); + + /* + _mesa_printf("%s\n", __FUNCTION__ ); + */ + + setup_sort_vertices( setup, prim ); + setup_tri_coefficients( setup ); + setup_tri_edges( setup ); + + setup->quad.prim = PRIM_TRI; + + setup->span.y = 0; + setup->span.y_flags = 0; + setup->span.right[0] = 0; + setup->span.right[1] = 0; + /* setup->span.z_mode = tri_z_mode( setup->ctx ); */ + + /* init_constant_attribs( setup ); */ + + if (setup->oneoverarea < 0.0) { + /* emaj on left: + */ + subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines ); + subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines ); + } + else { + /* emaj on right: + */ + subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines ); + subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines ); + } + + flush_spans( setup ); +} + + + +/** + * Compute a0, dadx and dady for a linearly interpolated coefficient, + * for a line. + */ +static void +line_linear_coeff(struct setup_stage *setup, GLuint slot, GLuint i) +{ + const GLfloat dz = setup->vmax->data[slot][i] - setup->vmin->data[slot][i]; + const GLfloat dadx = dz * setup->emaj.dx * setup->oneoverarea; + const GLfloat dady = dz * setup->emaj.dy * setup->oneoverarea; + setup->coef[slot].dadx[i] = dadx; + setup->coef[slot].dady[i] = dady; + setup->coef[slot].a0[i] + = (setup->vmin->data[slot][i] - + (dadx * (setup->vmin->data[0][0] - 0.5) + + dady * (setup->vmin->data[0][1] - 0.5))); +} + + +/** + * Compute a0, dadx and dady for a perspective-corrected interpolant, + * for a line. + */ +static void +line_persp_coeff(struct setup_stage *setup, GLuint slot, GLuint i) +{ + /* XXX to do */ + line_linear_coeff(setup, slot, i); /* XXX temporary */ +} + + +/** + * Compute the setup->coef[] array dadx, dady, a0 values. + * Must be called after setup->vmin,vmax are initialized. + */ +static INLINE void +setup_line_coefficients(struct setup_stage *setup, struct prim_header *prim) +{ + const enum interp_mode *interp = setup->softpipe->interp; + GLuint slot, j; + + /* use setup->vmin, vmax to point to vertices */ + setup->vprovoke = prim->v[1]; + setup->vmin = prim->v[0]; + setup->vmax = prim->v[1]; + + setup->emaj.dx = setup->vmax->data[0][0] - setup->vmin->data[0][0]; + setup->emaj.dy = setup->vmax->data[0][1] - setup->vmin->data[0][1]; + /* NOTE: this is not really 1/area */ + setup->oneoverarea = 1.0 / (setup->emaj.dx * setup->emaj.dx + + setup->emaj.dy * setup->emaj.dy); + + /* z and w are done by linear interpolation: + */ + line_linear_coeff(setup, 0, 2); + line_linear_coeff(setup, 0, 3); + + /* setup interpolation for all the remaining attributes: + */ + for (slot = 1; slot < setup->quad.nr_attrs; slot++) { + switch (interp[slot]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, slot, j); + break; + + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + line_linear_coeff(setup, slot, j); + break; + + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + line_persp_coeff(setup, slot, j); + break; + } + } +} + + +/** + * Plot a pixel in a line segment. + */ +static INLINE void +plot(struct setup_stage *setup, GLint x, GLint y) +{ + const GLint iy = y & 1; + const GLint ix = x & 1; + const GLint quadX = x - ix; + const GLint quadY = y - iy; + const GLint mask = (1 << ix) << (2 * iy); + + if (quadX != setup->quad.x0 || + quadY != setup->quad.y0) + { + /* flush prev quad, start new quad */ + + if (setup->quad.x0 != -1) + quad_emit(setup->softpipe, &setup->quad); + + setup->quad.x0 = quadX; + setup->quad.y0 = quadY; + setup->quad.mask = 0x0; + } + + setup->quad.mask |= mask; +} + + + +/** + * Do setup for line rasterization, then render the line. + * XXX single-pixel width, no stipple, etc + * XXX no scissoring yet. + */ +static void +setup_line(struct draw_stage *stage, struct prim_header *prim) +{ + const struct vertex_header *v0 = prim->v[0]; + const struct vertex_header *v1 = prim->v[1]; + struct setup_stage *setup = setup_stage( stage ); + + GLint x0 = (GLint) v0->data[0][0]; + GLint x1 = (GLint) v1->data[0][0]; + GLint y0 = (GLint) v0->data[0][1]; + GLint y1 = (GLint) v1->data[0][1]; + GLint dx = x1 - x0; + GLint dy = y1 - y0; + GLint xstep, ystep; + + if (dx == 0 && dy == 0) + return; + + setup_line_coefficients(setup, prim); + + if (dx < 0) { + dx = -dx; /* make positive */ + xstep = -1; + } + else { + xstep = 1; + } + + if (dy < 0) { + dy = -dy; /* make positive */ + ystep = -1; + } + else { + ystep = 1; + } + + assert(dx >= 0); + assert(dy >= 0); + + setup->quad.x0 = setup->quad.y0 = -1; + setup->quad.mask = 0x0; + setup->quad.prim = PRIM_LINE; + + if (dx > dy) { + /*** X-major line ***/ + GLint i; + const GLint errorInc = dy + dy; + GLint error = errorInc - dx; + const GLint errorDec = error - dx; + + for (i = 0; i < dx; i++) { + plot(setup, x0, y0); + + x0 += xstep; + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + y0 += ystep; + } + } + } + else { + /*** Y-major line ***/ + GLint i; + const GLint errorInc = dx + dx; + GLint error = errorInc - dy; + const GLint errorDec = error - dy; + + for (i = 0; i < dy; i++) { + plot(setup, x0, y0); + + y0 += ystep; + + if (error < 0) { + error += errorInc; + } + else { + error += errorDec; + x0 += xstep; + } + } + } + + /* draw final quad */ + if (setup->quad.mask) { + quad_emit(setup->softpipe, &setup->quad); + } +} + + +/** + * Do setup for point rasterization, then render the point. + * Round or square points... + * XXX could optimize a lot for 1-pixel points. + */ +static void +setup_point(struct draw_stage *stage, struct prim_header *prim) +{ + struct setup_stage *setup = setup_stage( stage ); + /*XXX this should be a vertex attrib! */ + GLfloat halfSize = 0.5 * setup->softpipe->setup.point_size; + GLboolean round = setup->softpipe->setup.point_smooth; + const struct vertex_header *v0 = prim->v[0]; + const GLfloat x = v0->data[FRAG_ATTRIB_WPOS][0]; + const GLfloat y = v0->data[FRAG_ATTRIB_WPOS][1]; + GLuint slot, j; + + /* For points, all interpolants are constant-valued. + * However, for point sprites, we'll need to setup texcoords appropriately. + * XXX: which coefficients are the texcoords??? + * We may do point sprites as textured quads... + * + * KW: We don't know which coefficients are texcoords - ultimately + * the choice of what interpolation mode to use for each attribute + * should be determined by the fragment program, using + * per-attribute declaration statements that include interpolation + * mode as a parameter. So either the fragment program will have + * to be adjusted for pointsprite vs normal point behaviour, or + * otherwise a special interpolation mode will have to be defined + * which matches the required behaviour for point sprites. But - + * the latter is not a feature of normal hardware, and as such + * probably should be ruled out on that basis. + */ + setup->vprovoke = prim->v[0]; + const_coeff(setup, 0, 2); + const_coeff(setup, 0, 3); + for (slot = 1; slot < setup->quad.nr_attrs; slot++) { + for (j = 0; j < NUM_CHANNELS; j++) + const_coeff(setup, slot, j); + } + + setup->quad.prim = PRIM_POINT; + + /* XXX need to clip against scissor bounds too */ + + if (halfSize <= 0.5 && !round) { + /* special case for 1-pixel points */ + const GLint ix = ((GLint) x) & 1; + const GLint iy = ((GLint) y) & 1; + setup->quad.x0 = x - ix; + setup->quad.y0 = y - iy; + setup->quad.mask = (1 << ix) << (2 * iy); + quad_emit(setup->softpipe, &setup->quad); + } + else { + const GLint ixmin = block((GLint) (x - halfSize)); + const GLint ixmax = block((GLint) (x + halfSize)); + const GLint iymin = block((GLint) (y - halfSize)); + const GLint iymax = block((GLint) (y + halfSize)); + GLint ix, iy; + + if (round) { + /* rounded points */ + const GLfloat rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */ + const GLfloat rmax = halfSize + 0.7071F; + const GLfloat rmin2 = MAX2(0.0F, rmin * rmin); + const GLfloat rmax2 = rmax * rmax; + const GLfloat cscale = 1.0F / (rmax2 - rmin2); + + for (iy = iymin; iy <= iymax; iy += 2) { + for (ix = ixmin; ix <= ixmax; ix += 2) { + GLfloat dx, dy, dist2, cover; + + setup->quad.mask = 0x0; + + dx = (ix + 0.5) - x; + dy = (iy + 0.5) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0); + setup->quad.mask |= MASK_BOTTOM_LEFT; + } + + dx = (ix + 1.5) - x; + dy = (iy + 0.5) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0); + setup->quad.mask |= MASK_BOTTOM_RIGHT; + } + + dx = (ix + 0.5) - x; + dy = (iy + 1.5) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0); + setup->quad.mask |= MASK_TOP_LEFT; + } + + dx = (ix + 1.5) - x; + dy = (iy + 1.5) - y; + dist2 = dx * dx + dy * dy; + if (dist2 <= rmax2) { + cover = 1.0F - (dist2 - rmin2) * cscale; + setup->quad.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0); + setup->quad.mask |= MASK_TOP_RIGHT; + } + + if (setup->quad.mask) { + setup->quad.x0 = ix; + setup->quad.y0 = iy; + quad_emit( setup->softpipe, &setup->quad ); + } + } + } + } + else { + /* square points */ + for (iy = iymin; iy <= iymax; iy += 2) { + for (ix = ixmin; ix <= ixmax; ix += 2) { + setup->quad.mask = 0xf; + + if (ix + 0.5 < x - halfSize) { + /* fragment is past left edge of point, turn off left bits */ + setup->quad.mask &= ~(MASK_BOTTOM_LEFT | MASK_TOP_LEFT); + } + + if (ix + 1.5 > x + halfSize) { + /* past the right edge */ + setup->quad.mask &= ~(MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT); + } + + if (iy + 0.5 < y - halfSize) { + /* below the bottom edge */ + setup->quad.mask &= ~(MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT); + } + + if (iy + 1.5 > y + halfSize) { + /* above the top edge */ + setup->quad.mask &= ~(MASK_TOP_LEFT | MASK_TOP_RIGHT); + } + + if (setup->quad.mask) { + setup->quad.x0 = ix; + setup->quad.y0 = iy; + quad_emit( setup->softpipe, &setup->quad ); + } + } + } + } + } +} + + + +static void setup_begin( struct draw_stage *stage ) +{ + struct setup_stage *setup = setup_stage(stage); + + setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs; + + /* + * XXX this is where we might map() the renderbuffers to begin + * s/w rendering. + */ +} + + +static void setup_end( struct draw_stage *stage ) +{ + /* + * XXX this is where we might unmap() the renderbuffers after + * s/w rendering. + */ +} + + +/** + * Create a new primitive setup/render stage. + */ +struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ) +{ + struct setup_stage *setup = CALLOC_STRUCT(setup_stage); + + setup->softpipe = softpipe; + setup->stage.draw = softpipe->draw; + setup->stage.begin = setup_begin; + setup->stage.point = setup_point; + setup->stage.line = setup_line; + setup->stage.tri = setup_tri; + setup->stage.end = setup_end; + + setup->quad.coef = setup->coef; + + return &setup->stage; +} diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.h b/src/mesa/pipe/softpipe/sp_prim_setup.h new file mode 100644 index 0000000000..e5abefcd49 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_prim_setup.h @@ -0,0 +1,122 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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 SP_PRIM_SETUP_H +#define SP_PRIM_SETUP_H + + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "glheader.h" +#include "imports.h" +#if 0 +#include "s_tri_public.h" +#endif +#include "s_context.h" + + +extern struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe ); + + +#if 0 /* UNUSED? */ +struct tri_context; +struct fp_context; +struct be_context; + +/* Note the rasterizer does not take a GLcontext argument. This is + * deliberate. + */ +struct tri_context *tri_create_context( GLcontext *ctx ); + +void tri_destroy_context( struct tri_context *tri ); + +void tri_set_fp_context( struct tri_context *tri, + struct fp_context *fp, + void (*fp_run)( struct fp_context *fp, + const struct fp_inputs *, + struct fp_outputs * )); + + +void tri_set_be_context( struct tri_context *tri, + struct be_context *be, + void (*be_run)( struct be_context *be, + const struct fp_outputs * )); + +void tri_set_attribs( struct tri_context *tri, + const struct attr_info *info, + GLuint nr_attrib ); + +void tri_set_backface( struct tri_context *tri, + GLfloat backface ); + +void tri_set_scissor( struct tri_context *tri, + GLint x, + GLint y, + GLuint width, + GLuint height, + GLboolean enabled ); + +void tri_set_stipple( struct tri_context *tri, + const GLuint *pattern, + GLboolean enabled ); + +/* Unfilled triangles will be handled elsewhere (higher in the + * pipeline), as will things like stipple (lower in the pipeline). + */ + +void tri_triangle( struct tri_context *tri, + const struct vertex *v0, + const struct vertex *v1, + const struct vertex *v2 ); + +/* TODO: rasterize_line, rasterize_point?? + * How will linestipple work? + */ + + +#ifdef SETUP_PRIVATE + +GLboolean tri_setup( struct tri_context *tri, + const struct vertex *v0, + const struct vertex *v1, + const struct vertex *v2 ); + +void tri_rasterize( struct tri_context *tri ); +void tri_rasterize_spans( struct tri_context *tri ); + +#endif + + +#endif + +#endif /* SP_PRIM_SETUP_H */ diff --git a/src/mesa/pipe/softpipe/sp_quad.c b/src/mesa/pipe/softpipe/sp_quad.c new file mode 100644 index 0000000000..0053b16e68 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad.c @@ -0,0 +1,71 @@ + + +#include "sp_context.h" + + + +void +sp_build_quad_pipeline(struct softpipe_context *sp) +{ + /* build up the pipeline in reverse order... */ + + sp->quad.first = sp->quad.output; + + if (sp->blend.colormask != 0xf) { + sp->quad.colormask->next = sp->quad.first; + sp->quad.first = sp->quad.colormask; + } + + if (sp->blend.blend_enable) { + sp->quad.blend->next = sp->quad.first; + sp->quad.first = sp->quad.blend; + } + + if (sp->framebuffer.num_cbufs == 1) { + /* the usual case: write to exactly one colorbuf */ + sp->cbuf = sp->framebuffer.cbufs[0]; + } + else { + /* insert bufloop stage */ + sp->quad.bufloop->next = sp->quad.first; + sp->quad.first = sp->quad.bufloop; + } + + if (sp->depth_test.occlusion_count) { + sp->quad.occlusion->next = sp->quad.first; + sp->quad.first = sp->quad.occlusion; + } + + if (sp->setup.poly_smooth || + sp->setup.line_smooth || + sp->setup.point_smooth) { + sp->quad.coverage->next = sp->quad.first; + sp->quad.first = sp->quad.coverage; + } + + if ( sp->stencil.front_enabled + || sp->stencil.front_enabled) { + sp->quad.stencil_test->next = sp->quad.first; + sp->quad.first = sp->quad.stencil_test; + } + else if (sp->depth_test.enabled) { + sp->quad.depth_test->next = sp->quad.first; + sp->quad.first = sp->quad.depth_test; + } + + if (sp->alpha_test.enabled) { + sp->quad.alpha_test->next = sp->quad.first; + sp->quad.first = sp->quad.alpha_test; + } + + /* XXX always enable shader? */ + if (1) { + sp->quad.shade->next = sp->quad.first; + sp->quad.first = sp->quad.shade; + } + + if (sp->setup.poly_stipple_enable) { + sp->quad.polygon_stipple->next = sp->quad.first; + sp->quad.first = sp->quad.polygon_stipple; + } +} diff --git a/src/mesa/pipe/softpipe/sp_quad.h b/src/mesa/pipe/softpipe/sp_quad.h new file mode 100644 index 0000000000..2ee53bdecd --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad.h @@ -0,0 +1,65 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SP_TILE_H +#define SP_TILE_H + + +struct softpipe_context; +struct quad_header; + + +struct quad_stage { + struct softpipe_context *softpipe; + + struct quad_stage *next; + + /** the stage action */ + void (*run)(struct quad_stage *qs, struct quad_header *quad); +}; + + +struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe ); +struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ); + +void sp_build_quad_pipeline(struct softpipe_context *sp); + +void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad); + +#endif /* SP_TILE_H */ diff --git a/src/mesa/pipe/softpipe/sp_quad_alpha_test.c b/src/mesa/pipe/softpipe/sp_quad_alpha_test.c new file mode 100644 index 0000000000..8c28a824be --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_alpha_test.c @@ -0,0 +1,94 @@ + +/** + * quad alpha test + */ + +#include "glheader.h" +#include "imports.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "pipe/p_defines.h" + + +static void +alpha_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + const GLfloat ref = softpipe->alpha_test.ref; + GLuint passMask = 0x0, j; + + switch (softpipe->alpha_test.func) { + case PIPE_FUNC_NEVER: + quad->mask = 0x0; + break; + case PIPE_FUNC_LESS: + /* + * If mask were an array [4] we could do this SIMD-style: + * passMask = (quad->outputs.color[3] <= vec4(ref)); + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->outputs.color[3][j] < ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->outputs.color[3][j] == ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->outputs.color[3][j] <= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->outputs.color[3][j] > ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->outputs.color[3][j] != ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->outputs.color[3][j] >= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_ALWAYS: + passMask = MASK_ALL; + break; + default: + abort(); + } + + quad->mask &= passMask; + + if (quad->mask) + qs->next->run(qs->next, quad); +} + + +struct quad_stage * +sp_quad_alpha_test_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = alpha_test_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_blend.c b/src/mesa/pipe/softpipe/sp_quad_blend.c new file mode 100644 index 0000000000..3d097aea65 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_blend.c @@ -0,0 +1,395 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * quad blending + * \author Brian Paul + */ + +#include "glheader.h" +#include "imports.h" +#include "macros.h" +#include "pipe/p_defines.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + + +#define VEC4_COPY(DST, SRC) \ +do { \ + DST[0] = SRC[0]; \ + DST[1] = SRC[1]; \ + DST[2] = SRC[2]; \ + DST[3] = SRC[3]; \ +} while(0) + +#define VEC4_SCALAR(DST, SRC) \ +do { \ + DST[0] = SRC; \ + DST[1] = SRC; \ + DST[2] = SRC; \ + DST[3] = SRC; \ +} while(0) + +#define VEC4_ADD(SUM, A, B) \ +do { \ + SUM[0] = A[0] + B[0]; \ + SUM[1] = A[1] + B[1]; \ + SUM[2] = A[2] + B[2]; \ + SUM[3] = A[3] + B[3]; \ +} while (0) + +#define VEC4_SUB(SUM, A, B) \ +do { \ + SUM[0] = A[0] - B[0]; \ + SUM[1] = A[1] - B[1]; \ + SUM[2] = A[2] - B[2]; \ + SUM[3] = A[3] - B[3]; \ +} while (0) + +#define VEC4_MUL(SUM, A, B) \ +do { \ + SUM[0] = A[0] * B[0]; \ + SUM[1] = A[1] * B[1]; \ + SUM[2] = A[2] * B[2]; \ + SUM[3] = A[3] * B[3]; \ +} while (0) + +#define VEC4_MIN(SUM, A, B) \ +do { \ + SUM[0] = (A[0] < B[0]) ? A[0] : B[0]; \ + SUM[1] = (A[1] < B[1]) ? A[1] : B[1]; \ + SUM[2] = (A[2] < B[2]) ? A[2] : B[2]; \ + SUM[3] = (A[3] < B[3]) ? A[3] : B[3]; \ +} while (0) + +#define VEC4_MAX(SUM, A, B) \ +do { \ + SUM[0] = (A[0] > B[0]) ? A[0] : B[0]; \ + SUM[1] = (A[1] > B[1]) ? A[1] : B[1]; \ + SUM[2] = (A[2] > B[2]) ? A[2] : B[2]; \ + SUM[3] = (A[3] > B[3]) ? A[3] : B[3]; \ +} while (0) + + + +static void +blend_quad(struct quad_stage *qs, struct quad_header *quad) +{ + static const GLfloat zero[4] = { 0, 0, 0, 0 }; + static const GLfloat one[4] = { 1, 1, 1, 1 }; + struct softpipe_context *softpipe = qs->softpipe; + struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf); + GLfloat source[4][QUAD_SIZE], dest[4][QUAD_SIZE]; + + /* get colors from framebuffer */ + sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest); + + /* + * Compute src/first term RGB + */ + switch (softpipe->blend.rgb_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[0], quad->outputs.color[0]); /* R */ + VEC4_COPY(source[1], quad->outputs.color[1]); /* G */ + VEC4_COPY(source[2], quad->outputs.color[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_COLOR: + VEC4_MUL(source[0], quad->outputs.color[0], quad->outputs.color[0]); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], quad->outputs.color[1]); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], quad->outputs.color[2]); /* B */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const GLfloat *alpha = quad->outputs.color[3]; + VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_DST_COLOR: + VEC4_MUL(source[0], quad->outputs.color[0], dest[0]); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], dest[1]); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], dest[2]); /* B */ + break; + case PIPE_BLENDFACTOR_DST_ALPHA: + { + const GLfloat *alpha = dest[3]; + VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_CONST_COLOR: + { + GLfloat comp[4]; + VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */ + VEC4_MUL(source[0], quad->outputs.color[0], comp); /* R */ + VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */ + VEC4_MUL(source[1], quad->outputs.color[1], comp); /* G */ + VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */ + VEC4_MUL(source[2], quad->outputs.color[2], comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_CONST_ALPHA: + { + GLfloat alpha[4]; + VEC4_SCALAR(alpha, softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quad->outputs.color[0], alpha); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], alpha); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[0], zero); /* R */ + VEC4_COPY(source[1], zero); /* G */ + VEC4_COPY(source[2], zero); /* B */ + break; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + { + GLfloat inv_comp[4]; + VEC4_SUB(inv_comp, one, quad->outputs.color[0]); /* R */ + VEC4_MUL(source[0], quad->outputs.color[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, quad->outputs.color[1]); /* G */ + VEC4_MUL(source[1], quad->outputs.color[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, quad->outputs.color[2]); /* B */ + VEC4_MUL(source[2], quad->outputs.color[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + GLfloat inv_alpha[4]; + VEC4_SUB(inv_alpha, one, quad->outputs.color[3]); + VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + { + GLfloat inv_alpha[4]; + VEC4_SUB(inv_alpha, one, dest[3]); + VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + { + GLfloat inv_comp[4]; + VEC4_SUB(inv_comp, one, dest[0]); /* R */ + VEC4_MUL(source[0], quad->outputs.color[0], inv_comp); /* R */ + VEC4_SUB(inv_comp, one, dest[1]); /* G */ + VEC4_MUL(source[1], quad->outputs.color[1], inv_comp); /* G */ + VEC4_SUB(inv_comp, one, dest[2]); /* B */ + VEC4_MUL(source[2], quad->outputs.color[2], inv_comp); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + { + GLfloat inv_comp[4]; + /* R */ + VEC4_SCALAR(inv_comp, 1.0 - softpipe->blend_color.color[0]); + VEC4_MUL(source[0], quad->outputs.color[0], inv_comp); + /* G */ + VEC4_SCALAR(inv_comp, 1.0 - softpipe->blend_color.color[1]); + VEC4_MUL(source[1], quad->outputs.color[1], inv_comp); + /* B */ + VEC4_SCALAR(inv_comp, 1.0 - softpipe->blend_color.color[2]); + VEC4_MUL(source[2], quad->outputs.color[2], inv_comp); + } + break; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + { + GLfloat alpha[4], inv_alpha[4]; + VEC4_SCALAR(alpha, 1.0 - softpipe->blend_color.color[3]); + VEC4_MUL(source[0], quad->outputs.color[0], inv_alpha); /* R */ + VEC4_MUL(source[1], quad->outputs.color[1], inv_alpha); /* G */ + VEC4_MUL(source[2], quad->outputs.color[2], inv_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + assert(0); /* to do */ + break; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + assert(0); /* to do */ + break; + default: + abort(); + } + + /* + * Compute src/first term A + */ + switch (softpipe->blend.alpha_src_factor) { + case PIPE_BLENDFACTOR_ONE: + VEC4_COPY(source[3], quad->outputs.color[3]); /* A */ + break; + case PIPE_BLENDFACTOR_SRC_ALPHA: + { + const GLfloat *alpha = quad->outputs.color[3]; + VEC4_MUL(source[3], quad->outputs.color[3], alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(source[3], zero); /* A */ + break; + /* XXX fill in remaining terms */ + default: + abort(); + } + + + /* + * Compute dest/second term RGB + */ + switch (softpipe->blend.rgb_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + GLfloat one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quad->outputs.color[3]); + VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */ + VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */ + VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[0], zero); /* R */ + VEC4_COPY(dest[1], zero); /* G */ + VEC4_COPY(dest[2], zero); /* B */ + break; + /* XXX fill in remaining terms */ + default: + abort(); + } + + /* + * Compute dest/second term A + */ + switch (softpipe->blend.alpha_dst_factor) { + case PIPE_BLENDFACTOR_ONE: + /* dest = dest * 1 NO-OP, leave dest as-is */ + break; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + { + GLfloat one_minus_alpha[QUAD_SIZE]; + VEC4_SUB(one_minus_alpha, one, quad->outputs.color[3]); + VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */ + } + break; + case PIPE_BLENDFACTOR_ZERO: + VEC4_COPY(dest[3], zero); /* A */ + break; + /* XXX fill in remaining terms */ + default: + abort(); + } + + /* + * Combine RGB terms + */ + switch (softpipe->blend.rgb_func) { + case PIPE_BLEND_ADD: + VEC4_ADD(quad->outputs.color[0], source[0], dest[0]); /* R */ + VEC4_ADD(quad->outputs.color[1], source[1], dest[1]); /* G */ + VEC4_ADD(quad->outputs.color[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB(quad->outputs.color[0], source[0], dest[0]); /* R */ + VEC4_SUB(quad->outputs.color[1], source[1], dest[1]); /* G */ + VEC4_SUB(quad->outputs.color[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB(quad->outputs.color[0], dest[0], source[0]); /* R */ + VEC4_SUB(quad->outputs.color[1], dest[1], source[1]); /* G */ + VEC4_SUB(quad->outputs.color[2], dest[2], source[2]); /* B */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quad->outputs.color[0], source[0], dest[0]); /* R */ + VEC4_MIN(quad->outputs.color[1], source[1], dest[1]); /* G */ + VEC4_MIN(quad->outputs.color[2], source[2], dest[2]); /* B */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quad->outputs.color[0], source[0], dest[0]); /* R */ + VEC4_MAX(quad->outputs.color[1], source[1], dest[1]); /* G */ + VEC4_MAX(quad->outputs.color[2], source[2], dest[2]); /* B */ + break; + default: + abort(); + } + + /* + * Combine A terms + */ + switch (softpipe->blend.alpha_func) { + case PIPE_BLEND_ADD: + VEC4_ADD(quad->outputs.color[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_SUBTRACT: + VEC4_SUB(quad->outputs.color[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + VEC4_SUB(quad->outputs.color[3], dest[3], source[3]); /* A */ + break; + case PIPE_BLEND_MIN: + VEC4_MIN(quad->outputs.color[3], source[3], dest[3]); /* A */ + break; + case PIPE_BLEND_MAX: + VEC4_MAX(quad->outputs.color[3], source[3], dest[3]); /* A */ + default: + abort(); + } + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quad); +} + + + + +struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = blend_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_bufloop.c b/src/mesa/pipe/softpipe/sp_quad_bufloop.c new file mode 100644 index 0000000000..be32d02a46 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_bufloop.c @@ -0,0 +1,62 @@ + + +#include "main/glheader.h" +#include "main/imports.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + + +/** + * Loop over colorbuffers, passing quad to next stage each time. + */ +static void +cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + GLfloat tmp[4][QUAD_SIZE]; + GLuint i; + + assert(sizeof(quad->outputs.color) == sizeof(tmp)); + assert(softpipe->framebuffer.num_cbufs <= PIPE_MAX_COLOR_BUFS); + + /* make copy of original colors since they can get modified + * by blending and masking. + * XXX we won't have to do this if the fragment program actually emits + * N separate colors and we're drawing to N color buffers (MRT). + * But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is + * in effect, we need to save/restore colors like this. + */ + memcpy(tmp, quad->outputs.color, sizeof(tmp)); + + for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) { + /* set current cbuffer */ + softpipe->cbuf = softpipe->framebuffer.cbufs[i]; + + /* pass blended quad to next stage */ + qs->next->run(qs->next, quad); + + /* restore quad's colors for next buffer */ + memcpy(quad->outputs.color, tmp, sizeof(tmp)); + } + + softpipe->cbuf = NULL; /* prevent accidental use */ +} + + +/** + * Create the colorbuffer loop stage. + * This is used to implement multiple render targets and GL_FRONT_AND_BACK + * rendering. + */ +struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = cbuf_loop_quad; + + return stage; +} + diff --git a/src/mesa/pipe/softpipe/sp_quad_colormask.c b/src/mesa/pipe/softpipe/sp_quad_colormask.c new file mode 100644 index 0000000000..fff6efa8f6 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_colormask.c @@ -0,0 +1,84 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +/** + * \brief quad colormask stage + * \author Brian Paul + */ + +#include "main/glheader.h" +#include "main/imports.h" +#include "main/macros.h" +#include "pipe/p_defines.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + + + +static void +colormask_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf); + GLfloat dest[4][QUAD_SIZE]; + + sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest); + + /* R */ + if (!(softpipe->blend.colormask & PIPE_MASK_R)) + COPY_4FV(quad->outputs.color[0], dest[0]); + + /* G */ + if (!(softpipe->blend.colormask & PIPE_MASK_G)) + COPY_4FV(quad->outputs.color[1], dest[1]); + + /* B */ + if (!(softpipe->blend.colormask & PIPE_MASK_B)) + COPY_4FV(quad->outputs.color[2], dest[2]); + + /* A */ + if (!(softpipe->blend.colormask & PIPE_MASK_A)) + COPY_4FV(quad->outputs.color[3], dest[3]); + + /* pass quad to next stage */ + qs->next->run(qs->next, quad); +} + + + + +struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = colormask_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_coverage.c b/src/mesa/pipe/softpipe/sp_quad_coverage.c new file mode 100644 index 0000000000..cdd8890c7f --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_coverage.c @@ -0,0 +1,74 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +/** + * \brief Apply AA coverage to quad alpha valus + * \author Brian Paul + */ + + +#include "main/glheader.h" +#include "main/macros.h" +#include "pipe/p_defines.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" + + +/** + * Multiply quad's alpha values by the fragment coverage. + */ +static void +coverage_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + + if ((softpipe->setup.poly_smooth && quad->prim == PRIM_TRI) || + (softpipe->setup.line_smooth && quad->prim == PRIM_LINE) || + (softpipe->setup.point_smooth && quad->prim == PRIM_POINT)) { + GLuint j; + for (j = 0; j < QUAD_SIZE; j++) { + assert(quad->coverage[j] >= 0.0); + assert(quad->coverage[j] <= 1.0); + quad->outputs.color[3][j] *= quad->coverage[j]; + } + } + + qs->next->run(qs->next, quad); +} + + +struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = coverage_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_depth_test.c b/src/mesa/pipe/softpipe/sp_quad_depth_test.c new file mode 100644 index 0000000000..d47c4c42b8 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_depth_test.c @@ -0,0 +1,167 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + +/** + * \brief Quad depth testing + */ + +#include "main/glheader.h" +#include "main/imports.h" +#include "pipe/p_defines.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + + +/** + * Do depth testing for a quad. + * Not static since it's used by the stencil code. + */ +void +sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct softpipe_surface *sps = softpipe_surface(softpipe->framebuffer.zbuf); + GLuint bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */ + GLuint qzzzz[QUAD_SIZE]; /**< Z values from the quad */ + GLuint zmask = 0; + GLuint j; + GLfloat scale; + + assert(sps); /* shouldn't get here if there's no zbuffer */ + + /* + * To increase efficiency, we should probably have multiple versions + * of this function that are specifically for Z16, Z32 and FP Z buffers. + * Try to effectively do that with codegen... + */ + if (sps->surface.format == PIPE_FORMAT_U_Z16) + scale = 65535.0; + else + assert(0); /* XXX fix this someday */ + + /* + * Convert quad's float depth values to int depth values. + * If the Z buffer stores integer values, we _have_ to do the depth + * compares with integers (not floats). Otherwise, the float->int->float + * conversion of Z values (which isn't an identity function) will cause + * Z-fighting errors. + */ + for (j = 0; j < QUAD_SIZE; j++) { + qzzzz[j] = (GLuint) (quad->outputs.depth[j] * scale); + } + + /* get zquad from zbuffer */ + sps->read_quad_z(sps, quad->x0, quad->y0, bzzzz); + + switch (softpipe->depth_test.func) { + case PIPE_FUNC_NEVER: + /* zmask = 0 */ + break; + case PIPE_FUNC_LESS: + /* Note this is pretty much a single sse or cell instruction. + * Like this: quad->mask &= (quad->outputs.depth < zzzz); + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] < bzzzz[j]) + zmask |= 1 << j; + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] == bzzzz[j]) + zmask |= 1 << j; + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] <= bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] > bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] != bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if (qzzzz[j] >= bzzzz[j]) + zmask |= (1 << j); + } + break; + case PIPE_FUNC_ALWAYS: + zmask = MASK_ALL; + break; + default: + abort(); + } + + quad->mask &= zmask; + + if (softpipe->depth_test.writemask) { + + /* This is also efficient with sse / spe instructions: + */ + for (j = 0; j < QUAD_SIZE; j++) { + if (quad->mask & (1 << j)) { + bzzzz[j] = qzzzz[j]; + } + } + + /* write updated zquad to zbuffer */ + sps->write_quad_z(sps, quad->x0, quad->y0, bzzzz); + } +} + + +static void +depth_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + sp_depth_test_quad(qs, quad); + + if (quad->mask) + qs->next->run(qs->next, quad); +} + + + + +struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = depth_test_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_fs.c b/src/mesa/pipe/softpipe/sp_quad_fs.c new file mode 100644 index 0000000000..7b1c90cba6 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_fs.c @@ -0,0 +1,218 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "glheader.h" +#include "imports.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" + +struct exec_machine { + const struct setup_coefficient *coef; /**< will point to quad->coef */ + + GLfloat attr[FRAG_ATTRIB_MAX][4][QUAD_SIZE]; +}; + + +/** + * Compute quad's attributes values, as constants (GL_FLAT shading). + */ +static INLINE void cinterp( struct exec_machine *exec, + GLuint attrib, + GLuint i ) +{ + GLuint j; + + for (j = 0; j < QUAD_SIZE; j++) { + exec->attr[attrib][i][j] = exec->coef[attrib].a0[i]; + } +} + + +/** + * Compute quad's attribute values by linear interpolation. + * + * Push into the fp: + * + * INPUT[attr] = MAD COEF_A0[attr], COEF_DADX[attr], INPUT_WPOS.xxxx + * INPUT[attr] = MAD INPUT[attr], COEF_DADY[attr], INPUT_WPOS.yyyy + */ +static INLINE void linterp( struct exec_machine *exec, + GLuint attrib, + GLuint i ) +{ + GLuint j; + + for (j = 0; j < QUAD_SIZE; j++) { + const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j]; + const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j]; + exec->attr[attrib][i][j] = (exec->coef[attrib].a0[i] + + exec->coef[attrib].dadx[i] * x + + exec->coef[attrib].dady[i] * y); + } +} + + +/** + * Compute quad's attribute values by linear interpolation with + * perspective correction. + * + * Push into the fp: + * + * INPUT[attr] = MAD COEF_A0[attr], COEF_DADX[attr], INPUT_WPOS.xxxx + * INPUT[attr] = MAD INPUT[attr], COEF_DADY[attr], INPUT_WPOS.yyyy + * INPUT[attr] = MUL INPUT[attr], INPUT_WPOS.wwww + * + * (Or should that be 1/w ???) + */ +static INLINE void pinterp( struct exec_machine *exec, + GLuint attrib, + GLuint i ) +{ + GLuint j; + + for (j = 0; j < QUAD_SIZE; j++) { + const GLfloat x = exec->attr[FRAG_ATTRIB_WPOS][0][j]; + const GLfloat y = exec->attr[FRAG_ATTRIB_WPOS][1][j]; + const GLfloat invW = exec->attr[FRAG_ATTRIB_WPOS][3][j]; + exec->attr[attrib][i][j] = ((exec->coef[attrib].a0[i] + + exec->coef[attrib].dadx[i] * x + + exec->coef[attrib].dady[i] * y) * invW); + } +} + + + +/* This should be done by the fragment shader execution unit (code + * generated from the decl instructions). Do it here for now. + */ +static void +shade_quad( struct quad_stage *qs, struct quad_header *quad ) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct exec_machine exec; + GLfloat fx = quad->x0; + GLfloat fy = quad->y0; + GLuint i, j; + GLboolean need_z = softpipe->depth_test.enabled; /* XXX hack */ + + exec.coef = quad->coef; + + /* Position: + */ + exec.attr[FRAG_ATTRIB_WPOS][0][0] = fx; + exec.attr[FRAG_ATTRIB_WPOS][0][1] = fx + 1.0; + exec.attr[FRAG_ATTRIB_WPOS][0][2] = fx; + exec.attr[FRAG_ATTRIB_WPOS][0][3] = fx + 1.0; + + exec.attr[FRAG_ATTRIB_WPOS][1][0] = fy; + exec.attr[FRAG_ATTRIB_WPOS][1][1] = fy; + exec.attr[FRAG_ATTRIB_WPOS][1][2] = fy + 1.0; + exec.attr[FRAG_ATTRIB_WPOS][1][3] = fy + 1.0; + + /* Z and W are done by linear interpolation: + * XXX we'll probably have to use integers for Z + */ + if (/*softpipe->*/need_z) { + linterp(&exec, 0, 2); /* attr[0].z */ + } + + if (softpipe->need_w) { + linterp(&exec, 0, 3); /* attr[0].w */ +// invert(&exec, 0, 3); + } + + /* Interpolate all the remaining attributes. This will get pushed + * into the fragment program's responsibilities at some point. + */ + for (i = 1; i < quad->nr_attrs; i++) { +#if 1 + for (j = 0; j < NUM_CHANNELS; j++) + linterp(&exec, i, j); +#else + switch (quad->interp[i]) { + case INTERP_CONSTANT: + for (j = 0; j < NUM_CHANNELS; j++) + cinterp(&exec, i, j); + break; + + case INTERP_LINEAR: + for (j = 0; j < NUM_CHANNELS; j++) + linterp(&exec, i, j); + break; + + case INTERP_PERSPECTIVE: + for (j = 0; j < NUM_CHANNELS; j++) + pinterp(&exec, i, j); + break; + } +#endif + } + +#if 0 + softpipe->run_fs( tri->fp, quad, &tri->outputs ); +#else + { + GLuint attr = softpipe->fp_attr_to_slot[FRAG_ATTRIB_COL0]; + assert(attr); + + memcpy(quad->outputs.color, + exec.attr[attr], + sizeof(quad->outputs.color)); + + if (need_z) { + quad->outputs.depth[0] = exec.attr[0][2][0]; + quad->outputs.depth[1] = exec.attr[0][2][1]; + quad->outputs.depth[2] = exec.attr[0][2][2]; + quad->outputs.depth[3] = exec.attr[0][2][3]; + } + } +#endif + + /* shader may cull fragments */ + if (quad->mask) + qs->next->run(qs->next, quad); +} + + + +struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = shade_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_occlusion.c b/src/mesa/pipe/softpipe/sp_quad_occlusion.c new file mode 100644 index 0000000000..843c462d48 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_occlusion.c @@ -0,0 +1,67 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + + +/** + * \brief Quad occlusion counter stage + * \author Brian Paul + */ + + +#include "main/glheader.h" +#include "main/imports.h" +#include "pipe/p_defines.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + + +static void +occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + + softpipe->occlusion_counter += (quad->mask ) & 1; + softpipe->occlusion_counter += (quad->mask >> 1) & 1; + softpipe->occlusion_counter += (quad->mask >> 2) & 1; + softpipe->occlusion_counter += (quad->mask >> 3) & 1; + + if (quad->mask) + qs->next->run(qs->next, quad); +} + + +struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = occlusion_count_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_output.c b/src/mesa/pipe/softpipe/sp_quad_output.c new file mode 100644 index 0000000000..12ab1eca1c --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_output.c @@ -0,0 +1,95 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL 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. + */ + +/* Vertices are just an array of floats, with all the attributes + * packed. We currently assume a layout like: + * + * attr[0][0..3] - window position + * attr[1..n][0..3] - remaining attributes. + * + * Attributes are assumed to be 4 floats wide but are packed so that + * all the enabled attributes run contiguously. + */ + +#include "glheader.h" +#include "imports.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" + + +static void mask_copy( GLfloat (*dest)[4], + GLfloat (*src)[4], + GLuint mask ) +{ + GLuint i, j; + + for (i = 0; i < 4; i++) { + if (mask & (1<<i)) { + for (j = 0; j < 4; j++) { + dest[j][i] = src[j][i]; + } + } + } +} + + +/** + * Write quad to framebuffer, taking mask into account. + * + * Note that surfaces support only full quad reads and writes. + */ +static void +output_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct softpipe_surface *sps = softpipe_surface(softpipe->cbuf); + + if (quad->mask != MASK_ALL) { + GLfloat tmp[4][QUAD_SIZE]; + + /* XXX probably add a masked-write function someday */ + + sps->read_quad_f_swz(sps, quad->x0, quad->y0, tmp); + + mask_copy( tmp, quad->outputs.color, quad->mask ); + + sps->write_quad_f_swz(sps, quad->x0, quad->y0, tmp); + } + else if (quad->mask) { + sps->write_quad_f_swz(sps, quad->x0, quad->y0, quad->outputs.color); + } +} + + +struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = output_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_stencil.c b/src/mesa/pipe/softpipe/sp_quad_stencil.c new file mode 100644 index 0000000000..0b37474c1a --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_stencil.c @@ -0,0 +1,288 @@ + +/** + * \brief Quad stencil testing + */ + + +#include "main/glheader.h" +#include "main/imports.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_surface.h" +#include "sp_quad.h" +#include "pipe/p_defines.h" + + +/** Only 8-bit stencil supported */ +#define STENCIL_MAX 0xff + + +/** + * Do the basic stencil test (compare stencil buffer values against the + * reference value. + * + * \param stencilVals the stencil values from the stencil buffer + * \param func the stencil func (PIPE_FUNC_x) + * \param ref the stencil reference value + * \param valMask the stencil value mask indicating which bits of the stencil + * values and ref value are to be used. + * \return mask indicating which pixels passed the stencil test + */ +static GLbitfield +do_stencil_test(const GLubyte stencilVals[QUAD_SIZE], GLuint func, + GLbitfield ref, GLbitfield valMask) +{ + GLbitfield passMask = 0x0; + GLuint j; + + ref &= valMask; + + switch (func) { + case PIPE_FUNC_NEVER: + /* passMask = 0x0 */ + break; + case PIPE_FUNC_LESS: + for (j = 0; j < QUAD_SIZE; j++) { + if ((stencilVals[j] & valMask) < ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_EQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if ((stencilVals[j] & valMask) == ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_LEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if ((stencilVals[j] & valMask) <= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GREATER: + for (j = 0; j < QUAD_SIZE; j++) { + if ((stencilVals[j] & valMask) > ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_NOTEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if ((stencilVals[j] & valMask) != ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_GEQUAL: + for (j = 0; j < QUAD_SIZE; j++) { + if ((stencilVals[j] & valMask) >= ref) { + passMask |= (1 << j); + } + } + break; + case PIPE_FUNC_ALWAYS: + passMask = MASK_ALL; + break; + default: + assert(0); + } + + return passMask; +} + + +/** + * Apply the stencil operator to stencil values. + * + * \param stencilVals the stencil buffer values (read and written) + * \param mask indicates which pixels to update + * \param op the stencil operator (PIPE_STENCIL_OP_x) + * \param ref the stencil reference value + * \param wrtMask writemask controlling which bits are changed in the + * stencil values + */ +static void +apply_stencil_op(GLubyte stencilVals[QUAD_SIZE], + GLbitfield mask, GLuint op, GLubyte ref, GLubyte wrtMask) +{ + GLuint j; + GLubyte newstencil[QUAD_SIZE]; + + for (j = 0; j < QUAD_SIZE; j++) { + newstencil[j] = stencilVals[j]; + } + + switch (op) { + case PIPE_STENCIL_OP_KEEP: + /* no-op */ + break; + case PIPE_STENCIL_OP_ZERO: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = 0; + } + } + break; + case PIPE_STENCIL_OP_REPLACE: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ref; + } + } + break; + case PIPE_STENCIL_OP_INCR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (stencilVals[j] < STENCIL_MAX) { + newstencil[j] = stencilVals[j] + 1; + } + } + } + break; + case PIPE_STENCIL_OP_DECR: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + if (stencilVals[j] > 0) { + newstencil[j] = stencilVals[j] - 1; + } + } + } + break; + case PIPE_STENCIL_OP_INCR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = stencilVals[j] + 1; + } + } + break; + case PIPE_STENCIL_OP_DECR_WRAP: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = stencilVals[j] - 1; + } + } + break; + case PIPE_STENCIL_OP_INVERT: + for (j = 0; j < QUAD_SIZE; j++) { + if (mask & (1 << j)) { + newstencil[j] = ~stencilVals[j]; + } + } + break; + default: + assert(0); + } + + /* + * update the stencil values + */ + if (wrtMask != STENCIL_MAX) { + /* apply bit-wise stencil buffer writemask */ + for (j = 0; j < QUAD_SIZE; j++) { + stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & stencilVals[j]); + } + } + else { + for (j = 0; j < QUAD_SIZE; j++) { + stencilVals[j] = newstencil[j]; + } + } +} + + +/** + * Do stencil (and depth) testing. Stenciling depends on the outcome of + * depth testing. + */ +static void +stencil_test_quad(struct quad_stage *qs, struct quad_header *quad) +{ + struct softpipe_context *softpipe = qs->softpipe; + struct softpipe_surface *s_surf = softpipe_surface(softpipe->framebuffer.sbuf); + GLuint func, zFailOp, zPassOp, failOp; + GLubyte ref, wrtMask, valMask; + GLubyte stencilVals[QUAD_SIZE]; + + /* choose front or back face function, operator, etc */ + /* XXX we could do these initializations once per primitive */ + if (softpipe->stencil.back_enabled && quad->facing) { + func = softpipe->stencil.back_func; + failOp = softpipe->stencil.back_fail_op; + zFailOp = softpipe->stencil.back_zfail_op; + zPassOp = softpipe->stencil.back_zpass_op; + ref = softpipe->stencil.ref_value[1]; + wrtMask = softpipe->stencil.write_mask[1]; + valMask = softpipe->stencil.value_mask[1]; + } + else { + func = softpipe->stencil.front_func; + failOp = softpipe->stencil.front_fail_op; + zFailOp = softpipe->stencil.front_zfail_op; + zPassOp = softpipe->stencil.front_zpass_op; + ref = softpipe->stencil.ref_value[0]; + wrtMask = softpipe->stencil.write_mask[0]; + valMask = softpipe->stencil.value_mask[0]; + } + + assert(s_surf); /* shouldn't get here if there's no stencil buffer */ + s_surf->read_quad_stencil(s_surf, quad->x0, quad->y0, stencilVals); + + /* do the stencil test first */ + { + GLbitfield passMask, failMask; + passMask = do_stencil_test(stencilVals, func, ref, valMask); + failMask = quad->mask & ~passMask; + quad->mask &= passMask; + + if (failOp != PIPE_STENCIL_OP_KEEP) { + apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask); + } + } + + if (quad->mask) { + + /* now the pixels that passed the stencil test are depth tested */ + if (softpipe->depth_test.enabled) { + const GLbitfield origMask = quad->mask; + + sp_depth_test_quad(qs, quad); /* quad->mask is updated */ + + /* update stencil buffer values according to z pass/fail result */ + if (zFailOp != PIPE_STENCIL_OP_KEEP) { + const GLbitfield failMask = origMask & ~quad->mask; + apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask); + } + + if (zPassOp != PIPE_STENCIL_OP_KEEP) { + const GLbitfield passMask = origMask & quad->mask; + apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask); + } + } + else { + /* no depth test, apply Zpass operator to stencil buffer values */ + apply_stencil_op(stencilVals, quad->mask, zPassOp, ref, wrtMask); + } + + } + + s_surf->write_quad_stencil(s_surf, quad->x0, quad->y0, stencilVals); + + if (quad->mask) + qs->next->run(qs->next, quad); +} + + + + +struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = stencil_test_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_quad_stipple.c b/src/mesa/pipe/softpipe/sp_quad_stipple.c new file mode 100644 index 0000000000..cad1a1400c --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_quad_stipple.c @@ -0,0 +1,48 @@ + +/** + * quad polygon stipple stage + */ + +#include "glheader.h" +#include "imports.h" +#include "sp_context.h" +#include "sp_headers.h" +#include "sp_quad.h" +#include "pipe/p_defines.h" + + +/** + * Apply polygon stipple to quads produced by triangle rasterization + */ +static void +stipple_quad(struct quad_stage *qs, struct quad_header *quad) +{ + if (quad->prim == PRIM_TRI) { + struct softpipe_context *softpipe = qs->softpipe; + const GLint col0 = quad->x0 % 32; + const GLint row0 = quad->y0 % 32; + const GLuint stipple0 = softpipe->poly_stipple.stipple[row0]; + const GLuint stipple1 = softpipe->poly_stipple.stipple[row0 + 1]; + + /* XXX there may be a better way to lay out the stored stipple + * values to further simplify this computation. + */ + quad->mask &= (((stipple0 >> col0) & 0x3) | + (((stipple1 >> col0) & 0x3) << 2)); + + if (quad->mask) + qs->next->run(qs->next, quad); + } +} + + +struct quad_stage * +sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe ) +{ + struct quad_stage *stage = CALLOC_STRUCT(quad_stage); + + stage->softpipe = softpipe; + stage->run = stipple_quad; + + return stage; +} diff --git a/src/mesa/pipe/softpipe/sp_state.h b/src/mesa/pipe/softpipe/sp_state.h new file mode 100644 index 0000000000..71c1a2d9ba --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state.h @@ -0,0 +1,87 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SP_STATE_H +#define SP_STATE_H + +#include "glheader.h" +#include "pipe/p_state.h" + + +void softpipe_set_framebuffer_state( struct pipe_context *, + const struct pipe_framebuffer_state * ); + +void softpipe_set_alpha_test_state( struct pipe_context *, + const struct pipe_alpha_test_state * ); + +void softpipe_set_blend_state( struct pipe_context *, + const struct pipe_blend_state * ); + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ); + +void softpipe_set_clear_color_state( struct pipe_context *, + const struct pipe_clear_color_state * ); + +void softpipe_set_clip_state( struct pipe_context *, + const struct pipe_clip_state * ); + +void softpipe_set_depth_test_state( struct pipe_context *, + const struct pipe_depth_state * ); + +void softpipe_set_fs_state( struct pipe_context *, + const struct pipe_fs_state * ); + +void softpipe_set_polygon_stipple( struct pipe_context *, + const struct pipe_poly_stipple * ); + +void softpipe_set_scissor_state( struct pipe_context *, + const struct pipe_scissor_state * ); + +void softpipe_set_setup_state( struct pipe_context *, + const struct pipe_setup_state * ); + +void softpipe_set_sampler_state( struct pipe_context *, + GLuint unit, + const struct pipe_sampler_state * ); + +void softpipe_set_stencil_state( struct pipe_context *, + const struct pipe_stencil_state * ); + +void softpipe_set_texture_state( struct pipe_context *, + GLuint unit, + struct pipe_texture_object * ); + +void softpipe_set_viewport_state( struct pipe_context *, + const struct pipe_viewport_state * ); + +void softpipe_update_derived( struct softpipe_context *softpipe ); + +#endif diff --git a/src/mesa/pipe/softpipe/sp_state_blend.c b/src/mesa/pipe/softpipe/sp_state_blend.c new file mode 100644 index 0000000000..8bc22b0efc --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state_blend.c @@ -0,0 +1,93 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ +#include "imports.h" + +#include "sp_context.h" +#include "sp_state.h" + + +void softpipe_set_blend_state( struct pipe_context *pipe, + const struct pipe_blend_state *blend ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->blend = *blend; + + softpipe->dirty |= SP_NEW_BLEND; +} + + +void softpipe_set_blend_color( struct pipe_context *pipe, + const struct pipe_blend_color *blend_color ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->blend_color = *blend_color; + + softpipe->dirty |= SP_NEW_BLEND; +} + + +/** XXX move someday? Or consolidate all these simple state setters + * into one file. + */ +void +softpipe_set_depth_test_state(struct pipe_context *pipe, + const struct pipe_depth_state *depth) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->depth_test = *depth; + + softpipe->dirty |= SP_NEW_DEPTH_TEST; +} + +void +softpipe_set_alpha_test_state(struct pipe_context *pipe, + const struct pipe_alpha_test_state *alpha) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->alpha_test = *alpha; + + softpipe->dirty |= SP_NEW_ALPHA_TEST; +} + +void +softpipe_set_stencil_state(struct pipe_context *pipe, + const struct pipe_stencil_state *stencil) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->stencil = *stencil; + + softpipe->dirty |= SP_NEW_STENCIL; +} + diff --git a/src/mesa/pipe/softpipe/sp_state_clip.c b/src/mesa/pipe/softpipe/sp_state_clip.c new file mode 100644 index 0000000000..8cf4383d3f --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state_clip.c @@ -0,0 +1,85 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ +#include "imports.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "pipe/draw/draw_context.h" + + +void softpipe_set_clip_state( struct pipe_context *pipe, + const struct pipe_clip_state *clip ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + /* pass the clip state to the draw module */ + draw_set_clip_state(softpipe->draw, clip); +} + + + +/* Called when driver state tracker notices changes to the viewport + * matrix: + */ +void softpipe_set_viewport_state( struct pipe_context *pipe, + const struct pipe_viewport_state *viewport ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->viewport = *viewport; /* struct copy */ + softpipe->dirty |= SP_NEW_VIEWPORT; + + /* pass the viewport info to the draw module */ + draw_set_viewport_state(softpipe->draw, viewport); + + /* Using tnl/ and vf/ modules is temporary while getting started. + * Full pipe will have vertex shader, vertex fetch of its own. + */ +} + + +void softpipe_set_scissor_state( struct pipe_context *pipe, + const struct pipe_scissor_state *scissor ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + memcpy( &softpipe->scissor, scissor, sizeof(*scissor) ); + softpipe->dirty |= SP_NEW_SCISSOR; +} + + +void softpipe_set_polygon_stipple( struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + memcpy( &softpipe->poly_stipple, stipple, sizeof(*stipple) ); + softpipe->dirty |= SP_NEW_STIPPLE; +} diff --git a/src/mesa/pipe/softpipe/sp_state_derived.c b/src/mesa/pipe/softpipe/sp_state_derived.c new file mode 100644 index 0000000000..18dfb50e38 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state_derived.c @@ -0,0 +1,153 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "main/glheader.h" +#include "main/macros.h" +#include "main/enums.h" +#include "shader/program.h" + +#include "vf/vf.h" +#include "pipe/draw/draw_context.h" +#include "sp_context.h" +#include "sp_state.h" + + +#define EMIT_ATTR( VF_ATTR, FRAG_ATTR, INTERP ) \ +do { \ + slot_to_vf_attr[softpipe->nr_attrs] = VF_ATTR; \ + softpipe->vf_attr_to_slot[VF_ATTR] = softpipe->nr_attrs; \ + softpipe->fp_attr_to_slot[FRAG_ATTR] = softpipe->nr_attrs; \ + softpipe->interp[softpipe->nr_attrs] = INTERP; \ + softpipe->nr_attrs++; \ + attr_mask |= (1 << (VF_ATTR)); \ +} while (0) + + +static const GLuint frag_to_vf[FRAG_ATTRIB_MAX] = +{ + VF_ATTRIB_POS, + VF_ATTRIB_COLOR0, + VF_ATTRIB_COLOR1, + VF_ATTRIB_FOG, + VF_ATTRIB_TEX0, + VF_ATTRIB_TEX1, + VF_ATTRIB_TEX2, + VF_ATTRIB_TEX3, + VF_ATTRIB_TEX4, + VF_ATTRIB_TEX5, + VF_ATTRIB_TEX6, + VF_ATTRIB_TEX7, +}; + + +/* Derived from: fs, setup states. + */ +static void calculate_vertex_layout( struct softpipe_context *softpipe ) +{ + struct gl_fragment_program *fp = softpipe->fs.fp; + const GLuint inputsRead = fp->Base.InputsRead; + GLuint slot_to_vf_attr[VF_ATTRIB_MAX]; + GLbitfield attr_mask = 0x0; + GLuint i; + + softpipe->nr_attrs = 0; + memset(slot_to_vf_attr, 0, sizeof(slot_to_vf_attr)); + + memset(softpipe->fp_attr_to_slot, 0, sizeof(softpipe->fp_attr_to_slot)); + memset(softpipe->vf_attr_to_slot, 0, sizeof(softpipe->vf_attr_to_slot)); + + /* TODO - Figure out if we need to do perspective divide, etc. + */ + EMIT_ATTR(VF_ATTRIB_POS, FRAG_ATTRIB_WPOS, INTERP_LINEAR); + + /* Pull in the rest of the attributes. They are all in float4 + * format. Future optimizations could be to keep some attributes + * as fixed point or ubyte format. + */ + for (i = 1; i < FRAG_ATTRIB_TEX0; i++) { + if (inputsRead & (i << i)) { + if (softpipe->setup.flatshade + && (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)) + EMIT_ATTR(frag_to_vf[i], i, INTERP_CONSTANT); + else + EMIT_ATTR(frag_to_vf[i], i, INTERP_LINEAR); + } + } + + for (i = FRAG_ATTRIB_TEX0; i < FRAG_ATTRIB_MAX; i++) { + if (inputsRead & (i << i)) { + EMIT_ATTR(frag_to_vf[i], i, INTERP_PERSPECTIVE); + } + } + + softpipe->nr_frag_attrs = softpipe->nr_attrs; + + /* Additional attributes required for setup: Just twosided + * lighting. Edgeflag is dealt with specially by setting bits in + * the vertex header. + */ + if (softpipe->setup.light_twoside) { + if (inputsRead & FRAG_BIT_COL0) { + EMIT_ATTR(VF_ATTRIB_BFC0, FRAG_ATTRIB_MAX, 0); /* XXX: mark as discarded after setup */ + } + + if (inputsRead & FRAG_BIT_COL1) { + EMIT_ATTR(VF_ATTRIB_BFC1, FRAG_ATTRIB_MAX, 0); /* XXX: discard after setup */ + } + } + + /* If the attributes have changed, tell the draw module (which in turn + * tells the vf module) about the new vertex layout. + */ + if (attr_mask != softpipe->attr_mask) { + softpipe->attr_mask = attr_mask; + + draw_set_vertex_attributes( softpipe->draw, + slot_to_vf_attr, + softpipe->nr_attrs ); + } +} + + +/* Hopefully this will remain quite simple, otherwise need to pull in + * something like the state tracker mechanism. + */ +void softpipe_update_derived( struct softpipe_context *softpipe ) +{ + if (softpipe->dirty & (SP_NEW_SETUP | SP_NEW_FS)) + calculate_vertex_layout( softpipe ); + + if (softpipe->dirty & (SP_NEW_BLEND | + SP_NEW_DEPTH_TEST | + SP_NEW_ALPHA_TEST | + SP_NEW_STENCIL | + SP_NEW_SETUP | + SP_NEW_FS)) + sp_build_quad_pipeline(softpipe); + + softpipe->dirty = 0; +} diff --git a/src/mesa/pipe/softpipe/sp_state_fs.c b/src/mesa/pipe/softpipe/sp_state_fs.c new file mode 100644 index 0000000000..c7ef1f1cfc --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state_fs.c @@ -0,0 +1,50 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "sp_context.h" +#include "sp_state.h" + + + +void softpipe_set_fs_state( struct pipe_context *pipe, + const struct pipe_fs_state *fs ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + memcpy(&softpipe->fs, fs, sizeof(*fs)); + + softpipe->dirty |= SP_NEW_FS; +} + + + + + + + + + diff --git a/src/mesa/pipe/softpipe/sp_state_sampler.c b/src/mesa/pipe/softpipe/sp_state_sampler.c new file mode 100644 index 0000000000..9ef71f73cb --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state_sampler.c @@ -0,0 +1,64 @@ +/************************************************************************** + * + * 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 "imports.h" + +#include "sp_context.h" +#include "sp_state.h" + + + +void +softpipe_set_sampler_state(struct pipe_context *pipe, + GLuint unit, + const struct pipe_sampler_state *sampler) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + assert(unit < PIPE_MAX_SAMPLERS); + softpipe->sampler[unit] = *sampler; + + softpipe->dirty |= SP_NEW_SAMPLER; +} + + +void +softpipe_set_texture_state(struct pipe_context *pipe, + GLuint unit, + struct pipe_texture_object *texture) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + assert(unit < PIPE_MAX_SAMPLERS); + softpipe->texture[unit] = texture; /* ptr, not struct */ + + softpipe->dirty |= SP_NEW_TEXTURE; +} diff --git a/src/mesa/pipe/softpipe/sp_state_setup.c b/src/mesa/pipe/softpipe/sp_state_setup.c new file mode 100644 index 0000000000..4715a26f55 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state_setup.c @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "pipe/p_defines.h" +#include "sp_context.h" +#include "sp_state.h" +#include "pipe/draw/draw_context.h" + + +void softpipe_set_setup_state( struct pipe_context *pipe, + const struct pipe_setup_state *setup ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + /* pass-through to draw module */ + draw_set_setup_state(softpipe->draw, setup); + + memcpy( &softpipe->setup, setup, sizeof(*setup) ); + + softpipe->dirty |= SP_NEW_SETUP; +} + + diff --git a/src/mesa/pipe/softpipe/sp_state_surface.c b/src/mesa/pipe/softpipe/sp_state_surface.c new file mode 100644 index 0000000000..8ce81eb2b0 --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_state_surface.c @@ -0,0 +1,61 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ +#include "imports.h" + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_surface.h" + + +/* + * XXX this might get moved someday + */ +void +softpipe_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->framebuffer = *fb; /* struct copy */ + + softpipe->dirty |= SP_NEW_FRAMEBUFFER; +} + + + + +void +softpipe_set_clear_color_state(struct pipe_context *pipe, + const struct pipe_clear_color_state *clear) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->clear_color = *clear; /* struct copy */ +} diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c new file mode 100644 index 0000000000..16bbacb12b --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -0,0 +1,153 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "sp_context.h" +#include "sp_state.h" +#include "sp_surface.h" +#include "sp_headers.h" + +static void rgba8_read_quad_f( struct softpipe_surface *gs, + GLint x, GLint y, + GLfloat (*rgba)[NUM_CHANNELS] ) +{ + GLuint i, j, k = 0; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++, k++) { + GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4; + rgba[k][0] = ptr[0] * (1.0 / 255.0); + rgba[k][1] = ptr[1] * (1.0 / 255.0); + rgba[k][2] = ptr[2] * (1.0 / 255.0); + rgba[k][3] = ptr[3] * (1.0 / 255.0); + } + } +} + +static void rgba8_read_quad_f_swz( struct softpipe_surface *gs, + GLint x, GLint y, + GLfloat (*rrrr)[QUAD_SIZE] ) +{ + GLuint i, j, k = 0; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++, k++) { + GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4; + rrrr[0][k] = ptr[0] * (1.0 / 255.0); + rrrr[1][k] = ptr[1] * (1.0 / 255.0); + rrrr[2][k] = ptr[2] * (1.0 / 255.0); + rrrr[3][k] = ptr[3] * (1.0 / 255.0); + } + } +} + +static void rgba8_write_quad_f( struct softpipe_surface *gs, + GLint x, GLint y, + GLfloat (*rgba)[NUM_CHANNELS] ) +{ + GLuint i, j, k = 0; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++, k++) { + GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4; + ptr[0] = rgba[k][0] * 255.0; + ptr[1] = rgba[k][1] * 255.0; + ptr[2] = rgba[k][2] * 255.0; + ptr[3] = rgba[k][3] * 255.0; + } + } +} + +static void rgba8_write_quad_f_swz( struct softpipe_surface *gs, + GLint x, GLint y, + GLfloat (*rrrr)[QUAD_SIZE] ) +{ + GLuint i, j, k = 0; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++, k++) { + GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4; + ptr[0] = rrrr[0][k] * 255.0; + ptr[1] = rrrr[1][k] * 255.0; + ptr[2] = rrrr[2][k] * 255.0; + ptr[3] = rrrr[3][k] * 255.0; + } + } +} + + + + +static void rgba8_read_quad_ub( struct softpipe_surface *gs, + GLint x, GLint y, + GLubyte (*rgba)[NUM_CHANNELS] ) +{ + GLuint i, j, k = 0; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++, k++) { + GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4; + rgba[k][0] = ptr[0]; + rgba[k][1] = ptr[1]; + rgba[k][2] = ptr[2]; + rgba[k][3] = ptr[3]; + } + } +} + + +static void rgba8_write_quad_ub( struct softpipe_surface *gs, + GLint x, GLint y, + GLubyte (*rgba)[NUM_CHANNELS] ) +{ + GLuint i, j, k = 0; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++, k++) { + GLubyte *ptr = gs->surface.ptr + (y+i) * gs->surface.stride + (x+j) * 4; + ptr[0] = rgba[k][0]; + ptr[1] = rgba[k][1]; + ptr[2] = rgba[k][2]; + ptr[3] = rgba[k][3]; + } + } +} + + + + +struct softpipe_surface_type gs_rgba8 = { + G_SURFACE_RGBA_8888, + rgba8_read_quad_f, + rgba8_read_quad_f_swz, + rgba8_read_quad_ub, + rgba8_write_quad_f, + rgba8_write_quad_f_swz, + rgba8_write_quad_ub, +}; + + + diff --git a/src/mesa/pipe/softpipe/sp_surface.h b/src/mesa/pipe/softpipe/sp_surface.h new file mode 100644 index 0000000000..3ba732cebe --- /dev/null +++ b/src/mesa/pipe/softpipe/sp_surface.h @@ -0,0 +1,101 @@ +/************************************************************************** + * + * 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: Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SP_SURFACE_H +#define SP_SURFACE_H + +#include "glheader.h" +#include "sp_headers.h" + +struct softpipe_surface; + +#define G_SURFACE_RGBA_8888 0x1 + + +/** + * Softpipe surface is derived from pipe_surface. + */ +struct softpipe_surface { + struct pipe_surface surface; + + /** + * Functions for read/writing surface data + */ + void (*read_quad_f)( struct softpipe_surface *, + GLint x, GLint y, + GLfloat (*rgba)[NUM_CHANNELS] ); + + void (*read_quad_f_swz)( struct softpipe_surface *, + GLint x, GLint y, + GLfloat (*rrrr)[QUAD_SIZE] ); + + void (*read_quad_ub)( struct softpipe_surface *, + GLint x, GLint y, + GLubyte (*rgba)[NUM_CHANNELS] ); + + + void (*write_quad_f)( struct softpipe_surface *, + GLint x, GLint y, + GLfloat (*rgba)[NUM_CHANNELS] ); + + void (*write_quad_f_swz)( struct softpipe_surface *, + GLint x, GLint y, + GLfloat (*rrrr)[QUAD_SIZE] ); + + + void (*write_quad_ub)( struct softpipe_surface *, + GLint x, GLint y, + GLubyte (*rgba)[NUM_CHANNELS] ); + + void (*write_mono_row_ub)( struct softpipe_surface *, + GLuint count, GLint x, GLint y, + GLubyte rgba[NUM_CHANNELS] ); + + void (*read_quad_z)(struct softpipe_surface *, + GLint x, GLint y, GLuint zzzz[QUAD_SIZE]); + void (*write_quad_z)(struct softpipe_surface *, + GLint x, GLint y, const GLuint zzzz[QUAD_SIZE]); + + void (*read_quad_stencil)(struct softpipe_surface *, + GLint x, GLint y, GLubyte ssss[QUAD_SIZE]); + void (*write_quad_stencil)(struct softpipe_surface *, + GLint x, GLint y, const GLubyte ssss[QUAD_SIZE]); +}; + + +/** Cast wrapper */ +static INLINE struct softpipe_surface * +softpipe_surface(struct pipe_surface *ps) +{ + return (struct softpipe_surface *) ps; +} + + +#endif /* SP_SURFACE_H */ |