draw_pt_fetch.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  *
00026  **************************************************************************/
00027 
00028 #include "util/u_memory.h"
00029 #include "draw/draw_context.h"
00030 #include "draw/draw_private.h"
00031 #include "draw/draw_vbuf.h"
00032 #include "draw/draw_vertex.h"
00033 #include "draw/draw_pt.h"
00034 #include "translate/translate.h"
00035 #include "translate/translate_cache.h"
00036 
00037 
00038 struct pt_fetch {
00039    struct draw_context *draw;
00040 
00041    struct translate *translate;
00042 
00043    unsigned vertex_size;
00044    boolean need_edgeflags;
00045 
00046    struct translate_cache *cache;
00047 };
00048 
00049 /* Perform the fetch from API vertex elements & vertex buffers, to a
00050  * contiguous set of float[4] attributes as required for the
00051  * vertex_shader->run_linear() method.
00052  *
00053  * This is used in all cases except pure passthrough
00054  * (draw_pt_fetch_emit.c) which has its own version to translate
00055  * directly to hw vertices.
00056  *
00057  */
00058 void draw_pt_fetch_prepare( struct pt_fetch *fetch,
00059                             unsigned vertex_size )
00060 {
00061    struct draw_context *draw = fetch->draw;
00062    unsigned i, nr = 0;
00063    unsigned dst_offset = 0;
00064    struct translate_key key;
00065 
00066    fetch->vertex_size = vertex_size;
00067 
00068    /* Always emit/leave space for a vertex header.
00069     *
00070     * It's worth considering whether the vertex headers should contain
00071     * a pointer to the 'data', rather than having it inline.
00072     * Something to look at after we've fully switched over to the pt
00073     * paths.
00074     */
00075    {
00076       /* Need to set header->vertex_id = 0xffff somehow.
00077        */
00078       key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT;
00079       key.element[nr].input_buffer = draw->pt.nr_vertex_buffers;
00080       key.element[nr].input_offset = 0;
00081       key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT;
00082       key.element[nr].output_offset = dst_offset;
00083       dst_offset += 1 * sizeof(float);
00084       nr++;
00085 
00086 
00087       /* Just leave the clip[] array untouched.
00088        */
00089       dst_offset += 4 * sizeof(float);
00090    }
00091       
00092 
00093    for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
00094       key.element[nr].input_format = draw->pt.vertex_element[i].src_format;
00095       key.element[nr].input_buffer = draw->pt.vertex_element[i].vertex_buffer_index;
00096       key.element[nr].input_offset = draw->pt.vertex_element[i].src_offset;
00097       key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
00098       key.element[nr].output_offset = dst_offset;
00099 
00100       dst_offset += 4 * sizeof(float);
00101       nr++;
00102    }
00103 
00104    assert(dst_offset <= vertex_size);
00105 
00106    key.nr_elements = nr;
00107    key.output_stride = vertex_size;
00108 
00109 
00110    if (!fetch->translate ||
00111        translate_key_compare(&fetch->translate->key, &key) != 0)
00112    {
00113       translate_key_sanitize(&key);
00114       fetch->translate = translate_cache_find(fetch->cache, &key);
00115 
00116       {
00117          static struct vertex_header vh = { 0, 1, 0, UNDEFINED_VERTEX_ID, { .0f, .0f, .0f, .0f } };
00118          fetch->translate->set_buffer(fetch->translate,
00119                                       draw->pt.nr_vertex_buffers,
00120                                       &vh,
00121                                       0);
00122       }
00123    }
00124 
00125    fetch->need_edgeflags = ((draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
00126                              draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) &&
00127                             draw->pt.user.edgeflag);
00128 }
00129 
00130 
00131 
00132 
00133 void draw_pt_fetch_run( struct pt_fetch *fetch,
00134                         const unsigned *elts,
00135                         unsigned count,
00136                         char *verts )
00137 {
00138    struct draw_context *draw = fetch->draw;
00139    struct translate *translate = fetch->translate;
00140    unsigned i;
00141 
00142    for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
00143       translate->set_buffer(translate, 
00144                             i, 
00145                             ((char *)draw->pt.user.vbuffer[i] + 
00146                              draw->pt.vertex_buffer[i].buffer_offset),
00147                             draw->pt.vertex_buffer[i].pitch );
00148    }
00149 
00150    translate->run_elts( translate,
00151                         elts, 
00152                         count,
00153                         verts );
00154 
00155    /* Edgeflags are hard to fit into a translate program, populate
00156     * them separately if required.  In the setup above they are
00157     * defaulted to one, so only need this if there is reason to change
00158     * that default:
00159     */
00160    if (fetch->need_edgeflags) {
00161       for (i = 0; i < count; i++) {
00162          struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
00163          vh->edgeflag = draw_pt_get_edgeflag( draw, elts[i] );
00164       }
00165    }
00166 }
00167 
00168 
00169 void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
00170                                unsigned start,
00171                                unsigned count,
00172                                char *verts )
00173 {
00174    struct draw_context *draw = fetch->draw;
00175    struct translate *translate = fetch->translate;
00176    unsigned i;
00177 
00178    for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
00179       translate->set_buffer(translate,
00180                             i,
00181                             ((char *)draw->pt.user.vbuffer[i] +
00182                              draw->pt.vertex_buffer[i].buffer_offset),
00183                             draw->pt.vertex_buffer[i].pitch );
00184    }
00185 
00186    translate->run( translate,
00187                    start,
00188                    count,
00189                    verts );
00190 
00191    /* Edgeflags are hard to fit into a translate program, populate
00192     * them separately if required.  In the setup above they are
00193     * defaulted to one, so only need this if there is reason to change
00194     * that default:
00195     */
00196    if (fetch->need_edgeflags) {
00197       for (i = 0; i < count; i++) {
00198          struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
00199          vh->edgeflag = draw_pt_get_edgeflag( draw, start + i );
00200       }
00201    }
00202 }
00203 
00204 
00205 struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw )
00206 {
00207    struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch);
00208    if (!fetch)
00209       return NULL;
00210 
00211    fetch->draw = draw;
00212    fetch->cache = translate_cache_create();
00213    if (!fetch->cache) {
00214       FREE(fetch);
00215       return NULL;
00216    }
00217 
00218    return fetch;
00219 }
00220 
00221 void draw_pt_fetch_destroy( struct pt_fetch *fetch )
00222 {
00223    if (fetch->cache)
00224       translate_cache_destroy(fetch->cache);
00225 
00226    FREE(fetch);
00227 }
00228 

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4