isl: add support for coarse pixel control surfaces

Those surfaces are used as attachment to rendering passes and describe
the rate of coarse pixel shading for the pass.

v2: Move CPB_BIT tile filtering to isl_gfx125_filter_tiling() (Nanley)

v3: Drop unused macro (Nanley)
    s/isl_to_gen/isl_encode/ (Nanley)
    Remove pitch alignment 128B constraint already covered by tiling (Nanley)
    Move some asserts together (Nanley)

v4: Disable miptail for now (Nanley)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13739>
This commit is contained in:
Lionel Landwerlin 2020-11-06 17:03:33 +02:00 committed by Marge Bot
parent 8d90fe587f
commit dff08cbf8e
7 changed files with 201 additions and 0 deletions

View file

@ -56,6 +56,8 @@ genX_bits_included_symbols = [
'3DSTATE_CLEAR_PARAMS',
'3DSTATE_SO_BUFFER::Surface Base Address',
'3DSTATE_SO_BUFFER::Stream Offset',
'3DSTATE_CPSIZE_CONTROL_BUFFER::Surface Base Address',
'3DSTATE_CPSIZE_CONTROL_BUFFER::Surface Pitch',
# structures
'RENDER_SURFACE_STATE::Surface Base Address',
'RENDER_SURFACE_STATE::Surface Pitch',

View file

@ -198,6 +198,9 @@ isl_mocs(const struct isl_device *dev, isl_surf_usage_flags_t usage,
if (usage & ISL_SURF_USAGE_STAGING_BIT)
return dev->mocs.internal;
if (usage & ISL_SURF_USAGE_CPB_BIT)
return dev->mocs.internal;
/* Using L1:HDC for storage buffers breaks Vulkan memory model
* tests that use shader atomics. This isn't likely to work out,
* and we can't know a priori whether they'll be used. So just
@ -307,6 +310,10 @@ isl_device_init(struct isl_device *dev,
dev->max_buffer_size = 1ull << 27;
}
dev->cpb.size = _3DSTATE_CPSIZE_CONTROL_BUFFER_length(info) * 4;
dev->cpb.offset =
_3DSTATE_CPSIZE_CONTROL_BUFFER_SurfaceBaseAddress_start(info) / 8;
isl_device_setup_mocs(dev);
}
@ -1599,6 +1606,9 @@ isl_calc_row_pitch_alignment(const struct isl_device *dev,
return tile_info->phys_extent_B.width;
}
/* We only support tiled fragment shading rate buffers. */
assert((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) == 0);
/* From the Broadwel PRM >> Volume 2d: Command Reference: Structures >>
* RENDER_SURFACE_STATE Surface Pitch (p349):
*
@ -1782,6 +1792,10 @@ isl_calc_row_pitch(const struct isl_device *dev,
!pitch_in_range(row_pitch_B, stencil_pitch_bits))
return false;
if ((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) &&
!pitch_in_range(row_pitch_B, _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfacePitch_bits(dev->info)))
return false;
done:
*out_row_pitch_B = row_pitch_B;
return true;
@ -1792,6 +1806,10 @@ isl_surf_init_s(const struct isl_device *dev,
struct isl_surf *surf,
const struct isl_surf_init_info *restrict info)
{
/* Some sanity checks */
assert(!(info->usage & ISL_SURF_USAGE_CPB_BIT) ||
dev->info->has_coarse_pixel_primitive_and_cb);
const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
const struct isl_extent4d logical_level0_px = {
@ -2459,6 +2477,21 @@ isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch,
isl_genX_call(dev, emit_depth_stencil_hiz_s, dev, batch, info);
}
void
isl_emit_cpb_control_s(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info)
{
if (info->surf) {
assert((info->surf->usage & ISL_SURF_USAGE_CPB_BIT));
assert(info->surf->dim != ISL_SURF_DIM_3D);
assert(info->surf->tiling == ISL_TILING_4 ||
info->surf->tiling == ISL_TILING_64);
assert(info->surf->format == ISL_FORMAT_R8_UINT);
}
isl_genX_call(dev, emit_cpb_control_s, dev, batch, info);
}
/**
* A variant of isl_surf_get_image_offset_sa() specific to
* ISL_DIM_LAYOUT_GFX4_2D.

View file

@ -1115,6 +1115,7 @@ typedef uint64_t isl_surf_usage_flags_t;
#define ISL_SURF_USAGE_INDEX_BUFFER_BIT (1u << 12)
#define ISL_SURF_USAGE_CONSTANT_BUFFER_BIT (1u << 13)
#define ISL_SURF_USAGE_STAGING_BIT (1u << 14)
#define ISL_SURF_USAGE_CPB_BIT (1u << 15)
/** @} */
/**
@ -1269,6 +1270,15 @@ struct isl_device {
uint8_t hiz_offset;
} ds;
/**
* Describes the layout of the coarse pixel control commands as emitted by
* isl_emit_cpb_control.
*/
struct {
uint8_t size;
uint8_t offset;
} cpb;
struct {
uint32_t internal;
uint32_t external;
@ -1770,6 +1780,28 @@ struct isl_null_fill_state_info {
uint32_t minimum_array_element;
};
struct isl_cpb_emit_info {
/**
* The coarse pixel shading control surface.
*/
const struct isl_surf *surf;
/**
* The view into the control surface.
*/
const struct isl_view *view;
/**
* The address of the control surface in GPU memory.
*/
uint64_t address;
/**
* The Memory Object Control state for the surface.
*/
uint32_t mocs;
};
extern const struct isl_format_layout isl_format_layouts[];
extern const char isl_format_names[];
extern const uint16_t isl_format_name_offsets[];
@ -2236,6 +2268,12 @@ isl_surf_usage_is_depth_or_stencil(isl_surf_usage_flags_t usage)
return usage & (ISL_SURF_USAGE_DEPTH_BIT | ISL_SURF_USAGE_STENCIL_BIT);
}
static inline bool
isl_surf_usage_is_cpb(isl_surf_usage_flags_t usage)
{
return usage & ISL_SURF_USAGE_CPB_BIT;
}
static inline bool
isl_surf_info_is_z16(const struct isl_surf_init_info *info)
{
@ -2423,6 +2461,10 @@ 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_emit_cpb_control_s(const struct isl_device *dev, void *batch,
const struct isl_cpb_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,110 @@
/*
* Copyright 2020 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 uint64_t
__gen_combine_address(__attribute__((unused)) void *data,
__attribute__((unused)) 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"
#if GFX_VERx10 >= 125
static const uint8_t isl_encode_tiling[] = {
[ISL_TILING_4] = TILE4,
[ISL_TILING_64] = TILE64,
};
#endif
void
isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info)
{
#if GFX_VERx10 >= 125
struct GENX(3DSTATE_CPSIZE_CONTROL_BUFFER) cpb = {
GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_header),
};
if (info->surf) {
/* BSpec 46962 has a number of restriction on the fields of this packet
* like :
*
* "The Width specified by this field must be less than or equal to
* the surface pitch (specified in bytes via the Surface Pitch field).
* For cube maps, Width must be set equal to Height.
*
* 1. The Width ofthis buffer must be the same as the Width of the
* render target(s) (defined in SURFACE_STATE), unless Surface
* Type is SURFTYPE_1D or SURFTYPE_2D with Depth = 0 (non-array)
* and LOD = 0 (non-mip mapped).
*
* 2. Depth buffer (defined in 3DSTATE_DEPTH_BUFFER) unless either
* the depth buffer or this buffer surf_typeare SURFTYPE_NULL"
*
* Unfortunately APIs like Vulkan do not give guarantees that every
* framebuffer attachment will match in size (RT & CPB surfaces for
* example). But at least it gives a guarantee that all the attachments
* of a render pass will be at least be large enough to handle the
* rendered area. So here we use the CPB surface values, even if they
* don't strictly match the various BSpec restrictions.
*/
cpb.Width = (info->surf->logical_level0_px.width * 8) - 1;
cpb.Height = (info->surf->logical_level0_px.height * 8) - 1;
cpb.Depth = info->view->array_len - 1;
cpb.RenderTargetViewExtent = cpb.Depth;
cpb.SurfLOD = info->view->base_level;
cpb.MinimumArrayElement = info->view->base_array_layer;
cpb.SurfaceType = SURFTYPE_2D;
cpb.SurfacePitch = info->surf->row_pitch_B - 1;
cpb.MOCS = info->mocs;
cpb.SurfaceQPitch = isl_surf_get_array_pitch_sa_rows(info->surf) >> 2;
cpb.TiledMode = isl_encode_tiling[info->surf->tiling];
cpb.SurfaceBaseAddress = info->address;
/* We don't use miptails yet. The PRM recommends that you set "Mip Tail
* Start LOD" to 15 to prevent the hardware from trying to use them.
*/
cpb.MipTailStartLOD = 15;
} else {
cpb.SurfaceType = SURFTYPE_NULL;
cpb.TiledMode = TILE64;
}
/* Pack everything into the batch */
uint32_t *dw = batch;
GENX(3DSTATE_CPSIZE_CONTROL_BUFFER_pack)(NULL, dw, &cpb);
#else
unreachable("Coarse pixel shading not supported");
#endif
}

View file

@ -47,3 +47,7 @@ isl_genX(emit_depth_stencil_hiz_s)(const struct isl_device *dev, void *batch,
void
isl_genX(null_fill_state)(const struct isl_device *dev, void *state,
const struct isl_null_fill_state_info *restrict info);
void
isl_genX(emit_cpb_control_s)(const struct isl_device *dev, void *batch,
const struct isl_cpb_emit_info *restrict info);

View file

@ -88,6 +88,15 @@ isl_gfx125_filter_tiling(const struct isl_device *dev,
/* Tile64 is not defined for format sizes that are 24, 48, and 96 bpb. */
if (isl_format_get_layout(info->format)->bpb % 3 == 0)
*flags &= ~ISL_TILING_64_BIT;
/* BSpec 46962: 3DSTATE_CPSIZE_CONTROL_BUFFER::Tiled Mode : TILE4 & TILE64
* are the only 2 valid values.
*
* TODO: For now we only TILE64 as we need to figure out potential
* additional requirements for TILE4.
*/
if (info->usage & ISL_SURF_USAGE_CPB_BIT)
*flags &= ISL_TILING_64_BIT;
}
void

View file

@ -19,6 +19,7 @@
# SOFTWARE.
isl_per_hw_ver_files = files(
'isl_emit_cpb.c',
'isl_emit_depth_stencil.c',
'isl_surface_state.c',
'isl_genX_helpers.h',