1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#ifndef SVGA_DRAW_H_ 27bf215546Sopenharmony_ci#define SVGA_DRAW_H_ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "pipe/p_compiler.h" 30bf215546Sopenharmony_ci#include "pipe/p_defines.h" 31bf215546Sopenharmony_ci#include "indices/u_indices.h" 32bf215546Sopenharmony_ci#include "util/u_prim.h" 33bf215546Sopenharmony_ci#include "svga_context.h" 34bf215546Sopenharmony_ci#include "svga_hw_reg.h" 35bf215546Sopenharmony_ci#include "svga3d_shaderdefs.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistruct svga_context; 38bf215546Sopenharmony_cistruct u_upload_mgr; 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci/** 41bf215546Sopenharmony_ci * Mask indicating which types of gallium primitives are actually 42bf215546Sopenharmony_ci * handled by the svga device. Other types will be converted to 43bf215546Sopenharmony_ci * these types by the index/translation code. 44bf215546Sopenharmony_ci */ 45bf215546Sopenharmony_cistatic const unsigned svga_hw_prims = 46bf215546Sopenharmony_ci ((1 << PIPE_PRIM_POINTS) | 47bf215546Sopenharmony_ci (1 << PIPE_PRIM_LINES) | 48bf215546Sopenharmony_ci (1 << PIPE_PRIM_LINE_STRIP) | 49bf215546Sopenharmony_ci (1 << PIPE_PRIM_TRIANGLES) | 50bf215546Sopenharmony_ci (1 << PIPE_PRIM_TRIANGLE_STRIP) | 51bf215546Sopenharmony_ci (1 << PIPE_PRIM_TRIANGLE_FAN) | 52bf215546Sopenharmony_ci (1 << PIPE_PRIM_LINES_ADJACENCY) | 53bf215546Sopenharmony_ci (1 << PIPE_PRIM_LINE_STRIP_ADJACENCY) | 54bf215546Sopenharmony_ci (1 << PIPE_PRIM_TRIANGLES_ADJACENCY) | 55bf215546Sopenharmony_ci (1 << PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY) | 56bf215546Sopenharmony_ci (1 << PIPE_PRIM_PATCHES)); 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci/** 60bf215546Sopenharmony_ci * Translate a gallium PIPE_PRIM_x value to an SVGA3D_PRIMITIVE_x value. 61bf215546Sopenharmony_ci * Also, compute the number of primitives that'll be drawn given a 62bf215546Sopenharmony_ci * vertex count. 63bf215546Sopenharmony_ci * Note that this function doesn't have to handle PIPE_PRIM_LINE_LOOP, 64bf215546Sopenharmony_ci * PIPE_PRIM_QUADS, PIPE_PRIM_QUAD_STRIP or PIPE_PRIM_POLYGON. We convert 65bf215546Sopenharmony_ci * those to other types of primitives with index/translation code. 66bf215546Sopenharmony_ci */ 67bf215546Sopenharmony_cistatic inline SVGA3dPrimitiveType 68bf215546Sopenharmony_cisvga_translate_prim(unsigned mode, unsigned vcount, unsigned *prim_count, 69bf215546Sopenharmony_ci ubyte vertices_per_patch) 70bf215546Sopenharmony_ci{ 71bf215546Sopenharmony_ci switch (mode) { 72bf215546Sopenharmony_ci case PIPE_PRIM_POINTS: 73bf215546Sopenharmony_ci *prim_count = vcount; 74bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_POINTLIST; 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci case PIPE_PRIM_LINES: 77bf215546Sopenharmony_ci *prim_count = vcount / 2; 78bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_LINELIST; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci case PIPE_PRIM_LINE_STRIP: 81bf215546Sopenharmony_ci *prim_count = vcount - 1; 82bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_LINESTRIP; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLES: 85bf215546Sopenharmony_ci *prim_count = vcount / 3; 86bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_TRIANGLELIST; 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLE_STRIP: 89bf215546Sopenharmony_ci *prim_count = vcount - 2; 90bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_TRIANGLESTRIP; 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLE_FAN: 93bf215546Sopenharmony_ci *prim_count = vcount - 2; 94bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_TRIANGLEFAN; 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_ci case PIPE_PRIM_LINES_ADJACENCY: 97bf215546Sopenharmony_ci *prim_count = vcount / 4; 98bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_LINELIST_ADJ; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci case PIPE_PRIM_LINE_STRIP_ADJACENCY: 101bf215546Sopenharmony_ci *prim_count = vcount - 3; 102bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_LINESTRIP_ADJ; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLES_ADJACENCY: 105bf215546Sopenharmony_ci *prim_count = vcount / 6; 106bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_TRIANGLELIST_ADJ; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: 109bf215546Sopenharmony_ci *prim_count = vcount / 2 - 2 ; 110bf215546Sopenharmony_ci return SVGA3D_PRIMITIVE_TRIANGLESTRIP_ADJ; 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci case PIPE_PRIM_PATCHES: 113bf215546Sopenharmony_ci *prim_count = vcount / vertices_per_patch ; 114bf215546Sopenharmony_ci assert(vertices_per_patch >= 1); 115bf215546Sopenharmony_ci assert(vertices_per_patch <= 32); 116bf215546Sopenharmony_ci return (SVGA3D_PRIMITIVE_1_CONTROL_POINT_PATCH - 1) 117bf215546Sopenharmony_ci + vertices_per_patch; 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci default: 120bf215546Sopenharmony_ci assert(0); 121bf215546Sopenharmony_ci *prim_count = 0; 122bf215546Sopenharmony_ci return 0; 123bf215546Sopenharmony_ci } 124bf215546Sopenharmony_ci} 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_cistruct index_cache { 128bf215546Sopenharmony_ci u_generate_func generate; 129bf215546Sopenharmony_ci unsigned gen_nr; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci /* If non-null, this buffer is filled by calling generate(nr, map(buffer)) 132bf215546Sopenharmony_ci */ 133bf215546Sopenharmony_ci struct pipe_resource *buffer; 134bf215546Sopenharmony_ci}; 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci/** Max number of primitives per draw call */ 138bf215546Sopenharmony_ci#define QSZ SVGA3D_MAX_DRAW_PRIMITIVE_RANGES 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_cistruct draw_cmd { 141bf215546Sopenharmony_ci struct svga_winsys_context *swc; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci /* vertex layout info */ 144bf215546Sopenharmony_ci SVGA3dVertexDecl vdecl[SVGA3D_INPUTREG_MAX]; 145bf215546Sopenharmony_ci unsigned vdecl_count; 146bf215546Sopenharmony_ci SVGA3dElementLayoutId vdecl_layout_id; 147bf215546Sopenharmony_ci unsigned vdecl_buffer_index[SVGA3D_INPUTREG_MAX]; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci /* vertex buffer info */ 150bf215546Sopenharmony_ci struct pipe_vertex_buffer vbufs[SVGA3D_INPUTREG_MAX]; 151bf215546Sopenharmony_ci unsigned vbuf_count; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci SVGA3dPrimitiveRange prim[QSZ]; 154bf215546Sopenharmony_ci struct pipe_resource *prim_ib[QSZ]; 155bf215546Sopenharmony_ci unsigned prim_count; /**< number of primitives for this draw */ 156bf215546Sopenharmony_ci unsigned min_index[QSZ]; 157bf215546Sopenharmony_ci unsigned max_index[QSZ]; 158bf215546Sopenharmony_ci}; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci#define IDX_CACHE_MAX 8 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_cistruct svga_hwtnl { 163bf215546Sopenharmony_ci struct svga_context *svga; 164bf215546Sopenharmony_ci struct u_upload_mgr *upload_ib; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci /* Additional negative index bias due to partial buffer uploads 167bf215546Sopenharmony_ci * This is compensated for in the offset associated with all 168bf215546Sopenharmony_ci * vertex buffers. 169bf215546Sopenharmony_ci */ 170bf215546Sopenharmony_ci int index_bias; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci /* Provoking vertex information (for flat shading). */ 173bf215546Sopenharmony_ci unsigned api_pv; /**< app-requested PV mode (PV_FIRST or PV_LAST) */ 174bf215546Sopenharmony_ci unsigned hw_pv; /**< device-supported PV mode (PV_FIRST or PV_LAST) */ 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci /* The triangle fillmode for the device (one of PIPE_POLYGON_MODE_{FILL, 177bf215546Sopenharmony_ci * LINE,POINT}). If the polygon front mode matches the back mode, 178bf215546Sopenharmony_ci * api_fillmode will be that mode. Otherwise, api_fillmode will be 179bf215546Sopenharmony_ci * PIPE_POLYGON_MODE_FILL. 180bf215546Sopenharmony_ci */ 181bf215546Sopenharmony_ci unsigned api_fillmode; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci /* Cache the results of running a particular generate func on each 184bf215546Sopenharmony_ci * primitive type. 185bf215546Sopenharmony_ci */ 186bf215546Sopenharmony_ci struct index_cache index_cache[PIPE_PRIM_MAX][IDX_CACHE_MAX]; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci /* Try to build the maximal draw command packet before emitting: 189bf215546Sopenharmony_ci */ 190bf215546Sopenharmony_ci struct draw_cmd cmd; 191bf215546Sopenharmony_ci}; 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci/** 196bf215546Sopenharmony_ci * Do we need to use the gallium 'indices' helper to render unfilled 197bf215546Sopenharmony_ci * triangles? 198bf215546Sopenharmony_ci */ 199bf215546Sopenharmony_cistatic inline boolean 200bf215546Sopenharmony_cisvga_need_unfilled_fallback(const struct svga_hwtnl *hwtnl, 201bf215546Sopenharmony_ci enum pipe_prim_type prim) 202bf215546Sopenharmony_ci{ 203bf215546Sopenharmony_ci if (u_reduced_prim(prim) != PIPE_PRIM_TRIANGLES) { 204bf215546Sopenharmony_ci /* if we're drawing points or lines, no fallback needed */ 205bf215546Sopenharmony_ci return FALSE; 206bf215546Sopenharmony_ci } 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci if ((prim == PIPE_PRIM_QUADS || 209bf215546Sopenharmony_ci prim == PIPE_PRIM_QUAD_STRIP || 210bf215546Sopenharmony_ci prim == PIPE_PRIM_POLYGON) && 211bf215546Sopenharmony_ci hwtnl->api_fillmode == PIPE_POLYGON_MODE_LINE) { 212bf215546Sopenharmony_ci /* We can't directly render quads or polygons. They're 213bf215546Sopenharmony_ci * converted to triangles. If we let the device draw the triangle 214bf215546Sopenharmony_ci * outlines we'll get an extra, stray lines in the interiors. 215bf215546Sopenharmony_ci * So, to draw unfilled quads correctly, we need the fallback. 216bf215546Sopenharmony_ci */ 217bf215546Sopenharmony_ci return true; 218bf215546Sopenharmony_ci } 219bf215546Sopenharmony_ci return false; 220bf215546Sopenharmony_ci} 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_cienum pipe_error 224bf215546Sopenharmony_cisvga_hwtnl_prim(struct svga_hwtnl *hwtnl, 225bf215546Sopenharmony_ci const SVGA3dPrimitiveRange *range, 226bf215546Sopenharmony_ci unsigned vcount, 227bf215546Sopenharmony_ci unsigned min_index, 228bf215546Sopenharmony_ci unsigned max_index, 229bf215546Sopenharmony_ci struct pipe_resource *ib, 230bf215546Sopenharmony_ci unsigned start_instance, unsigned instance_count, 231bf215546Sopenharmony_ci const struct pipe_draw_indirect_info *indirect, 232bf215546Sopenharmony_ci const struct pipe_stream_output_target *so_vertex_count); 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_cienum pipe_error 235bf215546Sopenharmony_cisvga_hwtnl_simple_draw_range_elements(struct svga_hwtnl *hwtnl, 236bf215546Sopenharmony_ci struct pipe_resource *indexBuffer, 237bf215546Sopenharmony_ci unsigned index_size, 238bf215546Sopenharmony_ci int index_bias, 239bf215546Sopenharmony_ci unsigned min_index, 240bf215546Sopenharmony_ci unsigned max_index, 241bf215546Sopenharmony_ci enum pipe_prim_type prim, 242bf215546Sopenharmony_ci unsigned start, 243bf215546Sopenharmony_ci unsigned count, 244bf215546Sopenharmony_ci unsigned start_instance, 245bf215546Sopenharmony_ci unsigned instance_count, 246bf215546Sopenharmony_ci ubyte vertices_per_patch); 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci#endif 249