panfrost: Flip point coords in hardware
On Bifrost, this is very easy: there's an RSD bit to Y-flip gl_PointCoord. It should map perfectly to the Gallium bit. With this change, we no longer use lower_pntc_ytransform on Bifrost, saving a bit of ALU when reading point coordinates. On Valhall, this is quite hard: the bit is in the framebuffer descriptor now! That means it can't be changed in a batch. This is expected to be ok: on GLES and VK, the origin is controlled only by the framebuffer orientation. It's a bigger problem on big GL, where GL_POINT_SPRITE_COORD_ORIGIN can be set freely. To cope, a tri-state data structure is used for the state tracking. This has a failure case on Valhall: every draw toggling the coord origin. However, the intention of the ORIGIN state bit is smoothing over coordinate system differences; it should never /actually/ change once set. Until we see an app doing something so stupid, I don't think we should worry about. We need all the Valhall tri-state infrastructure for handling provoking vertices on big GL anyway. Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16173>
This commit is contained in:
parent
5bab8e6cbe
commit
3641dfe436
|
@ -573,6 +573,13 @@ panfrost_prepare_fs_state(struct panfrost_context *ctx,
|
||||||
cfg.multisample_misc.evaluate_per_sample = true;
|
cfg.multisample_misc.evaluate_per_sample = true;
|
||||||
cfg.preload.fragment.sample_mask_id = true;
|
cfg.preload.fragment.sample_mask_id = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Flip gl_PointCoord (and point sprites) depending on API
|
||||||
|
* setting on framebuffer orientation. We do not use
|
||||||
|
* lower_wpos_pntc on Bifrost.
|
||||||
|
*/
|
||||||
|
cfg.properties.point_sprite_coord_origin_max_y =
|
||||||
|
(rast->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cfg.stencil_mask_misc.alpha_to_coverage = alpha_to_coverage;
|
cfg.stencil_mask_misc.alpha_to_coverage = alpha_to_coverage;
|
||||||
|
@ -3780,6 +3787,21 @@ panfrost_indirect_draw(struct panfrost_batch *batch,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static bool
|
||||||
|
panfrost_compatible_batch_state(struct panfrost_batch *batch)
|
||||||
|
{
|
||||||
|
/* Only applies on Valhall */
|
||||||
|
if (PAN_ARCH < 9)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
struct pipe_rasterizer_state *rast = &ctx->rasterizer->base;
|
||||||
|
|
||||||
|
bool coord = (rast->sprite_coord_mode == PIPE_SPRITE_COORD_LOWER_LEFT);
|
||||||
|
|
||||||
|
return pan_tristate_set(&batch->sprite_coord_origin, coord);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
panfrost_draw_vbo(struct pipe_context *pipe,
|
panfrost_draw_vbo(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
|
@ -3810,6 +3832,9 @@ panfrost_draw_vbo(struct pipe_context *pipe,
|
||||||
if (unlikely(batch->scoreboard.job_index > 10000))
|
if (unlikely(batch->scoreboard.job_index > 10000))
|
||||||
batch = panfrost_get_fresh_batch_for_fbo(ctx, "Too many draws");
|
batch = panfrost_get_fresh_batch_for_fbo(ctx, "Too many draws");
|
||||||
|
|
||||||
|
if (unlikely(!panfrost_compatible_batch_state(batch)))
|
||||||
|
batch = panfrost_get_fresh_batch_for_fbo(ctx, "State change");
|
||||||
|
|
||||||
/* panfrost_batch_skip_rasterization reads
|
/* panfrost_batch_skip_rasterization reads
|
||||||
* batch->scissor_culls_everything, which is set by
|
* batch->scissor_culls_everything, which is set by
|
||||||
* panfrost_emit_viewport, so call that first.
|
* panfrost_emit_viewport, so call that first.
|
||||||
|
@ -4371,14 +4396,7 @@ prepare_shader(struct panfrost_shader_state *state,
|
||||||
pan_pack(out, RENDERER_STATE, cfg) {
|
pan_pack(out, RENDERER_STATE, cfg) {
|
||||||
pan_shader_prepare_rsd(&state->info, state->bin.gpu, &cfg);
|
pan_shader_prepare_rsd(&state->info, state->bin.gpu, &cfg);
|
||||||
|
|
||||||
#if PAN_ARCH >= 6
|
}
|
||||||
/* Match the mesa/st convention. If this needs to be flipped,
|
|
||||||
* nir_lower_pntc_ytransform will do so.
|
|
||||||
*/
|
|
||||||
if (state->info.stage == MESA_SHADER_FRAGMENT)
|
|
||||||
cfg.properties.point_sprite_coord_origin_max_y = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
assert(upload);
|
assert(upload);
|
||||||
|
|
||||||
|
|
|
@ -435,6 +435,7 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch,
|
||||||
fb->extent.maxy = batch->maxy - 1;
|
fb->extent.maxy = batch->maxy - 1;
|
||||||
fb->nr_samples = util_framebuffer_get_num_samples(&batch->key);
|
fb->nr_samples = util_framebuffer_get_num_samples(&batch->key);
|
||||||
fb->rt_count = batch->key.nr_cbufs;
|
fb->rt_count = batch->key.nr_cbufs;
|
||||||
|
fb->sprite_coord_origin = pan_tristate_get(batch->sprite_coord_origin);
|
||||||
|
|
||||||
static const unsigned char id_swz[] = {
|
static const unsigned char id_swz[] = {
|
||||||
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W,
|
PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W,
|
||||||
|
|
|
@ -33,6 +33,52 @@
|
||||||
#include "pan_resource.h"
|
#include "pan_resource.h"
|
||||||
#include "pan_scoreboard.h"
|
#include "pan_scoreboard.h"
|
||||||
|
|
||||||
|
/* Simple tri-state data structure. In the default "don't care" state, the value
|
||||||
|
* may be set to true or false. However, once the value is set, it must not be
|
||||||
|
* changed. Declared inside of a struct to prevent casting to bool, which is an
|
||||||
|
* error. The getter needs to be used instead.
|
||||||
|
*/
|
||||||
|
struct pan_tristate {
|
||||||
|
enum {
|
||||||
|
PAN_TRISTATE_DONTCARE,
|
||||||
|
PAN_TRISTATE_FALSE,
|
||||||
|
PAN_TRISTATE_TRUE,
|
||||||
|
} v;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to set a tristate value to a desired boolean value. Returns whether the
|
||||||
|
* operation is successful.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
pan_tristate_set(struct pan_tristate *state, bool value)
|
||||||
|
{
|
||||||
|
switch (state->v) {
|
||||||
|
case PAN_TRISTATE_DONTCARE:
|
||||||
|
state->v = value ? PAN_TRISTATE_TRUE : PAN_TRISTATE_FALSE;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case PAN_TRISTATE_FALSE:
|
||||||
|
return (value == false);
|
||||||
|
|
||||||
|
case PAN_TRISTATE_TRUE:
|
||||||
|
return (value == true);
|
||||||
|
|
||||||
|
default:
|
||||||
|
unreachable("Invalid tristate value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the boolean value of a tristate. Return value undefined in the don't
|
||||||
|
* care state.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
pan_tristate_get(struct pan_tristate state)
|
||||||
|
{
|
||||||
|
return (state.v == PAN_TRISTATE_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/* A panfrost_batch corresponds to a bound FBO we're rendering to,
|
/* A panfrost_batch corresponds to a bound FBO we're rendering to,
|
||||||
* collecting over multiple draws. */
|
* collecting over multiple draws. */
|
||||||
|
|
||||||
|
@ -141,6 +187,11 @@ struct panfrost_batch {
|
||||||
*/
|
*/
|
||||||
mali_ptr images[PIPE_SHADER_TYPES];
|
mali_ptr images[PIPE_SHADER_TYPES];
|
||||||
|
|
||||||
|
/* On Valhall, these are properties of the batch. On Bifrost, they are
|
||||||
|
* per draw.
|
||||||
|
*/
|
||||||
|
struct pan_tristate sprite_coord_origin;
|
||||||
|
|
||||||
/* Referenced resources */
|
/* Referenced resources */
|
||||||
struct set *resources;
|
struct set *resources;
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,7 +48,6 @@ static const nir_shader_compiler_options bifrost_nir_options = {
|
||||||
.lower_fdph = true,
|
.lower_fdph = true,
|
||||||
.lower_fsqrt = true,
|
.lower_fsqrt = true,
|
||||||
|
|
||||||
.lower_wpos_pntc = true,
|
|
||||||
.lower_fsign = true,
|
.lower_fsign = true,
|
||||||
|
|
||||||
.lower_bitfield_insert_to_shifts = true,
|
.lower_bitfield_insert_to_shifts = true,
|
||||||
|
|
|
@ -690,6 +690,10 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
|
||||||
|
|
||||||
*valid |= full;
|
*valid |= full;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PAN_ARCH >= 9
|
||||||
|
cfg.point_sprite_coord_origin_max_y = fb->sprite_coord_origin;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PAN_ARCH >= 6
|
#if PAN_ARCH >= 6
|
||||||
|
|
|
@ -117,6 +117,9 @@ struct pan_fb_info {
|
||||||
union {
|
union {
|
||||||
struct pan_fb_bifrost_info bifrost;
|
struct pan_fb_bifrost_info bifrost;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Only used on Valhall */
|
||||||
|
bool sprite_coord_origin;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned
|
static inline unsigned
|
||||||
|
|
Loading…
Reference in New Issue