llvmpipe/linear: add support for sampling when cbuf order is different.

This rewrites bgra sampling when the output is rgba,
and vice-versa.

It allows to skip swaps if the sampling and cbuf match.

Reviewed-by: Brian Paul <brianp@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24066>
This commit is contained in:
Dave Airlie 2023-07-10 17:32:53 +10:00 committed by Marge Bot
parent a3f586685d
commit f96b6027a1
3 changed files with 143 additions and 59 deletions

View file

@ -85,6 +85,9 @@ lp_fs_linear_run(const struct lp_rast_state *state,
{
const struct lp_fragment_shader_variant *variant = state->variant;
const struct lp_tgsi_info *info = &variant->shader->info;
const struct lp_fragment_shader_variant_key *key = &variant->key;
bool rgba_order = (key->cbuf_format[0] == PIPE_FORMAT_R8G8B8A8_UNORM ||
key->cbuf_format[0] == PIPE_FORMAT_R8G8B8X8_UNORM);
uint8_t constants[LP_MAX_LINEAR_CONSTANTS * 4];
LP_DBG(DEBUG_RAST, "%s\n", __func__);
@ -182,7 +185,7 @@ lp_fs_linear_run(const struct lp_rast_state *state,
if (!lp_linear_init_sampler(&samp[i], tex_info,
lp_fs_variant_key_sampler_idx(&variant->key, samp_unit),
&state->jit_resources.textures[tex_unit],
x, y, width, height, a0, dadx, dady)) {
x, y, width, height, a0, dadx, dady, rgba_order)) {
if (LP_DEBUG & DEBUG_LINEAR2)
debug_printf(" -- init_sampler(%d) failed\n", i);
goto fail;

View file

@ -144,7 +144,7 @@ lp_linear_init_sampler(struct lp_linear_sampler *samp,
int x0, int y0, int width, int height,
const float (*a0)[4],
const float (*dadx)[4],
const float (*dady)[4]);
const float (*dady)[4], bool rgba_order);
bool

View file

@ -546,7 +546,8 @@ lp_linear_init_sampler(struct lp_linear_sampler *samp,
int x0, int y0, int width, int height,
const float (*a0)[4],
const float (*dadx)[4],
const float (*dady)[4])
const float (*dady)[4],
bool rgba_order)
{
const struct lp_tgsi_channel_info *schan = &info->coord[0];
const struct lp_tgsi_channel_info *tchan = &info->coord[1];
@ -693,44 +694,88 @@ lp_linear_init_sampler(struct lp_linear_sampler *samp,
if (is_nearest) {
switch (sampler_state->texture_state.format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_bgra;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgra;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgra;
else
samp->base.fetch = fetch_memcpy_bgra;
if (rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgra_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgra_swapped;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgra_swapped;
else
samp->base.fetch = fetch_memcpy_bgra_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgra;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgra;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgra;
else
samp->base.fetch = fetch_memcpy_bgra;
}
return true;
case PIPE_FORMAT_B8G8R8X8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_bgrx;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgrx;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgrx;
else
samp->base.fetch = fetch_memcpy_bgrx;
if (rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgrx_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgrx_swapped;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgrx_swapped;
else
samp->base.fetch = fetch_memcpy_bgrx_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgrx;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgrx;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgrx;
else
samp->base.fetch = fetch_memcpy_bgrx;
}
return true;
case PIPE_FORMAT_R8G8B8A8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_bgra_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgra_swapped;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgra_swapped;
else
samp->base.fetch = fetch_memcpy_bgra_swapped;
if (!rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgra_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgra_swapped;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgra_swapped;
else
samp->base.fetch = fetch_memcpy_bgra_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgra;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgra;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgra;
else
samp->base.fetch = fetch_memcpy_bgra;
}
return true;
case PIPE_FORMAT_R8G8B8X8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_bgrx_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgrx_swapped;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgrx_swapped;
else
samp->base.fetch = fetch_memcpy_bgrx_swapped;
if (!rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgrx_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgrx_swapped;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgrx_swapped;
else
samp->base.fetch = fetch_memcpy_bgrx_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_bgrx;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_bgrx;
else if (samp->dsdx != FIXED16_ONE) // TODO: could be relaxed
samp->base.fetch = fetch_axis_aligned_bgrx;
else
samp->base.fetch = fetch_memcpy_bgrx;
}
return true;
default:
break;
@ -744,36 +789,72 @@ lp_linear_init_sampler(struct lp_linear_sampler *samp,
switch (sampler_state->texture_state.format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgra;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgra;
else
samp->base.fetch = fetch_axis_aligned_linear_bgra;
if (rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgra_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgra_swapped;
else
samp->base.fetch = fetch_axis_aligned_linear_bgra_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgra;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgra;
else
samp->base.fetch = fetch_axis_aligned_linear_bgra;
}
return true;
case PIPE_FORMAT_B8G8R8X8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgrx;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgrx;
else
samp->base.fetch = fetch_axis_aligned_linear_bgrx;
if (rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgrx_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgrx_swapped;
else
samp->base.fetch = fetch_axis_aligned_linear_bgrx_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgrx;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgrx;
else
samp->base.fetch = fetch_axis_aligned_linear_bgrx;
}
return true;
case PIPE_FORMAT_R8G8B8A8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgra_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgra_swapped;
else
samp->base.fetch = fetch_axis_aligned_linear_bgra_swapped;
if (!rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgra_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgra_swapped;
else
samp->base.fetch = fetch_axis_aligned_linear_bgra_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgra;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgra;
else
samp->base.fetch = fetch_axis_aligned_linear_bgra;
}
return true;
case PIPE_FORMAT_R8G8B8X8_UNORM:
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgrx_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgrx_swapped;
else
samp->base.fetch = fetch_axis_aligned_linear_bgrx_swapped;
if (!rgba_order) {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgrx_swapped;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgrx_swapped;
else
samp->base.fetch = fetch_axis_aligned_linear_bgrx_swapped;
} else {
if (need_wrap)
samp->base.fetch = fetch_clamp_linear_bgrx;
else if (!samp->axis_aligned)
samp->base.fetch = fetch_linear_bgrx;
else
samp->base.fetch = fetch_axis_aligned_linear_bgrx;
}
return true;
default:
break;