ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw);
for (i = 0; i < num_targets; i++) {
- const unsigned idx = (blend->independent_blend_enable) ? i : 0;
- const struct ilo_blend_cso *cso = &blend->cso[idx];
- const int num_samples = fb->num_samples;
- const struct util_format_description *format_desc =
- (idx < fb->state.nr_cbufs && fb->state.cbufs[idx]) ?
- util_format_description(fb->state.cbufs[idx]->format) : NULL;
- bool rt_is_unorm, rt_is_pure_integer, rt_dst_alpha_forced_one;
-
- rt_is_unorm = true;
- rt_is_pure_integer = false;
- rt_dst_alpha_forced_one = false;
-
- if (format_desc) {
- int ch;
-
- switch (format_desc->format) {
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- /* force alpha to one when the HW format has alpha */
- assert(ilo_translate_render_format(builder->dev,
- PIPE_FORMAT_B8G8R8X8_UNORM) ==
- GEN6_FORMAT_B8G8R8A8_UNORM);
- rt_dst_alpha_forced_one = true;
- break;
- default:
- break;
- }
+ const struct ilo_blend_cso *cso =
+ &blend->cso[(blend->independent_blend_enable) ? i : 0];
- for (ch = 0; ch < 4; ch++) {
- if (format_desc->channel[ch].type == UTIL_FORMAT_TYPE_VOID)
- continue;
+ dw[0] = cso->payload[0];
+ dw[1] = cso->payload[1];
- if (format_desc->channel[ch].pure_integer) {
- rt_is_unorm = false;
- rt_is_pure_integer = true;
- break;
- }
+ if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) {
+ const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
- if (!format_desc->channel[ch].normalized ||
- format_desc->channel[ch].type != UTIL_FORMAT_TYPE_UNSIGNED)
- rt_is_unorm = false;
+ if (caps->can_blend) {
+ if (caps->dst_alpha_forced_one)
+ dw[0] |= cso->dw_blend_dst_alpha_forced_one;
+ else
+ dw[0] |= cso->dw_blend;
}
- }
- dw[0] = cso->payload[0];
- dw[1] = cso->payload[1];
-
- if (!rt_is_pure_integer) {
- if (rt_dst_alpha_forced_one)
- dw[0] |= cso->dw_blend_dst_alpha_forced_one;
- else
- dw[0] |= cso->dw_blend;
+ if (caps->can_logicop)
+ dw[1] |= cso->dw_logicop;
+
+ if (caps->can_alpha_test)
+ dw[1] |= dsa->dw_alpha;
+ } else {
+ dw[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_A |
+ GEN6_BLEND_DW1_WRITE_DISABLE_R |
+ GEN6_BLEND_DW1_WRITE_DISABLE_G |
+ GEN6_BLEND_DW1_WRITE_DISABLE_B |
+ dsa->dw_alpha;
}
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 365:
- *
- * "Logic Ops are only supported on *_UNORM surfaces (excluding
- * _SRGB variants), otherwise Logic Ops must be DISABLED."
- *
- * Since logicop is ignored for non-UNORM color buffers, no special care
- * is needed.
- */
- if (rt_is_unorm)
- dw[1] |= cso->dw_logicop;
-
/*
* From the Sandy Bridge PRM, volume 2 part 1, page 356:
*
* There is no such limitation on GEN7, or for AlphaToOne. But GL
* requires that anyway.
*/
- if (num_samples > 1)
+ if (fb->num_samples > 1)
dw[1] |= cso->dw_alpha_mod;
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 382:
- *
- * "Alpha Test can only be enabled if Pixel Shader outputs a float
- * alpha value."
- */
- if (!rt_is_pure_integer)
- dw[1] |= dsa->dw_alpha;
-
dw += 2;
}
}
}
+static void
+fb_set_blend_caps(const struct ilo_dev_info *dev,
+ enum pipe_format format,
+ struct ilo_fb_blend_caps *caps)
+{
+ const struct util_format_description *desc =
+ util_format_description(format);
+ const int ch = util_format_get_first_non_void_channel(format);
+
+ memset(caps, 0, sizeof(*caps));
+
+ if (format == PIPE_FORMAT_NONE || desc->is_mixed)
+ return;
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 365:
+ *
+ * "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
+ * variants), otherwise Logic Ops must be DISABLED."
+ */
+ caps->can_logicop = (ch >= 0 && desc->channel[ch].normalized &&
+ desc->channel[ch].type == UTIL_FORMAT_TYPE_UNSIGNED &&
+ desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB);
+
+ /* no blending for pure integer formats */
+ caps->can_blend = !util_format_is_pure_integer(format);
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 382:
+ *
+ * "Alpha Test can only be enabled if Pixel Shader outputs a float
+ * alpha value."
+ */
+ caps->can_alpha_test = !util_format_is_pure_integer(format);
+
+ caps->dst_alpha_forced_one =
+ (ilo_translate_render_format(dev, format) !=
+ ilo_translate_color_format(dev, format));
+
+ /* sanity check */
+ if (caps->dst_alpha_forced_one) {
+ enum pipe_format render_format;
+
+ switch (format) {
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ render_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ default:
+ render_format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ assert(ilo_translate_render_format(dev, format) ==
+ ilo_translate_color_format(dev, render_format));
+ }
+}
+
void
ilo_gpe_set_fb(const struct ilo_dev_info *dev,
const struct pipe_framebuffer_state *state,
struct ilo_fb_state *fb)
{
- const struct pipe_surface *first;
- unsigned first_idx;
+ const struct pipe_surface *first_surf = NULL;
+ int i;
ILO_DEV_ASSERT(dev, 6, 7.5);
(state->height) ? state->height : 1,
1, 0, &fb->null_rt);
- first = NULL;
- for (first_idx = 0; first_idx < state->nr_cbufs; first_idx++) {
- if (state->cbufs[first_idx]) {
- first = state->cbufs[first_idx];
- break;
+ for (i = 0; i < state->nr_cbufs; i++) {
+ if (state->cbufs[i]) {
+ fb_set_blend_caps(dev, state->cbufs[i]->format, &fb->blend_caps[i]);
+
+ if (!first_surf)
+ first_surf = state->cbufs[i];
+ } else {
+ fb_set_blend_caps(dev, PIPE_FORMAT_NONE, &fb->blend_caps[i]);
}
}
- if (!first)
- first = state->zsbuf;
- fb->num_samples = (first) ? first->texture->nr_samples : 1;
+ if (!first_surf && state->zsbuf)
+ first_surf = state->zsbuf;
+
+ fb->num_samples = (first_surf) ? first_surf->texture->nr_samples : 1;
if (!fb->num_samples)
fb->num_samples = 1;