aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-06-18 12:33:15 +0800
committerChia-I Wu <[email protected]>2013-06-18 16:23:13 +0800
commit443dc15cf77edcaa7804c4277f0cce5d7c1d6b25 (patch)
tree2373d502ca0da8d105400371b41f9fa6a953f912
parenteb2021507556633cd6ba64cda26653e3c43e80df (diff)
ilo: construct depth/stencil command in create_surface()
Add ilo_gpe_init_zs_surface() to construct 3DSTATE_DEPTH_BUFFER 3DSTATE_STENCIL_BUFFER 3DSTATE_HIER_DEPTH_BUFFER at surface creation time. This allows fast state emission in draw_vbo().
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c15
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c19
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe.h15
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe_gen6.c575
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe_gen6.h6
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c9
6 files changed, 368 insertions, 271 deletions
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
index c60fc014005..e5c9db1be02 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
@@ -717,12 +717,25 @@ gen6_pipeline_wm_depth(struct ilo_3d_pipeline *p,
{
/* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
if (DIRTY(FRAMEBUFFER) || session->batch_bo_changed) {
+ const struct ilo_zs_surface *zs;
+
+ if (ilo->fb.state.zsbuf) {
+ const struct ilo_surface_cso *surface =
+ (const struct ilo_surface_cso *) ilo->fb.state.zsbuf;
+
+ assert(!surface->is_rt);
+ zs = &surface->u.zs;
+ }
+ else {
+ zs = &ilo->fb.null_zs;
+ }
+
if (p->dev->gen == ILO_GEN(6)) {
gen6_wa_pipe_control_post_sync(p, false);
gen6_wa_pipe_control_wm_depth_flush(p);
}
- p->gen6_3DSTATE_DEPTH_BUFFER(p->dev, ilo->fb.state.zsbuf, p->cp);
+ p->gen6_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp);
/* TODO */
p->gen6_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp);
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
index 96e2e187427..878f6d0434b 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
@@ -532,9 +532,22 @@ gen7_pipeline_wm(struct ilo_3d_pipeline *p,
/* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
if (DIRTY(FRAMEBUFFER) || session->batch_bo_changed) {
- p->gen7_3DSTATE_DEPTH_BUFFER(p->dev, ilo->fb.state.zsbuf, p->cp);
- p->gen6_3DSTATE_HIER_DEPTH_BUFFER(p->dev, ilo->fb.state.zsbuf, p->cp);
- p->gen6_3DSTATE_STENCIL_BUFFER(p->dev, ilo->fb.state.zsbuf, p->cp);
+ const struct ilo_zs_surface *zs;
+
+ if (ilo->fb.state.zsbuf) {
+ const struct ilo_surface_cso *surface =
+ (const struct ilo_surface_cso *) ilo->fb.state.zsbuf;
+
+ assert(!surface->is_rt);
+ zs = &surface->u.zs;
+ }
+ else {
+ zs = &ilo->fb.null_zs;
+ }
+
+ p->gen7_3DSTATE_DEPTH_BUFFER(p->dev, zs, p->cp);
+ p->gen6_3DSTATE_HIER_DEPTH_BUFFER(p->dev, zs, p->cp);
+ p->gen6_3DSTATE_STENCIL_BUFFER(p->dev, zs, p->cp);
/* TODO */
p->gen6_3DSTATE_CLEAR_PARAMS(p->dev, 0, p->cp);
diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h
index 3a3b35535bf..fcbd5b888b6 100644
--- a/src/gallium/drivers/ilo/ilo_gpe.h
+++ b/src/gallium/drivers/ilo/ilo_gpe.h
@@ -216,12 +216,19 @@ struct ilo_surface_cso {
bool is_rt;
union {
struct ilo_view_surface rt;
+ struct ilo_zs_surface {
+ uint32_t payload[10];
+ struct intel_bo *bo;
+ struct intel_bo *hiz_bo;
+ struct intel_bo *separate_s8_bo;
+ } zs;
} u;
};
struct ilo_fb_state {
struct pipe_framebuffer_state state;
+ struct ilo_zs_surface null_zs;
unsigned num_samples;
};
@@ -413,4 +420,12 @@ ilo_gpe_init_view_surface_for_texture(const struct ilo_dev_info *dev,
}
}
+void
+ilo_gpe_init_zs_surface(const struct ilo_dev_info *dev,
+ const struct ilo_texture *tex,
+ enum pipe_format format,
+ unsigned level,
+ unsigned first_layer, unsigned num_layers,
+ struct ilo_zs_surface *zs);
+
#endif /* ILO_GPE_H */
diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.c b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
index 89566b72a04..56db7da8ee3 100644
--- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
@@ -2334,20 +2334,86 @@ gen6_emit_3DSTATE_DRAWING_RECTANGLE(const struct ilo_dev_info *dev,
ilo_cp_end(cp);
}
-static int
-gen6_get_depth_buffer_format(const struct ilo_dev_info *dev,
- enum pipe_format format,
- bool hiz,
- bool separate_stencil,
- bool *has_depth,
- bool *has_stencil)
+struct ilo_zs_surface_info {
+ int surface_type;
+ int format;
+
+ struct {
+ struct intel_bo *bo;
+ unsigned stride;
+ enum intel_tiling_mode tiling;
+ uint32_t offset;
+ } zs, stencil, hiz;
+
+ unsigned width, height, depth;
+ unsigned lod, first_layer, num_layers;
+ uint32_t x_offset, y_offset;
+};
+
+static void
+zs_init_info_null(const struct ilo_dev_info *dev,
+ struct ilo_zs_surface_info *info)
+{
+ ILO_GPE_VALID_GEN(dev, 6, 7);
+
+ memset(info, 0, sizeof(*info));
+
+ info->surface_type = BRW_SURFACE_NULL;
+ info->format = BRW_DEPTHFORMAT_D32_FLOAT;
+ info->width = 1;
+ info->height = 1;
+ info->depth = 1;
+ info->num_layers = 1;
+}
+
+static void
+zs_init_info(const struct ilo_dev_info *dev,
+ const struct ilo_texture *tex,
+ enum pipe_format format,
+ unsigned level,
+ unsigned first_layer, unsigned num_layers,
+ struct ilo_zs_surface_info *info)
{
- int depth_format;
+ const bool rebase_layer = true;
+ struct intel_bo * const hiz_bo = NULL;
+ bool separate_stencil;
+ uint32_t x_offset[3], y_offset[3];
ILO_GPE_VALID_GEN(dev, 6, 7);
- *has_depth = true;
- *has_stencil = false;
+ memset(info, 0, sizeof(*info));
+
+ info->surface_type = ilo_gpe_gen6_translate_texture(tex->base.target);
+
+ if (info->surface_type == BRW_SURFACE_CUBE) {
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 325-326:
+ *
+ * "For Other Surfaces (Cube Surfaces):
+ * This field (Minimum Array Element) is ignored."
+ *
+ * "For Other Surfaces (Cube Surfaces):
+ * This field (Render Target View Extent) is ignored."
+ *
+ * As such, we cannot set first_layer and num_layers on cube surfaces.
+ * To work around that, treat it as a 2D surface.
+ */
+ info->surface_type = BRW_SURFACE_2D;
+ }
+
+ if (dev->gen >= ILO_GEN(7)) {
+ separate_stencil = true;
+ }
+ else {
+ /*
+ * From the Sandy Bridge PRM, volume 2 part 1, page 317:
+ *
+ * "This field (Separate Stencil Buffer Enable) must be set to the
+ * same value (enabled or disabled) as Hierarchical Depth Buffer
+ * Enable."
+ */
+ separate_stencil = (hiz_bo != NULL);
+ }
/*
* From the Sandy Bridge PRM, volume 2 part 1, page 317:
@@ -2366,156 +2432,130 @@ gen6_get_depth_buffer_format(const struct ilo_dev_info *dev,
* is indeed used, the depth values output by the fragment shaders will
* be different when read back.
*
- * As for GEN7+, separate_stencil_buffer is always true.
+ * As for GEN7+, separate_stencil is always true.
*/
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
- depth_format = BRW_DEPTHFORMAT_D16_UNORM;
+ info->format = BRW_DEPTHFORMAT_D16_UNORM;
break;
case PIPE_FORMAT_Z32_FLOAT:
- depth_format = BRW_DEPTHFORMAT_D32_FLOAT;
+ info->format = BRW_DEPTHFORMAT_D32_FLOAT;
break;
case PIPE_FORMAT_Z24X8_UNORM:
- depth_format = (separate_stencil) ?
- BRW_DEPTHFORMAT_D24_UNORM_X8_UINT :
- BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
- break;
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
- depth_format = (separate_stencil) ?
+ info->format = (separate_stencil) ?
BRW_DEPTHFORMAT_D24_UNORM_X8_UINT :
BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
- *has_stencil = true;
break;
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
- depth_format = (separate_stencil) ?
+ info->format = (separate_stencil) ?
BRW_DEPTHFORMAT_D32_FLOAT :
BRW_DEPTHFORMAT_D32_FLOAT_S8X24_UINT;
- *has_stencil = true;
break;
case PIPE_FORMAT_S8_UINT:
if (separate_stencil) {
- depth_format = BRW_DEPTHFORMAT_D32_FLOAT;
- *has_depth = false;
- *has_stencil = true;
+ info->format = BRW_DEPTHFORMAT_D32_FLOAT;
break;
}
/* fall through */
default:
assert(!"unsupported depth/stencil format");
- depth_format = BRW_DEPTHFORMAT_D32_FLOAT;
- *has_depth = false;
- *has_stencil = false;
+ zs_init_info_null(dev, info);
+ return;
break;
}
- return depth_format;
-}
+ if (format != PIPE_FORMAT_S8_UINT) {
+ info->zs.bo = tex->bo;
+ info->zs.stride = tex->bo_stride;
+ info->zs.tiling = tex->tiling;
-static void
-gen6_emit_3DSTATE_DEPTH_BUFFER(const struct ilo_dev_info *dev,
- const struct pipe_surface *surface,
- struct ilo_cp *cp)
-{
- const uint32_t cmd = (dev->gen >= ILO_GEN(7)) ?
- ILO_GPE_CMD(0x3, 0x0, 0x05) : ILO_GPE_CMD(0x3, 0x1, 0x05);
- const uint8_t cmd_len = 7;
- const int max_2d_size = (dev->gen >= ILO_GEN(7)) ? 16384 : 8192;
- const int max_array_size = (dev->gen >= ILO_GEN(7)) ? 2048 : 512;
- const bool hiz = false;
- struct ilo_texture *tex;
- uint32_t dw1, dw3, dw4, dw6;
- uint32_t slice_offset, x_offset, y_offset;
- int surface_type, depth_format;
- unsigned lod, first_layer, num_layers;
- unsigned width, height, depth;
- bool separate_stencil, has_depth, has_stencil;
+ if (rebase_layer) {
+ info->zs.offset = ilo_texture_get_slice_offset(tex,
+ level, first_layer, &x_offset[0], &y_offset[0]);
+ }
+ }
- ILO_GPE_VALID_GEN(dev, 6, 7);
+ if (tex->separate_s8 || format == PIPE_FORMAT_S8_UINT) {
+ const struct ilo_texture *s8_tex =
+ (tex->separate_s8) ? tex->separate_s8 : tex;
+
+ info->stencil.bo = s8_tex->bo;
- if (dev->gen >= ILO_GEN(7)) {
- separate_stencil = true;
- }
- else {
/*
- * From the Sandy Bridge PRM, volume 2 part 1, page 317:
+ * From the Sandy Bridge PRM, volume 2 part 1, page 329:
*
- * "This field (Separate Stencil Buffer Enable) must be set to the
- * same value (enabled or disabled) as Hierarchical Depth Buffer
- * Enable."
+ * "The pitch must be set to 2x the value computed based on width,
+ * as the stencil buffer is stored with two rows interleaved."
+ *
+ * According to the classic driver, we need to do the same for GEN7+
+ * even though the Ivy Bridge PRM does not say anything about it.
*/
- separate_stencil = hiz;
- }
-
- if (surface) {
- depth_format = gen6_get_depth_buffer_format(dev,
- surface->format, hiz, separate_stencil, &has_depth, &has_stencil);
- }
- else {
- has_depth = false;
- has_stencil = false;
- }
+ info->stencil.stride = s8_tex->bo_stride * 2;
- if (!has_depth && !has_stencil) {
- dw1 = BRW_SURFACE_NULL << 29 |
- BRW_DEPTHFORMAT_D32_FLOAT << 18;
+ info->stencil.tiling = s8_tex->tiling;
- /* Y-tiled */
- if (dev->gen == ILO_GEN(6)) {
- dw1 |= 1 << 27 |
- 1 << 26;
+ if (rebase_layer) {
+ info->stencil.offset = ilo_texture_get_slice_offset(s8_tex,
+ level, first_layer, &x_offset[1], &y_offset[1]);
}
-
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, dw1);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_end(cp);
-
- return;
}
- tex = ilo_texture(surface->texture);
-
- surface_type = ilo_gpe_gen6_translate_texture(tex->base.target);
- lod = surface->u.tex.level;
- first_layer = surface->u.tex.first_layer;
- num_layers = surface->u.tex.last_layer - first_layer + 1;
+ if (hiz_bo) {
+ info->hiz.bo = hiz_bo;
+ info->hiz.stride = 0;
+ info->hiz.tiling = 0;
+ info->hiz.offset = 0;
+ x_offset[2] = 0;
+ y_offset[2] = 0;
+ }
- width = tex->base.width0;
- height = tex->base.height0;
- depth = (tex->base.target == PIPE_TEXTURE_3D) ?
+ info->width = tex->base.width0;
+ info->height = tex->base.height0;
+ info->depth = (tex->base.target == PIPE_TEXTURE_3D) ?
tex->base.depth0 : num_layers;
- if (surface_type == BRW_SURFACE_CUBE) {
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 325-326:
- *
- * "For Other Surfaces (Cube Surfaces):
- * This field (Minimum Array Element) is ignored."
- *
- * "For Other Surfaces (Cube Surfaces):
- * This field (Render Target View Extent) is ignored."
- *
- * As such, we cannot set first_layer and num_layers on cube surfaces.
- * To work around that, treat it as a 2D surface.
- */
- surface_type = BRW_SURFACE_2D;
- }
+ info->lod = level;
+ info->first_layer = first_layer;
+ info->num_layers = num_layers;
+
+ if (rebase_layer) {
+ /* the size of the layer */
+ info->width = u_minify(info->width, level);
+ info->height = u_minify(info->height, level);
+ if (info->surface_type == BRW_SURFACE_3D)
+ info->depth = u_minify(info->depth, level);
+ else
+ info->depth = 1;
- /*
- * we always treat the resource as non-mipmapped and set the slice/x/y
- * offsets manually
- */
- if (true) {
/* no layered rendering */
assert(num_layers == 1);
- slice_offset = ilo_texture_get_slice_offset(tex,
- lod, first_layer, &x_offset, &y_offset);
+ info->lod = 0;
+ info->first_layer = 0;
+ info->num_layers = 1;
+
+ /* all three share the same X/Y offsets */
+ if (info->zs.bo) {
+ if (info->stencil.bo) {
+ assert(x_offset[0] == x_offset[1]);
+ assert(y_offset[0] == y_offset[1]);
+ }
+
+ info->x_offset = x_offset[0];
+ info->y_offset = y_offset[0];
+ }
+ else {
+ assert(info->stencil.bo);
+
+ info->x_offset = x_offset[1];
+ info->y_offset = y_offset[1];
+ }
+
+ if (info->hiz.bo) {
+ assert(info->x_offset == x_offset[2]);
+ assert(info->y_offset == y_offset[2]);
+ }
/*
* From the Sandy Bridge PRM, volume 2 part 1, page 326:
@@ -2527,137 +2567,205 @@ gen6_emit_3DSTATE_DEPTH_BUFFER(const struct ilo_dev_info *dev,
* sure that does not happen eventually.
*/
if (dev->gen >= ILO_GEN(7)) {
- assert((x_offset & 7) == 0 && (y_offset & 7) == 0);
- x_offset &= ~7;
- y_offset &= ~7;
+ assert((info->x_offset & 7) == 0 && (info->y_offset & 7) == 0);
+ info->x_offset &= ~7;
+ info->y_offset &= ~7;
}
- /* the size of the layer */
- width = u_minify(width, lod);
- height = u_minify(height, lod);
- if (surface_type == BRW_SURFACE_3D)
- depth = u_minify(depth, lod);
- else
- depth = 1;
-
- lod = 0;
- first_layer = 0;
-
- width += x_offset;
- height += y_offset;
+ info->width += info->x_offset;
+ info->height += info->y_offset;
/* we have to treat them as 2D surfaces */
- if (surface_type == BRW_SURFACE_CUBE) {
+ if (info->surface_type == BRW_SURFACE_CUBE) {
assert(tex->base.width0 == tex->base.height0);
/* we will set slice_offset to point to the single face */
- surface_type = BRW_SURFACE_2D;
+ info->surface_type = BRW_SURFACE_2D;
}
- else if (surface_type == BRW_SURFACE_1D && height > 1) {
+ else if (info->surface_type == BRW_SURFACE_1D && info->height > 1) {
assert(tex->base.height0 == 1);
- surface_type = BRW_SURFACE_2D;
+ info->surface_type = BRW_SURFACE_2D;
}
}
- else {
- slice_offset = 0;
- x_offset = 0;
- y_offset = 0;
- }
+}
- /* required for GEN6+ */
- assert(tex->tiling == INTEL_TILING_Y);
- assert(tex->bo_stride > 0 && tex->bo_stride < 128 * 1024 &&
- tex->bo_stride % 128 == 0);
- assert(width <= tex->bo_stride);
+void
+ilo_gpe_init_zs_surface(const struct ilo_dev_info *dev,
+ const struct ilo_texture *tex,
+ enum pipe_format format,
+ unsigned level,
+ unsigned first_layer, unsigned num_layers,
+ struct ilo_zs_surface *zs)
+{
+ const int max_2d_size = (dev->gen >= ILO_GEN(7)) ? 16384 : 8192;
+ const int max_array_size = (dev->gen >= ILO_GEN(7)) ? 2048 : 512;
+ struct ilo_zs_surface_info info;
+ uint32_t dw1, dw2, dw3, dw4, dw5, dw6;
- switch (surface_type) {
+ ILO_GPE_VALID_GEN(dev, 6, 7);
+
+ if (tex)
+ zs_init_info(dev, tex, format, level, first_layer, num_layers, &info);
+ else
+ zs_init_info_null(dev, &info);
+
+ switch (info.surface_type) {
+ case BRW_SURFACE_NULL:
+ break;
case BRW_SURFACE_1D:
- assert(width <= max_2d_size && height == 1 &&
- depth <= max_array_size);
- assert(first_layer < max_array_size - 1 &&
- num_layers <= max_array_size);
+ assert(info.width <= max_2d_size && info.height == 1 &&
+ info.depth <= max_array_size);
+ assert(info.first_layer < max_array_size - 1 &&
+ info.num_layers <= max_array_size);
break;
case BRW_SURFACE_2D:
- assert(width <= max_2d_size && height <= max_2d_size &&
- depth <= max_array_size);
- assert(first_layer < max_array_size - 1 &&
- num_layers <= max_array_size);
+ assert(info.width <= max_2d_size && info.height <= max_2d_size &&
+ info.depth <= max_array_size);
+ assert(info.first_layer < max_array_size - 1 &&
+ info.num_layers <= max_array_size);
break;
case BRW_SURFACE_3D:
- assert(width <= 2048 && height <= 2048 && depth <= 2048);
- assert(first_layer < 2048 && num_layers <= max_array_size);
- assert(x_offset == 0 && y_offset == 0);
+ assert(info.width <= 2048 && info.height <= 2048 && info.depth <= 2048);
+ assert(info.first_layer < 2048 && info.num_layers <= max_array_size);
+ assert(info.x_offset == 0 && info.y_offset == 0);
break;
case BRW_SURFACE_CUBE:
- assert(width <= max_2d_size && height <= max_2d_size && depth == 1);
- assert(first_layer == 0 && num_layers == 1);
- assert(width == height);
- assert(x_offset == 0 && y_offset == 0);
+ assert(info.width <= max_2d_size && info.height <= max_2d_size &&
+ info.depth == 1);
+ assert(info.first_layer == 0 && info.num_layers == 1);
+ assert(info.width == info.height);
+ assert(info.x_offset == 0 && info.y_offset == 0);
break;
default:
assert(!"unexpected depth surface type");
break;
}
- dw1 = surface_type << 29 |
- depth_format << 18 |
- (tex->bo_stride - 1);
+ dw1 = info.surface_type << 29 |
+ info.format << 18;
+
+ if (info.zs.bo) {
+ /* required for GEN6+ */
+ assert(info.zs.tiling == INTEL_TILING_Y);
+ assert(info.zs.stride > 0 && info.zs.stride < 128 * 1024 &&
+ info.zs.stride % 128 == 0);
+ assert(info.width <= info.zs.stride);
+
+ dw1 |= (info.zs.stride - 1);
+ dw2 = info.zs.offset;
+ }
+ else {
+ dw2 = 0;
+ }
if (dev->gen >= ILO_GEN(7)) {
- if (has_depth)
+ if (info.zs.bo)
dw1 |= 1 << 28;
- if (has_stencil)
+ if (info.stencil.bo)
dw1 |= 1 << 27;
- if (hiz)
+ if (info.hiz.bo)
dw1 |= 1 << 22;
- dw3 = (height - 1) << 18 |
- (width - 1) << 4 |
- lod;
+ dw3 = (info.height - 1) << 18 |
+ (info.width - 1) << 4 |
+ info.lod;
+
+ dw4 = (info.depth - 1) << 21 |
+ info.first_layer << 10;
- dw4 = (depth - 1) << 21 |
- first_layer << 10;
+ dw5 = info.y_offset << 16 | info.x_offset;
- dw6 = (num_layers - 1) << 21;
+ dw6 = (info.num_layers - 1) << 21;
}
else {
- dw1 |= (tex->tiling != INTEL_TILING_NONE) << 27 |
- (tex->tiling == INTEL_TILING_Y) << 26;
+ /* always Y-tiled */
+ dw1 |= 1 << 27 |
+ 1 << 26;
- if (hiz) {
+ if (info.hiz.bo) {
dw1 |= 1 << 22 |
1 << 21;
}
- dw3 = (height - 1) << 19 |
- (width - 1) << 6 |
- lod << 2 |
+ dw3 = (info.height - 1) << 19 |
+ (info.width - 1) << 6 |
+ info.lod << 2 |
BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1;
- dw4 = (depth - 1) << 21 |
- first_layer << 10 |
- (num_layers - 1) << 1;
+ dw4 = (info.depth - 1) << 21 |
+ info.first_layer << 10 |
+ (info.num_layers - 1) << 1;
+
+ dw5 = info.y_offset << 16 | info.x_offset;
dw6 = 0;
}
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, dw1);
+ STATIC_ASSERT(Elements(zs->payload) >= 10);
+
+ zs->payload[0] = dw1;
+ zs->payload[1] = dw2;
+ zs->payload[2] = dw3;
+ zs->payload[3] = dw4;
+ zs->payload[4] = dw5;
+ zs->payload[5] = dw6;
- if (has_depth) {
- ilo_cp_write_bo(cp, slice_offset, tex->bo,
- INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
+ /* do not increment reference count */
+ zs->bo = info.zs.bo;
+
+ /* separate stencil */
+ if (info.stencil.bo) {
+ assert(info.stencil.stride > 0 && info.stencil.stride < 128 * 1024 &&
+ info.stencil.stride % 128 == 0);
+
+ zs->payload[6] = info.stencil.stride - 1;
+ zs->payload[7] = info.stencil.offset;
+
+ /* do not increment reference count */
+ zs->separate_s8_bo = info.stencil.bo;
}
else {
- ilo_cp_write(cp, 0);
+ zs->payload[6] = 0;
+ zs->payload[7] = 0;
+ zs->separate_s8_bo = NULL;
}
- ilo_cp_write(cp, dw3);
- ilo_cp_write(cp, dw4);
- ilo_cp_write(cp, y_offset << 16 | x_offset);
- ilo_cp_write(cp, dw6);
+ /* hiz */
+ if (info.hiz.bo) {
+ zs->payload[8] = info.hiz.stride - 1;
+ zs->payload[9] = info.hiz.offset;
+
+ /* do not increment reference count */
+ zs->hiz_bo = info.hiz.bo;
+ }
+ else {
+ zs->payload[8] = 0;
+ zs->payload[9] = 0;
+ zs->hiz_bo = NULL;
+ }
+}
+
+static void
+gen6_emit_3DSTATE_DEPTH_BUFFER(const struct ilo_dev_info *dev,
+ const struct ilo_zs_surface *zs,
+ struct ilo_cp *cp)
+{
+ const uint32_t cmd = (dev->gen >= ILO_GEN(7)) ?
+ ILO_GPE_CMD(0x3, 0x0, 0x05) : ILO_GPE_CMD(0x3, 0x1, 0x05);
+ const uint8_t cmd_len = 7;
+
+ ILO_GPE_VALID_GEN(dev, 6, 7);
+
+ ilo_cp_begin(cp, cmd_len);
+ ilo_cp_write(cp, cmd | (cmd_len - 2));
+ ilo_cp_write(cp, zs->payload[0]);
+ ilo_cp_write_bo(cp, zs->payload[1], zs->bo,
+ INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
+ ilo_cp_write(cp, zs->payload[2]);
+ ilo_cp_write(cp, zs->payload[3]);
+ ilo_cp_write(cp, zs->payload[4]);
+ ilo_cp_write(cp, zs->payload[5]);
ilo_cp_end(cp);
}
@@ -2824,102 +2932,42 @@ gen6_emit_3DSTATE_MULTISAMPLE(const struct ilo_dev_info *dev,
static void
gen6_emit_3DSTATE_STENCIL_BUFFER(const struct ilo_dev_info *dev,
- const struct pipe_surface *surface,
+ const struct ilo_zs_surface *zs,
struct ilo_cp *cp)
{
const uint32_t cmd = (dev->gen >= ILO_GEN(7)) ?
ILO_GPE_CMD(0x3, 0x0, 0x06) :
ILO_GPE_CMD(0x3, 0x1, 0x0e);
const uint8_t cmd_len = 3;
- struct ilo_texture *tex;
- uint32_t slice_offset, x_offset, y_offset;
- int pitch;
ILO_GPE_VALID_GEN(dev, 6, 7);
- tex = (surface) ? ilo_texture(surface->texture) : NULL;
- if (tex && surface->format != PIPE_FORMAT_S8_UINT)
- tex = tex->separate_s8;
-
- if (!tex) {
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_end(cp);
-
- return;
- }
-
- if (true) {
- slice_offset = ilo_texture_get_slice_offset(tex,
- surface->u.tex.level, surface->u.tex.first_layer,
- &x_offset, &y_offset);
- /* XXX X/Y offsets inherit from 3DSTATE_DEPTH_BUFFER */
- }
- else {
- slice_offset = 0;
- x_offset = 0;
- y_offset = 0;
- }
-
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 329:
- *
- * "The pitch must be set to 2x the value computed based on width, as
- * the stencil buffer is stored with two rows interleaved."
- *
- * According to the classic driver, we need to do the same for GEN7+ even
- * though the Ivy Bridge PRM does not say anything about it.
- */
- pitch = 2 * tex->bo_stride;
- assert(pitch > 0 && pitch < 128 * 1024 && pitch % 128 == 0);
-
ilo_cp_begin(cp, cmd_len);
ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, pitch - 1);
- ilo_cp_write_bo(cp, slice_offset, tex->bo,
+ /* see ilo_gpe_init_zs_surface() */
+ ilo_cp_write(cp, zs->payload[6]);
+ ilo_cp_write_bo(cp, zs->payload[7], zs->separate_s8_bo,
INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
ilo_cp_end(cp);
}
static void
gen6_emit_3DSTATE_HIER_DEPTH_BUFFER(const struct ilo_dev_info *dev,
- const struct pipe_surface *surface,
+ const struct ilo_zs_surface *zs,
struct ilo_cp *cp)
{
const uint32_t cmd = (dev->gen >= ILO_GEN(7)) ?
ILO_GPE_CMD(0x3, 0x0, 0x07) :
ILO_GPE_CMD(0x3, 0x1, 0x0f);
const uint8_t cmd_len = 3;
- const bool hiz = false;
- struct ilo_texture *tex;
- uint32_t slice_offset;
ILO_GPE_VALID_GEN(dev, 6, 7);
- if (!surface || !hiz) {
- ilo_cp_begin(cp, cmd_len);
- ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, 0);
- ilo_cp_write(cp, 0);
- ilo_cp_end(cp);
-
- return;
- }
-
- tex = ilo_texture(surface->texture);
-
- /* TODO */
- slice_offset = 0;
-
- assert(tex->bo_stride > 0 && tex->bo_stride < 128 * 1024 &&
- tex->bo_stride % 128 == 0);
-
ilo_cp_begin(cp, cmd_len);
ilo_cp_write(cp, cmd | (cmd_len - 2));
- ilo_cp_write(cp, tex->bo_stride - 1);
- ilo_cp_write_bo(cp, slice_offset, tex->bo,
+ /* see ilo_gpe_init_zs_surface() */
+ ilo_cp_write(cp, zs->payload[8]);
+ ilo_cp_write_bo(cp, zs->payload[9], zs->hiz_bo,
INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
ilo_cp_end(cp);
}
@@ -4754,6 +4802,7 @@ gen6_emit_SAMPLER_BORDER_COLOR_STATE(const struct ilo_dev_info *dev,
dw = ilo_cp_steal_ptr(cp, "SAMPLER_BORDER_COLOR_STATE",
state_len, state_align, &state_offset);
+ /* see ilo_gpe_init_sampler_cso() */
memcpy(dw, &sampler->payload[3], state_len * 4);
return state_offset;
diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.h b/src/gallium/drivers/ilo/ilo_gpe_gen6.h
index bc71b453be7..6e273645471 100644
--- a/src/gallium/drivers/ilo/ilo_gpe_gen6.h
+++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.h
@@ -299,7 +299,7 @@ typedef void
typedef void
(*ilo_gpe_gen6_3DSTATE_DEPTH_BUFFER)(const struct ilo_dev_info *dev,
- const struct pipe_surface *surface,
+ const struct ilo_zs_surface *zs,
struct ilo_cp *cp);
typedef void
@@ -338,12 +338,12 @@ typedef void
typedef void
(*ilo_gpe_gen6_3DSTATE_STENCIL_BUFFER)(const struct ilo_dev_info *dev,
- const struct pipe_surface *surface,
+ const struct ilo_zs_surface *zs,
struct ilo_cp *cp);
typedef void
(*ilo_gpe_gen6_3DSTATE_HIER_DEPTH_BUFFER)(const struct ilo_dev_info *dev,
- const struct pipe_surface *surface,
+ const struct ilo_zs_surface *zs,
struct ilo_cp *cp);
typedef void
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index 3210bb4bf33..ba0efdd09ce 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -952,7 +952,11 @@ ilo_create_surface(struct pipe_context *pipe,
else {
assert(res->target != PIPE_BUFFER);
- /* will construct dynamically */
+ ilo_gpe_init_zs_surface(ilo->dev, ilo_texture(res),
+ templ->format, templ->u.tex.level,
+ templ->u.tex.first_layer,
+ templ->u.tex.last_layer - templ->u.tex.first_layer + 1,
+ &surf->u.zs);
}
return &surf->base;
@@ -1133,6 +1137,9 @@ ilo_init_states(struct ilo_context *ilo)
{
ilo_gpe_set_scissor_null(ilo->dev, &ilo->scissor);
+ ilo_gpe_init_zs_surface(ilo->dev, NULL,
+ PIPE_FORMAT_NONE, 0, 0, 1, &ilo->fb.null_zs);
+
ilo->dirty = ILO_DIRTY_ALL;
}