X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_draw.c;h=a5e93186bf5e0f74a62d8ce87680b5cd8efe4cf7;hb=3dd299c3d5b88114894ec30d1fac85fba688201f;hp=15c5b80f2912108ba325854fbcbb358f6e21c351;hpb=94506e56424970f30861baf2808020609d752b00;p=mesa.git diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 15c5b80f291..a5e93186bf5 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -36,6 +36,7 @@ */ +#include "main/errors.h" #include "main/imports.h" #include "main/image.h" #include "main/bufferobj.h" @@ -54,9 +55,11 @@ #include "st_debug.h" #include "st_draw.h" #include "st_program.h" +#include "st_util.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "util/u_cpu_detect.h" #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_prim.h" @@ -65,25 +68,13 @@ #include "draw/draw_context.h" #include "cso_cache/cso_context.h" - -/** - * This is very similar to vbo_all_varyings_in_vbos() but we are - * only interested in per-vertex data. See bug 38626. - */ -static GLboolean -all_varyings_in_vbos(const struct gl_vertex_array *arrays[]) -{ - GLuint i; - - for (i = 0; i < VERT_ATTRIB_MAX; i++) - if (arrays[i]->StrideB && - !arrays[i]->InstanceDivisor && - !_mesa_is_bufferobj(arrays[i]->BufferObj)) - return GL_FALSE; - - return GL_TRUE; -} - +#if defined(PIPE_OS_LINUX) && !defined(ANDROID) +#include +#define HAVE_SCHED_GETCPU 1 +#else +#define sched_getcpu() 0 +#define HAVE_SCHED_GETCPU 0 +#endif /** * Set the restart index. @@ -98,7 +89,7 @@ setup_primitive_restart(struct gl_context *ctx, struct pipe_draw_info *info) _mesa_primitive_restart_index(ctx, index_size); /* Enable primitive restart only when the restart index can have an - * effect. This is required for correctness in radeonsi VI support. + * effect. This is required for correctness in radeonsi GFX8 support. * Other hardware may also benefit from taking a faster, non-restart path * when possible. */ @@ -140,12 +131,38 @@ prepare_draw(struct st_context *st, struct gl_context *ctx) st->gfx_shaders_may_be_dirty) { st_validate_state(st, ST_PIPELINE_RENDER); } + + struct pipe_context *pipe = st->pipe; + + /* Pin threads regularly to the same Zen CCX that the main thread is + * running on. The main thread can move between CCXs. + */ + if (unlikely(HAVE_SCHED_GETCPU && /* Linux */ + /* AMD Zen */ + util_cpu_caps.nr_cpus != util_cpu_caps.cores_per_L3 && + /* no glthread */ + ctx->CurrentClientDispatch != ctx->MarshalExec && + /* driver support */ + pipe->set_context_param && + /* do it occasionally */ + ++st->pin_thread_counter % 512 == 0)) { + int cpu = sched_getcpu(); + if (cpu >= 0) { + unsigned L3_cache = cpu / util_cpu_caps.cores_per_L3; + + pipe->set_context_param(pipe, + PIPE_CONTEXT_PARAM_PIN_THREADS_TO_L3_CACHE, + L3_cache); + } + } } /** * This function gets plugged into the VBO module and is called when * we have something to render. * Basically, translate the information into the format expected by gallium. + * + * Try to keep this logic in sync with st_feedback_draw_vbo. */ static void st_draw_vbo(struct gl_context *ctx, @@ -161,29 +178,26 @@ st_draw_vbo(struct gl_context *ctx, { struct st_context *st = st_context(ctx); struct pipe_draw_info info; - const struct gl_vertex_array **arrays = ctx->Array._DrawArrays; unsigned i; unsigned start = 0; prepare_draw(st, ctx); - if (st->vertex_array_out_of_memory) - return; - /* Initialize pipe_draw_info. */ info.primitive_restart = false; info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.indirect = NULL; info.count_from_stream_output = NULL; + info.restart_index = 0; if (ib) { struct gl_buffer_object *bufobj = ib->obj; /* Get index bounds for user buffers. */ - if (!index_bounds_valid) - if (!all_varyings_in_vbos(arrays)) - vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, - nr_prims); + if (!index_bounds_valid && st->draw_needs_minmax_index) { + vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, + nr_prims); + } info.index_size = ib->index_size; info.min_index = min_index; @@ -193,6 +207,13 @@ st_draw_vbo(struct gl_context *ctx, /* indices are in a real VBO */ info.has_user_indices = false; info.index.resource = st_buffer_object(bufobj)->buffer; + + /* Return if the bound element array buffer doesn't have any backing + * storage. (nothing to do) + */ + if (!info.index.resource) + return; + start = pointer_to_offset(ib->ptr) / info.index_size; } else { /* indices are in user space memory */ @@ -204,6 +225,7 @@ st_draw_vbo(struct gl_context *ctx, } else { info.index_size = 0; + info.has_user_indices = false; /* Transform feedback drawing is always non-indexed. */ /* Set info.count_from_stream_output. */ @@ -217,9 +239,14 @@ st_draw_vbo(struct gl_context *ctx, /* do actual drawing */ for (i = 0; i < nr_prims; i++) { + info.count = prims[i].count; + + /* Skip no-op draw calls. */ + if (!info.count && !tfb_vertcount) + continue; + info.mode = translate_prim(ctx, prims[i].mode); info.start = start + prims[i].start; - info.count = prims[i].count; info.start_instance = prims[i].base_instance; info.instance_count = prims[i].num_instances; info.index_bias = prims[i].basevertex; @@ -249,8 +276,8 @@ st_indirect_draw_vbo(struct gl_context *ctx, GLsizeiptr indirect_offset, unsigned draw_count, unsigned stride, - struct gl_buffer_object *indirect_params, - GLsizeiptr indirect_params_offset, + struct gl_buffer_object *indirect_draw_count, + GLsizeiptr indirect_draw_count_offset, const struct _mesa_index_buffer *ib) { struct st_context *st = st_context(ctx); @@ -260,12 +287,10 @@ st_indirect_draw_vbo(struct gl_context *ctx, assert(stride); prepare_draw(st, ctx); - if (st->vertex_array_out_of_memory) - return; - memset(&indirect, 0, sizeof(indirect)); util_draw_init_info(&info); info.start = 0; /* index offset / index size */ + info.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */ if (ib) { struct gl_buffer_object *bufobj = ib->obj; @@ -297,7 +322,7 @@ st_indirect_draw_vbo(struct gl_context *ctx, if (!st->has_multi_draw_indirect) { int i; - assert(!indirect_params); + assert(!indirect_draw_count); indirect.draw_count = 1; for (i = 0; i < draw_count; i++) { info.drawid = i; @@ -307,9 +332,10 @@ st_indirect_draw_vbo(struct gl_context *ctx, } else { indirect.draw_count = draw_count; indirect.stride = stride; - if (indirect_params) { - indirect.indirect_draw_count = st_buffer_object(indirect_params)->buffer; - indirect.indirect_draw_count_offset = indirect_params_offset; + if (indirect_draw_count) { + indirect.indirect_draw_count = + st_buffer_object(indirect_draw_count)->buffer; + indirect.indirect_draw_count_offset = indirect_draw_count_offset; } cso_draw_vbo(st->cso_context, &info); } @@ -317,12 +343,10 @@ st_indirect_draw_vbo(struct gl_context *ctx, void -st_init_draw(struct st_context *st) +st_init_draw_functions(struct dd_function_table *functions) { - struct gl_context *ctx = st->ctx; - - vbo_set_draw_func(ctx, st_draw_vbo); - vbo_set_indirect_draw_func(ctx, st_indirect_draw_vbo); + functions->Draw = st_draw_vbo; + functions->DrawIndirect = st_indirect_draw_vbo; } @@ -426,15 +450,7 @@ st_draw_quad(struct st_context *st, u_upload_unmap(st->pipe->stream_uploader); - /* At the time of writing, cso_get_aux_vertex_buffer_slot() always returns - * zero. If that ever changes we need to audit the calls to that function - * and make sure the slot number is used consistently everywhere. - */ - assert(cso_get_aux_vertex_buffer_slot(st->cso_context) == 0); - - cso_set_vertex_buffers(st->cso_context, - cso_get_aux_vertex_buffer_slot(st->cso_context), - 1, &vb); + cso_set_vertex_buffers(st->cso_context, 0, 1, &vb); if (num_instances > 1) { cso_draw_arrays_instanced(st->cso_context, PIPE_PRIM_TRIANGLE_FAN, 0, 4,