1/************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 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 VMWARE 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/* 29 * Render unclipped vertex buffers by emitting vertices directly to 30 * dma buffers. Use strip/fan hardware acceleration where possible. 31 * 32 */ 33#include "main/glheader.h" 34#include "main/context.h" 35#include "main/macros.h" 36#include "main/mtypes.h" 37#include "main/enums.h" 38 39#include "math/m_xform.h" 40 41#include "tnl/t_context.h" 42#include "tnl/t_vertex.h" 43#include "tnl/t_pipeline.h" 44 45#include "intel_screen.h" 46#include "intel_context.h" 47#include "intel_tris.h" 48#include "intel_batchbuffer.h" 49#include "intel_reg.h" 50 51/* 52 * Render unclipped vertex buffers by emitting vertices directly to 53 * dma buffers. Use strip/fan hardware primitives where possible. 54 * Try to simulate missing primitives with indexed vertices. 55 */ 56#define HAVE_POINTS 1 57#define HAVE_LINES 1 58#define HAVE_LINE_STRIPS 1 59#define HAVE_TRIANGLES 1 60#define HAVE_TRI_STRIPS 1 61#define HAVE_TRI_FANS 1 62#define HAVE_POLYGONS 1 63 64#define HAVE_QUADS 0 65#define HAVE_QUAD_STRIPS 0 66#define HAVE_ELTS 0 67 68static const uint32_t hw_prim[GL_POLYGON + 1] = { 69 [GL_POINTS] = PRIM3D_POINTLIST, 70 [GL_LINES ] = PRIM3D_LINELIST, 71 [GL_LINE_LOOP] = PRIM3D_LINESTRIP, 72 [GL_LINE_STRIP] = PRIM3D_LINESTRIP, 73 [GL_TRIANGLES] = PRIM3D_TRILIST, 74 [GL_TRIANGLE_STRIP] = PRIM3D_TRISTRIP, 75 [GL_TRIANGLE_FAN] = PRIM3D_TRIFAN, 76 [GL_QUADS] = 0, 77 [GL_QUAD_STRIP] = 0, 78 [GL_POLYGON] = PRIM3D_POLY, 79}; 80 81static const GLenum reduced_prim[GL_POLYGON + 1] = { 82 [GL_POINTS] = GL_POINTS, 83 [GL_LINES] = GL_LINES, 84 [GL_LINE_LOOP] = GL_LINES, 85 [GL_LINE_STRIP] = GL_LINES, 86 [GL_TRIANGLES] = GL_TRIANGLES, 87 [GL_TRIANGLE_STRIP] = GL_TRIANGLES, 88 [GL_TRIANGLE_FAN] = GL_TRIANGLES, 89 [GL_QUADS] = GL_TRIANGLES, 90 [GL_QUAD_STRIP] = GL_TRIANGLES, 91 [GL_POLYGON] = GL_TRIANGLES, 92}; 93 94static const int scale_prim[GL_POLYGON + 1] = { 95 [GL_POINTS] = 1, 96 [GL_LINES] = 1, 97 [GL_LINE_LOOP] = 2, 98 [GL_LINE_STRIP] = 2, 99 [GL_TRIANGLES] = 1, 100 [GL_TRIANGLE_STRIP] = 3, 101 [GL_TRIANGLE_FAN] = 3, 102 [GL_QUADS] = 0, /* fallback case */ 103 [GL_QUAD_STRIP] = 0, /* fallback case */ 104 [GL_POLYGON] = 3, 105}; 106 107 108static void 109intelDmaPrimitive(struct intel_context *intel, GLenum prim) 110{ 111 if (0) 112 fprintf(stderr, "%s %s\n", __func__, _mesa_enum_to_string(prim)); 113 INTEL_FIREVERTICES(intel); 114 intel->vtbl.reduced_primitive_state(intel, reduced_prim[prim]); 115 intel_set_prim(intel, hw_prim[prim]); 116} 117 118#define INTEL_NO_VBO_STATE_RESERVED 1500 119 120static inline GLuint intel_get_vb_max(struct intel_context *intel) 121{ 122 GLuint ret; 123 124 if (intel->intelScreen->no_vbo) { 125 ret = intel->batch.bo->size - INTEL_NO_VBO_STATE_RESERVED; 126 } else 127 ret = INTEL_VB_SIZE; 128 ret /= (intel->vertex_size * 4); 129 return ret; 130} 131 132static inline GLuint intel_get_current_max(struct intel_context *intel) 133{ 134 GLuint ret; 135 136 if (intel->intelScreen->no_vbo) { 137 ret = intel_batchbuffer_space(intel); 138 ret = ret <= INTEL_NO_VBO_STATE_RESERVED ? 0 : ret - INTEL_NO_VBO_STATE_RESERVED; 139 } else 140 ret = (INTEL_VB_SIZE - intel->prim.current_offset); 141 142 return ret / (intel->vertex_size * 4); 143} 144 145#define LOCAL_VARS struct intel_context *intel = intel_context(ctx) 146#define INIT( prim ) \ 147do { \ 148 intelDmaPrimitive( intel, prim ); \ 149} while (0) 150 151#define FLUSH() INTEL_FIREVERTICES(intel) 152 153#define GET_SUBSEQUENT_VB_MAX_VERTS() intel_get_vb_max(intel) 154#define GET_CURRENT_VB_MAX_VERTS() intel_get_current_max(intel) 155 156#define ALLOC_VERTS(nr) intel_get_prim_space(intel, nr) 157 158#define EMIT_VERTS( ctx, j, nr, buf ) \ 159 _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf ) 160 161#define TAG(x) intel_##x 162#include "tnl_dd/t_dd_dmatmp.h" 163 164 165/**********************************************************************/ 166/* Render pipeline stage */ 167/**********************************************************************/ 168 169/* Heuristic to choose between the two render paths: 170 */ 171static bool 172choose_render(struct intel_context *intel, struct vertex_buffer *VB) 173{ 174 int vertsz = intel->vertex_size; 175 int cost_render = 0; 176 int cost_fallback = 0; 177 int nr_prims = 0; 178 int nr_rprims = 0; 179 int nr_rverts = 0; 180 int rprim = intel->reduced_primitive; 181 int i = 0; 182 183 for (i = 0; i < VB->PrimitiveCount; i++) { 184 GLuint prim = VB->Primitive[i].mode; 185 GLuint length = VB->Primitive[i].count; 186 187 if (!length) 188 continue; 189 190 nr_prims++; 191 nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK]; 192 193 if (reduced_prim[prim & PRIM_MODE_MASK] != rprim) { 194 nr_rprims++; 195 rprim = reduced_prim[prim & PRIM_MODE_MASK]; 196 } 197 } 198 199 /* One point for each generated primitive: 200 */ 201 cost_render = nr_prims; 202 cost_fallback = nr_rprims; 203 204 /* One point for every 1024 dwords (4k) of dma: 205 */ 206 cost_render += (vertsz * i) / 1024; 207 cost_fallback += (vertsz * nr_rverts) / 1024; 208 209 if (0) 210 fprintf(stderr, "cost render: %d fallback: %d\n", 211 cost_render, cost_fallback); 212 213 if (cost_render > cost_fallback) 214 return false; 215 216 return true; 217} 218 219 220static GLboolean 221intel_run_render(struct gl_context * ctx, struct tnl_pipeline_stage *stage) 222{ 223 struct intel_context *intel = intel_context(ctx); 224 TNLcontext *tnl = TNL_CONTEXT(ctx); 225 struct vertex_buffer *VB = &tnl->vb; 226 GLuint i; 227 228 intel->vtbl.render_prevalidate( intel ); 229 230 /* Don't handle clipping or indexed vertices. 231 */ 232 if (intel->RenderIndex != 0 || 233 !intel_validate_render(ctx, VB) || !choose_render(intel, VB)) { 234 return true; 235 } 236 237 tnl->clipspace.new_inputs |= VERT_BIT_POS; 238 239 tnl->Driver.Render.Start(ctx); 240 241 for (i = 0; i < VB->PrimitiveCount; i++) { 242 GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); 243 GLuint start = VB->Primitive[i].start; 244 GLuint length = VB->Primitive[i].count; 245 246 if (!length) 247 continue; 248 249 intel_render_tab_verts[prim & PRIM_MODE_MASK] (ctx, start, 250 length, prim); 251 } 252 253 tnl->Driver.Render.Finish(ctx); 254 255 INTEL_FIREVERTICES(intel); 256 257 return false; /* finished the pipe */ 258} 259 260static const struct tnl_pipeline_stage _intel_render_stage = { 261 "intel render", 262 NULL, 263 NULL, 264 NULL, 265 NULL, 266 intel_run_render /* run */ 267}; 268 269const struct tnl_pipeline_stage *intel_pipeline[] = { 270 &_tnl_vertex_transform_stage, 271 &_tnl_normal_transform_stage, 272 &_tnl_lighting_stage, 273 &_tnl_fog_coordinate_stage, 274 &_tnl_texgen_stage, 275 &_tnl_texture_transform_stage, 276 &_tnl_point_attenuation_stage, 277 &_tnl_vertex_program_stage, 278#if 1 279 &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */ 280#endif 281 &_tnl_render_stage, 282 0, 283}; 284