mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 13:00:09 +01:00
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:
parent
5b3840d961
commit
bd4121fe04
5 changed files with 47 additions and 46 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) |
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue