enum pipe_error svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl, unsigned prim, unsigned start, unsigned count) { unsigned gen_prim, gen_size, gen_nr, gen_type; u_generate_func gen_func; enum pipe_error ret = PIPE_OK; if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL && prim >= PIPE_PRIM_TRIANGLES) { gen_type = u_unfilled_generator( prim, start, count, hwtnl->api_fillmode, &gen_prim, &gen_size, &gen_nr, &gen_func ); } else { gen_type = u_index_generator( svga_hw_prims, prim, start, count, hwtnl->api_pv, hwtnl->hw_pv, &gen_prim, &gen_size, &gen_nr, &gen_func ); } if (gen_type == U_GENERATE_LINEAR) { return simple_draw_arrays( hwtnl, gen_prim, start, count ); } else { struct pipe_buffer *gen_buf = NULL; /* Need to draw as indexed primitive. * Potentially need to run the gen func to build an index buffer. */ ret = retrieve_or_generate_indices( hwtnl, prim, gen_type, gen_nr, gen_size, gen_func, &gen_buf ); if (ret) goto done; ret = svga_hwtnl_simple_draw_range_elements( hwtnl, gen_buf, gen_size, 0, count - 1, gen_prim, 0, gen_nr, start ); if (ret) goto done; done: if (gen_buf) pipe_buffer_reference( &gen_buf, NULL ); return ret; } }
enum pipe_error svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl, unsigned prim, unsigned start, unsigned count) { unsigned gen_prim, gen_size, gen_nr, gen_type; u_generate_func gen_func; enum pipe_error ret = PIPE_OK; if (hwtnl->api_fillmode != PIPE_POLYGON_MODE_FILL && prim >= PIPE_PRIM_TRIANGLES) { /* Convert unfilled polygons into points, lines, triangles */ gen_type = u_unfilled_generator( prim, start, count, hwtnl->api_fillmode, &gen_prim, &gen_size, &gen_nr, &gen_func ); } else { /* Convert PIPE_PRIM_LINE_LOOP to PIPE_PRIM_LINESTRIP, * convert PIPE_PRIM_POLYGON to PIPE_PRIM_TRIANGLE_FAN, * etc, if needed (as determined by svga_hw_prims mask). */ gen_type = u_index_generator( svga_hw_prims, prim, start, count, hwtnl->api_pv, hwtnl->hw_pv, &gen_prim, &gen_size, &gen_nr, &gen_func ); } if (gen_type == U_GENERATE_LINEAR) { return simple_draw_arrays( hwtnl, gen_prim, start, count ); } else { struct pipe_resource *gen_buf = NULL; /* Need to draw as indexed primitive. * Potentially need to run the gen func to build an index buffer. */ ret = retrieve_or_generate_indices( hwtnl, prim, gen_type, gen_nr, gen_size, gen_func, &gen_buf ); if (ret != PIPE_OK) goto done; ret = svga_hwtnl_simple_draw_range_elements( hwtnl, gen_buf, gen_size, start, 0, count - 1, gen_prim, 0, gen_nr ); if (ret != PIPE_OK) goto done; done: if (gen_buf) pipe_resource_reference( &gen_buf, NULL ); return ret; } }
enum pipe_error svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl, enum pipe_prim_type prim, unsigned start, unsigned count, unsigned start_instance, unsigned instance_count) { enum pipe_prim_type gen_prim; unsigned gen_size, gen_nr; enum indices_mode gen_type; u_generate_func gen_func; enum pipe_error ret = PIPE_OK; unsigned api_pv = hwtnl->api_pv; struct svga_context *svga = hwtnl->svga; if (svga->curr.rast->templ.fill_front != svga->curr.rast->templ.fill_back) { assert(hwtnl->api_fillmode == PIPE_POLYGON_MODE_FILL); } if (svga->curr.rast->templ.flatshade && svga->state.hw_draw.fs->constant_color_output) { /* The fragment color is a constant, not per-vertex so the whole * primitive will be the same color (except for possible blending). * We can ignore the current provoking vertex state and use whatever * the hardware wants. */ api_pv = hwtnl->hw_pv; if (hwtnl->api_fillmode == PIPE_POLYGON_MODE_FILL) { /* Do some simple primitive conversions to avoid index buffer * generation below. Note that polygons and quads are not directly * supported by the svga device. Also note, we can only do this * for flat/constant-colored rendering because of provoking vertex. */ if (prim == PIPE_PRIM_POLYGON) { prim = PIPE_PRIM_TRIANGLE_FAN; } else if (prim == PIPE_PRIM_QUADS && count == 4) { prim = PIPE_PRIM_TRIANGLE_FAN; } } } if (svga_need_unfilled_fallback(hwtnl, prim)) { /* Convert unfilled polygons into points, lines, triangles */ gen_type = u_unfilled_generator(prim, start, count, hwtnl->api_fillmode, &gen_prim, &gen_size, &gen_nr, &gen_func); } else { /* Convert PIPE_PRIM_LINE_LOOP to PIPE_PRIM_LINESTRIP, * convert PIPE_PRIM_POLYGON to PIPE_PRIM_TRIANGLE_FAN, * etc, if needed (as determined by svga_hw_prims mask). */ gen_type = u_index_generator(svga_hw_prims, prim, start, count, api_pv, hwtnl->hw_pv, &gen_prim, &gen_size, &gen_nr, &gen_func); } if (gen_type == U_GENERATE_LINEAR) { return simple_draw_arrays(hwtnl, gen_prim, start, count, start_instance, instance_count); } else { struct pipe_resource *gen_buf = NULL; /* Need to draw as indexed primitive. * Potentially need to run the gen func to build an index buffer. */ ret = retrieve_or_generate_indices(hwtnl, prim, gen_type, gen_nr, gen_size, gen_func, &gen_buf); if (ret != PIPE_OK) goto done; pipe_debug_message(&svga->debug.callback, PERF_INFO, "generating temporary index buffer for drawing %s", u_prim_name(prim)); ret = svga_hwtnl_simple_draw_range_elements(hwtnl, gen_buf, gen_size, start, 0, count - 1, gen_prim, 0, gen_nr, start_instance, instance_count); if (ret != PIPE_OK) goto done; done: if (gen_buf) pipe_resource_reference(&gen_buf, NULL); return ret; } }