[Mesa-dev] [PATCH 1/2] radeonsi: enable out-of-order rasterization when possible on VI and GFX9 dGPUs
Nicolai Hähnle
nhaehnle at gmail.com
Thu Sep 7 08:21:13 UTC 2017
On 07.09.2017 00:35, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> ---
> src/gallium/drivers/radeonsi/si_pipe.c | 2 +
> src/gallium/drivers/radeonsi/si_pipe.h | 1 +
> src/gallium/drivers/radeonsi/si_state.c | 143 +++++++++++++++++++++++-
> src/gallium/drivers/radeonsi/si_state.h | 10 +-
> src/gallium/drivers/radeonsi/si_state_shaders.c | 5 +
> 5 files changed, 156 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
> index 640b57c..9642edd 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.c
> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
> @@ -1041,20 +1041,22 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws,
> sscreen->b.info.pfp_fw_version >= 121 &&
> sscreen->b.info.me_fw_version >= 87) ||
> (sscreen->b.chip_class == CIK &&
> sscreen->b.info.pfp_fw_version >= 211 &&
> sscreen->b.info.me_fw_version >= 173) ||
> (sscreen->b.chip_class == SI &&
> sscreen->b.info.pfp_fw_version >= 79 &&
> sscreen->b.info.me_fw_version >= 142);
>
> sscreen->has_ds_bpermute = sscreen->b.chip_class >= VI;
> + sscreen->has_out_of_order_rast = sscreen->b.chip_class >= VI &&
> + sscreen->b.info.max_se >= 2;
> sscreen->has_msaa_sample_loc_bug = (sscreen->b.family >= CHIP_POLARIS10 &&
> sscreen->b.family <= CHIP_POLARIS12) ||
> sscreen->b.family == CHIP_VEGA10 ||
> sscreen->b.family == CHIP_RAVEN;
> sscreen->dpbb_allowed = sscreen->b.chip_class >= GFX9 &&
> !(sscreen->b.debug_flags & DBG_NO_DPBB);
> sscreen->dfsm_allowed = sscreen->dpbb_allowed &&
> !(sscreen->b.debug_flags & DBG_NO_DFSM);
>
> /* While it would be nice not to have this flag, we are constrained
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
> index 8db7028..b8073ce 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.h
> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
> @@ -88,20 +88,21 @@ struct hash_table;
> struct u_suballocator;
>
> struct si_screen {
> struct r600_common_screen b;
> unsigned gs_table_depth;
> unsigned tess_offchip_block_dw_size;
> bool has_clear_state;
> bool has_distributed_tess;
> bool has_draw_indirect_multi;
> bool has_ds_bpermute;
> + bool has_out_of_order_rast;
> bool has_msaa_sample_loc_bug;
> bool dpbb_allowed;
> bool dfsm_allowed;
> bool llvm_has_working_vgpr_indexing;
>
> /* Whether shaders are monolithic (1-part) or separate (3-part). */
> bool use_monolithic_shaders;
> bool record_llvm_ir;
>
> mtx_t shader_parts_mutex;
> diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
> index 7e9140b..855ad27 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -416,20 +416,21 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
> struct si_pm4_state *pm4 = &blend->pm4;
> uint32_t sx_mrt_blend_opt[8] = {0};
> uint32_t color_control = 0;
>
> if (!blend)
> return NULL;
>
> blend->alpha_to_coverage = state->alpha_to_coverage;
> blend->alpha_to_one = state->alpha_to_one;
> blend->dual_src_blend = util_blend_state_is_dual(state, 0);
> + blend->logicop_enable = state->logicop_enable;
>
> if (state->logicop_enable) {
> color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
> } else {
> color_control |= S_028808_ROP3(0xcc);
> }
>
> si_pm4_set_reg(pm4, R_028B70_DB_ALPHA_TO_MASK,
> S_028B70_ALPHA_TO_MASK_ENABLE(state->alpha_to_coverage) |
> S_028B70_ALPHA_TO_MASK_OFFSET0(2) |
> @@ -623,20 +624,27 @@ static void si_bind_blend_state(struct pipe_context *ctx, void *state)
> old_blend->blend_enable_4bit != blend->blend_enable_4bit ||
> old_blend->need_src_alpha_4bit != blend->need_src_alpha_4bit)
> sctx->do_update_shaders = true;
>
> if (sctx->screen->dpbb_allowed &&
> (!old_blend ||
> old_blend->alpha_to_coverage != blend->alpha_to_coverage ||
> old_blend->blend_enable_4bit != blend->blend_enable_4bit ||
> old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit))
> si_mark_atom_dirty(sctx, &sctx->dpbb_state);
> +
> + if (sctx->screen->has_out_of_order_rast &&
> + (!old_blend ||
> + (old_blend->blend_enable_4bit != blend->blend_enable_4bit ||
> + old_blend->cb_target_enabled_4bit != blend->cb_target_enabled_4bit ||
> + old_blend->logicop_enable != blend->logicop_enable)))
> + si_mark_atom_dirty(sctx, &sctx->msaa_config);
> }
>
> static void si_delete_blend_state(struct pipe_context *ctx, void *state)
> {
> struct si_context *sctx = (struct si_context *)ctx;
> si_pm4_delete_state(sctx, blend, (struct si_state_blend *)state);
> }
>
> static void si_set_blend_color(struct pipe_context *ctx,
> const struct pipe_blend_color *state)
> @@ -1118,20 +1126,47 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
>
> dsa->depth_enabled = state->depth.enabled;
> dsa->depth_write_enabled = state->depth.enabled &&
> state->depth.writemask;
> dsa->stencil_enabled = state->stencil[0].enabled;
> dsa->stencil_write_enabled = state->stencil[0].enabled &&
> (si_dsa_writes_stencil(&state->stencil[0]) ||
> si_dsa_writes_stencil(&state->stencil[1]));
> dsa->db_can_write = dsa->depth_write_enabled ||
> dsa->stencil_write_enabled;
> + dsa->stencil_can_run_out_of_order = !dsa->stencil_enabled ||
> + !dsa->db_can_write;
> +
> + bool depth_forces_ordering =
> + dsa->depth_enabled &&
> + (state->depth.func == PIPE_FUNC_NEVER ||
> + state->depth.func == PIPE_FUNC_LESS ||
> + state->depth.func == PIPE_FUNC_LEQUAL ||
> + state->depth.func == PIPE_FUNC_GREATER ||
> + state->depth.func == PIPE_FUNC_GEQUAL);
> +
> + /* Option to allow inexact behavior with out-of-order rasterization
> + * when two overlapping pixels have the same Z, and depth and color
> + * writes are enabled, and the depth function is LESS/LEQUAL/GREATER/
> + * GEQUAL.
> + */
> + const bool aggressive_opt_out_of_order = false;
> +
> + /* Stencil isn't checked here and must be AND'ed with this. */
> + dsa->depth_forces_ordering_color_off =
> + !dsa->depth_enabled || /* no depth tests and writes */
> + !dsa->depth_write_enabled || /* any depth function is OK */
> + depth_forces_ordering;
> + dsa->depth_forces_ordering_color_on =
> + depth_forces_ordering &&
> + (aggressive_opt_out_of_order || !dsa->depth_write_enabled);
> +
> return dsa;
> }
>
> static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
> {
> struct si_context *sctx = (struct si_context *)ctx;
> struct si_state_dsa *old_dsa = sctx->queued.named.dsa;
> struct si_state_dsa *dsa = state;
>
> if (!state)
> @@ -1147,20 +1182,29 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
>
> if (!old_dsa || old_dsa->alpha_func != dsa->alpha_func)
> sctx->do_update_shaders = true;
>
> if (sctx->screen->dpbb_allowed &&
> (!old_dsa ||
> (old_dsa->depth_enabled != dsa->depth_enabled ||
> old_dsa->stencil_enabled != dsa->stencil_enabled ||
> old_dsa->db_can_write != dsa->db_can_write)))
> si_mark_atom_dirty(sctx, &sctx->dpbb_state);
> +
> + if (sctx->screen->has_out_of_order_rast &&
> + (!old_dsa ||
> + (old_dsa->depth_enabled != dsa->depth_enabled ||
> + old_dsa->stencil_enabled != dsa->stencil_enabled ||
> + old_dsa->stencil_can_run_out_of_order != dsa->stencil_can_run_out_of_order ||
> + old_dsa->depth_forces_ordering_color_off != dsa->depth_forces_ordering_color_off ||
> + old_dsa->depth_forces_ordering_color_on != dsa->depth_forces_ordering_color_on)))
> + si_mark_atom_dirty(sctx, &sctx->msaa_config);
> }
>
> static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
> {
> struct si_context *sctx = (struct si_context *)ctx;
> si_pm4_delete_state(sctx, dsa, (struct si_state_dsa *)state);
> }
>
> static void *si_create_db_flush_dsa(struct si_context *sctx)
> {
> @@ -2532,20 +2576,26 @@ static void si_dec_framebuffer_counters(const struct pipe_framebuffer_state *sta
>
> static void si_set_framebuffer_state(struct pipe_context *ctx,
> const struct pipe_framebuffer_state *state)
> {
> struct si_context *sctx = (struct si_context *)ctx;
> struct pipe_constant_buffer constbuf = {0};
> struct r600_surface *surf = NULL;
> struct r600_texture *rtex;
> bool old_any_dst_linear = sctx->framebuffer.any_dst_linear;
> unsigned old_nr_samples = sctx->framebuffer.nr_samples;
> + unsigned old_colorbuf_enabled_4bit = sctx->framebuffer.colorbuf_enabled_4bit;
> + bool old_has_zsbuf = !!sctx->framebuffer.state.zsbuf;
> + bool old_has_stencil =
> + old_has_zsbuf &&
> + ((struct r600_texture*)sctx->framebuffer.state.zsbuf)->surface.flags &
> + RADEON_SURF_SBUFFER;
> bool unbound = false;
> int i;
>
> si_update_fb_dirtiness_after_rendering(sctx);
>
> for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++) {
> if (!sctx->framebuffer.state.cbufs[i])
> continue;
>
> rtex = (struct r600_texture*)sctx->framebuffer.state.cbufs[i]->texture;
> @@ -2689,44 +2739,52 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
>
> p_atomic_inc(&rtex->framebuffers_bound);
>
> if (rtex->dcc_gather_statistics) {
> /* Dirty tracking must be enabled for DCC usage analysis. */
> sctx->framebuffer.compressed_cb_mask |= 1 << i;
> vi_separate_dcc_start_query(ctx, rtex);
> }
> }
>
> + struct r600_texture *zstex = NULL;
> +
> if (state->zsbuf) {
> surf = (struct r600_surface*)state->zsbuf;
> - rtex = (struct r600_texture*)surf->base.texture;
> + zstex = (struct r600_texture*)surf->base.texture;
>
> if (!surf->depth_initialized) {
> si_init_depth_surface(sctx, surf);
> }
>
> - if (vi_tc_compat_htile_enabled(rtex, surf->base.u.tex.level))
> + if (vi_tc_compat_htile_enabled(zstex, surf->base.u.tex.level))
> sctx->framebuffer.DB_has_shader_readable_metadata = true;
>
> r600_context_add_resource_size(ctx, surf->base.texture);
> }
>
> si_update_poly_offset_state(sctx);
> si_mark_atom_dirty(sctx, &sctx->cb_render_state);
> si_mark_atom_dirty(sctx, &sctx->framebuffer.atom);
>
> if (sctx->screen->dpbb_allowed)
> si_mark_atom_dirty(sctx, &sctx->dpbb_state);
>
> if (sctx->framebuffer.any_dst_linear != old_any_dst_linear)
> si_mark_atom_dirty(sctx, &sctx->msaa_config);
>
> + if (sctx->screen->has_out_of_order_rast &&
> + (sctx->framebuffer.colorbuf_enabled_4bit != old_colorbuf_enabled_4bit ||
> + !!sctx->framebuffer.state.zsbuf != old_has_zsbuf ||
> + (zstex && !!(zstex->surface.flags & RADEON_SURF_SBUFFER) != old_has_stencil)))
> + si_mark_atom_dirty(sctx, &sctx->msaa_config);
> +
> if (sctx->framebuffer.nr_samples != old_nr_samples) {
> si_mark_atom_dirty(sctx, &sctx->msaa_config);
> si_mark_atom_dirty(sctx, &sctx->db_render_state);
>
> /* Set sample locations as fragment shader constants. */
> switch (sctx->framebuffer.nr_samples) {
> case 1:
> constbuf.user_buffer = sctx->b.sample_locations_1x;
> break;
> case 2:
> @@ -3049,30 +3107,111 @@ static void si_emit_msaa_sample_locs(struct si_context *sctx,
> if (has_msaa_sample_loc_bug &&
> sctx->framebuffer.nr_samples > 1 &&
> rs && !rs->multisample_enable)
> small_prim_filter_cntl &= C_028830_SMALL_PRIM_FILTER_ENABLE;
>
> radeon_set_context_reg(cs, R_028830_PA_SU_SMALL_PRIM_FILTER_CNTL,
> small_prim_filter_cntl);
> }
> }
>
> +static bool si_out_of_order_rasterization(struct si_context *sctx)
> +{
> + struct si_state_blend *blend = sctx->queued.named.blend;
> + struct si_state_dsa *dsa = sctx->queued.named.dsa;
> +
> + if (!sctx->screen->has_out_of_order_rast)
> + return false;
> +
> + /* PS with memory stores can't run out-of-order. */
> + if (sctx->ps_shader.cso &&
> + sctx->ps_shader.cso->info.writes_memory)
> + return false;
I'm actually not sure this is necessary. The spec is quite relaxed about
the order of pixel shader invocations and whether they happen at all.
> +
> + unsigned colormask = sctx->framebuffer.colorbuf_enabled_4bit &
> + blend->cb_target_enabled_4bit;
> +
> + /* No logic op. */
> + if (colormask && blend->logicop_enable)
> + return false;
> +
> + struct r600_texture *zstex =
> + (struct r600_texture*)sctx->framebuffer.state.zsbuf->texture;
> + bool has_stencil = sctx->framebuffer.state.zsbuf &&
> + zstex->surface.flags & RADEON_SURF_SBUFFER;
> + bool blend_enabled = (colormask & blend->blend_enable_4bit) != 0;
> +
> + /* Out-of-order rasterization can be enabled for these cases:
> + *
> + * - color-only rendering:
> + * + blending must be enabled and commutative
> + * + only when inexact behavior due to rounding is allowed
> + *
> + * - depth-only rendering:
> + * + depth must force ordering
> + *
> + * - stencil-only rendering:
> + * + never --- can we do better here?
> + *
> + * - color rendering with read-only depth:
> + * + blending must be disabled
> + * + depth must force ordering
> + *
> + * - color rendering with read-only stencil:
> + * + blending must be disabled
> + *
> + * - color+depth rendering:
> + * + blending must be disabled
> + * + depth must force ordering
> + * + only when Z-fighting is allowed to result in inexact behavior
> + *
> + * - color+stencil rendering:
> + * + never --- can we do better here?
> + *
> + * - color+depth+stencil rendering:
> + * + never --- can we do better here?
> + */
I can't quite wrap my head around the logic here.
Here's a suggestion for cleaning it up conceptually:
- Record in DSA whether DSA *by itself* can run out-of-order or not,
meaning that the final result in Z/S is unaffected by out-of-order
-- This is trivially the case when there are no Z/S writes
-- It is also the case when stencil writes are disabled and Zfunc is
NEVER or one of the ordered ones ("depth_forces_ordering", currently)
-- It is also the case when depth writes are disabled, Sfunc is ALWAYS,
and zpass_op/zfail_op are KEEP, ZERO, REPLACE, INVERT, INCR_WRAP,
DECR_WRAP, or Sfunc is NEVER and the same applies to fail_op [I think
this allows out-of-order to be enabled for stencil shadow passes]
- Record in DSA whether the set of fragments passing DSA is unaffected
by out-of-order
-- This is trivially the case when there are no Z/S writes
-- It is the case when stencil writes are disabled and Zfunc is ALWAYS
or NEVER
-- It is the case when depth writes are disabled and Sfunc is ALWAYS or
NEVER
- Record in DSA whether the *last* fragment passing DSA for each sample
is unaffected by out-of-order
-- This is *never* the case if we're being honest, but we can enable it
in an optional "aggressive" mode when stencil writes are disabled, Z
writes are enabled and Z func is one of the ordered functions
The overall out-of-order enable is then:
- if DSA by itself cannot run out-of-order, disable
- if color writes are disabled, enable
- if logic op is enabled, disable
- if blending is enabled:
o disable if non-commutative
o enable if commutative and the set of fragments passing DSA is
unaffected by out-of-rder
- if blending is disabled, enable iff the *last* fragment passing DSA is
unaffected
Thinking it through in this way, I believe I discovered at least one bug
in the patch as-is, in the following configuration
- blending disabled and no stencil
- depth is enabled, depth writes are disabled, and Zfunc == LESS
In this case, dsa->depth_forces_ordering_color_on will be true and
out-of-order will be enabled. But that's not correct, because there may
be multiple triangles with Z-values less than whatever's in the depth
buffer.
On second thought, the whole "record in DSA" thing gets a bit more
complicated because it interacts with whether Z/S buffers are actually
present. The no-Z/S case is easy (the first two bits are "Yes", the last
one is "No"), but we need to distinguish whether stencil is present or
not. Maybe both of these can be pre-calculated and stored in DSA.
Cheers,
Nicolai
> +
> + /* If depth and stencil are disabled, blending must be enabled and commutative. */
> + if (!sctx->framebuffer.state.zsbuf ||
> + (!dsa->depth_enabled && (!has_stencil || !dsa->stencil_enabled))) {
> + if (!colormask)
> + return true; /* Color writes are disabled. */
> +
> + /* If color writes are enabled, blending must be enabled and
> + * commutative.
> + */
> + return false; /* TODO: check for commutative blending */
> + }
> +
> + /* Depth or stencil is enabled. */
> + if (blend_enabled ||
> + (has_stencil && !dsa->stencil_can_run_out_of_order))
> + return false;
> +
> + return colormask ? dsa->depth_forces_ordering_color_on :
> + dsa->depth_forces_ordering_color_off;
> +}
> +
> static void si_emit_msaa_config(struct si_context *sctx, struct r600_atom *atom)
> {
> struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
> unsigned num_tile_pipes = sctx->screen->b.info.num_tile_pipes;
> /* 33% faster rendering to linear color buffers */
> bool dst_is_linear = sctx->framebuffer.any_dst_linear;
> + bool out_of_order_rast = si_out_of_order_rasterization(sctx);
> unsigned sc_mode_cntl_1 =
> S_028A4C_WALK_SIZE(dst_is_linear) |
> S_028A4C_WALK_FENCE_ENABLE(!dst_is_linear) |
> S_028A4C_WALK_FENCE_SIZE(num_tile_pipes == 2 ? 2 : 3) |
> + S_028A4C_OUT_OF_ORDER_PRIMITIVE_ENABLE(out_of_order_rast) |
> + S_028A4C_OUT_OF_ORDER_WATER_MARK(0x7) |
> /* always 1: */
> S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(1) |
> S_028A4C_SUPERTILE_WALK_ORDER_ENABLE(1) |
> S_028A4C_TILE_WALK_ORDER_ENABLE(1) |
> S_028A4C_MULTI_SHADER_ENGINE_PRIM_DISCARD_ENABLE(1) |
> S_028A4C_FORCE_EOV_CNTDWN_ENABLE(1) |
> S_028A4C_FORCE_EOV_REZ_ENABLE(1);
>
> cayman_emit_msaa_config(cs, sctx->framebuffer.nr_samples,
> sctx->ps_iter_samples,
> diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
> index 17d210a..ed66a63 100644
> --- a/src/gallium/drivers/radeonsi/si_state.h
> +++ b/src/gallium/drivers/radeonsi/si_state.h
> @@ -42,29 +42,30 @@
> #define SI_NUM_IMAGES 16
> #define SI_NUM_SHADER_BUFFERS 16
>
> struct si_screen;
> struct si_shader;
> struct si_shader_selector;
>
> struct si_state_blend {
> struct si_pm4_state pm4;
> uint32_t cb_target_mask;
> - bool alpha_to_coverage;
> - bool alpha_to_one;
> - bool dual_src_blend;
> /* Set 0xf or 0x0 (4 bits) per render target if the following is
> * true. ANDed with spi_shader_col_format.
> */
> unsigned cb_target_enabled_4bit;
> unsigned blend_enable_4bit;
> unsigned need_src_alpha_4bit;
> + bool alpha_to_coverage:1;
> + bool alpha_to_one:1;
> + bool dual_src_blend:1;
> + bool logicop_enable:1;
> };
>
> struct si_state_rasterizer {
> struct si_pm4_state pm4;
> /* poly offset states for 16-bit, 24-bit, and 32-bit zbuffers */
> struct si_pm4_state *pm4_poly_offset;
> unsigned pa_sc_line_stipple;
> unsigned pa_cl_clip_cntl;
> unsigned sprite_coord_enable:8;
> unsigned clip_plane_enable:8;
> @@ -91,20 +92,23 @@ struct si_dsa_stencil_ref_part {
>
> struct si_state_dsa {
> struct si_pm4_state pm4;
> struct si_dsa_stencil_ref_part stencil_ref;
> ubyte alpha_func:3;
> bool depth_enabled:1;
> bool depth_write_enabled:1;
> bool stencil_enabled:1;
> bool stencil_write_enabled:1;
> bool db_can_write:1;
> + bool stencil_can_run_out_of_order:1;
> + bool depth_forces_ordering_color_off:1;
> + bool depth_forces_ordering_color_on:1;
> };
>
> struct si_stencil_ref {
> struct r600_atom atom;
> struct pipe_stencil_ref state;
> struct si_dsa_stencil_ref_part dsa_part;
> };
>
> struct si_vertex_elements
> {
> diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
> index fe25598..23ea1a3 100644
> --- a/src/gallium/drivers/radeonsi/si_state_shaders.c
> +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
> @@ -2405,20 +2405,25 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
> sctx->ps_shader.current = sel ? sel->first_variant : NULL;
>
> si_update_common_shader_state(sctx);
> if (sel) {
> if (sctx->ia_multi_vgt_param_key.u.uses_tess)
> si_update_tess_uses_prim_id(sctx);
>
> if (!old_sel ||
> old_sel->info.colors_written != sel->info.colors_written)
> si_mark_atom_dirty(sctx, &sctx->cb_render_state);
> +
> + if (sctx->screen->has_out_of_order_rast &&
> + (!old_sel ||
> + (old_sel->info.writes_memory != sel->info.writes_memory)))
> + si_mark_atom_dirty(sctx, &sctx->msaa_config);
> }
> si_set_active_descriptors_for_shader(sctx, sel);
> }
>
> static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
> {
> if (shader->is_optimized) {
> util_queue_drop_job(&sctx->screen->shader_compiler_queue_low_priority,
> &shader->optimized_ready);
> util_queue_fence_destroy(&shader->optimized_ready);
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list