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;
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);
};
clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
- true, isurf->view.format, *color);
+ true, isurf->view.format, isurf->view.swizzle,
+ *color);
}
}
}
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);
}
}
clear_color(ice, psurf->texture, psurf->u.tex.level, &box,
render_condition_enabled,
- isurf->view.format, *color);
+ isurf->view.format, isurf->view.swizzle, *color);
}
/**
[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,
[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,
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 };
}
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) &&
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));
} 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) {
}
} 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);
}