draw_context.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 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  /*
00029   * Authors:
00030   *   Keith Whitwell <keith@tungstengraphics.com>
00031   */
00032 
00033 
00034 #include "util/u_memory.h"
00035 #include "util/u_math.h"
00036 #include "draw_context.h"
00037 #include "draw_vbuf.h"
00038 #include "draw_vs.h"
00039 #include "draw_pt.h"
00040 #include "draw_pipe.h"
00041 
00042 
00043 struct draw_context *draw_create( void )
00044 {
00045    struct draw_context *draw = CALLOC_STRUCT( draw_context );
00046    if (draw == NULL)
00047       goto fail;
00048 
00049    ASSIGN_4V( draw->plane[0], -1,  0,  0, 1 );
00050    ASSIGN_4V( draw->plane[1],  1,  0,  0, 1 );
00051    ASSIGN_4V( draw->plane[2],  0, -1,  0, 1 );
00052    ASSIGN_4V( draw->plane[3],  0,  1,  0, 1 );
00053    ASSIGN_4V( draw->plane[4],  0,  0,  1, 1 ); /* yes these are correct */
00054    ASSIGN_4V( draw->plane[5],  0,  0, -1, 1 ); /* mesa's a bit wonky */
00055    draw->nr_planes = 6;
00056 
00057 
00058    draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */
00059 
00060 
00061    if (!draw_pipeline_init( draw ))
00062       goto fail;
00063 
00064    if (!draw_pt_init( draw ))
00065       goto fail;
00066 
00067    if (!draw_vs_init( draw ))
00068       goto fail;
00069 
00070    return draw;
00071 
00072 fail:
00073    draw_destroy( draw );   
00074    return NULL;
00075 }
00076 
00077 
00078 void draw_destroy( struct draw_context *draw )
00079 {
00080    if (!draw)
00081       return;
00082 
00083 
00084 
00085    /* Not so fast -- we're just borrowing this at the moment.
00086     * 
00087    if (draw->render)
00088       draw->render->destroy( draw->render );
00089    */
00090 
00091    draw_pipeline_destroy( draw );
00092    draw_pt_destroy( draw );
00093    draw_vs_destroy( draw );
00094 
00095    FREE( draw );
00096 }
00097 
00098 
00099 
00100 void draw_flush( struct draw_context *draw )
00101 {
00102    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
00103 }
00104 
00105 
00113 void draw_set_mrd(struct draw_context *draw, double mrd)
00114 {
00115    draw->mrd = mrd;
00116 }
00117 
00118 
00123 void draw_set_rasterizer_state( struct draw_context *draw,
00124                                 const struct pipe_rasterizer_state *raster )
00125 {
00126    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00127 
00128    draw->rasterizer = raster;
00129    draw->bypass_clipping =
00130       ((draw->rasterizer && draw->rasterizer->bypass_clipping) ||
00131        draw->driver.bypass_clipping);
00132 }
00133 
00134 
00135 void draw_set_driver_clipping( struct draw_context *draw,
00136                                boolean bypass_clipping )
00137 {
00138    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00139 
00140    draw->driver.bypass_clipping = bypass_clipping;
00141    draw->bypass_clipping = (draw->rasterizer->bypass_clipping || 
00142                             draw->driver.bypass_clipping);
00143 }
00144 
00145 
00151 void draw_set_rasterize_stage( struct draw_context *draw,
00152                                struct draw_stage *stage )
00153 {
00154    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00155 
00156    draw->pipeline.rasterize = stage;
00157 }
00158 
00159 
00163 void draw_set_clip_state( struct draw_context *draw,
00164                           const struct pipe_clip_state *clip )
00165 {
00166    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00167 
00168    assert(clip->nr <= PIPE_MAX_CLIP_PLANES);
00169    memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
00170    draw->nr_planes = 6 + clip->nr;
00171 }
00172 
00173 
00177 void draw_set_viewport_state( struct draw_context *draw,
00178                               const struct pipe_viewport_state *viewport )
00179 {
00180    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00181    draw->viewport = *viewport; /* struct copy */
00182    draw->identity_viewport = (viewport->scale[0] == 1.0f &&
00183                               viewport->scale[1] == 1.0f &&
00184                               viewport->scale[2] == 1.0f &&
00185                               viewport->scale[3] == 1.0f &&
00186                               viewport->translate[0] == 0.0f &&
00187                               viewport->translate[1] == 0.0f &&
00188                               viewport->translate[2] == 0.0f &&
00189                               viewport->translate[3] == 0.0f);
00190 
00191    draw_vs_set_viewport( draw, viewport );
00192 }
00193 
00194 
00195 
00196 void
00197 draw_set_vertex_buffers(struct draw_context *draw,
00198                         unsigned count,
00199                         const struct pipe_vertex_buffer *buffers)
00200 {
00201    assert(count <= PIPE_MAX_ATTRIBS);
00202 
00203    memcpy(draw->pt.vertex_buffer, buffers, count * sizeof(buffers[0]));
00204    draw->pt.nr_vertex_buffers = count;
00205 }
00206 
00207 
00208 void
00209 draw_set_vertex_elements(struct draw_context *draw,
00210                          unsigned count,
00211                          const struct pipe_vertex_element *elements)
00212 {
00213    assert(count <= PIPE_MAX_ATTRIBS);
00214 
00215    memcpy(draw->pt.vertex_element, elements, count * sizeof(elements[0]));
00216    draw->pt.nr_vertex_elements = count;
00217 }
00218 
00219 
00223 void
00224 draw_set_mapped_vertex_buffer(struct draw_context *draw,
00225                               unsigned attr, const void *buffer)
00226 {
00227    draw->pt.user.vbuffer[attr] = buffer;
00228 }
00229 
00230 
00231 void
00232 draw_set_mapped_constant_buffer(struct draw_context *draw,
00233                                 const void *buffer, 
00234                                 unsigned size )
00235 {
00236    draw->pt.user.constants = buffer;
00237    draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
00238 }
00239 
00240 
00245 void
00246 draw_wide_point_threshold(struct draw_context *draw, float threshold)
00247 {
00248    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00249    draw->pipeline.wide_point_threshold = threshold;
00250 }
00251 
00252 
00257 void
00258 draw_wide_line_threshold(struct draw_context *draw, float threshold)
00259 {
00260    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00261    draw->pipeline.wide_line_threshold = threshold;
00262 }
00263 
00264 
00268 void
00269 draw_enable_line_stipple(struct draw_context *draw, boolean enable)
00270 {
00271    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00272    draw->pipeline.line_stipple = enable;
00273 }
00274 
00275 
00279 void
00280 draw_enable_point_sprites(struct draw_context *draw, boolean enable)
00281 {
00282    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00283    draw->pipeline.point_sprite = enable;
00284 }
00285 
00286 
00287 void
00288 draw_set_force_passthrough( struct draw_context *draw, boolean enable )
00289 {
00290    draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00291    draw->force_passthrough = enable;
00292 }
00293 
00294 
00310 int
00311 draw_find_vs_output(const struct draw_context *draw,
00312                     uint semantic_name, uint semantic_index)
00313 {
00314    const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
00315    uint i;
00316    for (i = 0; i < vs->info.num_outputs; i++) {
00317       if (vs->info.output_semantic_name[i] == semantic_name &&
00318           vs->info.output_semantic_index[i] == semantic_index)
00319          return i;
00320    }
00321 
00322    /* XXX there may be more than one extra vertex attrib.
00323     * For example, simulated gl_FragCoord and gl_PointCoord.
00324     */
00325    if (draw->extra_vp_outputs.semantic_name == semantic_name &&
00326        draw->extra_vp_outputs.semantic_index == semantic_index) {
00327       return draw->extra_vp_outputs.slot;
00328    }
00329    return 0;
00330 }
00331 
00332 
00336 uint
00337 draw_num_vs_outputs(const struct draw_context *draw)
00338 {
00339    uint count = draw->vs.vertex_shader->info.num_outputs;
00340    if (draw->extra_vp_outputs.slot > 0)
00341       count++;
00342    return count;
00343 }
00344 
00345 
00346 
00347 void draw_set_render( struct draw_context *draw, 
00348                       struct vbuf_render *render )
00349 {
00350    draw->render = render;
00351 }
00352 
00353 void draw_set_edgeflags( struct draw_context *draw,
00354                          const unsigned *edgeflag )
00355 {
00356    draw->pt.user.edgeflag = edgeflag;
00357 }
00358 
00359 
00360 
00361 
00372 void
00373 draw_set_mapped_element_buffer_range( struct draw_context *draw,
00374                                       unsigned eltSize,
00375                                       unsigned min_index,
00376                                       unsigned max_index,
00377                                       const void *elements )
00378 {
00379    draw->pt.user.elts = elements;
00380    draw->pt.user.eltSize = eltSize;
00381    draw->pt.user.min_index = min_index;
00382    draw->pt.user.max_index = max_index;
00383 }
00384 
00385 
00386 void
00387 draw_set_mapped_element_buffer( struct draw_context *draw,
00388                                 unsigned eltSize,
00389                                 const void *elements )
00390 {
00391    draw->pt.user.elts = elements;
00392    draw->pt.user.eltSize = eltSize;
00393    draw->pt.user.min_index = 0;
00394    draw->pt.user.max_index = 0xffffffff;
00395 }
00396 
00397  
00398 /* Revamp me please:
00399  */
00400 void draw_do_flush( struct draw_context *draw, unsigned flags )
00401 {
00402    if (!draw->suspend_flushing)
00403    {
00404       assert(!draw->flushing); /* catch inadvertant recursion */
00405 
00406       draw->flushing = TRUE;
00407 
00408       draw_pipeline_flush( draw, flags );
00409 
00410       draw->reduced_prim = ~0; /* is reduced_prim needed any more? */
00411       
00412       draw->flushing = FALSE;
00413    }
00414 }

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