draw_pt_fetch_shade_pipeline.c revision c503e55d74cf84f87f82b3dab3cb4d38b201d47a
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "pipe/p_util.h" 29#include "draw/draw_context.h" 30#include "draw/draw_vbuf.h" 31#include "draw/draw_vertex.h" 32#include "draw/draw_pt.h" 33#include "draw/draw_vs.h" 34#include "translate/translate.h" 35 36 37struct fetch_pipeline_middle_end { 38 struct draw_pt_middle_end base; 39 struct draw_context *draw; 40 41 struct pt_emit *emit; 42 43 unsigned pipeline_vertex_size; 44 unsigned prim; 45 unsigned opt; 46}; 47 48 49static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, 50 unsigned prim, 51 unsigned opt ) 52{ 53 struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; 54 55 fpme->prim = prim; 56 fpme->opt = opt; 57 58 if (!(opt & PT_PIPELINE)) 59 draw_pt_emit_prepare( fpme->emit, prim, opt ); 60 61 //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float); 62 fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION; 63} 64 65 66 67 68static void fetch_pipeline_run( struct draw_pt_middle_end *middle, 69 const unsigned *fetch_elts, 70 unsigned fetch_count, 71 const ushort *draw_elts, 72 unsigned draw_count ) 73{ 74 struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle; 75 struct draw_context *draw = fpme->draw; 76 struct draw_vertex_shader *shader = draw->vertex_shader; 77 char *pipeline_verts; 78 unsigned pipeline = PT_PIPELINE; 79 80 pipeline_verts = MALLOC(fpme->pipeline_vertex_size * 81 fetch_count); 82 83 if (!pipeline_verts) { 84 assert(0); 85 return; 86 } 87 88 89 /* Shade 90 */ 91 shader->prepare(shader, draw); 92 93 if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts, 94 fpme->pipeline_vertex_size)) 95 { 96 pipeline |= PT_CLIPTEST; 97 } 98 99 100 /* Do we need to run the pipeline? 101 */ 102 if (fpme->opt & pipeline) { 103 draw_pt_run_pipeline( fpme->draw, 104 fpme->prim, 105 pipeline_verts, 106 fpme->pipeline_vertex_size, 107 fetch_count, 108 draw_elts, 109 draw_count ); 110 } else { 111 draw_pt_emit( fpme->emit, 112 pipeline_verts, 113 fpme->pipeline_vertex_size, 114 fetch_count, 115 draw_elts, 116 draw_count ); 117 } 118 119 120 FREE(pipeline_verts); 121} 122 123 124 125static void fetch_pipeline_finish( struct draw_pt_middle_end *middle ) 126{ 127 /* nothing to do */ 128} 129 130static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle ) 131{ 132 FREE(middle); 133} 134 135 136struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *draw ) 137{ 138 struct fetch_pipeline_middle_end *fpme = CALLOC_STRUCT( fetch_pipeline_middle_end ); 139 if (!fpme) 140 goto fail; 141 142 fpme->base.prepare = fetch_pipeline_prepare; 143 fpme->base.run = fetch_pipeline_run; 144 fpme->base.finish = fetch_pipeline_finish; 145 fpme->base.destroy = fetch_pipeline_destroy; 146 147 fpme->draw = draw; 148 149 fpme->emit = draw_pt_emit_create( draw ); 150 if (!fpme->emit) 151 goto fail; 152 153 return &fpme->base; 154 155 fail: 156 if (fpme) 157 fetch_pipeline_destroy( &fpme->base ); 158 159 return NULL; 160} 161