From 443dc15cf77edcaa7804c4277f0cce5d7c1d6b25 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 18 Jun 2013 12:33:15 +0800 Subject: [PATCH] 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(). --- .../drivers/ilo/ilo_3d_pipeline_gen6.c | 15 +- .../drivers/ilo/ilo_3d_pipeline_gen7.c | 19 +- src/gallium/drivers/ilo/ilo_gpe.h | 15 + src/gallium/drivers/ilo/ilo_gpe_gen6.c | 575 ++++++++++-------- src/gallium/drivers/ilo/ilo_gpe_gen6.h | 6 +- src/gallium/drivers/ilo/ilo_state.c | 9 +- 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; } -- 2.30.2