diff options
-rw-r--r-- | src/gallium/drivers/iris/iris_blit.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/iris/iris_clear.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/iris/iris_formats.c | 154 | ||||
-rw-r--r-- | src/gallium/drivers/iris/iris_state.c | 35 |
4 files changed, 117 insertions, 85 deletions
diff --git a/src/gallium/drivers/iris/iris_blit.c b/src/gallium/drivers/iris/iris_blit.c index eb795a08cbe..6562c7b60ec 100644 --- a/src/gallium/drivers/iris/iris_blit.c +++ b/src/gallium/drivers/iris/iris_blit.c @@ -406,7 +406,7 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info) &src_surf, info->src.level, info->src.box.z + slice, src_fmt.fmt, src_fmt.swizzle, &dst_surf, info->dst.level, info->dst.box.z + slice, - dst_fmt.fmt, ISL_SWIZZLE_IDENTITY, + dst_fmt.fmt, dst_fmt.swizzle, src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, filter, mirror_x, mirror_y); diff --git a/src/gallium/drivers/iris/iris_clear.c b/src/gallium/drivers/iris/iris_clear.c index e71d7f450bd..817087f4966 100644 --- a/src/gallium/drivers/iris/iris_clear.c +++ b/src/gallium/drivers/iris/iris_clear.c @@ -42,6 +42,7 @@ clear_color(struct iris_context *ice, const struct pipe_box *box, bool render_condition_enabled, enum isl_format format, + struct isl_swizzle swizzle, union isl_color_value color) { struct iris_resource *res = (void *) p_res; @@ -79,7 +80,7 @@ clear_color(struct iris_context *ice, isl_format_is_rgbx(format)) format = isl_format_rgbx_to_rgba(format); - blorp_clear(&blorp_batch, &surf, format, ISL_SWIZZLE_IDENTITY, + blorp_clear(&blorp_batch, &surf, format, swizzle, level, box->z, box->depth, box->x, box->y, box->x + box->width, box->y + box->height, color, color_write_disable); @@ -205,7 +206,8 @@ iris_clear(struct pipe_context *ctx, }; clear_color(ice, psurf->texture, psurf->u.tex.level, &box, - true, isurf->view.format, *color); + true, isurf->view.format, isurf->view.swizzle, + *color); } } } @@ -270,7 +272,8 @@ iris_clear_texture(struct pipe_context *ctx, isl_color_value_unpack(&color, format, data); - clear_color(ice, p_res, level, box, true, format, color); + clear_color(ice, p_res, level, box, true, format, + ISL_SWIZZLE_IDENTITY, color); } } @@ -303,7 +306,7 @@ iris_clear_render_target(struct pipe_context *ctx, clear_color(ice, psurf->texture, psurf->u.tex.level, &box, render_condition_enabled, - isurf->view.format, *color); + isurf->view.format, isurf->view.swizzle, *color); } /** diff --git a/src/gallium/drivers/iris/iris_formats.c b/src/gallium/drivers/iris/iris_formats.c index c160d19f4ea..91c86efca4d 100644 --- a/src/gallium/drivers/iris/iris_formats.c +++ b/src/gallium/drivers/iris/iris_formats.c @@ -153,26 +153,8 @@ iris_isl_format_for_pipe_format(enum pipe_format pf) [PIPE_FORMAT_B10G10R10A2_UNORM] = ISL_FORMAT_B10G10R10A2_UNORM, [PIPE_FORMAT_R8G8B8X8_UNORM] = ISL_FORMAT_R8G8B8X8_UNORM, -#if 0 - /* Leave these disabled for now, we'd need border color hacks and - * we don't currently have the surface format in that code... - */ - //[PIPE_FORMAT_A8_UINT] = ISL_FORMAT_A8_UINT, - //[PIPE_FORMAT_A8_SINT] = ISL_FORMAT_A8_SINT, - //[PIPE_FORMAT_A8_SNORM] = ISL_FORMAT_A8_SNORM, - //[PIPE_FORMAT_A16_UINT] = ISL_FORMAT_A16_UINT, - //[PIPE_FORMAT_A16_SINT] = ISL_FORMAT_A16_SINT, - //[PIPE_FORMAT_A16_SNORM] = ISL_FORMAT_A16_SNORM, - [PIPE_FORMAT_A16_FLOAT] = ISL_FORMAT_A16_FLOAT, - //[PIPE_FORMAT_A32_UINT] = ISL_FORMAT_A32_UINT, - //[PIPE_FORMAT_A32_SINT] = ISL_FORMAT_A32_SINT, - [PIPE_FORMAT_A32_FLOAT] = ISL_FORMAT_A32_FLOAT, -#endif - [PIPE_FORMAT_A8_UNORM] = ISL_FORMAT_A8_UNORM, - [PIPE_FORMAT_A16_UNORM] = ISL_FORMAT_A16_UNORM, - /* Just use red formats for these - they're actually renderable, - * and faster to sample than the legacy L/I formats. + * and faster to sample than the legacy L/I/A/LA formats. */ [PIPE_FORMAT_I8_UNORM] = ISL_FORMAT_R8_UNORM, [PIPE_FORMAT_I8_UINT] = ISL_FORMAT_R8_UINT, @@ -200,26 +182,38 @@ iris_isl_format_for_pipe_format(enum pipe_format pf) [PIPE_FORMAT_L32_SINT] = ISL_FORMAT_R32_SINT, [PIPE_FORMAT_L32_FLOAT] = ISL_FORMAT_R32_FLOAT, - /* Sadly, there is no R8_SRGB format so we have to use luminance. */ + /* We also map alpha and luminance-alpha formats to red as well, + * though most of these (other than A8_UNORM) will be non-renderable. + */ + [PIPE_FORMAT_A8_UINT] = ISL_FORMAT_R8_UINT, + [PIPE_FORMAT_A8_UNORM] = ISL_FORMAT_R8_UNORM, + [PIPE_FORMAT_A8_SINT] = ISL_FORMAT_R8_SINT, + [PIPE_FORMAT_A8_SNORM] = ISL_FORMAT_R8_SNORM, + [PIPE_FORMAT_A16_UINT] = ISL_FORMAT_R16_UINT, + [PIPE_FORMAT_A16_UNORM] = ISL_FORMAT_R16_UNORM, + [PIPE_FORMAT_A16_SINT] = ISL_FORMAT_R16_SINT, + [PIPE_FORMAT_A16_SNORM] = ISL_FORMAT_R16_SNORM, + [PIPE_FORMAT_A16_FLOAT] = ISL_FORMAT_R16_FLOAT, + [PIPE_FORMAT_A32_UINT] = ISL_FORMAT_R32_UINT, + [PIPE_FORMAT_A32_SINT] = ISL_FORMAT_R32_SINT, + [PIPE_FORMAT_A32_FLOAT] = ISL_FORMAT_R32_FLOAT, + + [PIPE_FORMAT_L8A8_UINT] = ISL_FORMAT_R8G8_UINT, + [PIPE_FORMAT_L8A8_UNORM] = ISL_FORMAT_R8G8_UNORM, + [PIPE_FORMAT_L8A8_SINT] = ISL_FORMAT_R8G8_SINT, + [PIPE_FORMAT_L8A8_SNORM] = ISL_FORMAT_R8G8_SNORM, + [PIPE_FORMAT_L16A16_UINT] = ISL_FORMAT_R16G16_UINT, + [PIPE_FORMAT_L16A16_UNORM] = ISL_FORMAT_R16G16_UNORM, + [PIPE_FORMAT_L16A16_SINT] = ISL_FORMAT_R16G16_SINT, + [PIPE_FORMAT_L16A16_SNORM] = ISL_FORMAT_R16G16_SNORM, + [PIPE_FORMAT_L16A16_FLOAT] = ISL_FORMAT_R16G16_FLOAT, + [PIPE_FORMAT_L32A32_UINT] = ISL_FORMAT_R32G32_UINT, + [PIPE_FORMAT_L32A32_SINT] = ISL_FORMAT_R32G32_SINT, + [PIPE_FORMAT_L32A32_FLOAT] = ISL_FORMAT_R32G32_FLOAT, + + /* Sadly, we have to use luminance[-alpha] formats for sRGB decoding. */ [PIPE_FORMAT_L8_SRGB] = ISL_FORMAT_L8_UNORM_SRGB, - -#if 0 - /* Just fake these with RGBA at a higher level for now */ - [PIPE_FORMAT_L8A8_UINT] = ISL_FORMAT_L8A8_UINT, - [PIPE_FORMAT_L8A8_UNORM] = ISL_FORMAT_L8A8_UNORM, - [PIPE_FORMAT_L8A8_SINT] = ISL_FORMAT_L8A8_SINT, - //[PIPE_FORMAT_L8A8_SNORM] = ISL_FORMAT_L8A8_SNORM, - //[PIPE_FORMAT_L16A16_UINT] = ISL_FORMAT_L16A16_UINT, - [PIPE_FORMAT_L16A16_UNORM] = ISL_FORMAT_L16A16_UNORM, - //[PIPE_FORMAT_L16A16_SINT] = ISL_FORMAT_L16A16_SINT, - //[PIPE_FORMAT_L16A16_SNORM] = ISL_FORMAT_L16A16_SNORM, - [PIPE_FORMAT_L16A16_FLOAT] = ISL_FORMAT_L16A16_FLOAT, - //[PIPE_FORMAT_L32A32_UINT] = ISL_FORMAT_L32A32_UINT, - //[PIPE_FORMAT_L32A32_SINT] = ISL_FORMAT_L32A32_SINT, - [PIPE_FORMAT_L32A32_FLOAT] = ISL_FORMAT_L32A32_FLOAT, - [PIPE_FORMAT_L8A8_SRGB] = ISL_FORMAT_L8A8_UNORM_SRGB, -#endif [PIPE_FORMAT_R10G10B10A2_SSCALED] = ISL_FORMAT_R10G10B10A2_SSCALED, [PIPE_FORMAT_R10G10B10A2_SNORM] = ISL_FORMAT_R10G10B10A2_SNORM, @@ -325,57 +319,45 @@ iris_isl_format_for_pipe_format(enum pipe_format pf) return table[pf]; } -// XXX: use RED for ALPHA textures -UNUSED static enum pipe_format -alpha_to_red(enum pipe_format pf) -{ - switch (pf) { - case PIPE_FORMAT_A8_UNORM: return PIPE_FORMAT_R8_UNORM; - case PIPE_FORMAT_A16_UNORM: return PIPE_FORMAT_R16_UNORM; - case PIPE_FORMAT_A8_SNORM: return PIPE_FORMAT_R8_SNORM; - case PIPE_FORMAT_A16_SNORM: return PIPE_FORMAT_R16_SNORM; - case PIPE_FORMAT_A16_FLOAT: return PIPE_FORMAT_R16_FLOAT; - case PIPE_FORMAT_A32_FLOAT: return PIPE_FORMAT_R32_FLOAT; - case PIPE_FORMAT_A8_UINT: return PIPE_FORMAT_A8_UINT; - case PIPE_FORMAT_A8_SINT: return PIPE_FORMAT_A8_SINT; - case PIPE_FORMAT_A16_UINT: return PIPE_FORMAT_R16_UINT; - case PIPE_FORMAT_A16_SINT: return PIPE_FORMAT_R16_SINT; - case PIPE_FORMAT_A32_UINT: return PIPE_FORMAT_R32_UINT; - case PIPE_FORMAT_A32_SINT: return PIPE_FORMAT_R32_SINT; - default: return pf; - } -} - struct iris_format_info iris_format_for_usage(const struct gen_device_info *devinfo, enum pipe_format pformat, isl_surf_usage_flags_t usage) { + enum isl_format format = iris_isl_format_for_pipe_format(pformat); struct isl_swizzle swizzle = ISL_SWIZZLE_IDENTITY; - if (usage & ISL_SURF_USAGE_TEXTURE_BIT) { - if (!util_format_is_srgb(pformat)) { - if (util_format_is_intensity(pformat)) { - swizzle = ISL_SWIZZLE(RED, RED, RED, RED); - } else if (util_format_is_luminance(pformat)) { - swizzle = ISL_SWIZZLE(RED, RED, RED, ONE); - //} else if (util_format_is_alpha(pformat)) { - //pformat = alpha_to_red(pformat); - //swizzle = ISL_SWIZZLE(ZERO, ZERO, ZERO, RED); - } + if (!util_format_is_srgb(pformat)) { + if (util_format_is_intensity(pformat)) { + swizzle = ISL_SWIZZLE(RED, RED, RED, RED); + } else if (util_format_is_luminance(pformat)) { + swizzle = ISL_SWIZZLE(RED, RED, RED, ONE); + } else if (util_format_is_luminance_alpha(pformat)) { + swizzle = ISL_SWIZZLE(RED, RED, RED, GREEN); + } else if (util_format_is_alpha(pformat)) { + swizzle = ISL_SWIZZLE(ZERO, ZERO, ZERO, RED); } - if (pformat == PIPE_FORMAT_DXT1_RGB || - pformat == PIPE_FORMAT_DXT1_SRGB) - swizzle = ISL_SWIZZLE(RED, GREEN, BLUE, ONE); } - enum isl_format format = iris_isl_format_for_pipe_format(pformat); + if (pformat == PIPE_FORMAT_DXT1_RGB || + pformat == PIPE_FORMAT_DXT1_SRGB) { + swizzle = ISL_SWIZZLE(RED, GREEN, BLUE, ONE); + } - /* Convert RGBX into RGBA for rendering */ - if (isl_format_is_rgbx(format) && - (usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) && - !isl_format_supports_rendering(devinfo, format)) { - format = isl_format_rgbx_to_rgba(format); + if (usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) { + if (isl_format_is_rgbx(format) && + !isl_format_supports_rendering(devinfo, format)) { + format = isl_format_rgbx_to_rgba(format); + } else if (pformat == PIPE_FORMAT_A8_UNORM) { + /* Most of the hardware A/LA formats are not renderable, except + * for A8_UNORM. SURFACE_STATE's shader channel select fields + * cannot be used to swap RGB and A channels when rendering (as + * it could impact alpha blending), so we have to use the actual + * A8_UNORM format when rendering. + */ + format = ISL_FORMAT_A8_UNORM; + swizzle = ISL_SWIZZLE_IDENTITY; + } } return (struct iris_format_info) { .fmt = format, .swizzle = swizzle }; @@ -427,6 +409,24 @@ iris_is_format_supported(struct pipe_screen *pscreen, } if (usage & PIPE_BIND_RENDER_TARGET) { + /* Alpha and luminance-alpha formats other than A8_UNORM are not + * renderable. For texturing, we can use R or RG formats with + * shader channel selects (SCS) to swizzle the data into the correct + * channels. But for render targets, the hardware prohibits using + * SCS to move shader outputs between the RGB and A channels, as it + * would alter what data is used for alpha blending. + * + * For BLORP, we can apply the swizzle in the shader. But for + * general rendering, this would mean recompiling the shader, which + * we'd like to avoid doing. So we mark these formats non-renderable. + * + * We do support A8_UNORM as it's required and is renderable. + */ + if (pformat != PIPE_FORMAT_A8_UNORM && + (util_format_is_alpha(pformat) || + util_format_is_luminance_alpha(pformat))) + supported = false; + enum isl_format rt_format = format; if (isl_format_is_rgbx(format) && diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 0483bb8caa0..f8d23dd784b 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -1498,6 +1498,7 @@ iris_upload_sampler_states(struct iris_context *ice, gl_shader_stage stage) for (int i = 0; i < count; i++) { struct iris_sampler_state *state = shs->samplers[i]; + struct iris_sampler_view *tex = shs->textures[i]; if (!state) { memset(map, 0, 4 * GENX(SAMPLER_STATE_length)); @@ -1506,9 +1507,37 @@ iris_upload_sampler_states(struct iris_context *ice, gl_shader_stage stage) } else { ice->state.need_border_colors |= 1 << stage; + /* We may need to swizzle the border color for format faking. + * A/LA formats are faked as R/RG with 000R or R00G swizzles. + * This means we need to move the border color's A channel into + * the R or G channels so that those read swizzles will move it + * back into A. + */ + union pipe_color_union *color = &state->border_color; + if (tex) { + union pipe_color_union tmp; + enum pipe_format internal_format = tex->res->internal_format; + + if (util_format_is_alpha(internal_format)) { + unsigned char swz[4] = { + PIPE_SWIZZLE_W, PIPE_SWIZZLE_0, + PIPE_SWIZZLE_0, PIPE_SWIZZLE_0 + }; + util_format_apply_color_swizzle(&tmp, color, swz, true); + color = &tmp; + } else if (util_format_is_luminance_alpha(internal_format) && + internal_format != PIPE_FORMAT_L8A8_SRGB) { + unsigned char swz[4] = { + PIPE_SWIZZLE_X, PIPE_SWIZZLE_W, + PIPE_SWIZZLE_0, PIPE_SWIZZLE_0 + }; + util_format_apply_color_swizzle(&tmp, color, swz, true); + color = &tmp; + } + } + /* Stream out the border color and merge the pointer. */ - uint32_t offset = - iris_upload_border_color(ice, &state->border_color); + uint32_t offset = iris_upload_border_color(ice, color); uint32_t dynamic[GENX(SAMPLER_STATE_length)]; iris_pack_state(GENX(SAMPLER_STATE), dynamic, dyns) { @@ -1709,7 +1738,7 @@ iris_create_sampler_view(struct pipe_context *ctx, } } else { fill_buffer_surface_state(&screen->isl_dev, isv->res->bo, map, - isv->view.format, ISL_SWIZZLE_IDENTITY, + isv->view.format, isv->view.swizzle, tmpl->u.buf.offset, tmpl->u.buf.size); } |