intel/isl: Add support for emitting depth/stencil/hiz

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
This commit is contained in:
Jason Ekstrand
2017-03-29 21:10:50 -07:00
parent 957ccbe04a
commit bf95f7c209
5 changed files with 401 additions and 0 deletions

View File

@@ -144,32 +144,39 @@ ISL_FILES = \
ISL_GEN4_FILES = \
isl/isl_gen4.c \
isl/isl_gen4.h \
isl/isl_emit_depth_stencil.c \
isl/isl_surface_state.c
ISL_GEN5_FILES = \
isl/isl_emit_depth_stencil.c \
isl/isl_surface_state.c
ISL_GEN6_FILES = \
isl/isl_gen6.c \
isl/isl_gen6.h \
isl/isl_emit_depth_stencil.c \
isl/isl_surface_state.c
ISL_GEN7_FILES = \
isl/isl_gen7.c \
isl/isl_gen7.h \
isl/isl_emit_depth_stencil.c \
isl/isl_surface_state.c
ISL_GEN75_FILES = \
isl/isl_emit_depth_stencil.c \
isl/isl_surface_state.c
ISL_GEN8_FILES = \
isl/isl_gen8.c \
isl/isl_gen8.h \
isl/isl_emit_depth_stencil.c \
isl/isl_surface_state.c
ISL_GEN9_FILES = \
isl/isl_gen9.c \
isl/isl_gen9.h \
isl/isl_emit_depth_stencil.c \
isl/isl_surface_state.c
ISL_GENERATED_FILES = \

View File

