From c503e55d74cf84f87f82b3dab3cb4d38b201d47a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Apr 2008 14:43:40 +0100 Subject: [PATCH] draw: move hw vertex emit to a new module --- src/gallium/auxiliary/draw/Makefile | 1 + src/gallium/auxiliary/draw/draw_private.h | 8 - src/gallium/auxiliary/draw/draw_pt.h | 33 +++ src/gallium/auxiliary/draw/draw_pt_emit.c | 208 ++++++++++++++++++ .../draw/draw_pt_fetch_shade_pipeline.c | 161 +++----------- 5 files changed, 270 insertions(+), 141 deletions(-) create mode 100644 src/gallium/auxiliary/draw/draw_pt_emit.c diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile index 5ab3cfe5ce9..836e98f086a 100644 --- a/src/gallium/auxiliary/draw/Makefile +++ b/src/gallium/auxiliary/draw/Makefile @@ -21,6 +21,7 @@ C_SOURCES = \ draw_pt_fetch_pipeline.c \ draw_pt_fetch_shade_pipeline.c \ draw_pt_pipeline.c \ + draw_pt_emit.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 7953dbb7d9e..9407217fd33 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -376,14 +376,6 @@ boolean draw_pt_arrays( struct draw_context *draw, unsigned count ); void draw_pt_reset_vertex_ids( struct draw_context *draw ); -void draw_pt_run_pipeline( struct draw_context *draw, - unsigned prim, - char *verts, - unsigned vertex_stride, - unsigned vertex_count, - const ushort *elts, - unsigned count ); - #define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */ #define DRAW_FLUSH_PRIM_QUEUE 0x2 diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 08afb606457..31d18ec62be 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -128,4 +128,37 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw ); struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw); +/* More helpers: + */ +void draw_pt_run_pipeline( struct draw_context *draw, + unsigned prim, + char *verts, + unsigned vertex_stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); + + +/* HW vertex emit: + */ +struct pt_emit; + +void draw_pt_emit_prepare( struct pt_emit *emit, + unsigned prim, + unsigned opt ); + +void draw_pt_emit( struct pt_emit *emit, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ); + +void draw_pt_emit_destroy( struct pt_emit *emit ); + +struct pt_emit *draw_pt_emit_create( struct draw_context *draw ); + + + + #endif diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c new file mode 100644 index 00000000000..e9ed29450af --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -0,0 +1,208 @@ +/************************************************************************** + * + * Copyright 2008 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_util.h" +#include "draw/draw_context.h" +#include "draw/draw_private.h" +#include "draw/draw_vbuf.h" +#include "draw/draw_vertex.h" +#include "draw/draw_pt.h" +#include "translate/translate.h" + + +struct pt_emit { + struct draw_context *draw; + + struct translate *translate; + + unsigned pipeline_vertex_size; + unsigned prim; + unsigned opt; +}; + + +void draw_pt_emit_prepare( struct pt_emit *emit, + unsigned prim, + unsigned opt ) +{ + struct draw_context *draw = emit->draw; + const struct vertex_info *vinfo; + unsigned dst_offset; + struct translate_key hw_key; + 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); + + + /* In passthrough mode, need to translate from vertex shader + * outputs to hw vertices. + */ + dst_offset = 0; + for (i = 0; i < vinfo->num_attribs; i++) { + unsigned emit_sz = 0; + unsigned src_buffer = 0; + unsigned output_format; + unsigned src_offset = (sizeof(struct vertex_header) + + vinfo->src_index[i] * 4 * sizeof(float) ); + + + + switch (vinfo->emit[i]) { + case EMIT_4F: + output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + emit_sz = 4 * sizeof(float); + break; + case EMIT_3F: + output_format = PIPE_FORMAT_R32G32B32_FLOAT; + emit_sz = 3 * sizeof(float); + break; + case EMIT_2F: + output_format = PIPE_FORMAT_R32G32_FLOAT; + emit_sz = 2 * sizeof(float); + break; + case EMIT_1F: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + break; + case EMIT_1F_PSIZE: + output_format = PIPE_FORMAT_R32_FLOAT; + emit_sz = 1 * sizeof(float); + src_buffer = 1; + src_offset = 0; + break; + case EMIT_4UB: + output_format = PIPE_FORMAT_B8G8R8A8_UNORM; + emit_sz = 4 * sizeof(ubyte); + default: + assert(0); + output_format = PIPE_FORMAT_NONE; + emit_sz = 0; + break; + } + + hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; + hw_key.element[i].input_buffer = src_buffer; + hw_key.element[i].input_offset = src_offset; + hw_key.element[i].output_format = output_format; + hw_key.element[i].output_offset = dst_offset; + + dst_offset += emit_sz; + } + + hw_key.nr_elements = vinfo->num_attribs; + hw_key.output_stride = vinfo->size * 4; + + /* Don't bother with caching at this stage: + */ + if (!emit->translate || + memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) + { + if (emit->translate) + emit->translate->release(emit->translate); + + emit->translate = translate_generic_create( &hw_key ); + } +} + + +void draw_pt_emit( struct pt_emit *emit, + char *verts, + unsigned stride, + unsigned vertex_count, + const ushort *elts, + unsigned count ) +{ + struct draw_context *draw = emit->draw; + struct translate *translate = emit->translate; + struct vbuf_render *render = draw->render; + void *hw_verts; + + /* XXX: need to flush to get prim_vbuf.c to release its allocation?? + */ + draw_do_flush( draw, DRAW_FLUSH_BACKEND ); + + hw_verts = render->allocate_vertices(render, + (ushort)translate->key.output_stride, + (ushort)count); + if (!hw_verts) { + assert(0); + return; + } + + translate->set_buffer(translate, + 0, + verts, + stride ); + + translate->set_buffer(translate, + 1, + &draw->rasterizer->point_size, + 0); + + translate->run( translate, + 0, + vertex_count, + hw_verts ); + + render->draw(render, + elts, + count); + + render->release_vertices(render, + hw_verts, + translate->key.output_stride, + vertex_count); +} + + +struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) +{ + struct pt_emit *emit = CALLOC_STRUCT(pt_emit); + if (!emit) + return NULL; + + emit->draw = draw; + + return emit; +} + +void draw_pt_emit_destroy( struct pt_emit *emit ) +{ + if (emit->translate) + emit->translate->release( emit->translate ); + + FREE(emit); +} diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index cf37493eb62..8db9e31e2dd 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -38,7 +38,7 @@ struct fetch_pipeline_middle_end { struct draw_pt_middle_end base; struct draw_context *draw; - struct translate *translate; + struct pt_emit *emit; unsigned pipeline_vertex_size; unsigned prim; @@ -51,98 +51,12 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, unsigned opt ) { struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; - struct draw_context *draw = fpme->draw; - unsigned i; - boolean ok; - const struct vertex_info *vinfo; - unsigned dst_offset; - struct translate_key hw_key; fpme->prim = prim; fpme->opt = opt; - if (!(opt & PT_PIPELINE)) { - 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); - - - /* In passthrough mode, need to translate from vertex shader - * outputs to hw vertices. - */ - dst_offset = 0; - for (i = 0; i < vinfo->num_attribs; i++) { - unsigned emit_sz = 0; - unsigned src_buffer = 0; - unsigned output_format; - unsigned src_offset = (sizeof(struct vertex_header) + - vinfo->src_index[i] * 4 * sizeof(float) ); - - - - switch (vinfo->emit[i]) { - case EMIT_4F: - output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - emit_sz = 4 * sizeof(float); - break; - case EMIT_3F: - output_format = PIPE_FORMAT_R32G32B32_FLOAT; - emit_sz = 3 * sizeof(float); - break; - case EMIT_2F: - output_format = PIPE_FORMAT_R32G32_FLOAT; - emit_sz = 2 * sizeof(float); - break; - case EMIT_1F: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - break; - case EMIT_1F_PSIZE: - output_format = PIPE_FORMAT_R32_FLOAT; - emit_sz = 1 * sizeof(float); - src_buffer = 1; - src_offset = 0; - break; - case EMIT_4UB: - output_format = PIPE_FORMAT_B8G8R8A8_UNORM; - emit_sz = 4 * sizeof(ubyte); - default: - assert(0); - output_format = PIPE_FORMAT_NONE; - emit_sz = 0; - break; - } - - hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; - hw_key.element[i].input_buffer = src_buffer; - hw_key.element[i].input_offset = src_offset; - hw_key.element[i].output_format = output_format; - hw_key.element[i].output_offset = dst_offset; - - dst_offset += emit_sz; - } - - hw_key.nr_elements = vinfo->num_attribs; - hw_key.output_stride = vinfo->size * 4; - - /* Don't bother with caching at this stage: - */ - if (!fpme->translate || - memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) - { - if (fpme->translate) - fpme->translate->release(fpme->translate); - - fpme->translate = translate_generic_create( &hw_key ); - } - } - + if (!(opt & PT_PIPELINE)) + draw_pt_emit_prepare( fpme->emit, prim, opt ); //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; @@ -194,43 +108,12 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle, draw_elts, draw_count ); } else { - struct translate *translate = fpme->translate; - void *hw_verts; - - /* XXX: need to flush to get prim_vbuf.c to release its allocation?? - */ - draw_do_flush( draw, DRAW_FLUSH_BACKEND ); - - hw_verts = draw->render->allocate_vertices(draw->render, - (ushort)fpme->translate->key.output_stride, - (ushort)fetch_count); - if (!hw_verts) { - assert(0); - return; - } - - translate->set_buffer(translate, - 0, - pipeline_verts, - fpme->pipeline_vertex_size ); - - translate->set_buffer(translate, - 1, - &fpme->draw->rasterizer->point_size, - 0); - - translate->run( translate, - 0, fetch_count, - hw_verts ); - - draw->render->draw(draw->render, - draw_elts, - draw_count); - - draw->render->release_vertices(draw->render, - hw_verts, - fpme->translate->key.output_stride, - fetch_count); + draw_pt_emit( fpme->emit, + pipeline_verts, + fpme->pipeline_vertex_size, + fetch_count, + draw_elts, + draw_count ); } @@ -252,14 +135,26 @@ static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *draw ) { - struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end ); + struct fetch_pipeline_middle_end *fpme = CALLOC_STRUCT( fetch_pipeline_middle_end ); + if (!fpme) + goto fail; + + fpme->base.prepare = fetch_pipeline_prepare; + fpme->base.run = fetch_pipeline_run; + fpme->base.finish = fetch_pipeline_finish; + fpme->base.destroy = fetch_pipeline_destroy; + + fpme->draw = draw; + + fpme->emit = draw_pt_emit_create( draw ); + if (!fpme->emit) + goto fail; - 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; + return &fpme->base; - fetch_pipeline->draw = draw; + fail: + if (fpme) + fetch_pipeline_destroy( &fpme->base ); - return &fetch_pipeline->base; + return NULL; } -- 2.30.2