From 10a46226b1ea157189120acc68ffad4abb728e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 13 Aug 2021 02:29:56 -0400 Subject: [PATCH] gallium: remove vertices_per_patch, add pipe_context::set_patch_vertices We would like draw-only display lists to have immutable draw info and this is the only GL non-draw state in pipe_draw_info (not counting view_mask). It also allows removing some code from draw_vbo for tessellation. Reviewed-By: Mike Blumenkrantz Part-of: --- docs/gallium/context.rst | 2 ++ src/gallium/auxiliary/draw/draw_context.h | 3 +- src/gallium/auxiliary/draw/draw_pt.c | 5 ++-- .../auxiliary/driver_ddebug/dd_context.c | 10 +++++++ .../auxiliary/driver_noop/noop_state.c | 6 ++++ .../auxiliary/driver_trace/tr_context.c | 15 ++++++++++ .../auxiliary/driver_trace/tr_dump_state.c | 2 -- src/gallium/auxiliary/util/u_dump_state.c | 2 -- .../auxiliary/util/u_threaded_context.c | 28 +++++++++++++++++-- .../auxiliary/util/u_threaded_context_calls.h | 1 + src/gallium/drivers/crocus/crocus_context.h | 1 + src/gallium/drivers/crocus/crocus_draw.c | 4 +-- src/gallium/drivers/crocus/crocus_state.c | 13 +++++++-- .../drivers/freedreno/a6xx/fd6_const.c | 4 +-- src/gallium/drivers/freedreno/a6xx/fd6_draw.c | 7 +++-- src/gallium/drivers/freedreno/a6xx/fd6_emit.h | 1 + .../drivers/freedreno/freedreno_context.h | 2 ++ .../drivers/freedreno/freedreno_program.c | 9 ++++++ src/gallium/drivers/i915/i915_context.c | 2 +- src/gallium/drivers/iris/iris_context.h | 1 + src/gallium/drivers/iris/iris_draw.c | 4 +-- src/gallium/drivers/iris/iris_state.c | 11 +++++++- src/gallium/drivers/llvmpipe/lp_context.h | 2 ++ src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 3 +- src/gallium/drivers/llvmpipe/lp_state_tess.c | 9 ++++++ src/gallium/drivers/nouveau/nv30/nv30_draw.c | 2 +- .../drivers/nouveau/nvc0/nvc0_context.h | 1 + src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 9 ++++++ src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 4 +-- src/gallium/drivers/r300/r300_render.c | 2 +- src/gallium/drivers/r600/evergreen_state.c | 14 ++++++++-- src/gallium/drivers/r600/r600_pipe.h | 1 + src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 8 ++++++ .../drivers/radeonsi/si_state_draw.cpp | 10 +++---- src/gallium/drivers/softpipe/sp_draw_arrays.c | 2 +- src/gallium/drivers/svga/svga_context.h | 1 + src/gallium/drivers/svga/svga_draw_elements.c | 4 +-- src/gallium/drivers/svga/svga_pipe_draw.c | 10 +++---- src/gallium/drivers/svga/svga_pipe_ts.c | 10 +++++++ src/gallium/drivers/svga/svga_swtnl_draw.c | 3 +- src/gallium/drivers/swr/swr_context.h | 1 + src/gallium/drivers/swr/swr_draw.cpp | 6 ++-- src/gallium/drivers/swr/swr_state.cpp | 12 +++++++- src/gallium/drivers/virgl/virgl_context.c | 8 ++++++ src/gallium/drivers/virgl/virgl_context.h | 1 + src/gallium/drivers/virgl/virgl_encode.c | 2 +- src/gallium/drivers/zink/zink_context.c | 8 ++++++ src/gallium/drivers/zink/zink_draw.cpp | 4 +-- src/gallium/drivers/zink/zink_pipeline.h | 2 ++ src/gallium/frontends/lavapipe/lvp_execute.c | 12 ++++++-- src/gallium/include/pipe/p_context.h | 5 ++++ src/gallium/include/pipe/p_state.h | 6 ++-- src/mesa/drivers/dri/i965/brw_state_upload.c | 2 +- src/mesa/main/draw.c | 4 --- src/mesa/main/mtypes.h | 3 +- src/mesa/main/shaderapi.c | 21 ++++++++++---- src/mesa/state_tracker/st_atom_tess.c | 12 ++++---- src/mesa/state_tracker/st_context.c | 2 +- src/mesa/state_tracker/st_draw.c | 2 -- src/mesa/state_tracker/st_draw_feedback.c | 4 +-- src/mesa/vbo/vbo_exec_draw.c | 3 -- src/mesa/vbo/vbo_save_draw.c | 1 - 63 files changed, 266 insertions(+), 84 deletions(-) diff --git a/docs/gallium/context.rst b/docs/gallium/context.rst index e9332edfd71..6b35a981d9b 100644 --- a/docs/gallium/context.rst +++ b/docs/gallium/context.rst @@ -118,6 +118,8 @@ objects. They all follow simple, one-method binding calls, e.g. levels. This corresponds to GL's ``PATCH_DEFAULT_OUTER_LEVEL``. * ``default_inner_level`` is the default value for the inner tessellation levels. This corresponds to GL's ``PATCH_DEFAULT_INNER_LEVEL``. +* ``set_patch_vertices`` sets the number of vertices per input patch + for tessellation. * ``set_debug_callback`` sets the callback to be used for reporting various debug messages, eventually reported via KHR_debug and diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 1069954c9ef..ab10c60e1ef 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -328,7 +328,8 @@ void draw_vbo(struct draw_context *draw, unsigned drawid_offset, const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count_bias *draws, - unsigned num_draws); + unsigned num_draws, + uint8_t patch_vertices); /******************************************************************************* diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 80084bc7724..f1821878ba6 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -498,7 +498,8 @@ draw_vbo(struct draw_context *draw, unsigned drawid_offset, const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count_bias *draws, - unsigned num_draws) + unsigned num_draws, + uint8_t patch_vertices) { unsigned index_limit; unsigned fpstate = util_fpstate_get(); @@ -532,7 +533,7 @@ draw_vbo(struct draw_context *draw, draw->pt.user.drawid = drawid_offset; draw->pt.user.increment_draw_id = use_info->increment_draw_id; draw->pt.user.viewid = 0; - draw->pt.vertices_per_patch = use_info->vertices_per_patch; + draw->pt.vertices_per_patch = patch_vertices; if (0) { for (unsigned i = 0; i < num_draws; i++) diff --git a/src/gallium/auxiliary/driver_ddebug/dd_context.c b/src/gallium/auxiliary/driver_ddebug/dd_context.c index 2b2d5929d7b..53b68a3529c 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_context.c +++ b/src/gallium/auxiliary/driver_ddebug/dd_context.c @@ -411,6 +411,15 @@ static void dd_context_set_tess_state(struct pipe_context *_pipe, pipe->set_tess_state(pipe, default_outer_level, default_inner_level); } +static void dd_context_set_patch_vertices(struct pipe_context *_pipe, + uint8_t patch_vertices) +{ + struct dd_context *dctx = dd_context(_pipe); + struct pipe_context *pipe = dctx->pipe; + + pipe->set_patch_vertices(pipe, patch_vertices); +} + static void dd_context_set_window_rectangles(struct pipe_context *_pipe, bool include, unsigned num_rectangles, @@ -904,6 +913,7 @@ dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe) CTX_INIT(set_viewport_states); CTX_INIT(set_sampler_views); CTX_INIT(set_tess_state); + CTX_INIT(set_patch_vertices); CTX_INIT(set_shader_buffers); CTX_INIT(set_shader_images); CTX_INIT(set_vertex_buffers); diff --git a/src/gallium/auxiliary/driver_noop/noop_state.c b/src/gallium/auxiliary/driver_noop/noop_state.c index 6cd366666c0..f3313cd805c 100644 --- a/src/gallium/auxiliary/driver_noop/noop_state.c +++ b/src/gallium/auxiliary/driver_noop/noop_state.c @@ -397,6 +397,11 @@ static void noop_make_image_handle_resident(struct pipe_context *ctx, uint64_t h { } +static void noop_set_patch_vertices(struct pipe_context *ctx, + uint8_t patch_vertices) +{ +} + void noop_init_state_functions(struct pipe_context *ctx); void noop_init_state_functions(struct pipe_context *ctx) @@ -477,4 +482,5 @@ void noop_init_state_functions(struct pipe_context *ctx) ctx->create_image_handle = noop_create_image_handle; ctx->delete_image_handle = noop_delete_image_handle; ctx->make_image_handle_resident = noop_make_image_handle_resident; + ctx->set_patch_vertices = noop_set_patch_vertices; } diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c index a03e72a642b..0f3b6cd79d7 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.c +++ b/src/gallium/auxiliary/driver_trace/tr_context.c @@ -1951,6 +1951,20 @@ trace_context_set_tess_state(struct pipe_context *_context, context->set_tess_state(context, default_outer_level, default_inner_level); } +static void +trace_context_set_patch_vertices(struct pipe_context *_context, + uint8_t patch_vertices) +{ + struct trace_context *tr_context = trace_context(_context); + struct pipe_context *context = tr_context->pipe; + + trace_dump_call_begin("pipe_context", "set_patch_vertices"); + trace_dump_arg(ptr, context); + trace_dump_arg(uint, patch_vertices); + trace_dump_call_end(); + + context->set_patch_vertices(context, patch_vertices); +} static void trace_context_set_shader_buffers(struct pipe_context *_context, enum pipe_shader_type shader, @@ -2229,6 +2243,7 @@ trace_context_create(struct trace_screen *tr_scr, TR_CTX_INIT(memory_barrier); TR_CTX_INIT(resource_commit); TR_CTX_INIT(set_tess_state); + TR_CTX_INIT(set_patch_vertices); TR_CTX_INIT(set_shader_buffers); TR_CTX_INIT(launch_grid); TR_CTX_INIT(set_shader_images); diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.c b/src/gallium/auxiliary/driver_trace/tr_dump_state.c index 65d9a0acc1d..1af57f70a5f 100644 --- a/src/gallium/auxiliary/driver_trace/tr_dump_state.c +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.c @@ -820,8 +820,6 @@ void trace_dump_draw_info(const struct pipe_draw_info *state) trace_dump_member(uint, state, start_instance); trace_dump_member(uint, state, instance_count); - trace_dump_member(uint, state, vertices_per_patch); - trace_dump_member(uint, state, min_index); trace_dump_member(uint, state, max_index); diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c index 85a4d010274..f0bca16805a 100644 --- a/src/gallium/auxiliary/util/u_dump_state.c +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -913,8 +913,6 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) util_dump_member(stream, uint, state, start_instance); util_dump_member(stream, uint, state, instance_count); - util_dump_member(stream, uint, state, vertices_per_patch); - util_dump_member(stream, uint, state, min_index); util_dump_member(stream, uint, state, max_index); diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 6615c453cfb..cfdd1280d57 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -1081,6 +1081,29 @@ tc_set_tess_state(struct pipe_context *_pipe, memcpy(p + 4, default_inner_level, 2 * sizeof(float)); } +struct tc_patch_vertices { + struct tc_call_base base; + ubyte patch_vertices; +}; + +static uint16_t +tc_call_set_patch_vertices(struct pipe_context *pipe, void *call, uint64_t *last) +{ + uint8_t patch_vertices = to_call(call, tc_patch_vertices)->patch_vertices; + + pipe->set_patch_vertices(pipe, patch_vertices); + return call_size(tc_patch_vertices); +} + +static void +tc_set_patch_vertices(struct pipe_context *_pipe, uint8_t patch_vertices) +{ + struct threaded_context *tc = threaded_context(_pipe); + + tc_add_call(tc, TC_CALL_set_patch_vertices, + tc_patch_vertices)->patch_vertices = patch_vertices; +} + struct tc_constant_buffer_base { struct tc_call_base base; ubyte shader, index; @@ -2911,13 +2934,11 @@ simplify_draw_info(struct pipe_draw_info *info) info->index_bounds_valid = false; info->take_index_buffer_ownership = false; info->index_bias_varies = false; + info->_pad = 0; /* This shouldn't be set when merging single draws. */ info->increment_draw_id = false; - if (info->mode != PIPE_PRIM_PATCHES) - info->vertices_per_patch = 0; - if (info->index_size) { if (!info->primitive_restart) info->restart_index = 0; @@ -4148,6 +4169,7 @@ threaded_context_create(struct pipe_context *pipe, CTX_INIT(set_window_rectangles); CTX_INIT(set_sampler_views); CTX_INIT(set_tess_state); + CTX_INIT(set_patch_vertices); CTX_INIT(set_shader_buffers); CTX_INIT(set_shader_images); CTX_INIT(set_vertex_buffers); diff --git a/src/gallium/auxiliary/util/u_threaded_context_calls.h b/src/gallium/auxiliary/util/u_threaded_context_calls.h index 7174d3ab941..a425852211c 100644 --- a/src/gallium/auxiliary/util/u_threaded_context_calls.h +++ b/src/gallium/auxiliary/util/u_threaded_context_calls.h @@ -10,6 +10,7 @@ CALL(render_condition) CALL(bind_sampler_states) CALL(set_framebuffer_state) CALL(set_tess_state) +CALL(set_patch_vertices) CALL(set_constant_buffer) CALL(set_inlinable_constants) CALL(set_sample_locations) diff --git a/src/gallium/drivers/crocus/crocus_context.h b/src/gallium/drivers/crocus/crocus_context.h index 15b41079ce1..f83170b0bb9 100644 --- a/src/gallium/drivers/crocus/crocus_context.h +++ b/src/gallium/drivers/crocus/crocus_context.h @@ -590,6 +590,7 @@ struct crocus_context { enum pipe_prim_type prim_mode:8; bool prim_is_points_or_lines; uint8_t vertices_per_patch; + uint8_t patch_vertices; bool window_space_position; diff --git a/src/gallium/drivers/crocus/crocus_draw.c b/src/gallium/drivers/crocus/crocus_draw.c index feef4e78ecf..c3b12a7d8ae 100644 --- a/src/gallium/drivers/crocus/crocus_draw.c +++ b/src/gallium/drivers/crocus/crocus_draw.c @@ -159,8 +159,8 @@ crocus_update_draw_info(struct crocus_context *ice, } if (info->mode == PIPE_PRIM_PATCHES && - ice->state.vertices_per_patch != info->vertices_per_patch) { - ice->state.vertices_per_patch = info->vertices_per_patch; + ice->state.vertices_per_patch != ice->state.patch_vertices) { + ice->state.vertices_per_patch = ice->state.patch_vertices; if (screen->devinfo.ver == 8) ice->state.dirty |= CROCUS_DIRTY_GEN8_VF_TOPOLOGY; diff --git a/src/gallium/drivers/crocus/crocus_state.c b/src/gallium/drivers/crocus/crocus_state.c index ed99e77b7e5..b2327f1979c 100644 --- a/src/gallium/drivers/crocus/crocus_state.c +++ b/src/gallium/drivers/crocus/crocus_state.c @@ -3203,6 +3203,14 @@ crocus_set_tess_state(struct pipe_context *ctx, shs->sysvals_need_upload = true; } +static void +crocus_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertices) +{ + struct crocus_context *ice = (struct crocus_context *) ctx; + + ice->state.patch_vertices = patch_vertices; +} + static void crocus_surface_destroy(struct pipe_context *ctx, struct pipe_surface *p_surf) { @@ -7498,7 +7506,7 @@ crocus_upload_dirty_render_state(struct crocus_context *ice, if (dirty & CROCUS_DIRTY_GEN8_VF_TOPOLOGY) { crocus_emit_cmd(batch, GENX(3DSTATE_VF_TOPOLOGY), topo) { topo.PrimitiveTopologyType = - translate_prim_type(draw->mode, draw->vertices_per_patch); + translate_prim_type(draw->mode, ice->state.patch_vertices); } } #endif @@ -7965,7 +7973,7 @@ crocus_upload_render_state(struct crocus_context *ice, prim.PredicateEnable = use_predicate; #endif - prim.PrimitiveTopologyType = translate_prim_type(ice->state.prim_mode, draw->vertices_per_patch); + prim.PrimitiveTopologyType = translate_prim_type(ice->state.prim_mode, ice->state.patch_vertices); if (indirect) { // XXX Probably have to do something for gen6 here? #if GFX_VER >= 7 @@ -9214,6 +9222,7 @@ genX(crocus_init_state)(struct crocus_context *ice) ctx->set_shader_images = crocus_set_shader_images; ctx->set_sampler_views = crocus_set_sampler_views; ctx->set_tess_state = crocus_set_tess_state; + ctx->set_patch_vertices = crocus_set_patch_vertices; ctx->set_framebuffer_state = crocus_set_framebuffer_state; ctx->set_polygon_stipple = crocus_set_polygon_stipple; ctx->set_sample_mask = crocus_set_sample_mask; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_const.c b/src/gallium/drivers/freedreno/a6xx/fd6_const.c index b30b4415588..dc8343f8814 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_const.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_const.c @@ -148,7 +148,7 @@ fd6_build_tess_consts(struct fd6_emit *emit) * size is dwords, since that's what LDG/STG use. */ unsigned num_vertices = emit->hs - ? emit->info->vertices_per_patch + ? emit->patch_vertices : emit->gs->shader->nir->info.gs.vertices_in; uint32_t vs_params[4] = { @@ -162,7 +162,7 @@ fd6_build_tess_consts(struct fd6_emit *emit) uint32_t hs_params[4] = { emit->vs->output_size * num_vertices * 4, /* vs primitive stride */ emit->vs->output_size * 4, /* vs vertex stride */ - emit->hs->output_size, emit->info->vertices_per_patch}; + emit->hs->output_size, emit->patch_vertices}; emit_stage_tess_consts(constobj, emit->hs, hs_params, ARRAY_SIZE(hs_params)); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index 466bbdd8cd3..1bc4478e9cf 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -161,6 +161,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable, .sprite_coord_mode = ctx->rasterizer->sprite_coord_mode, .primitive_restart = info->primitive_restart && info->index_size, + .patch_vertices = ctx->patch_vertices, }; if (!(ctx->prog.vs && ctx->prog.fs)) @@ -270,7 +271,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, unreachable("bad tessmode"); } - draw0.prim_type = DI_PT_PATCHES0 + info->vertices_per_patch; + draw0.prim_type = DI_PT_PATCHES0 + ctx->patch_vertices; draw0.tess_enable = true; const unsigned max_count = 2048; @@ -281,10 +282,10 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, * limit. But in the indirect-draw case we must assume the worst. */ if (indirect && indirect->buffer) { - count = ALIGN_NPOT(max_count, info->vertices_per_patch); + count = ALIGN_NPOT(max_count, ctx->patch_vertices); } else { count = MIN2(max_count, draw->count); - count = ALIGN_NPOT(count, info->vertices_per_patch); + count = ALIGN_NPOT(count, ctx->patch_vertices); } OUT_PKT7(ring, CP_SET_SUBDRAW_SIZE, 1); diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h index 5d54f8d8a1a..0c46d8a569c 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.h @@ -100,6 +100,7 @@ struct fd6_emit { bool sprite_coord_mode; bool rasterflat; bool primitive_restart; + uint8_t patch_vertices; /* cached to avoid repeated lookups: */ const struct fd6_program_state *prog; diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index ac0fce4429b..64b00447d20 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -250,6 +250,8 @@ struct fd_context { struct list_head acc_active_queries dt; /*@}*/ + uint8_t patch_vertices; + /* Whether we need to recheck the active_queries list next * fd_batch_update_queries(). */ diff --git a/src/gallium/drivers/freedreno/freedreno_program.c b/src/gallium/drivers/freedreno/freedreno_program.c index 4068edbc7a5..3a7963f0323 100644 --- a/src/gallium/drivers/freedreno/freedreno_program.c +++ b/src/gallium/drivers/freedreno/freedreno_program.c @@ -43,6 +43,14 @@ update_bound_stage(struct fd_context *ctx, enum pipe_shader_type shader, } } +static void +fd_set_patch_vertices(struct pipe_context *pctx, uint8_t patch_vertices) in_dt +{ + struct fd_context *ctx = fd_context(pctx); + + ctx->patch_vertices = patch_vertices; +} + static void fd_vs_state_bind(struct pipe_context *pctx, void *hwcso) in_dt { @@ -194,6 +202,7 @@ fd_prog_init(struct pipe_context *pctx) pctx->bind_tes_state = fd_tes_state_bind; pctx->bind_gs_state = fd_gs_state_bind; pctx->bind_fs_state = fd_fs_state_bind; + pctx->set_patch_vertices = fd_set_patch_vertices; ctx->solid_prog.fs = assemble_tgsi(pctx, solid_fs, true); ctx->solid_prog.vs = assemble_tgsi(pctx, solid_vs, false); diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index d86e036b732..1bbe2246fd7 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -113,7 +113,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, /* * Do the drawing */ - draw_vbo(i915->draw, info, drawid_offset, NULL, draws, num_draws); + draw_vbo(i915->draw, info, drawid_offset, NULL, draws, num_draws, 0); /* * unmap vertex/index buffers diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 60d2cd2fcfa..eb5e1ee787e 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -721,6 +721,7 @@ struct iris_context { /** Bitfield of which vertex buffers are bound (non-null). */ uint64_t bound_vertex_buffers; + uint8_t patch_vertices; bool primitive_restart; unsigned cut_index; enum pipe_prim_type prim_mode:8; diff --git a/src/gallium/drivers/iris/iris_draw.c b/src/gallium/drivers/iris/iris_draw.c index b12f7109231..2f76be17968 100644 --- a/src/gallium/drivers/iris/iris_draw.c +++ b/src/gallium/drivers/iris/iris_draw.c @@ -81,8 +81,8 @@ iris_update_draw_info(struct iris_context *ice, } if (info->mode == PIPE_PRIM_PATCHES && - ice->state.vertices_per_patch != info->vertices_per_patch) { - ice->state.vertices_per_patch = info->vertices_per_patch; + ice->state.vertices_per_patch != ice->state.patch_vertices) { + ice->state.vertices_per_patch = ice->state.patch_vertices; ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY; /* 8_PATCH TCS needs this for key->input_vertices */ diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 9c41d3697af..a2426c3352d 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -2912,6 +2912,14 @@ iris_set_tess_state(struct pipe_context *ctx, shs->sysvals_need_upload = true; } +static void +iris_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertices) +{ + struct iris_context *ice = (struct iris_context *) ctx; + + ice->state.patch_vertices = patch_vertices; +} + static void iris_surface_destroy(struct pipe_context *ctx, struct pipe_surface *p_surf) { @@ -6321,7 +6329,7 @@ iris_upload_dirty_render_state(struct iris_context *ice, if (dirty & IRIS_DIRTY_VF_TOPOLOGY) { iris_emit_cmd(batch, GENX(3DSTATE_VF_TOPOLOGY), topo) { topo.PrimitiveTopologyType = - translate_prim_type(draw->mode, draw->vertices_per_patch); + translate_prim_type(draw->mode, ice->state.vertices_per_patch); } } @@ -8095,6 +8103,7 @@ genX(init_state)(struct iris_context *ice) ctx->set_compute_resources = iris_set_compute_resources; ctx->set_global_binding = iris_set_global_binding; ctx->set_tess_state = iris_set_tess_state; + ctx->set_patch_vertices = iris_set_patch_vertices; ctx->set_framebuffer_state = iris_set_framebuffer_state; ctx->set_polygon_stipple = iris_set_polygon_stipple; ctx->set_sample_mask = iris_set_sample_mask; diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 22f177eee24..c42aeca80e8 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -117,6 +117,8 @@ struct llvmpipe_context { /** Vertex format */ struct vertex_info vertex_info; + + uint8_t patch_vertices; /** Which vertex shader output slot contains color */ int8_t color_slot[2]; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 33ab84f9507..48d112ac08c 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -146,7 +146,8 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, !lp->queries_disabled); /* draw! */ - draw_vbo(draw, info, drawid_offset, indirect, draws, num_draws); + draw_vbo(draw, info, drawid_offset, indirect, draws, num_draws, + lp->patch_vertices); /* * unmap vertex/index buffers diff --git a/src/gallium/drivers/llvmpipe/lp_state_tess.c b/src/gallium/drivers/llvmpipe/lp_state_tess.c index b9e919e76fc..28cc1258b7a 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_tess.c +++ b/src/gallium/drivers/llvmpipe/lp_state_tess.c @@ -181,6 +181,14 @@ llvmpipe_set_tess_state(struct pipe_context *pipe, draw_set_tess_state(llvmpipe->draw, default_outer_level, default_inner_level); } +static void +llvmpipe_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + llvmpipe->patch_vertices = patch_vertices; +} + void llvmpipe_init_tess_funcs(struct llvmpipe_context *llvmpipe) { @@ -193,4 +201,5 @@ llvmpipe_init_tess_funcs(struct llvmpipe_context *llvmpipe) llvmpipe->pipe.delete_tes_state = llvmpipe_delete_tes_state; llvmpipe->pipe.set_tess_state = llvmpipe_set_tess_state; + llvmpipe->pipe.set_patch_vertices = llvmpipe_set_patch_vertices; } diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c index a41778827b3..c1392cf7762 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c @@ -445,7 +445,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, draw_set_indexes(draw, NULL, 0, 0); } - draw_vbo(draw, info, drawid_offset, NULL, draw_one, 1); + draw_vbo(draw, info, drawid_offset, NULL, draw_one, 1, 0); draw_flush(draw); if (info->index_size && transferi) diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h index c6871dc5440..0ad06db7984 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h @@ -254,6 +254,7 @@ struct nvc0_context { float default_tess_outer[4]; float default_tess_inner[2]; + uint8_t patch_vertices; bool vbo_push_hint; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c index e0b43ec1623..13c4fc6a27b 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c @@ -1003,6 +1003,14 @@ nvc0_set_tess_state(struct pipe_context *pipe, nvc0->dirty_3d |= NVC0_NEW_3D_TESSFACTOR; } +static void +nvc0_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices) +{ + struct nvc0_context *nvc0 = nvc0_context(pipe); + + nvc0->patch_vertices = patch_vertices; +} + static void nvc0_set_vertex_buffers(struct pipe_context *pipe, unsigned start_slot, unsigned count, @@ -1499,6 +1507,7 @@ nvc0_init_state_functions(struct nvc0_context *nvc0) pipe->set_viewport_states = nvc0_set_viewport_states; pipe->set_window_rectangles = nvc0_set_window_rectangles; pipe->set_tess_state = nvc0_set_tess_state; + pipe->set_patch_vertices = nvc0_set_patch_vertices; pipe->create_vertex_elements_state = nvc0_vertex_state_create; pipe->delete_vertex_elements_state = nvc0_vertex_state_delete; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index 29bc9b28fac..ca6bfda6c11 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c @@ -977,8 +977,8 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, } if (info->mode == PIPE_PRIM_PATCHES && - nvc0->state.patch_vertices != info->vertices_per_patch) { - nvc0->state.patch_vertices = info->vertices_per_patch; + nvc0->state.patch_vertices != nvc0->patch_vertices) { + nvc0->state.patch_vertices = nvc0->patch_vertices; PUSH_SPACE(push, 1); IMMED_NVC0(push, NVC0_3D(PATCH_VERTICES), nvc0->state.patch_vertices); } diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 1c09e9ef64d..7d670892976 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -886,7 +886,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, r300_update_derived_state(r300); - draw_vbo(r300->draw, info, drawid_offset, NULL, &draw, 1); + draw_vbo(r300->draw, info, drawid_offset, NULL, &draw, 1, 0); draw_flush(r300->draw); } diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 83a521102af..9d9d40ae62f 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -3997,6 +3997,13 @@ static void evergreen_set_tess_state(struct pipe_context *ctx, rctx->driver_consts[PIPE_SHADER_TESS_CTRL].tcs_default_levels_dirty = true; } +static void evergreen_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertices) +{ + struct r600_context *rctx = (struct r600_context *)ctx; + + rctx->patch_vertices = patch_vertices; +} + static void evergreen_setup_immed_buffer(struct r600_context *rctx, struct r600_image_view *rview, enum pipe_format pformat) @@ -4489,6 +4496,7 @@ void evergreen_init_state_functions(struct r600_context *rctx) rctx->b.b.set_polygon_stipple = evergreen_set_polygon_stipple; rctx->b.b.set_min_samples = evergreen_set_min_samples; rctx->b.b.set_tess_state = evergreen_set_tess_state; + rctx->b.b.set_patch_vertices = evergreen_set_patch_vertices; rctx->b.b.set_hw_atomic_buffers = evergreen_set_hw_atomic_buffers; rctx->b.b.set_shader_images = evergreen_set_shader_images; rctx->b.b.set_shader_buffers = evergreen_set_shader_buffers; @@ -4524,7 +4532,7 @@ void evergreen_setup_tess_constants(struct r600_context *rctx, const struct pipe struct pipe_constant_buffer constbuf = {0}; struct r600_pipe_shader_selector *tcs = rctx->tcs_shader ? rctx->tcs_shader : rctx->tes_shader; struct r600_pipe_shader_selector *ls = rctx->vs_shader; - unsigned num_tcs_input_cp = info->vertices_per_patch; + unsigned num_tcs_input_cp = rctx->patch_vertices; unsigned num_tcs_outputs; unsigned num_tcs_output_cp; unsigned num_tcs_patch_outputs; @@ -4624,10 +4632,10 @@ uint32_t evergreen_get_ls_hs_config(struct r600_context *rctx, num_output_cp = rctx->tcs_shader ? rctx->tcs_shader->info.properties[TGSI_PROPERTY_TCS_VERTICES_OUT] : - info->vertices_per_patch; + rctx->patch_vertices; return S_028B58_NUM_PATCHES(num_patches) | - S_028B58_HS_NUM_INPUT_CP(info->vertices_per_patch) | + S_028B58_HS_NUM_INPUT_CP(rctx->patch_vertices) | S_028B58_HS_NUM_OUTPUT_CP(num_output_cp); } diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 3cb171a0d53..60e4ef3e00d 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -614,6 +614,7 @@ struct r600_context { struct r600_resource *trace_buf; unsigned trace_id; + uint8_t patch_vertices; bool cmd_buf_is_compute; struct pipe_resource *append_fence; uint32_t append_fence_id; diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 17f42bd7ee8..9eb434f9f4c 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1074,6 +1074,7 @@ struct si_context { bool compute_image_sgprs_dirty; bool vs_uses_base_instance; bool vs_uses_draw_id; + uint8_t patch_vertices; /* shader descriptors */ struct si_descriptors descriptors[SI_NUM_DESCS]; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index db7252e9fad..d50d04bdf39 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -5003,6 +5003,13 @@ static void si_set_tess_state(struct pipe_context *ctx, const float default_oute si_set_internal_const_buffer(sctx, SI_HS_CONST_DEFAULT_TESS_LEVELS, &cb); } +static void si_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertices) +{ + struct si_context *sctx = (struct si_context *)ctx; + + sctx->patch_vertices = patch_vertices; +} + static void si_texture_barrier(struct pipe_context *ctx, unsigned flags) { struct si_context *sctx = (struct si_context *)ctx; @@ -5132,6 +5139,7 @@ void si_init_state_functions(struct si_context *sctx) sctx->b.texture_barrier = si_texture_barrier; sctx->b.set_min_samples = si_set_min_samples; sctx->b.set_tess_state = si_set_tess_state; + sctx->b.set_patch_vertices = si_set_patch_vertices; sctx->b.set_active_query_state = si_set_active_query_state; } diff --git a/src/gallium/drivers/radeonsi/si_state_draw.cpp b/src/gallium/drivers/radeonsi/si_state_draw.cpp index 4fc81ab1811..0bfb8f66db2 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.cpp +++ b/src/gallium/drivers/radeonsi/si_state_draw.cpp @@ -1593,7 +1593,7 @@ static void si_emit_all_states(struct si_context *sctx, const struct pipe_draw_i si_emit_rasterizer_prim_state(sctx); if (HAS_TESS) - si_emit_derived_tess_state(sctx, info->vertices_per_patch, &num_patches); + si_emit_derived_tess_state(sctx, sctx->patch_vertices, &num_patches); /* Emit state atoms. */ unsigned mask = sctx->dirty_atoms & ~skip_atom_mask; @@ -1625,8 +1625,8 @@ static void si_emit_all_states(struct si_context *sctx, const struct pipe_draw_i /* Emit draw states. */ si_emit_vs_state(sctx, info->index_size); si_emit_draw_registers - (sctx, indirect, prim, num_patches, instance_count, info->vertices_per_patch, - primitive_restart, info->restart_index, min_vertex_count); + (sctx, indirect, prim, num_patches, instance_count, sctx->patch_vertices, primitive_restart, + info->restart_index, min_vertex_count); } static bool si_all_vs_resources_read_only(struct si_context *sctx, struct pipe_resource *indexbuf) @@ -1764,7 +1764,7 @@ static void si_draw_vbo(struct pipe_context *ctx, /* The rarely occuring tcs == NULL case is not optimized. */ bool same_patch_vertices = GFX_VERSION >= GFX9 && - tcs && info->vertices_per_patch == tcs->info.base.tess.tcs_vertices_out; + tcs && sctx->patch_vertices == tcs->info.base.tess.tcs_vertices_out; if (sctx->same_patch_vertices != same_patch_vertices) { sctx->same_patch_vertices = same_patch_vertices; @@ -1780,7 +1780,7 @@ static void si_draw_vbo(struct pipe_context *ctx, * function TCS. */ bool ls_vgpr_fix = - tcs && info->vertices_per_patch > tcs->info.base.tess.tcs_vertices_out; + tcs && sctx->patch_vertices > tcs->info.base.tess.tcs_vertices_out; if (ls_vgpr_fix != sctx->ls_vgpr_fix) { sctx->ls_vgpr_fix = ls_vgpr_fix; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 6a5f34703a3..f73131f95bc 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -141,7 +141,7 @@ softpipe_draw_vbo(struct pipe_context *pipe, sp->active_statistics_queries > 0); /* draw! */ - draw_vbo(draw, info, drawid_offset, indirect, draws, num_draws); + draw_vbo(draw, info, drawid_offset, indirect, draws, num_draws, 0); /* unmap vertex/index buffers - will cause draw module to flush */ for (i = 0; i < sp->num_vertex_buffers; i++) { diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 578e1794a48..d5ef4c3455b 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -655,6 +655,7 @@ struct svga_context boolean render_condition; boolean disable_rasterizer; /* Set if to disable rasterization */ + uint8_t patch_vertices; struct { struct svga_tcs_shader *passthrough_tcs; diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c index fa165da2675..225edf06c9f 100644 --- a/src/gallium/drivers/svga/svga_draw_elements.c +++ b/src/gallium/drivers/svga/svga_draw_elements.c @@ -284,7 +284,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl, gen_prim, index_offset, count, info->start_instance, info->instance_count, - info->vertices_per_patch); + hwtnl->svga->patch_vertices); pipe_resource_reference(&index_buffer, NULL); } else { @@ -313,7 +313,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl, gen_nr, info->start_instance, info->instance_count, - info->vertices_per_patch); + hwtnl->svga->patch_vertices); } if (gen_buf) { diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index f1c6276fc76..745fdad64a4 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -102,7 +102,7 @@ retry_draw_auto(struct svga_context *svga, unsigned hw_count; range.primType = svga_translate_prim(info->mode, 12, &hw_count, - info->vertices_per_patch); + svga->patch_vertices); range.primitiveCount = 0; range.indexArray.surfaceId = SVGA3D_INVALID_ID; range.indexArray.offset = 0; @@ -151,7 +151,7 @@ retry_draw_indirect(struct svga_context *svga, unsigned hw_count; range.primType = svga_translate_prim(info->mode, 12, &hw_count, - info->vertices_per_patch); + svga->patch_vertices); range.primitiveCount = 0; /* specified in indirect buffer */ range.indexArray.surfaceId = SVGA3D_INVALID_ID; range.indexArray.offset = 0; @@ -269,8 +269,8 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, svga->dirty |= SVGA_NEW_VS_CONSTS; } - if (svga->curr.vertices_per_patch != info->vertices_per_patch) { - svga->curr.vertices_per_patch = info->vertices_per_patch; + if (svga->curr.vertices_per_patch != svga->patch_vertices) { + svga->curr.vertices_per_patch = svga->patch_vertices; /* If input patch size changes, we need to notifiy the TCS * code to reevaluate the shader variant since the @@ -369,7 +369,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, else { ret = retry_draw_arrays(svga, info->mode, draws[0].start, count, info->start_instance, info->instance_count, - info->vertices_per_patch); + svga->patch_vertices); } } diff --git a/src/gallium/drivers/svga/svga_pipe_ts.c b/src/gallium/drivers/svga/svga_pipe_ts.c index 12a3bf486b7..e0318ae7b1e 100644 --- a/src/gallium/drivers/svga/svga_pipe_ts.c +++ b/src/gallium/drivers/svga/svga_pipe_ts.c @@ -47,6 +47,15 @@ svga_set_tess_state(struct pipe_context *pipe, } +static void +svga_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices) +{ + struct svga_context *svga = svga_context(pipe); + + svga->patch_vertices = patch_vertices; +} + + static void * svga_create_tcs_state(struct pipe_context *pipe, const struct pipe_shader_state *templ) @@ -210,6 +219,7 @@ void svga_init_ts_functions(struct svga_context *svga) { svga->pipe.set_tess_state = svga_set_tess_state; + svga->pipe.set_patch_vertices = svga_set_patch_vertices; svga->pipe.create_tcs_state = svga_create_tcs_state; svga->pipe.bind_tcs_state = svga_bind_tcs_state; svga->pipe.delete_tcs_state = svga_delete_tcs_state; diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c index 11d9724c7e8..da2d5f46121 100644 --- a/src/gallium/drivers/svga/svga_swtnl_draw.c +++ b/src/gallium/drivers/svga/svga_swtnl_draw.c @@ -115,7 +115,8 @@ svga_swtnl_draw_vbo(struct svga_context *svga, svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer->width0); } - draw_vbo(draw, info, drawid_offset, indirect, draw_one, 1); + draw_vbo(draw, info, drawid_offset, indirect, draw_one, 1, + svga->patch_vertices); draw_flush(svga->swtnl.draw); diff --git a/src/gallium/drivers/swr/swr_context.h b/src/gallium/drivers/swr/swr_context.h index b0681d8387f..11578764c23 100644 --- a/src/gallium/drivers/swr/swr_context.h +++ b/src/gallium/drivers/swr/swr_context.h @@ -201,6 +201,7 @@ struct swr_context { SWR_TILE_INTERFACE tileApi; uint32_t max_draws_in_flight; + uint8_t patch_vertices; }; static INLINE struct swr_context * diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp index 91e43e0e2a9..4b42a8e0390 100644 --- a/src/gallium/drivers/swr/swr_draw.cpp +++ b/src/gallium/drivers/swr/swr_draw.cpp @@ -90,7 +90,7 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, // trick copied from softpipe to modify const struct *info memcpy(&resolved_info, (void*)info, sizeof(struct pipe_draw_info)); resolved_draw.start = draws[0].start; - resolved_draw.count = ctx->so_primCounter * resolved_info.vertices_per_patch; + resolved_draw.count = ctx->so_primCounter * ctx->patch_vertices; resolved_info.max_index = resolved_draw.count - 1; info = &resolved_info; indirect = NULL; @@ -252,7 +252,7 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, if (info->index_size) ctx->api.pfnSwrDrawIndexedInstanced(ctx->swrContext, - swr_convert_prim_topology(info->mode, info->vertices_per_patch), + swr_convert_prim_topology(info->mode, ctx->patch_vertices), draws[0].count, info->instance_count, draws[0].start, @@ -260,7 +260,7 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, info->start_instance); else ctx->api.pfnSwrDrawInstanced(ctx->swrContext, - swr_convert_prim_topology(info->mode, info->vertices_per_patch), + swr_convert_prim_topology(info->mode, ctx->patch_vertices), draws[0].count, info->instance_count, draws[0].start, diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index e4be42a8215..5f1464e6d0e 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -1658,7 +1658,7 @@ swr_update_derived(struct pipe_context *pipe, SWR_NEW_SAMPLER | SWR_NEW_SAMPLER_VIEW)) { if (ctx->tcs) { - ctx->tcs->vertices_per_patch = p_draw_info->vertices_per_patch; + ctx->tcs->vertices_per_patch = ctx->patch_vertices; swr_jit_tcs_key key; swr_generate_tcs_key(key, ctx, ctx->tcs); @@ -2162,6 +2162,14 @@ swr_set_so_targets(struct pipe_context *pipe, swr->dirty |= SWR_NEW_SO; } +static void +swr_set_patch_vertices(struct pipe_context *pipe, uint8_t patch_vertices) +{ + struct swr_context *swr = swr_context(pipe); + + swr->patch_vertices = patch_vertices; +} + void swr_state_init(struct pipe_context *pipe) @@ -2230,4 +2238,6 @@ swr_state_init(struct pipe_context *pipe) pipe->create_stream_output_target = swr_create_so_target; pipe->stream_output_target_destroy = swr_destroy_so_target; pipe->set_stream_output_targets = swr_set_so_targets; + + pipe->set_patch_vertices = swr_set_patch_vertices; } diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 349e7425f5e..e9b8c2430dc 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -1163,6 +1163,13 @@ static void virgl_set_tess_state(struct pipe_context *ctx, virgl_encode_set_tess_state(vctx, default_outer_level, default_inner_level); } +static void virgl_set_patch_vertices(struct pipe_context *ctx, uint8_t patch_vertices) +{ + struct virgl_context *vctx = virgl_context(ctx); + + vctx->patch_vertices = patch_vertices; +} + static void virgl_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, @@ -1546,6 +1553,7 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen, vctx->base.set_constant_buffer = virgl_set_constant_buffer; vctx->base.set_tess_state = virgl_set_tess_state; + vctx->base.set_patch_vertices = virgl_set_patch_vertices; vctx->base.create_vs_state = virgl_create_vs_state; vctx->base.create_tcs_state = virgl_create_tcs_state; vctx->base.create_tes_state = virgl_create_tes_state; diff --git a/src/gallium/drivers/virgl/virgl_context.h b/src/gallium/drivers/virgl/virgl_context.h index 9acd698bc71..638f0117f68 100644 --- a/src/gallium/drivers/virgl/virgl_context.h +++ b/src/gallium/drivers/virgl/virgl_context.h @@ -85,6 +85,7 @@ struct virgl_context { struct virgl_staging_mgr staging; bool encoded_transfers; bool supports_staging; + uint8_t patch_vertices; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned num_vertex_buffers; diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c index 27595b6817c..519b3018efc 100644 --- a/src/gallium/drivers/virgl/virgl_encode.c +++ b/src/gallium/drivers/virgl/virgl_encode.c @@ -764,7 +764,7 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx, else virgl_encoder_write_dword(ctx->cbuf, 0); if (length >= VIRGL_DRAW_VBO_SIZE_TESS) { - virgl_encoder_write_dword(ctx->cbuf, info->vertices_per_patch); /* vertices per patch */ + virgl_encoder_write_dword(ctx->cbuf, ctx->patch_vertices); /* vertices per patch */ virgl_encoder_write_dword(ctx->cbuf, drawid_offset); /* drawid */ } if (length == VIRGL_DRAW_VBO_SIZE_INDIRECT) { diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 9ce7ea013fa..ad9f4da64aa 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1487,6 +1487,13 @@ zink_set_tess_state(struct pipe_context *pctx, memcpy(&ctx->default_outer_level, default_outer_level, sizeof(ctx->default_outer_level)); } +static void +zink_set_patch_vertices(struct pipe_context *pctx, uint8_t patch_vertices) +{ + struct zink_context *ctx = zink_context(pctx); + ctx->gfx_pipeline_state.patch_vertices = patch_vertices; +} + static uint32_t hash_render_pass_state(const void *key) { @@ -3380,6 +3387,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->base.set_clip_state = zink_set_clip_state; ctx->base.set_blend_color = zink_set_blend_color; ctx->base.set_tess_state = zink_set_tess_state; + ctx->base.set_patch_vertices = zink_set_patch_vertices; ctx->base.set_sample_mask = zink_set_sample_mask; diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 15ea1a4527c..b59a566dd5e 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -428,7 +428,7 @@ zink_draw_vbo(struct pipe_context *pctx, update_barriers(ctx, false); - if (ctx->gfx_pipeline_state.vertices_per_patch != dinfo->vertices_per_patch) + if (ctx->gfx_pipeline_state.vertices_per_patch != ctx->gfx_pipeline_state.patch_vertices) ctx->gfx_pipeline_state.dirty = true; bool drawid_broken = ctx->drawid_broken; ctx->drawid_broken = false; @@ -438,7 +438,7 @@ zink_draw_vbo(struct pipe_context *pctx, (HAS_MULTIDRAW && num_draws > 1 && !dinfo->increment_draw_id)); if (drawid_broken != ctx->drawid_broken) ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_VERTEX); - ctx->gfx_pipeline_state.vertices_per_patch = dinfo->vertices_per_patch; + ctx->gfx_pipeline_state.vertices_per_patch = ctx->gfx_pipeline_state.patch_vertices; if (ctx->rast_state->base.point_quad_rasterization && ctx->gfx_prim_mode != mode) { if (ctx->gfx_prim_mode == PIPE_PRIM_POINTS || mode == PIPE_PRIM_POINTS) diff --git a/src/gallium/drivers/zink/zink_pipeline.h b/src/gallium/drivers/zink/zink_pipeline.h index 69464808027..5d1113275b2 100644 --- a/src/gallium/drivers/zink/zink_pipeline.h +++ b/src/gallium/drivers/zink/zink_pipeline.h @@ -79,6 +79,8 @@ struct zink_gfx_pipeline_state { VkPipeline pipeline; enum pipe_prim_type mode : 8; + + uint8_t patch_vertices; }; struct zink_compute_pipeline_state { diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 532ac8551e3..425527b1192 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -97,6 +97,7 @@ struct rendering_state { int num_viewports; struct pipe_viewport_state viewports[16]; + uint8_t patch_vertices; ubyte index_size; unsigned index_offset; struct pipe_resource *index_buffer; @@ -764,10 +765,10 @@ static void handle_graphics_pipeline(struct lvp_cmd_buffer_entry *cmd, if (pipeline->graphics_create_info.pTessellationState) { if (!dynamic_states[conv_dynamic_state_idx(VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT)]) { const VkPipelineTessellationStateCreateInfo *ts = pipeline->graphics_create_info.pTessellationState; - state->info.vertices_per_patch = ts->patchControlPoints; + state->patch_vertices = ts->patchControlPoints; } } else - state->info.vertices_per_patch = 0; + state->patch_vertices = 0; if (pipeline->graphics_create_info.pViewportState) { const VkPipelineViewportStateCreateInfo *vpi= pipeline->graphics_create_info.pViewportState; @@ -1676,6 +1677,7 @@ static void handle_draw(struct lvp_cmd_buffer_entry *cmd, if (cmd->u.draw.draw_count > 1) state->info.increment_draw_id = true; + state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, cmd->u.draw.draws, cmd->u.draw.draw_count); } @@ -2252,6 +2254,7 @@ static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd, cmd->u.draw_indexed.calc_start = false; } state->info.index_bias_varies = cmd->u.draw_indexed.vertex_offset_changes; + state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); state->pctx->draw_vbo(state->pctx, &state->info, 0, NULL, cmd->u.draw_indexed.draws, cmd->u.draw_indexed.draw_count); } @@ -2273,6 +2276,7 @@ static void handle_draw_indirect(struct lvp_cmd_buffer_entry *cmd, state->indirect_info.buffer = cmd->u.draw_indirect.buffer->bo; state->info.view_mask = subpass->view_mask; + state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1); } @@ -2746,6 +2750,7 @@ static void handle_draw_indirect_count(struct lvp_cmd_buffer_entry *cmd, state->indirect_info.indirect_draw_count = cmd->u.draw_indirect_count.count_buffer->bo; state->info.view_mask = subpass->view_mask; + state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1); } @@ -2920,6 +2925,7 @@ static void handle_draw_indirect_byte_count(struct lvp_cmd_buffer_entry *cmd, draw.count /= cmd->u.draw_indirect_byte_count.vertex_stride; state->info.view_mask = subpass->view_mask; + state->pctx->set_patch_vertices(state->pctx, state->patch_vertices); state->pctx->draw_vbo(state->pctx, &state->info, 0, &state->indirect_info, &draw, 1); } @@ -3079,7 +3085,7 @@ static void handle_set_logic_op(struct lvp_cmd_buffer_entry *cmd, static void handle_set_patch_control_points(struct lvp_cmd_buffer_entry *cmd, struct rendering_state *state) { - state->info.vertices_per_patch = cmd->u.set_patch_control_points.vertices_per_patch; + state->patch_vertices = cmd->u.set_patch_control_points.vertices_per_patch; } static void handle_set_primitive_restart_enable(struct lvp_cmd_buffer_entry *cmd, diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 0a8c57e00f3..f5775e7470e 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -453,6 +453,11 @@ struct pipe_context { const float default_outer_level[4], const float default_inner_level[2]); + /** + * Set the number of vertices per input patch for tessellation. + */ + void (*set_patch_vertices)(struct pipe_context *ctx, uint8_t patch_vertices); + /** * Sets the debug callback. If the pointer is null, then no callback is * set, otherwise a copy of the data should be made. diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 9394f899ef4..4354d93055b 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -765,9 +765,8 @@ struct pipe_draw_start_count_bias { struct pipe_draw_info { enum pipe_prim_type mode:8; /**< the mode of the primitive */ - ubyte vertices_per_patch; /**< the number of vertices per patch */ - unsigned index_size:4; /**< if 0, the draw is not indexed. */ - unsigned view_mask:6; /**< mask of multiviews for this draw */ + uint8_t index_size; /**< if 0, the draw is not indexed. */ + uint8_t view_mask; /**< mask of multiviews for this draw */ bool primitive_restart:1; bool has_user_indices:1; /**< if true, use index.user_buffer */ bool index_bounds_valid:1; /**< whether min_index and max_index are valid; @@ -776,6 +775,7 @@ struct pipe_draw_info bool take_index_buffer_ownership:1; /**< callee inherits caller's refcount (no need to reference indexbuf, but still needs to unreference it) */ bool index_bias_varies:1; /**< true if index_bias varies between draws */ + uint8_t _pad:2; unsigned start_instance; /**< first instance id */ unsigned instance_count; /**< number of instances */ diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index c8fb42f56bc..94fda31d692 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -353,7 +353,7 @@ void brw_init_state( struct brw_context *brw ) ctx->DriverFlags.NewTextureBuffer = BRW_NEW_TEXTURE_BUFFER; ctx->DriverFlags.NewAtomicBuffer = BRW_NEW_UNIFORM_BUFFER; ctx->DriverFlags.NewImageUnits = BRW_NEW_IMAGE_UNITS; - ctx->DriverFlags.NewDefaultTessLevels = BRW_NEW_DEFAULT_TESS_LEVELS; + ctx->DriverFlags.NewTessState = BRW_NEW_DEFAULT_TESS_LEVELS; ctx->DriverFlags.NewIntelConservativeRasterization = BRW_NEW_CONSERVATIVE_RASTERIZATION; } diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 95f60b0880f..6d389f83cc2 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -1286,7 +1286,6 @@ _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, struct pipe_draw_start_count_bias draw; info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 0; /* Packed section begin. */ info.primitive_restart = false; @@ -1614,7 +1613,6 @@ _mesa_MultiDrawArrays(GLenum mode, const GLint *first, ALLOC_PRIMS(draw, primcount, "glMultiDrawElements"); info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 0; /* Packed section begin. */ info.primitive_restart = false; @@ -1728,7 +1726,6 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 1 << index_size_shift; /* Packed section begin. */ info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; @@ -2115,7 +2112,6 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, struct pipe_draw_info info; info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 1 << index_size_shift; /* Packed section begin. */ info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 1646482e5a1..acda78eb74c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -4799,8 +4799,9 @@ struct gl_driver_flags /** * gl_context::TessCtrlProgram::patch_default_* + * gl_context::TessCtrlProgram::patch_vertices */ - uint64_t NewDefaultTessLevels; + uint64_t NewTessState; /** * gl_context::IntelConservativeRasterization diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 0a19f62559f..955790f274d 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -2760,6 +2760,16 @@ _mesa_CreateShaderProgramv(GLenum type, GLsizei count, } +static void +set_patch_vertices(struct gl_context *ctx, GLint value) +{ + if (ctx->TessCtrlProgram.patch_vertices != value) { + FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT); + ctx->NewDriverState |= ctx->DriverFlags.NewTessState; + ctx->TessCtrlProgram.patch_vertices = value; + } +} + /** * For GL_ARB_tessellation_shader */ @@ -2767,8 +2777,8 @@ void GLAPIENTRY _mesa_PatchParameteri_no_error(GLenum pname, GLint value) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT); - ctx->TessCtrlProgram.patch_vertices = value; + + set_patch_vertices(ctx, value); } @@ -2792,8 +2802,7 @@ _mesa_PatchParameteri(GLenum pname, GLint value) return; } - FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT); - ctx->TessCtrlProgram.patch_vertices = value; + set_patch_vertices(ctx, value); } @@ -2812,13 +2821,13 @@ _mesa_PatchParameterfv(GLenum pname, const GLfloat *values) FLUSH_VERTICES(ctx, 0, 0); memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values, 4 * sizeof(GLfloat)); - ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels; + ctx->NewDriverState |= ctx->DriverFlags.NewTessState; return; case GL_PATCH_DEFAULT_INNER_LEVEL: FLUSH_VERTICES(ctx, 0, 0); memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values, 2 * sizeof(GLfloat)); - ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels; + ctx->NewDriverState |= ctx->DriverFlags.NewTessState; return; default: _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv"); diff --git a/src/mesa/state_tracker/st_atom_tess.c b/src/mesa/state_tracker/st_atom_tess.c index 6cf3ff7339a..6a2d246b559 100644 --- a/src/mesa/state_tracker/st_atom_tess.c +++ b/src/mesa/state_tracker/st_atom_tess.c @@ -43,10 +43,12 @@ st_update_tess(struct st_context *st) const struct gl_context *ctx = st->ctx; struct pipe_context *pipe = st->pipe; - if (!pipe->set_tess_state) - return; + if (pipe->set_tess_state) { + pipe->set_tess_state(pipe, + ctx->TessCtrlProgram.patch_default_outer_level, + ctx->TessCtrlProgram.patch_default_inner_level); + } - pipe->set_tess_state(pipe, - ctx->TessCtrlProgram.patch_default_outer_level, - ctx->TessCtrlProgram.patch_default_inner_level); + if (pipe->set_patch_vertices) + pipe->set_patch_vertices(pipe, ctx->TessCtrlProgram.patch_vertices); } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 6b57538eb86..6af4bf15147 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -487,7 +487,7 @@ st_init_driver_flags(struct st_context *st) f->NewRasterizerDiscard = ST_NEW_RASTERIZER; f->NewTileRasterOrder = ST_NEW_RASTERIZER; f->NewUniformBuffer = ST_NEW_UNIFORM_BUFFER; - f->NewDefaultTessLevels = ST_NEW_TESS_STATE; + f->NewTessState = ST_NEW_TESS_STATE; /* Shader resources */ f->NewTextureBuffer = ST_NEW_SAMPLER_VIEWS; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 2b6cb8c8a17..28eb69e52d7 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -259,7 +259,6 @@ st_indirect_draw_vbo(struct gl_context *ctx, } info.mode = translate_prim(ctx, mode); - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; indirect.buffer = st_buffer_object(indirect_data)->buffer; indirect.offset = indirect_offset; @@ -300,7 +299,6 @@ st_draw_transform_feedback(struct gl_context *ctx, GLenum mode, util_draw_init_info(&info); info.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */ info.mode = translate_prim(ctx, mode); - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.instance_count = num_instances; /* Transform feedback drawing is always non-indexed. */ diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 54e502e46af..6359926429e 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -125,7 +125,6 @@ st_feedback_draw_vbo(struct gl_context *ctx, /* Initialize pipe_draw_info. */ info.primitive_restart = false; info.take_index_buffer_ownership = false; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.restart_index = 0; info.view_mask = 0; @@ -459,7 +458,8 @@ st_feedback_draw_vbo(struct gl_context *ctx, info.max_index = d.start + d.count - 1; } - draw_vbo(draw, &info, prims[i].draw_id, NULL, &d, 1); + draw_vbo(draw, &info, prims[i].draw_id, NULL, &d, 1, + ctx->TessCtrlProgram.patch_vertices); } /* unmap images */ diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index af5ae03ef9a..53307736b0f 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -330,9 +330,6 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec) printf("%s %d %d\n", __func__, exec->vtx.prim_count, exec->vtx.vert_count); - exec->vtx.info.vertices_per_patch = - ctx->TessCtrlProgram.patch_vertices; - ctx->Driver.DrawGalliumMultiMode(ctx, &exec->vtx.info, exec->vtx.draw, exec->vtx.mode, diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index 7170a3b7be6..5c5dc8c8ae2 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -221,7 +221,6 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data, bool copy_to_c assert(ctx->NewState == 0); struct pipe_draw_info *info = (struct pipe_draw_info *) &node->merged.info; - info->vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; void *gl_bo = info->index.gl_bo; if (node->merged.mode) { ctx->Driver.DrawGalliumMultiMode(ctx, info,