@@ -83,6 +83,32 @@ isl_device_init(struct isl_device *dev,
*/
dev->ss.aux_addr_offset =
(RENDER_SURFACE_STATE_AuxiliarySurfaceBaseAddress_start(info) & ~31) / 8;
dev->ds.size =
_3DSTATE_DEPTH_BUFFER_length(info) * 4 +
_3DSTATE_STENCIL_BUFFER_length(info) * 4 +
_3DSTATE_HIER_DEPTH_BUFFER_length(info) * 4 +
_3DSTATE_CLEAR_PARAMS_length(info) * 4;
assert(_3DSTATE_DEPTH_BUFFER_SurfaceBaseAddress_start(info) % 8 == 0);
dev->ds.depth_offset =
_3DSTATE_DEPTH_BUFFER_SurfaceBaseAddress_start(info) / 8;
if (info->has_hiz_and_separate_stencil) {
assert(_3DSTATE_STENCIL_BUFFER_SurfaceBaseAddress_start(info) % 8 == 0);
dev->ds.stencil_offset =
_3DSTATE_DEPTH_BUFFER_length(info) * 4 +
_3DSTATE_STENCIL_BUFFER_SurfaceBaseAddress_start(info) / 8;
assert(_3DSTATE_HIER_DEPTH_BUFFER_SurfaceBaseAddress_start(info) % 8 == 0);
dev->ds.hiz_offset =
_3DSTATE_DEPTH_BUFFER_length(info) * 4 +
_3DSTATE_STENCIL_BUFFER_length(info) * 4 +
_3DSTATE_HIER_DEPTH_BUFFER_SurfaceBaseAddress_start(info) / 8;
} else {
dev->ds.stencil_offset = 0;
dev->ds.hiz_offset = 0;
}
}
/**
@@ -1684,6 +1710,73 @@ isl_buffer_fill_state_s(const struct isl_device *dev, void *state,
}
}
void
isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info)
{
if (info->depth_surf && info->stencil_surf) {
if (!dev->info->has_hiz_and_separate_stencil) {
assert(info->depth_surf == info->stencil_surf);
assert(info->depth_address == info->stencil_address);
}
assert(info->depth_surf->dim == info->stencil_surf->dim);
}
if (info->depth_surf) {
assert((info->depth_surf->usage & ISL_SURF_USAGE_DEPTH_BIT));
if (info->depth_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->depth_surf->logical_level0_px.array_len);
}
}
if (info->stencil_surf) {
assert((info->stencil_surf->usage & ISL_SURF_USAGE_STENCIL_BIT));
if (info->stencil_surf->dim == ISL_SURF_DIM_3D) {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.depth);
} else {
assert(info->view->base_array_layer + info->view->array_len <=
info->stencil_surf->logical_level0_px.array_len);
}
}
switch (ISL_DEV_GEN(dev)) {
case 4:
if (ISL_DEV_IS_G4X(dev)) {
/* G45 surface state is the same as gen5 */
isl_gen5_emit_depth_stencil_hiz_s(dev, batch, info);
} else {
isl_gen4_emit_depth_stencil_hiz_s(dev, batch, info);
}
break;
case 5:
isl_gen5_emit_depth_stencil_hiz_s(dev, batch, info);
break;
case 6:
isl_gen6_emit_depth_stencil_hiz_s(dev, batch, info);
break;
case 7:
if (ISL_DEV_IS_HASWELL(dev)) {
isl_gen75_emit_depth_stencil_hiz_s(dev, batch, info);
} else {
isl_gen7_emit_depth_stencil_hiz_s(dev, batch, info);
}
break;
case 8:
isl_gen8_emit_depth_stencil_hiz_s(dev, batch, info);
break;
case 9:
isl_gen9_emit_depth_stencil_hiz_s(dev, batch, info);
break;
default:
assert(!"Cannot fill surface state for this gen");
}
}
/**
* A variant of isl_surf_get_image_offset_sa() specific to
* ISL_DIM_LAYOUT_GEN4_2D.

View File

@@ -682,6 +682,17 @@ struct isl_device {
uint8_t addr_offset;
uint8_t aux_addr_offset;
} ss;
/**
* Describes the layout of the depth/stencil/hiz commands as emitted by
* isl_emit_depth_stencil_hiz.
*/
struct {
uint8_t size;
uint8_t depth_offset;
uint8_t stencil_offset;
uint8_t hiz_offset;
} ds;
};
struct isl_extent2d {
@@ -1017,6 +1028,61 @@ struct isl_buffer_fill_state_info {
uint32_t stride;
};
struct isl_depth_stencil_hiz_emit_info {
/**
* The depth surface
*/
const struct isl_surf *depth_surf;
/**
* The stencil surface
*
* If separate stencil is not available, this must point to the same
* isl_surf as depth_surf.
*/
const struct isl_surf *stencil_surf;
/**
* The view into the depth and stencil surfaces.
*
* This view applies to both surfaces simultaneously.
*/
const struct isl_view *view;
/**
* The address of the depth surface in GPU memory
*/
uint64_t depth_address;
/**
* The address of the stencil surface in GPU memory
*
* If separate stencil is not available, this must have the same value as
* depth_address.
*/
uint64_t stencil_address;
/**
* The Memory Object Control state for depth and stencil buffers
*
* Both depth and stencil will get the same MOCS value. The exact format
* of this value depends on hardware generation.
*/
uint32_t mocs;
/**
* The HiZ surfae or NULL if HiZ is disabled.
*/
const struct isl_surf *hiz_surf;
enum isl_aux_usage hiz_usage;
uint64_t hiz_address;
/**
* The depth clear value
*/
float depth_clear_value;
};
extern const struct isl_format_layout isl_format_layouts[];
void
@@ -1315,6 +1381,14 @@ void
isl_buffer_fill_state_s(const struct isl_device *dev, void *state,
const struct isl_buffer_fill_state_info *restrict info);
#define isl_emit_depth_stencil_hiz(dev, batch, ...) \
isl_emit_depth_stencil_hiz_s((dev), (batch), \
&(struct isl_depth_stencil_hiz_emit_info) { __VA_ARGS__ })
void
isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_surf_fill_image_param(const struct isl_device *dev,
struct brw_image_param *param,

View File

@@ -0,0 +1,199 @@
/*
* Copyright 2016 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdint.h>
#define __gen_address_type uint64_t
#define __gen_user_data void
static inline uint64_t
__gen_combine_address(void *data, void *loc, uint64_t addr, uint32_t delta)
{
return addr + delta;
}
#include "genxml/gen_macros.h"
#include "genxml/genX_pack.h"
#include "isl_priv.h"
#define __PASTE2(x, y) x ## y
#define __PASTE(x, y) __PASTE2(x, y)
#define isl_genX(x) __PASTE(isl_, genX(x))
static const uint32_t isl_to_gen_ds_surftype [] = {
#if GEN_GEN >= 9
/* From the SKL PRM, "3DSTATE_DEPTH_STENCIL::SurfaceType":
*
* "If depth/stencil is enabled with 1D render target, depth/stencil
* surface type needs to be set to 2D surface type and height set to 1.
* Depth will use (legacy) TileY and stencil will use TileW. For this
* case only, the Surface Type of the depth buffer can be 2D while the
* Surface Type of the render target(s) are 1D, representing an
* exception to a programming note above.
*/
[ISL_SURF_DIM_1D] = SURFTYPE_2D,
#else
[ISL_SURF_DIM_1D] = SURFTYPE_1D,
#endif
[ISL_SURF_DIM_2D] = SURFTYPE_2D,
[ISL_SURF_DIM_3D] = SURFTYPE_3D,
};
void
isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info)
{
struct GENX(3DSTATE_DEPTH_BUFFER) db = {
GENX(3DSTATE_DEPTH_BUFFER_header),
};
if (info->depth_surf) {
db.SurfaceType = isl_to_gen_ds_surftype[info->depth_surf->dim];
db.SurfaceFormat = isl_surf_get_depth_format(dev, info->depth_surf);
db.Width = info->depth_surf->logical_level0_px.width - 1;
db.Height = info->depth_surf->logical_level0_px.height - 1;
} else if (info->stencil_surf) {
db.SurfaceType = isl_to_gen_ds_surftype[info->stencil_surf->dim];
db.SurfaceFormat = D32_FLOAT;
db.Width = info->stencil_surf->logical_level0_px.width - 1;
db.Height = info->stencil_surf->logical_level0_px.height - 1;
} else {
db.SurfaceType = SURFTYPE_NULL;
db.SurfaceFormat = D32_FLOAT;
}
if (info->depth_surf || info->stencil_surf) {
/* These are based entirely on the view */
db.Depth = db.RenderTargetViewExtent = info->view->array_len - 1;
db.LOD = info->view->base_level;
db.MinimumArrayElement = info->view->base_array_layer;
}
if (info->depth_surf) {
#if GEN_GEN >= 7
db.DepthWriteEnable = true;
#endif
db.SurfaceBaseAddress = info->depth_address;
#if GEN_GEN >= 6
db.DepthBufferMOCS = info->mocs;
#endif
#if GEN_GEN <= 6
db.TiledSurface = info->depth_surf->tiling != ISL_TILING_LINEAR;
db.TileWalk = info->depth_surf->tiling == ISL_TILING_Y0 ? TILEWALK_YMAJOR :
TILEWALK_XMAJOR;
db.MIPMapLayoutMode = MIPLAYOUT_BELOW;
#endif
db.SurfacePitch = info->depth_surf->row_pitch - 1;
#if GEN_GEN >= 8
db.SurfaceQPitch =
isl_surf_get_array_pitch_el_rows(info->depth_surf) >> 2;
#endif
}
#if GEN_GEN >= 6
struct GENX(3DSTATE_STENCIL_BUFFER) sb = {
GENX(3DSTATE_STENCIL_BUFFER_header),
};
#else
# define sb db
#endif
if (info->stencil_surf) {
#if GEN_GEN >= 7
db.StencilWriteEnable = true;
#endif
#if GEN_GEN >= 8 || GEN_IS_HASWELL
sb.StencilBufferEnable = true;
#endif
sb.SurfaceBaseAddress = info->stencil_address;
#if GEN_GEN >= 6
sb.StencilBufferMOCS = info->mocs;
#endif
sb.SurfacePitch = info->stencil_surf->row_pitch - 1;
#if GEN_GEN >= 8
sb.SurfaceQPitch =
isl_surf_get_array_pitch_el_rows(info->stencil_surf) >> 2;
#endif
}
#if GEN_GEN >= 6
struct GENX(3DSTATE_HIER_DEPTH_BUFFER) hiz = {
GENX(3DSTATE_HIER_DEPTH_BUFFER_header),
};
struct GENX(3DSTATE_CLEAR_PARAMS) clear = {
GENX(3DSTATE_CLEAR_PARAMS_header),
};
assert(info->hiz_usage == ISL_AUX_USAGE_NONE ||
info->hiz_usage == ISL_AUX_USAGE_HIZ);
if (info->hiz_usage == ISL_AUX_USAGE_HIZ) {
db.HierarchicalDepthBufferEnable = true;
#if GEN_GEN == 5 || GEN_GEN == 6
db.SeparateStencilBufferEnable = true;
#endif
hiz.SurfaceBaseAddress = info->hiz_address;
hiz.HierarchicalDepthBufferMOCS = info->mocs;
hiz.SurfacePitch = info->hiz_surf->row_pitch - 1;
#if GEN_GEN >= 8
/* From the SKL PRM Vol2a:
*
* The interpretation of this field is dependent on Surface Type
* as follows:
* - SURFTYPE_1D: distance in pixels between array slices
* - SURFTYPE_2D/CUBE: distance in rows between array slices
* - SURFTYPE_3D: distance in rows between R - slices
*
* Unfortunately, the docs aren't 100% accurate here. They fail to
* mention that the 1-D rule only applies to linear 1-D images.
* Since depth and HiZ buffers are always tiled, they are treated as
* 2-D images. Prior to Sky Lake, this field is always in rows.
*/
hiz.SurfaceQPitch =
isl_surf_get_array_pitch_sa_rows(info->hiz_surf) >> 2;
#endif
clear.DepthClearValueValid = true;
clear.DepthClearValue = info->depth_clear_value;
}
#endif /* GEN_GEN >= 6 */
/* Pack everything into the batch */
uint32_t *dw = batch;
GENX(3DSTATE_DEPTH_BUFFER_pack)(NULL, dw, &db);
dw += GENX(3DSTATE_DEPTH_BUFFER_length);
#if GEN_GEN >= 6
GENX(3DSTATE_STENCIL_BUFFER_pack)(NULL, dw, &sb);
dw += GENX(3DSTATE_STENCIL_BUFFER_length);
GENX(3DSTATE_HIER_DEPTH_BUFFER_pack)(NULL, dw, &hiz);
dw += GENX(3DSTATE_HIER_DEPTH_BUFFER_length);
GENX(3DSTATE_CLEAR_PARAMS_pack)(NULL, dw, &clear);
dw += GENX(3DSTATE_CLEAR_PARAMS_length);
#endif
}

View File

@@ -205,4 +205,32 @@ void
isl_gen9_buffer_fill_state_s(void *state,
const struct isl_buffer_fill_state_info *restrict info);
void
isl_gen4_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_gen5_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_gen6_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_gen7_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_gen75_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_gen8_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
void
isl_gen9_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
const struct isl_depth_stencil_hiz_emit_info *restrict info);
#endif /* ISL_PRIV_H */