X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fsvga%2Fsvga_draw_private.h;h=52a2c0f18b357ac344af56f49c8bdbba8b416528;hb=40258fb8b83325bf208876babf779e7ea08a870c;hp=9aa40e16642d44acf823be6861394092fb1afcfb;hpb=3192633d4abe262d413e41feb871fe8deed409d8;p=mesa.git diff --git a/src/gallium/drivers/svga/svga_draw_private.h b/src/gallium/drivers/svga/svga_draw_private.h index 9aa40e16642..52a2c0f18b3 100644 --- a/src/gallium/drivers/svga/svga_draw_private.h +++ b/src/gallium/drivers/svga/svga_draw_private.h @@ -29,55 +29,87 @@ #include "pipe/p_compiler.h" #include "pipe/p_defines.h" #include "indices/u_indices.h" +#include "util/u_prim.h" +#include "svga_context.h" #include "svga_hw_reg.h" #include "svga3d_shaderdefs.h" struct svga_context; struct u_upload_mgr; -/* Should include polygon? +/** + * Mask indicating which types of gallium primitives are actually + * handled by the svga device. Other types will be converted to + * these types by the index/translation code. */ -static const unsigned svga_hw_prims = +static const unsigned svga_hw_prims = ((1 << PIPE_PRIM_POINTS) | (1 << PIPE_PRIM_LINES) | (1 << PIPE_PRIM_LINE_STRIP) | (1 << PIPE_PRIM_TRIANGLES) | (1 << PIPE_PRIM_TRIANGLE_STRIP) | - (1 << PIPE_PRIM_TRIANGLE_FAN)); - - -static INLINE unsigned svga_translate_prim(unsigned mode, - unsigned count, - unsigned *out_count) + (1 << PIPE_PRIM_TRIANGLE_FAN) | + (1 << PIPE_PRIM_LINES_ADJACENCY) | + (1 << PIPE_PRIM_LINE_STRIP_ADJACENCY) | + (1 << PIPE_PRIM_TRIANGLES_ADJACENCY) | + (1 << PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY)); + + +/** + * Translate a gallium PIPE_PRIM_x value to an SVGA3D_PRIMITIVE_x value. + * Also, compute the number of primitives that'll be drawn given a + * vertex count. + * Note that this function doesn't have to handle PIPE_PRIM_LINE_LOOP, + * PIPE_PRIM_QUADS, PIPE_PRIM_QUAD_STRIP or PIPE_PRIM_POLYGON. We convert + * those to other types of primitives with index/translation code. + */ +static inline SVGA3dPrimitiveType +svga_translate_prim(unsigned mode, unsigned vcount, unsigned *prim_count) { switch (mode) { case PIPE_PRIM_POINTS: - *out_count = count; + *prim_count = vcount; return SVGA3D_PRIMITIVE_POINTLIST; case PIPE_PRIM_LINES: - *out_count = count / 2; - return SVGA3D_PRIMITIVE_LINELIST; + *prim_count = vcount / 2; + return SVGA3D_PRIMITIVE_LINELIST; case PIPE_PRIM_LINE_STRIP: - *out_count = count - 1; - return SVGA3D_PRIMITIVE_LINESTRIP; + *prim_count = vcount - 1; + return SVGA3D_PRIMITIVE_LINESTRIP; case PIPE_PRIM_TRIANGLES: - *out_count = count / 3; - return SVGA3D_PRIMITIVE_TRIANGLELIST; + *prim_count = vcount / 3; + return SVGA3D_PRIMITIVE_TRIANGLELIST; case PIPE_PRIM_TRIANGLE_STRIP: - *out_count = count - 2; - return SVGA3D_PRIMITIVE_TRIANGLESTRIP; + *prim_count = vcount - 2; + return SVGA3D_PRIMITIVE_TRIANGLESTRIP; case PIPE_PRIM_TRIANGLE_FAN: - *out_count = count - 2; - return SVGA3D_PRIMITIVE_TRIANGLEFAN; + *prim_count = vcount - 2; + return SVGA3D_PRIMITIVE_TRIANGLEFAN; + + case PIPE_PRIM_LINES_ADJACENCY: + *prim_count = vcount / 4; + return SVGA3D_PRIMITIVE_LINELIST_ADJ; + + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + *prim_count = vcount - 3; + return SVGA3D_PRIMITIVE_LINESTRIP_ADJ; + + case PIPE_PRIM_TRIANGLES_ADJACENCY: + *prim_count = vcount / 6; + return SVGA3D_PRIMITIVE_TRIANGLELIST_ADJ; + + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + *prim_count = vcount / 2 - 2 ; + return SVGA3D_PRIMITIVE_TRIANGLESTRIP_ADJ; default: assert(0); - *out_count = 0; + *prim_count = 0; return 0; } } @@ -87,24 +119,31 @@ struct index_cache { u_generate_func generate; unsigned gen_nr; - /* If non-null, this buffer is filled by calling - * generate(nr, map(buffer)) + /* If non-null, this buffer is filled by calling generate(nr, map(buffer)) */ - struct pipe_buffer *buffer; + struct pipe_resource *buffer; }; -#define QSZ 32 + +/** Max number of primitives per draw call */ +#define QSZ SVGA3D_MAX_DRAW_PRIMITIVE_RANGES struct draw_cmd { struct svga_winsys_context *swc; + /* vertex layout info */ SVGA3dVertexDecl vdecl[SVGA3D_INPUTREG_MAX]; - struct pipe_buffer *vdecl_vb[SVGA3D_INPUTREG_MAX]; unsigned vdecl_count; + SVGA3dElementLayoutId vdecl_layout_id; + unsigned vdecl_buffer_index[SVGA3D_INPUTREG_MAX]; + + /* vertex buffer info */ + struct pipe_vertex_buffer vbufs[SVGA3D_INPUTREG_MAX]; + unsigned vbuf_count; SVGA3dPrimitiveRange prim[QSZ]; - struct pipe_buffer *prim_ib[QSZ]; - unsigned prim_count; + struct pipe_resource *prim_ib[QSZ]; + unsigned prim_count; /**< number of primitives for this draw */ unsigned min_index[QSZ]; unsigned max_index[QSZ]; }; @@ -114,11 +153,22 @@ struct draw_cmd { struct svga_hwtnl { struct svga_context *svga; struct u_upload_mgr *upload_ib; - - /* Flatshade information: + + /* Additional negative index bias due to partial buffer uploads + * This is compensated for in the offset associated with all + * vertex buffers. + */ + int index_bias; + + /* Provoking vertex information (for flat shading). */ + unsigned api_pv; /**< app-requested PV mode (PV_FIRST or PV_LAST) */ + unsigned hw_pv; /**< device-supported PV mode (PV_FIRST or PV_LAST) */ + + /* The triangle fillmode for the device (one of PIPE_POLYGON_MODE_{FILL, + * LINE,POINT}). If the polygon front mode matches the back mode, + * api_fillmode will be that mode. Otherwise, api_fillmode will be + * PIPE_POLYGON_MODE_FILL. */ - unsigned api_pv; - unsigned hw_pv; unsigned api_fillmode; /* Cache the results of running a particular generate func on each @@ -133,26 +183,54 @@ struct svga_hwtnl { -/*********************************************************************** - * Internal functions +/** + * Do we need to use the gallium 'indices' helper to render unfilled + * triangles? */ -enum pipe_error -svga_hwtnl_prim( struct svga_hwtnl *hwtnl, - const SVGA3dPrimitiveRange *range, - unsigned min_index, - unsigned max_index, - struct pipe_buffer *ib ); +static inline boolean +svga_need_unfilled_fallback(const struct svga_hwtnl *hwtnl, + enum pipe_prim_type prim) +{ + if (u_reduced_prim(prim) != PIPE_PRIM_TRIANGLES) { + /* if we're drawing points or lines, no fallback needed */ + return FALSE; + } + + if ((prim == PIPE_PRIM_QUADS || + prim == PIPE_PRIM_QUAD_STRIP || + prim == PIPE_PRIM_POLYGON) && + hwtnl->api_fillmode == PIPE_POLYGON_MODE_LINE) { + /* We can't directly render quads or polygons. They're + * converted to triangles. If we let the device draw the triangle + * outlines we'll get an extra, stray lines in the interiors. + * So, to draw unfilled quads correctly, we need the fallback. + */ + return true; + } + return false; +} + enum pipe_error -svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl, - struct pipe_buffer *indexBuffer, - unsigned index_size, - unsigned min_index, - unsigned max_index, - unsigned prim, - unsigned start, - unsigned count, - unsigned bias ); +svga_hwtnl_prim(struct svga_hwtnl *hwtnl, + const SVGA3dPrimitiveRange *range, + unsigned vcount, + unsigned min_index, + unsigned max_index, + struct pipe_resource *ib, + unsigned start_instance, unsigned instance_count); +enum pipe_error +svga_hwtnl_simple_draw_range_elements(struct svga_hwtnl *hwtnl, + struct pipe_resource *indexBuffer, + unsigned index_size, + int index_bias, + unsigned min_index, + unsigned max_index, + enum pipe_prim_type prim, + unsigned start, + unsigned count, + unsigned start_instance, + unsigned instance_count); #endif