i915g: Move cbuf color swizzle lookup to CSO creation time.

Saves walking the loop, and makes a nice place to store a swizzle for use
in other atoms.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11512>
This commit is contained in:
Emma Anholt 2021-06-20 09:19:59 -07:00
parent 5b3840d961
commit bd4121fe04
5 changed files with 47 additions and 46 deletions

View file

@ -73,7 +73,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers,
}
/* correctly swizzle clear value */
if (i915->current.target_fixup_format)
if (i915->current.fixup_swizzle)
util_pack_color(color->f, cbuf->format, &u_color);
else
util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);

View file

@ -170,7 +170,8 @@ struct i915_state
unsigned dst_buf_vars;
uint32_t draw_offset;
uint32_t draw_size;
uint32_t target_fixup_format;
/* Reswizzle for OC writes in PIXEL_SHADER_PROGRAM, or 0 if unnecessary. */
uint32_t fixup_swizzle;
unsigned id; /* track lost context events */
@ -214,6 +215,11 @@ struct i915_sampler_state {
struct i915_surface {
struct pipe_surface templ;
uint32_t buf_info; /* _3DSTATE_BUF_INFO_CMD flags */
/* PIXEL_SHADER_PROGRAM swizzle for OC buffer to handle the cbuf format (or 0 if none). */
uint32_t oc_swizzle;
/* cbuf swizzle from dst r/g/b/a channels in memory to channels of gallium API. */
uint8_t color_swizzle[4];
};
struct i915_velems_state {

View file

@ -179,7 +179,8 @@ static void emit_immediate_s6(struct i915_context *i915, uint imm)
* and therefore we need to use the color factor for alphas. */
uint srcRGB;
if (i915->current.target_fixup_format == PIPE_FORMAT_A8_UNORM) {
if (i915->framebuffer.cbufs[0] &&
i915->framebuffer.cbufs[0]->format == PIPE_FORMAT_A8_UNORM) {
srcRGB = (imm >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK;
if (srcRGB == BLENDFACT_DST_ALPHA)
srcRGB = BLENDFACT_DST_COLR;
@ -425,7 +426,7 @@ validate_program(struct i915_context *i915, unsigned *batch_space)
{
uint additional_size = 0;
additional_size += i915->current.target_fixup_format ? 3 : 0;
additional_size += i915->current.fixup_swizzle ? 3 : 0;
/* we need more batch space if we want to emulate rgba framebuffers */
*batch_space = i915->fs->decl_len + i915->fs->program_len + additional_size;
@ -464,7 +465,7 @@ emit_program(struct i915_context *i915)
}
/* we emit an additional mov with swizzle to fake RGBA framebuffers */
if (i915->current.target_fixup_format) {
if (i915->current.fixup_swizzle) {
/* mov out_color, out_color.zyxw */
OUT_BATCH(A0_MOV |
(REG_TYPE_OC << A0_DEST_TYPE_SHIFT) |

View file

@ -82,6 +82,7 @@ static void update_framebuffer(struct i915_context *i915)
unsigned x, y;
int layer;
uint32_t draw_offset, draw_size;
uint32_t oc_swizzle = 0;
if (cbuf_surface) {
struct i915_surface *surf = i915_surface(cbuf_surface);
@ -95,6 +96,8 @@ static void update_framebuffer(struct i915_context *i915)
x = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksx;
y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy;
oc_swizzle = surf->oc_swizzle;
} else {
i915->current.cbuf_bo = NULL;
x = y = 0;
@ -134,6 +137,11 @@ static void update_framebuffer(struct i915_context *i915)
i915->hardware_dirty |= I915_HW_STATIC;
if (i915->current.fixup_swizzle != oc_swizzle) {
i915->current.fixup_swizzle = oc_swizzle;
i915->hardware_dirty |= I915_HW_PROGRAM;
}
/* flush the cache in case we sample from the old renderbuffers */
i915_set_flush_dirty(i915, I915_FLUSH_CACHE);
}
@ -144,45 +152,12 @@ struct i915_tracked_state i915_hw_framebuffer = {
I915_NEW_FRAMEBUFFER
};
static uint32_t need_target_fixup(struct pipe_surface* p, uint32_t *fixup)
{
const struct
{
enum pipe_format format;
uint hw_swizzle;
} fixup_formats[] = {
{ PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */},
{ PIPE_FORMAT_R8G8B8X8_UNORM, 0x21030000 /* BGRX */},
{ PIPE_FORMAT_L8_UNORM, 0x00030000 /* RRRA */},
{ PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */},
{ PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */},
{ PIPE_FORMAT_NONE, 0x00000000},
};
enum pipe_format f;
/* if we don't have a surface bound yet, we don't need to fixup the shader */
if (!p)
return 0;
f = p->format;
for(int i = 0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
if (fixup_formats[i].format == f) {
*fixup = fixup_formats[i].hw_swizzle;
return f;
}
*fixup = 0;
return 0;
}
static void update_dst_buf_vars(struct i915_context *i915)
{
struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
uint32_t dst_buf_vars, cformat, zformat;
uint32_t early_z = 0;
uint32_t fixup = 0;
int need_fixup;
if (cbuf_surface)
cformat = cbuf_surface->format;
@ -219,14 +194,6 @@ static void update_dst_buf_vars(struct i915_context *i915)
i915->hardware_dirty |= I915_HW_STATIC;
}
need_fixup = need_target_fixup(cbuf_surface, &fixup);
if (i915->current.target_fixup_format != need_fixup ||
i915->current.fixup_swizzle != fixup) {
i915->current.target_fixup_format = need_fixup;
i915->current.fixup_swizzle = fixup;
/* we also send a new program to make sure the fixup for RGBA surfaces happens */
i915->hardware_dirty |= I915_HW_PROGRAM;
}
}
struct i915_tracked_state i915_hw_dst_buf_vars = {

View file

@ -349,6 +349,31 @@ i915_clear_depth_stencil_blitter(struct pipe_context *pipe,
* Screen surface functions
*/
static void i915_set_color_surface_swizzle(struct i915_surface *surf)
{
const struct {
enum pipe_format format;
uint8_t color_swizzle[4];
uint32_t oc_swizzle;
} fixup_formats[] = {
{ PIPE_FORMAT_R8G8B8A8_UNORM, {2, 1, 0, 3 }, 0x21030000 /* BGRA */},
{ PIPE_FORMAT_R8G8B8X8_UNORM, {2, 1, 0, 3 }, 0x21030000 /* BGRX */},
{ PIPE_FORMAT_L8_UNORM, {0, 0, 0, 0 }, 0x00030000 /* RRRA */},
{ PIPE_FORMAT_I8_UNORM, {0, 0, 0, 0 }, 0x00030000 /* RRRA */},
{ PIPE_FORMAT_A8_UNORM, {3, 3, 3, 3 }, 0x33330000 /* AAAA */},
};
for (int i = 0; i < ARRAY_SIZE(fixup_formats); i++) {
if (fixup_formats[i].format == surf->templ.format) {
memcpy(surf->color_swizzle, fixup_formats[i].color_swizzle, sizeof(surf->color_swizzle));
surf->oc_swizzle = fixup_formats[i].oc_swizzle;
return;
}
}
for (int i = 0; i < 4; i++)
surf->color_swizzle[i] = i;
}
static struct pipe_surface *
i915_create_surface_custom(struct pipe_context *ctx,
@ -385,6 +410,8 @@ i915_create_surface_custom(struct pipe_context *ctx,
surf->buf_info = BUF_3D_ID_DEPTH;
} else {
surf->buf_info = BUF_3D_ID_COLOR_BACK;
i915_set_color_surface_swizzle(surf);
}
surf->buf_info |= BUF_3D_PITCH(tex->stride); /* pitch in bytes */