From bc739440c29c551fcc44e9e12d0d9c170d8d24fb Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 10:43:37 +0100 Subject: gallium: add temporary facility for rasterization-time clamping of point sizes --- src/gallium/auxiliary/draw/draw_wide_point.c | 14 +++++++++++++- src/gallium/include/pipe/p_state.h | 2 ++ src/mesa/state_tracker/st_atom_rasterizer.c | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index c53f7e6cb3..86281ca3d8 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -38,6 +38,8 @@ struct widepoint_stage { struct draw_stage stage; float half_point_size; + float point_size_min; + float point_size_max; uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; @@ -128,7 +130,15 @@ static void widepoint_point( struct draw_stage *stage, /* point size is either per-vertex or fixed size */ if (wide->psize_slot >= 0) { - half_size = 0.5f * header->v[0]->data[wide->psize_slot][0]; + half_size = header->v[0]->data[wide->psize_slot][0]; + + /* XXX: temporary -- do this in the vertex shader?? + */ + half_size = CLAMP(half_size, + wide->point_size_min, + wide->point_size_max); + + half_size *= 0.5f; } else { half_size = wide->half_point_size; @@ -182,6 +192,8 @@ static void widepoint_first_point( struct draw_stage *stage, struct draw_context *draw = stage->draw; wide->half_point_size = 0.5f * draw->rasterizer->point_size; + wide->point_size_min = draw->rasterizer->point_size_min; + wide->point_size_max = draw->rasterizer->point_size_max; /* XXX we won't know the real size if it's computed by the vertex shader! */ if ((draw->rasterizer->point_size > draw->wide_point_threshold) || diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index a73028814e..e407e3bc72 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -118,6 +118,8 @@ struct pipe_rasterizer_state float line_width; float point_size; /**< used when no per-vertex size */ + float point_size_min; /* XXX - temporary, will go away */ + float point_size_max; /* XXX - temporary, will go away */ float offset_units; float offset_scale; ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 17d77f90ae..14c26c16c0 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -198,6 +198,10 @@ static void update_raster_state( struct st_context *st ) /* _NEW_POINT */ raster->point_size = ctx->Point.Size; + + raster->point_size_min = 0; /* temporary, will go away */ + raster->point_size_max = 1000; /* temporary, will go away */ + raster->point_smooth = ctx->Point.SmoothFlag; raster->point_sprite = ctx->Point.PointSprite; for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { -- cgit v1.2.3 From 8e33194837dd206d920889851d9cf22190100c99 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 11:38:33 +0100 Subject: gallium: add a flag to turn on gl rasterization rules Use this to set up hardware rasterization (if your hardware can do it) or otherwise turn on various tweaks in the draw module. Currently only hooked up to point biasing code. --- src/gallium/auxiliary/draw/draw_wide_point.c | 19 +++++++++++++------ src/gallium/include/pipe/p_state.h | 1 + src/mesa/state_tracker/st_atom_rasterizer.c | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c index 86281ca3d8..6fc7c9fcd7 100644 --- a/src/gallium/auxiliary/draw/draw_wide_point.c +++ b/src/gallium/auxiliary/draw/draw_wide_point.c @@ -41,6 +41,9 @@ struct widepoint_stage { float point_size_min; float point_size_max; + float xbias; + float ybias; + uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS]; uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS]; uint num_texcoords; @@ -126,8 +129,6 @@ static void widepoint_point( struct draw_stage *stage, float *pos2 = v2->data[0]; float *pos3 = v3->data[0]; - const float xbias = 0.0, ybias = -0.125; - /* point size is either per-vertex or fixed size */ if (wide->psize_slot >= 0) { half_size = header->v[0]->data[wide->psize_slot][0]; @@ -144,10 +145,10 @@ static void widepoint_point( struct draw_stage *stage, half_size = wide->half_point_size; } - left_adj = -half_size + xbias; - right_adj = half_size + xbias; - bot_adj = half_size + ybias; - top_adj = -half_size + ybias; + left_adj = -half_size + wide->xbias; + right_adj = half_size + wide->xbias; + bot_adj = half_size + wide->ybias; + top_adj = -half_size + wide->ybias; pos0[0] += left_adj; pos0[1] += top_adj; @@ -194,6 +195,12 @@ static void widepoint_first_point( struct draw_stage *stage, wide->half_point_size = 0.5f * draw->rasterizer->point_size; wide->point_size_min = draw->rasterizer->point_size_min; wide->point_size_max = draw->rasterizer->point_size_max; + wide->xbias = 0.0; + wide->ybias = 0.0; + + if (draw->rasterizer->gl_rasterization_rules) { + wide->ybias = -0.125; + } /* XXX we won't know the real size if it's computed by the vertex shader! */ if ((draw->rasterizer->point_size > draw->wide_point_threshold) || diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index e407e3bc72..3593446e1c 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -115,6 +115,7 @@ struct pipe_rasterizer_state still needed though, to indicate inputs/outputs */ unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ + unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */ float line_width; float point_size; /**< used when no per-vertex size */ diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 14c26c16c0..bb14cf9045 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -261,6 +261,8 @@ static void update_raster_state( struct st_context *st ) if (ctx->Scissor.Enabled) raster->scissor = 1; + raster->gl_rasterization_rules = 1; + cso_set_rasterizer(st->cso_context, raster); } -- cgit v1.2.3 From ae3c91e98ce3355bca22738440f8ba313b3b8b23 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 11:55:03 +0100 Subject: draw: Set the backend prim in the pt 'prepare' operation Leaving it until 'run' is bad as the primitive is pretty much state for some drivers and so needs to get set early. In some drivers this is used to determine things like vertex format, etc -- by the time we get to 'run', it's too late to change this. --- src/gallium/auxiliary/draw/draw_pt.c | 3 +-- src/gallium/auxiliary/draw/draw_pt.h | 6 ++--- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 33 ++++++++++++++----------- src/gallium/auxiliary/draw/draw_pt_vcache.c | 17 +++++++------ 4 files changed, 31 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 2ea96c686d..c3baf5b7da 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -171,10 +171,9 @@ draw_pt_arrays(struct draw_context *draw, */ draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - frontend->prepare( frontend, middle ); + frontend->prepare( frontend, prim, middle ); frontend->run( frontend, - prim, draw_pt_elt_func( draw ), draw_pt_elt_ptr( draw, start ), count ); diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index f878616079..428b1e0e6b 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -53,10 +53,10 @@ struct draw_context; */ struct draw_pt_front_end { void (*prepare)( struct draw_pt_front_end *, + unsigned prim, struct draw_pt_middle_end * ); void (*run)( struct draw_pt_front_end *, - unsigned prim, pt_elt_func elt_func, const void *elt_ptr, unsigned count ); @@ -79,10 +79,10 @@ struct draw_pt_front_end { * Currenly only using the passthrough version. */ struct draw_pt_middle_end { - void (*prepare)( struct draw_pt_middle_end * ); + void (*prepare)( struct draw_pt_middle_end *, + unsigned prim ); void (*run)( struct draw_pt_middle_end *, - unsigned prim, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 9b098bc173..9339cf1f88 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -203,16 +203,29 @@ fetch_store_general( struct fetch_emit_middle_end *feme, -static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) +static void fetch_emit_prepare( struct draw_pt_middle_end *middle, + unsigned prim ) { static const float zero = 0; struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; - const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render); - unsigned nr_attrs = vinfo->num_attribs; + const struct vertex_info *vinfo; unsigned i; + boolean ok; + + + ok = draw->render->set_primitive( draw->render, + prim ); + if (!ok) { + assert(0); + return; + } + + /* Must do this after set_primitive() above: + */ + vinfo = draw->render->get_vertex_info(draw->render); - for (i = 0; i < nr_attrs; i++) { + for (i = 0; i < vinfo->num_attribs; i++) { unsigned src_element = vinfo->src_index[i]; unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index; @@ -275,7 +288,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) } } - feme->nr_fetch = nr_attrs; + feme->nr_fetch = vinfo->num_attribs; feme->hw_vertex_size = vinfo->size * 4; } @@ -284,7 +297,6 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle ) static void fetch_emit_run( struct draw_pt_middle_end *middle, - unsigned prim, const unsigned *fetch_elts, unsigned fetch_count, const ushort *draw_elts, @@ -293,16 +305,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle, struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle; struct draw_context *draw = feme->draw; void *hw_verts; - boolean ok; - - ok = draw->render->set_primitive( draw->render, - prim ); - if (!ok) { - assert(0); - return; - } - hw_verts = draw->render->allocate_vertices( draw->render, (ushort)feme->hw_vertex_size, (ushort)fetch_count ); diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 16ffedf580..5a068761df 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -59,6 +59,8 @@ struct vcache_frontend { const void *elt_ptr; struct draw_pt_middle_end *middle; + + unsigned input_prim; unsigned output_prim; }; @@ -77,7 +79,6 @@ static void vcache_flush( struct vcache_frontend *vcache ) if (vcache->draw_count) { vcache->middle->run( vcache->middle, - vcache->output_prim, vcache->fetch_elts, vcache->fetch_count, vcache->draw_elts, @@ -173,7 +174,6 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = { static void vcache_run_pv2( struct draw_pt_front_end *frontend, - unsigned prim, pt_elt_func get_elt, const void *elts, unsigned count ) @@ -185,9 +185,8 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, */ vcache->elt_func = get_elt; vcache->elt_ptr = elts; - vcache->output_prim = reduced_prim[prim]; - switch (prim) { + switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { vcache_point( vcache, @@ -304,7 +303,6 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend, static void vcache_run_pv0( struct draw_pt_front_end *frontend, - unsigned prim, pt_elt_func get_elt, const void *elts, unsigned count ) @@ -316,9 +314,8 @@ static void vcache_run_pv0( struct draw_pt_front_end *frontend, */ vcache->elt_func = get_elt; vcache->elt_ptr = elts; - vcache->output_prim = reduced_prim[prim]; - switch (prim) { + switch (vcache->input_prim) { case PIPE_PRIM_POINTS: for (i = 0; i < count; i ++) { vcache_point( vcache, @@ -389,6 +386,7 @@ static void vcache_run_pv0( struct draw_pt_front_end *frontend, } static void vcache_prepare( struct draw_pt_front_end *frontend, + unsigned prim, struct draw_pt_middle_end *middle ) { struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; @@ -398,8 +396,11 @@ static void vcache_prepare( struct draw_pt_front_end *frontend, else vcache->base.run = vcache_run_pv2; + vcache->input_prim = prim; + vcache->output_prim = reduced_prim[prim]; + vcache->middle = middle; - middle->prepare( middle ); + middle->prepare( middle, vcache->output_prim ); } -- cgit v1.2.3 From add46fbc8cc04d3bce303815541a7bc5d0b33953 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 2 Apr 2008 12:05:55 +0100 Subject: draw: add missing break statement --- src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index 9339cf1f88..f863a46d9c 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -281,6 +281,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, feme->fetch[i].pitch = 0; feme->fetch[i].fetch = fetch_R32_FLOAT; feme->fetch[i].emit = emit_R32_FLOAT; + break; default: assert(0); feme->fetch[i].emit = NULL; -- cgit v1.2.3 From d2cb4ba0bb2388c784f145c59f3798f914dc7f39 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 3 Apr 2008 12:21:30 +0100 Subject: draw: add passthrough path to the pipeline This handles the case where bypass_vs is set, but vertices need to go through the pipeline for some reason - eg unfilled polygon mode. Demonstrates how to drive the pipeline from inside one of these things. --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/SConscript | 1 + src/gallium/auxiliary/draw/draw_private.h | 6 + src/gallium/auxiliary/draw/draw_pt.c | 23 +- src/gallium/auxiliary/draw/draw_pt.h | 1 + src/gallium/auxiliary/draw/draw_pt_fetch_emit.c | 64 +--- .../auxiliary/draw/draw_pt_fetch_pipeline.c | 391 +++++++++++++++++++++ src/gallium/auxiliary/draw/draw_vertex_fetch.c | 4 +- 8 files changed, 424 insertions(+), 67 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c (limited to 'src') diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index a0db2e4555..b28e516396 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -18,6 +18,7 @@ C_SOURCES = \ draw_pt.c \ draw_pt_vcache.c \ draw_pt_fetch_emit.c \ + draw_pt_fetch_pipeline.c \ draw_pt_elts.c \ draw_prim.c \ draw_pstipple.c \ diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript index 981225a8c2..9ca4197441 100644 --- a/src/gallium/auxiliary/draw/SConscript +++ b/src/gallium/auxiliary/draw/SConscript @@ -17,6 +17,7 @@ draw = env.ConvenienceLibrary( 'draw_pt.c', 'draw_pt_vcache.c', 'draw_pt_fetch_emit.c', + 'draw_pt_fetch_pipeline.c', 'draw_pt_elts.c', 'draw_prim.c', 'draw_pstipple.c', diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 9a9b25297f..0c9f9c2e03 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -160,6 +160,11 @@ struct draw_vertex_shader { /* Internal function for vertex fetch. */ typedef void (*fetch_func)(const void *ptr, float *attrib); + +fetch_func draw_get_fetch_func( enum pipe_format format ); + + + typedef void (*full_fetch_func)( struct draw_context *draw, struct tgsi_exec_machine *machine, const unsigned *elts, @@ -211,6 +216,7 @@ struct draw_context struct { struct draw_pt_middle_end *fetch_emit; + struct draw_pt_middle_end *fetch_pipeline; struct draw_pt_middle_end *fetch_shade_emit; struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit; } middle; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index c3baf5b7da..f59fb86f78 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -73,7 +73,6 @@ draw_pt_arrays(struct draw_context *draw, */ -#if 0 if (!cliptest && !pipeline && !shading) { /* This is the 'passthrough' path: */ @@ -81,6 +80,14 @@ draw_pt_arrays(struct draw_context *draw, */ middle = draw->pt.middle.fetch_emit; } + else if (!cliptest && !shading) { + /* This is the 'passthrough' path targetting the pipeline backend. + */ + /* Fetch user verts, emit pipeline verts, run pipeline: + */ + middle = draw->pt.middle.fetch_pipeline; + } +#if 0 else if (!cliptest && !pipeline) { /* Fetch user verts, run vertex shader, emit hw verts: */ @@ -117,10 +124,9 @@ draw_pt_arrays(struct draw_context *draw, middle = draw->pt.middle.fetch_shade_cliptest_pipeline; } #else - if (cliptest || pipeline || shading) + else { return FALSE; - - middle = draw->pt.middle.fetch_emit; + } #endif @@ -190,6 +196,10 @@ boolean draw_pt_init( struct draw_context *draw ) if (!draw->pt.middle.fetch_emit) return FALSE; + draw->pt.middle.fetch_pipeline = draw_pt_fetch_pipeline( draw ); + if (!draw->pt.middle.fetch_pipeline) + return FALSE; + draw->pt.front.vcache = draw_pt_vcache( draw ); if (!draw->pt.front.vcache) return FALSE; @@ -205,6 +215,11 @@ void draw_pt_destroy( struct draw_context *draw ) draw->pt.middle.fetch_emit = NULL; } + if (draw->pt.middle.fetch_pipeline) { + draw->pt.middle.fetch_pipeline->destroy( draw->pt.middle.fetch_pipeline ); + draw->pt.middle.fetch_pipeline = NULL; + } + if (draw->pt.front.vcache) { draw->pt.front.vcache->destroy( draw->pt.front.vcache ); draw->pt.front.vcache = NULL; diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 428b1e0e6b..800072c511 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -112,6 +112,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw, */ struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw ); +struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c index f863a46d9c..39f0b40838 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c @@ -85,45 +85,6 @@ struct fetch_emit_middle_end { }; -static void fetch_B8G8R8A8_UNORM( const void *from, - float *attrib ) -{ - ubyte *ub = (ubyte *) from; - attrib[2] = UBYTE_TO_FLOAT(ub[0]); - attrib[1] = UBYTE_TO_FLOAT(ub[1]); - attrib[0] = UBYTE_TO_FLOAT(ub[2]); - attrib[3] = UBYTE_TO_FLOAT(ub[3]); -} - -static void fetch_R32G32B32A32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = f[3]; -} - -static void fetch_R32G32B32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = f[2]; - attrib[3] = 1.0; -} - -static void fetch_R32G32_FLOAT( const void *from, - float *attrib ) -{ - float *f = (float *) from; - attrib[0] = f[0]; - attrib[1] = f[1]; - attrib[2] = 0.0; - attrib[3] = 1.0; -} static void fetch_R32_FLOAT( const void *from, float *attrib ) @@ -235,28 +196,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle, feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch; - switch (draw->vertex_element[src_element].src_format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - feme->fetch[i].fetch = fetch_B8G8R8A8_UNORM; - break; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - feme->fetch[i].fetch = fetch_R32G32B32A32_FLOAT; - break; - case PIPE_FORMAT_R32G32B32_FLOAT: - feme->fetch[i].fetch = fetch_R32G32B32_FLOAT; - break; - case PIPE_FORMAT_R32G32_FLOAT: - feme->fetch[i].fetch = fetch_R32G32_FLOAT; - break; - case PIPE_FORMAT_R32_FLOAT: - feme->fetch[i].fetch = fetch_R32_FLOAT; - break; - default: - assert(0); - feme->fetch[i].fetch = NULL; - break; - } - + feme->fetch[i].fetch = draw_get_fetch_func(draw->vertex_element[src_element].src_format); + + switch (vinfo->emit[i]) { case EMIT_4F: feme->fetch[i].emit = emit_R32G32B32A32_FLOAT; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c new file mode 100644 index 0000000000..94e7d01be4 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c @@ -0,0 +1,391 @@ +/************************************************************************** + * + * 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 + */ + +#include "pipe/p_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" + +/* The simplest 'middle end' in the new vertex code. + * + * The responsibilities of a middle end are to: + * - perform vertex fetch using + * - draw vertex element/buffer state + * - a list of fetch indices we received as an input + * - run the vertex shader + * - cliptest, + * - clip coord calculation + * - viewport transformation + * - if necessary, run the primitive pipeline, passing it: + * - a linear array of vertex_header vertices constructed here + * - a set of draw indices we received as an input + * - otherwise, drive the hw backend, + * - allocate space for hardware format vertices + * - translate the vertex-shader output vertices to hw format + * - calling the backend draw functions. + * + * For convenience, we provide a helper function to drive the hardware + * backend given similar inputs to those required to run the pipeline. + * + * In the case of passthrough mode, many of these actions are disabled + * or noops, so we end up doing: + * + * - perform vertex fetch + * - drive the hw backend + * + * IE, basically just vertex fetch to post-vs-format vertices, + * followed by a call to the backend helper function. + */ + + +struct fetch_pipeline_middle_end { + struct draw_pt_middle_end base; + struct draw_context *draw; + + struct { + const ubyte *ptr; + unsigned pitch; + void (*fetch)( const void *from, float *attrib); + void (*emit)( const float *attrib, float **out ); + } fetch[PIPE_MAX_ATTRIBS]; + + unsigned nr_fetch; + unsigned pipeline_vertex_size; + unsigned prim; +}; + + +static void fetch_NULL( const void *from, + float *attrib ) +{ +} + + + +static void emit_R32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out) += 1; +} + +static void emit_R32G32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out) += 2; +} + +static void emit_R32G32B32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out) += 3; +} + +static void emit_R32G32B32A32_FLOAT( const float *attrib, + float **out ) +{ + (*out)[0] = attrib[0]; + (*out)[1] = attrib[1]; + (*out)[2] = attrib[2]; + (*out)[3] = attrib[3]; + (*out) += 4; +} + +static void emit_header( const float *attrib, + float **out ) +{ + (*out)[0] = 0; + (*out)[1] = 0; + (*out)[2] = 0; + (*out)[3] = 0; + (*out)[3] = 1; + (*out) += 5; +} + +/** + * General-purpose fetch from user's vertex arrays, emit to driver's + * vertex buffer. + * + * XXX this is totally temporary. + */ +static void +fetch_store_general( struct fetch_pipeline_middle_end *fpme, + void *out_ptr, + const unsigned *fetch_elts, + unsigned count ) +{ + float *out = (float *)out_ptr; + uint i, j; + + for (i = 0; i < count; i++) { + unsigned elt = fetch_elts[i]; + + for (j = 0; j < fpme->nr_fetch; j++) { + float attrib[4]; + const ubyte *from = (fpme->fetch[j].ptr + + fpme->fetch[j].pitch * elt); + + fpme->fetch[j].fetch( from, attrib ); + fpme->fetch[j].emit( attrib, &out ); + } + } +} + + +/* We aren't running a vertex shader, but are running the pipeline. + * That means the vertices we need to build look like: + * + * dw0: vertex header (zero?) + * dw1: clip coord 0 + * dw2: clip coord 1 + * dw3: clip coord 2 + * dw4: clip coord 4 + * dw5: screen coord 0 + * dw6: screen coord 0 + * dw7: screen coord 0 + * dw8: screen coord 0 + * dw9: other attribs... + * + */ +static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, + unsigned prim ) +{ + static const float zero = 0; + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + unsigned i, nr = 0; + + fpme->prim = prim; + + /* Emit the vertex header and empty clipspace coord field: + */ + { + fpme->fetch[nr].ptr = NULL; + fpme->fetch[nr].pitch = 0; + fpme->fetch[nr].fetch = fetch_NULL; + fpme->fetch[nr].emit = emit_header; + nr++; + } + + + /* Need to look at vertex shader inputs (we know it is a + * passthrough shader, so these define the outputs too). If we + * were running a shader, we'd still be looking at the inputs at + * this point. + */ + for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) { + unsigned buf = draw->vertex_element[i].vertex_buffer_index; + enum pipe_format format = draw->vertex_element[i].src_format; + + fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] + + draw->vertex_buffer[buf].buffer_offset + + draw->vertex_element[i].src_offset); + + fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch; + fpme->fetch[nr].fetch = draw_get_fetch_func( format ); + + /* Always do this -- somewhat redundant... + */ + fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT; + nr++; + } + + fpme->nr_fetch = nr; + fpme->pipeline_vertex_size = (5 + (nr-1) * 4) * sizeof(float); +} + + + +/** + * Add a point to the primitive queue. + * \param i0 index into user's vertex arrays + */ +static void do_point( struct draw_context *draw, + const char *v0 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 0; + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + + draw->pipeline.first->point( draw->pipeline.first, &prim ); +} + + +/** + * Add a line to the primitive queue. + * \param i0 index into user's vertex arrays + * \param i1 index into user's vertex arrays + */ +static void do_line( struct draw_context *draw, + const char *v0, + const char *v1 ) +{ + struct prim_header prim; + + prim.reset_line_stipple = 1; /* fixme */ + prim.edgeflags = 1; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + + draw->pipeline.first->line( draw->pipeline.first, &prim ); +} + +/** + * Add a triangle to the primitive queue. + */ +static void do_triangle( struct draw_context *draw, + char *v0, + char *v1, + char *v2 ) +{ + struct prim_header prim; + +// _mesa_printf("tri %d %d %d\n", i0, i1, i2); + prim.reset_line_stipple = 1; + prim.edgeflags = ~0; + prim.pad = 0; + prim.v[0] = (struct vertex_header *)v0; + prim.v[1] = (struct vertex_header *)v1; + prim.v[2] = (struct vertex_header *)v2; + + draw->pipeline.first->tri( draw->pipeline.first, &prim ); +} + + +static void run_pipeline( struct fetch_pipeline_middle_end *fpme, + char *verts, + const ushort *elts, + unsigned count ) +{ + struct draw_context *draw = fpme->draw; + unsigned stride = fpme->pipeline_vertex_size; + unsigned i; + + switch (fpme->prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) + do_point( draw, + verts + stride * elts[i] ); + break; + case PIPE_PRIM_LINES: + for (i = 0; i+1 < count; i += 2) + do_line( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1]); + break; + case PIPE_PRIM_TRIANGLES: + for (i = 0; i+2 < count; i += 3) + do_triangle( draw, + verts + stride * elts[i+0], + verts + stride * elts[i+1], + verts + stride * elts[i+2]); + break; + } +} + + + + +static void fetch_pipeline_run( struct draw_pt_middle_end *middle, + const unsigned *fetch_elts, + unsigned fetch_count, + const ushort *draw_elts, + unsigned draw_count ) +{ + struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; + struct draw_context *draw = fpme->draw; + char *pipeline_verts; + + pipeline_verts = MALLOC( fpme->pipeline_vertex_size * + fetch_count ); + if (!pipeline_verts) { + assert(0); + return; + } + + + /* Single routine to fetch vertices and emit pipeline verts. + */ + fetch_store_general( fpme, + pipeline_verts, + fetch_elts, + fetch_count ); + + + run_pipeline( fpme, + pipeline_verts, + draw_elts, + draw_count ); + + + /* Done -- that was easy, wasn't it: + */ + FREE( pipeline_verts ); +} + + + +static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) +{ + /* nothing to do */ +} + +static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) +{ + FREE(middle); +} + + +struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ) +{ + struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); + + fetch_pipeline->base.prepare = fetch_pipeline_prepare; + fetch_pipeline->base.run = fetch_pipeline_run; + fetch_pipeline->base.finish = fetch_pipeline_finish; + fetch_pipeline->base.destroy = fetch_pipeline_destroy; + + fetch_pipeline->draw = draw; + + return &fetch_pipeline->base; +} + diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c index 11f99babf6..9041041006 100644 --- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c +++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c @@ -166,7 +166,7 @@ fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) } -static fetch_func get_fetch_func( enum pipe_format format ) +fetch_func draw_get_fetch_func( enum pipe_format format ) { #if 0 { @@ -502,7 +502,7 @@ void draw_update_vertex_fetch( struct draw_context *draw ) draw->vertex_element[i].src_offset; draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch; - draw->vertex_fetch.fetch[i] = get_fetch_func( format ); + draw->vertex_fetch.fetch[i] = draw_get_fetch_func( format ); } draw->vertex_fetch.nr_attrs = nr_attrs; -- cgit v1.2.3 From 333df9656a257507d5eb5a6a8e8f2d9fc7577f20 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 3 Apr 2008 13:19:38 +0100 Subject: gallium: Only build softpipe driver by default for xlib winsys with scons. --- src/gallium/winsys/xlib/SConscript | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript index c38b5be52c..218b89285f 100644 --- a/src/gallium/winsys/xlib/SConscript +++ b/src/gallium/winsys/xlib/SConscript @@ -22,8 +22,6 @@ sources = [ drivers = [ softpipe, - i915simple, - i965simple, ] # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions -- cgit v1.2.3 From f07fe3c728aec5a715cf615822151e11a00cda44 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Apr 2008 12:01:17 -0600 Subject: gallium: set gl_rasterization_rules --- src/mesa/state_tracker/st_cb_drawpixels.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c181575f15..c7796cfb6a 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -536,6 +536,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, { struct pipe_rasterizer_state rasterizer; memset(&rasterizer, 0, sizeof(rasterizer)); + rasterizer.gl_rasterization_rules = 1; rasterizer.scissor = ctx->Scissor.Enabled; cso_set_rasterizer(cso, &rasterizer); } -- cgit v1.2.3 From 0bc2e2c9cd552e4187dd8a2250e350efcdc9aea1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Apr 2008 12:01:53 -0600 Subject: gallium: call st_flush_bitmap_cache() --- src/mesa/state_tracker/st_cb_readpixels.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index e9fcdf69a1..82df28b29a 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -159,6 +159,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, if (!dest) return; + st_flush_bitmap_cache(ctx->st); + /* make sure rendering has completed */ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); -- cgit v1.2.3 From 4f67a3f7d3bdeaa8d16d877ce9b277c97bd2f6b4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Apr 2008 12:42:26 -0600 Subject: gallium: use identity viewport fix broken clear_with_quad() path Since bypass_clipping is set and we're specifying quad vertexes in window coords, setup identity viewport. --- src/mesa/state_tracker/st_cb_clear.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index ec8d3e1022..0c6f77bc82 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -271,17 +271,15 @@ clear_with_quad(GLcontext *ctx, #endif #if !TEST_DRAW_PASSTHROUGH - /* viewport state: viewport matching window dims */ + /* viewport state: identity since we're drawing in window coords */ { - const float width = ctx->DrawBuffer->Width; - const float height = ctx->DrawBuffer->Height; struct pipe_viewport_state vp; - vp.scale[0] = 0.5 * width; - vp.scale[1] = -0.5 * height; + vp.scale[0] = 1.0; + vp.scale[1] = 1.0; vp.scale[2] = 1.0; vp.scale[3] = 1.0; - vp.translate[0] = 0.5 * width; - vp.translate[1] = 0.5 * height; + vp.translate[0] = 0.0; + vp.translate[1] = 0.0; vp.translate[2] = 0.0; vp.translate[3] = 0.0; cso_set_viewport(st->cso_context, &vp); -- cgit v1.2.3 From c4f8c8b304a47b2490fe5b1d133e314b045854df Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Apr 2008 12:44:58 -0600 Subject: gallium: remove the temporary/test TEST_DRAW_PASSTHROUGH code --- src/mesa/state_tracker/st_cb_clear.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 0c6f77bc82..041b9be2cc 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -55,11 +55,6 @@ #include "cso_cache/cso_context.h" -/* XXX for testing draw module vertex passthrough: */ -/* XXX this hack is broken now */ -#define TEST_DRAW_PASSTHROUGH 0 - - void st_destroy_clear(struct st_context *st) { @@ -243,9 +238,6 @@ clear_with_quad(GLcontext *ctx, struct pipe_rasterizer_state raster; memset(&raster, 0, sizeof(raster)); raster.bypass_clipping = 1; -#if TEST_DRAW_PASSTHROUGH - raster.bypass_vs = 1; -#endif cso_set_rasterizer(st->cso_context, &raster); } @@ -256,7 +248,6 @@ clear_with_quad(GLcontext *ctx, pipe->bind_fs_state(pipe, st->clear.fs); -#if !TEST_DRAW_PASSTHROUGH /* vertex shader state: color/position pass-through */ if (!st->clear.vs) { const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, @@ -268,9 +259,7 @@ clear_with_quad(GLcontext *ctx, &st->clear.vert_shader); } pipe->bind_vs_state(pipe, st->clear.vs); -#endif -#if !TEST_DRAW_PASSTHROUGH /* viewport state: identity since we're drawing in window coords */ { struct pipe_viewport_state vp; @@ -284,7 +273,6 @@ clear_with_quad(GLcontext *ctx, vp.translate[3] = 0.0; cso_set_viewport(st->cso_context, &vp); } -#endif /* draw quad matching scissor rect (XXX verify coord round-off) */ draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor); -- cgit v1.2.3 From e8823bb7dfad7c6241da185cd0ac94ede42c33e5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Apr 2008 12:52:55 -0600 Subject: gallium: include st_cb_bitmap.h to silence warning --- src/mesa/state_tracker/st_cb_readpixels.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 82df28b29a..2bcc8c99fb 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -43,6 +43,7 @@ #include "pipe/p_inlines.h" #include "util/p_tile.h" #include "st_context.h" +#include "st_cb_bitmap.h" #include "st_cb_readpixels.h" #include "st_cb_fbo.h" #include "st_format.h" -- cgit v1.2.3 From ce5c867cbb17b2444ebc3db5c6a03cee5e2edb8a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Apr 2008 12:54:32 -0600 Subject: gallium: streamline viewport/raster/shader state for clearing with quads Move init of these items to new st_init_clear(). --- src/mesa/state_tracker/st_cb_clear.c | 75 ++++++++++++++++++------------------ src/mesa/state_tracker/st_cb_clear.h | 4 ++ src/mesa/state_tracker/st_context.c | 1 + src/mesa/state_tracker/st_context.h | 2 + 4 files changed, 45 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 041b9be2cc..b5e737e0d1 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -55,6 +55,42 @@ #include "cso_cache/cso_context.h" +void +st_init_clear(struct st_context *st) +{ + struct pipe_context *pipe = st->pipe; + + /* rasterizer state: bypass clipping */ + memset(&st->clear.raster, 0, sizeof(st->clear.raster)); + st->clear.raster.bypass_clipping = 1; + + /* viewport state: identity since we're drawing in window coords */ + st->clear.viewport.scale[0] = 1.0; + st->clear.viewport.scale[1] = 1.0; + st->clear.viewport.scale[2] = 1.0; + st->clear.viewport.scale[3] = 1.0; + st->clear.viewport.translate[0] = 0.0; + st->clear.viewport.translate[1] = 0.0; + st->clear.viewport.translate[2] = 0.0; + st->clear.viewport.translate[3] = 0.0; + + /* fragment shader state: color pass-through program */ + st->clear.fs = + util_make_fragment_passthrough_shader(pipe, &st->clear.frag_shader); + + /* vertex shader state: color/position pass-through */ + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_COLOR }; + const uint semantic_indexes[] = { 0, 0 }; + st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2, + semantic_names, + semantic_indexes, + &st->clear.vert_shader); + } +} + + void st_destroy_clear(struct st_context *st) { @@ -233,47 +269,12 @@ clear_with_quad(GLcontext *ctx, cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil); } - /* rasterizer state: bypass clipping */ - { - struct pipe_rasterizer_state raster; - memset(&raster, 0, sizeof(raster)); - raster.bypass_clipping = 1; - cso_set_rasterizer(st->cso_context, &raster); - } + cso_set_rasterizer(st->cso_context, &st->clear.raster); + cso_set_viewport(st->cso_context, &st->clear.viewport); - /* fragment shader state: color pass-through program */ - if (!st->clear.fs) { - st->clear.fs = util_make_fragment_passthrough_shader(pipe, &st->clear.frag_shader); - } pipe->bind_fs_state(pipe, st->clear.fs); - - - /* vertex shader state: color/position pass-through */ - if (!st->clear.vs) { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_COLOR }; - const uint semantic_indexes[] = { 0, 0 }; - st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2, - semantic_names, - semantic_indexes, - &st->clear.vert_shader); - } pipe->bind_vs_state(pipe, st->clear.vs); - /* viewport state: identity since we're drawing in window coords */ - { - struct pipe_viewport_state vp; - vp.scale[0] = 1.0; - vp.scale[1] = 1.0; - vp.scale[2] = 1.0; - vp.scale[3] = 1.0; - vp.translate[0] = 0.0; - vp.translate[1] = 0.0; - vp.translate[2] = 0.0; - vp.translate[3] = 0.0; - cso_set_viewport(st->cso_context, &vp); - } - /* draw quad matching scissor rect (XXX verify coord round-off) */ draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor); diff --git a/src/mesa/state_tracker/st_cb_clear.h b/src/mesa/state_tracker/st_cb_clear.h index dfa4033faa..f49387747d 100644 --- a/src/mesa/state_tracker/st_cb_clear.h +++ b/src/mesa/state_tracker/st_cb_clear.h @@ -30,6 +30,10 @@ #define ST_CB_CLEAR_H +extern void +st_init_clear(struct st_context *st); + + extern void st_destroy_clear(struct st_context *st); diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index a20195f2de..7511c28074 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -110,6 +110,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) st_init_atoms( st ); st_init_bitmap(st); + st_init_clear(st); st_init_draw( st ); st_init_generate_mipmap(st); st_init_blit(st); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 44705bc89a..bcebbd4943 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -161,6 +161,8 @@ struct st_context struct { struct pipe_shader_state vert_shader; struct pipe_shader_state frag_shader; + struct pipe_rasterizer_state raster; + struct pipe_viewport_state viewport; void *vs; void *fs; float vertices[4][2][4]; /**< vertex pos + color */ -- cgit v1.2.3 From 124e1345c9ba4abe17bb04b8781ec0fe803eda7b Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 3 Apr 2008 13:16:37 -0600 Subject: gallium: set rasterizer.gl_rasterization_rules = 1 in a few more places --- src/mesa/state_tracker/st_cb_bitmap.c | 1 + src/mesa/state_tracker/st_cb_clear.c | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 975a55d6dc..0872f2bd28 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -754,6 +754,7 @@ st_init_bitmap(struct st_context *st) /* init baseline rasterizer state once */ memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer)); + st->bitmap.rasterizer.gl_rasterization_rules = 1; st->bitmap.rasterizer.bypass_vs = 1; init_bitmap_cache(st); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index b5e737e0d1..fa9f986f11 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -62,6 +62,7 @@ st_init_clear(struct st_context *st) /* rasterizer state: bypass clipping */ memset(&st->clear.raster, 0, sizeof(st->clear.raster)); + st->clear.raster.gl_rasterization_rules = 1; st->clear.raster.bypass_clipping = 1; /* viewport state: identity since we're drawing in window coords */ -- cgit v1.2.3 From 766f3a545ebb317d2115b9053a8fc13b49ceec12 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 3 Apr 2008 16:36:07 -0600 Subject: gallium: implement ycbcr->rgba tile conversion --- src/gallium/auxiliary/util/p_tile.c | 71 +++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'src') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index 287d783981..c9a9c8f4f7 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -560,6 +560,69 @@ z24s8_get_tile_rgba(unsigned *src, } +/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/ + +/** + * Convert YCbCr (or YCrCb) to RGBA. + */ +static void +ycbcr_get_tile_rgba(ushort *src, + unsigned w, unsigned h, + float *p, + unsigned dst_stride, + boolean rev) +{ + const float scale = 1.0f / 255.0f; + unsigned i, j; + + /* we're assuming we're being asked for an even number of texels */ + assert((w & 1) == 0); + + for (i = 0; i < h; i++) { + float *pRow = p; + /* do two texels at a time */ + for (j = 0; j < w; j += 2, src += 2) { + const ushort t0 = src[0]; + const ushort t1 = src[1]; + const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ + const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ + ubyte cb, cr; + if (rev) { + cb = t1 & 0xff; /* chroma U */ + cr = t0 & 0xff; /* chroma V */ + } + else { + cb = t0 & 0xff; /* chroma U */ + cr = t1 & 0xff; /* chroma V */ + } + float r, g, b; + + /* even pixel: y0,cr,cb */ + r = 1.164 * (y0-16) + 1.596 * (cr-128); + g = 1.164 * (y0-16) - 0.813 * (cr-128) - 0.391 * (cb-128); + b = 1.164 * (y0-16) + 2.018 * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + + /* odd pixel: use y1,cr,cb */ + r = 1.164 * (y1-16) + 1.596 * (cr-128); + g = 1.164 * (y1-16) - 0.813 * (cr-128) - 0.391 * (cb-128); + b = 1.164 * (y1-16) + 2.018 * (cb-128); + pRow[0] = r * scale; + pRow[1] = g * scale; + pRow[2] = b * scale; + pRow[3] = 1.0f; + pRow += 4; + + } + p += dst_stride; + } +} + + void pipe_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *ps, @@ -622,6 +685,14 @@ pipe_get_tile_rgba(struct pipe_context *pipe, case PIPE_FORMAT_Z24S8_UNORM: z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride); break; + case PIPE_FORMAT_YCBCR: + assert((x & 1) == 0); + ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE); + break; + case PIPE_FORMAT_YCBCR_REV: + assert((x & 1) == 0); + ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE); + break; default: assert(0); } -- cgit v1.2.3 From 1307eebfa07e3440554eb2871e5dbd94e98ed7a8 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 3 Apr 2008 16:37:30 -0600 Subject: gallium: test if PIPE_FORMAT_YCBCR[_REV] is supported and enable GL_MESA_ycbcr_texture Update texture format selection code too. --- src/mesa/state_tracker/st_extensions.c | 5 +++++ src/mesa/state_tracker/st_format.c | 25 +++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 20f4652413..47a50d40ca 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -220,4 +220,9 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE; } + if (screen->is_format_supported(screen, PIPE_FORMAT_YCBCR, PIPE_TEXTURE) || + screen->is_format_supported(screen, PIPE_FORMAT_YCBCR_REV, PIPE_TEXTURE)) { + ctx->Extensions.MESA_ycbcr_texture = GL_TRUE; + } + } diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index cb6fa9a573..761645c105 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -189,15 +189,14 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo) pinfo->base_format = GL_RGBA; } } + else if (pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR) { + pinfo->base_format = GL_YCBCR_MESA; + pinfo->datatype = GL_UNSIGNED_SHORT; + pinfo->size = 2; /* two bytes per "texel" */ + } else { - pipe_format_ycbcr_t info; - - assert( pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR ); - - info = format; - - /* TODO */ - assert( 0 ); + /* compressed format? */ + assert(0); } #if 0 @@ -275,6 +274,8 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat) return PIPE_FORMAT_Z32_UNORM; case MESA_FORMAT_Z24_S8: return PIPE_FORMAT_Z24S8_UNORM; + case MESA_FORMAT_YCBCR: + return PIPE_FORMAT_YCBCR; default: assert(0); return 0; @@ -435,6 +436,14 @@ choose_format(struct pipe_context *pipe, GLint internalFormat, uint surfType) return default_rgba_format( screen, surfType ); case GL_YCBCR_MESA: + if (screen->is_format_supported(screen, PIPE_FORMAT_YCBCR, + PIPE_TEXTURE)) { + return PIPE_FORMAT_YCBCR; + } + if (screen->is_format_supported(screen, PIPE_FORMAT_YCBCR_REV, + PIPE_TEXTURE)) { + return PIPE_FORMAT_YCBCR_REV; + } return PIPE_FORMAT_NONE; case GL_RGB_S3TC: -- cgit v1.2.3 From 217d37940771dd02ff1aa365105eca2c7a09d623 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 2 Apr 2008 14:01:42 -0600 Subject: cell: minor texture improvements Precompute tiles_per_row. Use ushort multiplies in a few places. New comments. --- src/gallium/drivers/cell/spu/spu_main.c | 2 ++ src/gallium/drivers/cell/spu/spu_main.h | 3 ++- src/gallium/drivers/cell/spu/spu_texture.c | 32 ++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index 1ab1c40379..e04ffeb9b1 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -343,6 +343,8 @@ cmd_state_texture(const struct cell_command_texture *texture) spu.texture[unit].width = width; spu.texture[unit].height = height; + spu.texture[unit].tiles_per_row = width / TILE_SIZE; + spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0}; spu.texture[unit].tex_size_mask = (vector unsigned int) { width - 1, height - 1, 0, 0 }; diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index e9e39cbeab..e962e1426c 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -105,7 +105,8 @@ struct spu_framebuffer { struct spu_texture { void *start; - uint width, height; + ushort width, height; + ushort tiles_per_row; vector float tex_size; vector unsigned int tex_size_mask; /**< == int(size - 1) */ vector unsigned int tex_size_x_mask; /**< == int(size - 1) */ diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index ceab246980..e9a2754e57 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -51,22 +51,25 @@ invalidate_tex_cache(void) static uint get_texel(uint unit, vec_uint4 coordinate) { + const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; + ushort x = spu_extract(coordinate, 0); + ushort y = spu_extract(coordinate, 1); + unsigned tile_offset = sizeof(tile_t) + * ((y / TILE_SIZE * spu.texture[unit].tiles_per_row) + (x / TILE_SIZE)); + ushort texel_offset = (ushort) 4 + * (ushort) (((ushort) (y % TILE_SIZE) * (ushort) TILE_SIZE) + (x % TILE_SIZE)); vec_uint4 tmp; - unsigned x = spu_extract(coordinate, 0); - unsigned y = spu_extract(coordinate, 1); - const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE; - unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row) - + (x / TILE_SIZE)); - unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE) - + (x % TILE_SIZE)); spu_dcache_fetch_unaligned((qword *) & tmp, - spu.texture[unit].start + tile_offset + texel_offset, + texture_ea + tile_offset + texel_offset, 4); return spu_extract(tmp, 0); } +/** + * Get four texels from locations (x[0], y[0]), (x[1], y[1]) ... + */ static void get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) { @@ -76,7 +79,7 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) const qword offset_x = si_andi((qword) x, 0x1f); const qword offset_y = si_andi((qword) y, 0x1f); - const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE); + const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].tiles_per_row); const qword tile_size = (qword) spu_splats(sizeof(tile_t)); qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x); @@ -97,6 +100,7 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) texture_ea + spu_extract(offset, 3), 4); } + /** * Get texture sample at texcoord. * XXX this is extremely primitive for now. @@ -126,17 +130,25 @@ sample_texture_bilinear(uint unit, vector float texcoord) vec_uint4 texels[4]; + /* setup texcoords for quad: + * +-----+-----+ + * |x0,y0|x1,y1| + * +-----+-----+ + * |x2,y2|x3,y3| + * +-----+-----+ + */ vec_uint4 x = spu_splats(spu_extract(itc, 0)); vec_uint4 y = spu_splats(spu_extract(itc, 1)); - x = spu_add(x, offset_x); y = spu_add(y, offset_y); + /* GL_REPEAT wrap mode: */ x = spu_and(x, spu.texture[unit].tex_size_x_mask); y = spu_and(y, spu.texture[unit].tex_size_y_mask); get_four_texels(unit, x, y, texels); + /* integer A8R8G8B8 to float texel conversion */ vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0)); vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0)); vector float texel10 = spu_unpack_A8R8G8B8(spu_extract(texels[2], 0)); -- cgit v1.2.3 From a7504ad587ee8cbfa9958ad23321a691ce0823d3 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 2 Apr 2008 14:30:28 -0600 Subject: cell: added some comments/ideas about better texture sampling --- src/gallium/drivers/cell/spu/spu_texture.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index e9a2754e57..5051774f00 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -48,9 +48,16 @@ invalidate_tex_cache(void) } +/** + * XXX look into getting texels for all four pixels in a quad at once. + */ static uint get_texel(uint unit, vec_uint4 coordinate) { + /* + * XXX we could do the "/ TILE_SIZE" and "% TILE_SIZE" operations as + * SIMD since X and Y are already in a SIMD register. + */ const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; ushort x = spu_extract(coordinate, 0); ushort y = spu_extract(coordinate, 1); @@ -69,6 +76,16 @@ get_texel(uint unit, vec_uint4 coordinate) /** * Get four texels from locations (x[0], y[0]), (x[1], y[1]) ... + * + * NOTE: in the typical case of bilinear filtering, the four texels + * are in a 2x2 group so we could get by with just two dcache fetches + * (two side-by-side texels per fetch). But when bilinear filtering + * wraps around a texture edge, we'll probably need code like we have + * now. + * FURTHERMORE: since we're rasterizing a quad of 2x2 pixels at a time, + * it's quite likely that the four pixels in a quad will need some of the + * same texels. So look into doing texture fetches for four pixels at + * a time. */ static void get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) @@ -103,7 +120,6 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels) /** * Get texture sample at texcoord. - * XXX this is extremely primitive for now. */ vector float sample_texture_nearest(uint unit, vector float texcoord) -- cgit v1.2.3 From c07d3f6a9e62bd88e05d4ebf72430139b0531be8 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 4 Apr 2008 09:06:13 +0100 Subject: gallium: Always allocate new const buffers instead of modifying existing ones. --- src/mesa/state_tracker/st_atom_constbuf.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index cd7372902b..03093579e1 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -71,13 +71,12 @@ void st_upload_constants( struct st_context *st, _mesa_load_state_parameters(st->ctx, params); - if (cbuf->buffer && cbuf->size != paramBytes) - pipe_buffer_reference( ws, &cbuf->buffer, NULL ); - - if (!cbuf->buffer) { - cbuf->buffer = ws->buffer_create(ws, 1, PIPE_BUFFER_USAGE_CONSTANT, - paramBytes); - } + /* We always need to get a new buffer, to keep the drivers simple and + * avoid gratuitous rendering synchronization. + */ + pipe_buffer_reference( ws, &cbuf->buffer, NULL ); + cbuf->buffer = ws->buffer_create( ws, 1, PIPE_BUFFER_USAGE_CONSTANT, + paramBytes ); if (0) { -- cgit v1.2.3 From 7a7bce7b24ea4f63faa1d5bfe3f71d09b412c838 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 4 Apr 2008 11:13:10 +0100 Subject: gallium: make msvc less unhappy --- src/gallium/auxiliary/util/p_tile.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c index c9a9c8f4f7..520da5cecd 100644 --- a/src/gallium/auxiliary/util/p_tile.c +++ b/src/gallium/auxiliary/util/p_tile.c @@ -587,6 +587,8 @@ ycbcr_get_tile_rgba(ushort *src, const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */ const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */ ubyte cb, cr; + float r, g, b; + if (rev) { cb = t1 & 0xff; /* chroma U */ cr = t0 & 0xff; /* chroma V */ @@ -595,12 +597,11 @@ ycbcr_get_tile_rgba(ushort *src, cb = t0 & 0xff; /* chroma U */ cr = t1 & 0xff; /* chroma V */ } - float r, g, b; /* even pixel: y0,cr,cb */ - r = 1.164 * (y0-16) + 1.596 * (cr-128); - g = 1.164 * (y0-16) - 0.813 * (cr-128) - 0.391 * (cb-128); - b = 1.164 * (y0-16) + 2.018 * (cb-128); + r = 1.164f * (y0-16) + 1.596f * (cr-128); + g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y0-16) + 2.018f * (cb-128); pRow[0] = r * scale; pRow[1] = g * scale; pRow[2] = b * scale; @@ -608,9 +609,9 @@ ycbcr_get_tile_rgba(ushort *src, pRow += 4; /* odd pixel: use y1,cr,cb */ - r = 1.164 * (y1-16) + 1.596 * (cr-128); - g = 1.164 * (y1-16) - 0.813 * (cr-128) - 0.391 * (cb-128); - b = 1.164 * (y1-16) + 2.018 * (cb-128); + r = 1.164f * (y1-16) + 1.596f * (cr-128); + g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128); + b = 1.164f * (y1-16) + 2.018f * (cb-128); pRow[0] = r * scale; pRow[1] = g * scale; pRow[2] = b * scale; -- cgit v1.2.3