static inline void
gen6_3DSTATE_MULTISAMPLE(struct ilo_builder *builder,
const struct ilo_state_raster *rs,
- const uint32_t *pattern, int pattern_len)
+ const struct ilo_state_sample_pattern *pattern,
+ uint8_t sample_count)
{
const uint8_t cmd_len = (ilo_dev_gen(builder->dev) >= ILO_GEN(7)) ? 4 : 3;
+ const uint32_t *packed = (const uint32_t *)
+ ilo_state_sample_pattern_get_packed_offsets(pattern,
+ builder->dev, sample_count);
uint32_t *dw;
ILO_DEV_ASSERT(builder->dev, 6, 7.5);
/* see raster_set_gen8_3DSTATE_MULTISAMPLE() */
dw[1] = rs->sample[0];
- assert(pattern_len == 1 || pattern_len == 2);
- dw[2] = pattern[0];
+ /* see sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN() */
+ dw[2] = (sample_count >= 4) ? packed[0] : 0;
if (ilo_dev_gen(builder->dev) >= ILO_GEN(7))
- dw[3] = (pattern_len == 2) ? pattern[1] : 0;
+ dw[3] = (sample_count >= 8) ? packed[1] : 0;
}
static inline void
static inline void
gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_builder *builder,
- const uint32_t *pattern_1x,
- const uint32_t *pattern_2x,
- const uint32_t *pattern_4x,
- const uint32_t *pattern_8x,
- const uint32_t *pattern_16x)
+ const struct ilo_state_sample_pattern *pattern)
{
const uint8_t cmd_len = 9;
uint32_t *dw;
ilo_builder_batch_pointer(builder, cmd_len, &dw);
dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_SAMPLE_PATTERN) | (cmd_len - 2);
- dw[1] = pattern_16x[3];
- dw[2] = pattern_16x[2];
- dw[3] = pattern_16x[1];
- dw[4] = pattern_16x[0];
- dw[5] = pattern_8x[1];
- dw[6] = pattern_8x[0];
- dw[7] = pattern_4x[0];
- dw[8] = pattern_1x[0] << 16 |
- pattern_2x[0];
+ dw[1] = 0;
+ dw[2] = 0;
+ dw[3] = 0;
+ dw[4] = 0;
+ /* see sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN() */
+ dw[5] = ((const uint32_t *) pattern->pattern_8x)[1];
+ dw[6] = ((const uint32_t *) pattern->pattern_8x)[0];
+ dw[7] = ((const uint32_t *) pattern->pattern_4x)[0];
+ dw[8] = pattern->pattern_1x[0] << 16 |
+ ((const uint16_t *) pattern->pattern_2x)[0];
}
static inline void
return true;
}
+static bool
+sample_pattern_get_gen6_packed_offsets(const struct ilo_dev *dev,
+ uint8_t sample_count,
+ const struct ilo_state_sample_pattern_offset_info *in,
+ uint8_t *out)
+{
+ uint8_t max_dist, i;
+
+ ILO_DEV_ASSERT(dev, 6, 8);
+
+ max_dist = 0;
+ for (i = 0; i < sample_count; i++) {
+ const int8_t dist_x = (int8_t) in[i].x - 8;
+ const int8_t dist_y = (int8_t) in[i].y - 8;
+ const uint8_t dist = dist_x * dist_x + dist_y * dist_y;
+
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 305:
+ *
+ * "Programming Note: When programming the sample offsets (for
+ * NUMSAMPLES_4 or _8 and MSRASTMODE_xxx_PATTERN), the order of the
+ * samples 0 to 3 (or 7 for 8X) must have monotonically increasing
+ * distance from the pixel center. This is required to get the
+ * correct centroid computation in the device."
+ */
+ assert(dist >= max_dist);
+ max_dist = dist;
+
+ assert(in[i].x < 16);
+ assert(in[i].y < 16);
+
+ out[i] = in[i].x << 4 | in[i].y;
+ }
+
+ return true;
+}
+
+static bool
+sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev,
+ const struct ilo_state_sample_pattern_info *info)
+{
+ ILO_DEV_ASSERT(dev, 6, 8);
+
+ STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_1x) >= 1);
+ STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_2x) >= 2);
+ STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_4x) >= 4);
+ STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_8x) >= 8);
+ STATIC_ASSERT(ARRAY_SIZE(pattern->pattern_16x) >= 16);
+
+ return (sample_pattern_get_gen6_packed_offsets(dev, 1,
+ info->pattern_1x, pattern->pattern_1x) &&
+ sample_pattern_get_gen6_packed_offsets(dev, 2,
+ info->pattern_2x, pattern->pattern_2x) &&
+ sample_pattern_get_gen6_packed_offsets(dev, 4,
+ info->pattern_4x, pattern->pattern_4x) &&
+ sample_pattern_get_gen6_packed_offsets(dev, 8,
+ info->pattern_8x, pattern->pattern_8x) &&
+ sample_pattern_get_gen6_packed_offsets(dev, 16,
+ info->pattern_16x, pattern->pattern_16x));
+
+}
+
bool
ilo_state_raster_init(struct ilo_state_raster *rs,
const struct ilo_dev *dev,
delta->dirty |= ILO_STATE_RASTER_3DSTATE_WM_HZ_OP;
}
}
+
+bool
+ilo_state_sample_pattern_init(struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev,
+ const struct ilo_state_sample_pattern_info *info)
+{
+ bool ret = true;
+
+ ret &= sample_pattern_set_gen8_3DSTATE_SAMPLE_PATTERN(pattern, dev, info);
+
+ assert(ret);
+
+ return ret;
+}
+
+bool
+ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev)
+{
+ static const struct ilo_state_sample_pattern_info default_info = {
+ .pattern_1x = {
+ { 8, 8 },
+ },
+
+ .pattern_2x = {
+ { 4, 4 }, { 12, 12 },
+ },
+
+ .pattern_4x = {
+ { 6, 2 }, { 14, 6 }, { 2, 10 }, { 10, 14 },
+ },
+
+ /* \see brw_multisample_positions_8x */
+ .pattern_8x = {
+ { 7, 9 }, { 9, 13 }, { 11, 3 }, { 13, 11 },
+ { 1, 7 }, { 5, 1 }, { 15, 5 }, { 3, 15 },
+ },
+
+ .pattern_16x = {
+ { 8, 10 }, { 11, 8 }, { 5, 6 }, { 6, 4 },
+ { 12, 11 }, { 13, 9 }, { 14, 7 }, { 10, 2 },
+ { 4, 13 }, { 3, 3 }, { 7, 1 }, { 15, 5 },
+ { 1, 12 }, { 9, 0 }, { 2, 14 }, { 0, 15 },
+ },
+ };
+
+ return ilo_state_sample_pattern_init(pattern, dev, &default_info);
+}
+
+const uint8_t *
+ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev,
+ uint8_t sample_count)
+{
+ switch (sample_count) {
+ case 1: return pattern->pattern_1x;
+ case 2: return pattern->pattern_2x;
+ case 4: return pattern->pattern_4x;
+ case 8: return pattern->pattern_8x;
+ case 16: return pattern->pattern_16x;
+ default:
+ assert(!"unknown sample count");
+ return NULL;
+ }
+}
+
+void
+ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev,
+ uint8_t sample_count, uint8_t sample_index,
+ uint8_t *x, uint8_t *y)
+{
+ const const uint8_t *packed =
+ ilo_state_sample_pattern_get_packed_offsets(pattern, dev, sample_count);
+
+ assert(sample_index < sample_count);
+
+ *x = (packed[sample_index] >> 4) & 0xf;
+ *y = packed[sample_index] & 0xf;
+}
uint32_t dirty;
};
+struct ilo_state_sample_pattern_offset_info {
+ /* in U0.4 */
+ uint8_t x;
+ uint8_t y;
+};
+
+struct ilo_state_sample_pattern_info {
+ struct ilo_state_sample_pattern_offset_info pattern_1x[1];
+ struct ilo_state_sample_pattern_offset_info pattern_2x[2];
+ struct ilo_state_sample_pattern_offset_info pattern_4x[4];
+ struct ilo_state_sample_pattern_offset_info pattern_8x[8];
+ struct ilo_state_sample_pattern_offset_info pattern_16x[16];
+};
+
+struct ilo_state_sample_pattern {
+ uint8_t pattern_1x[1];
+ uint8_t pattern_2x[2];
+ uint8_t pattern_4x[4];
+ uint8_t pattern_8x[8];
+ uint8_t pattern_16x[16];
+};
+
bool
ilo_state_raster_init(struct ilo_state_raster *rs,
const struct ilo_dev *dev,
const struct ilo_state_raster *old,
struct ilo_state_raster_delta *delta);
+bool
+ilo_state_sample_pattern_init(struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev,
+ const struct ilo_state_sample_pattern_info *info);
+
+bool
+ilo_state_sample_pattern_init_default(struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev);
+
+const uint8_t *
+ilo_state_sample_pattern_get_packed_offsets(const struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev,
+ uint8_t sample_count);
+
+void
+ilo_state_sample_pattern_get_offset(const struct ilo_state_sample_pattern *pattern,
+ const struct ilo_dev *dev,
+ uint8_t sample_count, uint8_t sample_index,
+ uint8_t *x, uint8_t *y);
+
#endif /* ILO_STATE_RASTER_H */
#include "ilo_query.h"
#include "ilo_render_gen.h"
-/* in S1.3 */
-struct sample_position {
- int8_t x, y;
-};
-
-static const struct sample_position ilo_sample_pattern_1x[1] = {
- { 0, 0 },
-};
-
-static const struct sample_position ilo_sample_pattern_2x[2] = {
- { -4, -4 },
- { 4, 4 },
-};
-
-static const struct sample_position ilo_sample_pattern_4x[4] = {
- { -2, -6 },
- { 6, -2 },
- { -6, 2 },
- { 2, 6 },
-};
-
-/* \see brw_multisample_positions_8x */
-static const struct sample_position ilo_sample_pattern_8x[8] = {
- { -1, 1 },
- { 1, 5 },
- { 3, -5 },
- { 5, 3 },
- { -7, -1 },
- { -3, -7 },
- { 7, -3 },
- { -5, 7 },
-};
-
-static const struct sample_position ilo_sample_pattern_16x[16] = {
- { 0, 2 },
- { 3, 0 },
- { -3, -2 },
- { -2, -4 },
- { 4, 3 },
- { 5, 1 },
- { 6, -1 },
- { 2, -6 },
- { -4, 5 },
- { -5, -5 },
- { -1, -7 },
- { 7, -3 },
- { -7, 4 },
- { 1, -8 },
- { -6, 6 },
- { -8, 7 },
-};
-
-static uint8_t
-pack_sample_position(const struct sample_position *pos)
-{
- return (pos->x + 8) << 4 | (pos->y + 8);
-}
-
-static void
-get_sample_position(const struct sample_position *pos, float *x, float *y)
-{
- *x = (float) (pos->x + 8) / 16.0f;
- *y = (float) (pos->y + 8) / 16.0f;
-}
-
struct ilo_render *
ilo_render_create(struct ilo_builder *builder)
{
struct ilo_render *render;
- int i;
render = CALLOC_STRUCT(ilo_render);
if (!render)
return NULL;
}
- /* pack into dwords */
- render->sample_pattern_1x = pack_sample_position(ilo_sample_pattern_1x);
- render->sample_pattern_2x =
- pack_sample_position(&ilo_sample_pattern_2x[1]) << 8 |
- pack_sample_position(&ilo_sample_pattern_2x[0]);
- for (i = 0; i < 4; i++) {
- render->sample_pattern_4x |=
- pack_sample_position(&ilo_sample_pattern_4x[i]) << (8 * i);
-
- render->sample_pattern_8x[0] |=
- pack_sample_position(&ilo_sample_pattern_8x[i]) << (8 * i);
- render->sample_pattern_8x[1] |=
- pack_sample_position(&ilo_sample_pattern_8x[i + 4]) << (8 * i);
-
- render->sample_pattern_16x[0] |=
- pack_sample_position(&ilo_sample_pattern_16x[i]) << (8 * i);
- render->sample_pattern_16x[1] |=
- pack_sample_position(&ilo_sample_pattern_16x[i + 4]) << (8 * i);
- render->sample_pattern_16x[2] |=
- pack_sample_position(&ilo_sample_pattern_16x[i + 8]) << (8 * i);
- render->sample_pattern_16x[3] |=
- pack_sample_position(&ilo_sample_pattern_16x[i + 12]) << (8 * i);
- }
+ ilo_state_sample_pattern_init_default(&render->sample_pattern,
+ render->dev);
ilo_render_invalidate_hw(render);
ilo_render_invalidate_builder(render);
unsigned sample_index,
float *x, float *y)
{
- const struct sample_position *pattern;
+ uint8_t off_x, off_y;
- switch (sample_count) {
- case 1:
- assert(sample_index < Elements(ilo_sample_pattern_1x));
- pattern = ilo_sample_pattern_1x;
- break;
- case 2:
- assert(sample_index < Elements(ilo_sample_pattern_2x));
- pattern = ilo_sample_pattern_2x;
- break;
- case 4:
- assert(sample_index < Elements(ilo_sample_pattern_4x));
- pattern = ilo_sample_pattern_4x;
- break;
- case 8:
- assert(sample_index < Elements(ilo_sample_pattern_8x));
- pattern = ilo_sample_pattern_8x;
- break;
- case 16:
- assert(sample_index < Elements(ilo_sample_pattern_16x));
- pattern = ilo_sample_pattern_16x;
- break;
- default:
- assert(!"unknown sample count");
- *x = 0.5f;
- *y = 0.5f;
- return;
- break;
- }
+ ilo_state_sample_pattern_get_offset(&render->sample_pattern, render->dev,
+ sample_count, sample_index, &off_x, &off_y);
- get_sample_position(&pattern[sample_index], x, y);
+ *x = (float) off_x / 16.0f;
+ *y = (float) off_y / 16.0f;
}
void
void
ilo_render_destroy(struct ilo_render *render);
-/**
- * Estimate the size of an action.
- */
void
ilo_render_get_sample_position(const struct ilo_render *render,
unsigned sample_count,
struct intel_bo *workaround_bo;
- uint32_t sample_pattern_1x;
- uint32_t sample_pattern_2x;
- uint32_t sample_pattern_4x;
- uint32_t sample_pattern_8x[2];
- uint32_t sample_pattern_16x[4];
+ struct ilo_state_sample_pattern sample_pattern;
bool hw_ctx_changed;
/* 3DSTATE_MULTISAMPLE */
if (DIRTY(FB) || (session->rs_delta.dirty &
ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)) {
- const uint32_t *pattern;
-
- pattern = (vec->fb.num_samples > 1) ?
- &r->sample_pattern_4x : &r->sample_pattern_1x;
+ const uint8_t sample_count = (vec->fb.num_samples > 1) ? 4 : 1;
if (ilo_dev_gen(r->dev) == ILO_GEN(6)) {
gen6_wa_pre_non_pipelined(r);
gen6_wa_pre_3dstate_multisample(r);
}
- gen6_3DSTATE_MULTISAMPLE(r->builder,
- &vec->rasterizer->rs, pattern, 1);
+ gen6_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs,
+ &r->sample_pattern, sample_count);
}
/* 3DSTATE_SAMPLE_MASK */
gen6_rectlist_wm_multisample(struct ilo_render *r,
const struct ilo_blitter *blitter)
{
- const uint32_t *pattern = (blitter->fb.num_samples > 1) ?
- &r->sample_pattern_4x : &r->sample_pattern_1x;
+ const uint8_t sample_count = (blitter->fb.num_samples > 1) ? 4 : 1;
gen6_wa_pre_3dstate_multisample(r);
- gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs, pattern, true);
+ gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs, &r->sample_pattern, sample_count);
gen6_3DSTATE_SAMPLE_MASK(r->builder, &blitter->fb.rs);
}
/* 3DSTATE_MULTISAMPLE */
if (DIRTY(FB) || (session->rs_delta.dirty &
ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)) {
- const uint32_t *pattern;
- int pattern_len;
+ const uint8_t sample_count = (vec->fb.num_samples > 4) ? 8 :
+ (vec->fb.num_samples > 1) ? 4 : 1;
gen7_wa_pre_3dstate_multisample(r);
- if (vec->fb.num_samples > 4) {
- pattern = r->sample_pattern_8x;
- pattern_len = ARRAY_SIZE(r->sample_pattern_8x);
- } else {
- pattern = (vec->fb.num_samples > 1) ?
- &r->sample_pattern_4x : &r->sample_pattern_1x;
- pattern_len = 1;
- }
-
gen6_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs,
- pattern, pattern_len);
+ &r->sample_pattern, sample_count);
}
/* 3DSTATE_SAMPLE_MASK */
gen7_rectlist_wm_multisample(struct ilo_render *r,
const struct ilo_blitter *blitter)
{
- const uint32_t *pattern;
- int pattern_len;
-
- if (blitter->fb.num_samples > 4) {
- pattern = r->sample_pattern_8x;
- pattern_len = ARRAY_SIZE(r->sample_pattern_8x);
- } else {
- pattern = (blitter->fb.num_samples > 1) ?
- &r->sample_pattern_4x : &r->sample_pattern_1x;
- pattern_len = 1;
- }
+ const uint8_t sample_count = (blitter->fb.num_samples > 4) ? 8 :
+ (blitter->fb.num_samples > 1) ? 4 : 1;
gen7_wa_pre_3dstate_multisample(r);
gen6_3DSTATE_MULTISAMPLE(r->builder, &blitter->fb.rs,
- pattern, pattern_len);
+ &r->sample_pattern, sample_count);
gen6_3DSTATE_SAMPLE_MASK(r->builder, &blitter->fb.rs);
}
struct ilo_render_draw_session *session)
{
/* 3DSTATE_SAMPLE_PATTERN */
- if (r->hw_ctx_changed) {
- gen8_3DSTATE_SAMPLE_PATTERN(r->builder,
- &r->sample_pattern_1x,
- &r->sample_pattern_2x,
- &r->sample_pattern_4x,
- r->sample_pattern_8x,
- r->sample_pattern_16x);
- }
+ if (r->hw_ctx_changed)
+ gen8_3DSTATE_SAMPLE_PATTERN(r->builder, &r->sample_pattern);
}
static void