mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-11-01 03:18:02 +03:00
init
This commit is contained in:
12511 files changed
+6156641
No files matched your search
@@ -0,0 +1,665 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Collabora, Ltd.
|
||||
* Copyright (C) 2026 Arm Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef __PAN_FB_H
|
||||
#define __PAN_FB_H
|
||||
|
||||
#include "genxml/gen_macros.h"
|
||||
#include "util/format/u_formats.h"
|
||||
#include "compiler/shader_enums.h"
|
||||
|
||||
struct nir_shader;
|
||||
struct nir_shader_compiler_options;
|
||||
struct pan_fb_info;
|
||||
struct pan_image_view;
|
||||
|
||||
#define PAN_MAX_RTS 8
|
||||
|
||||
/** Bounding box used by the framebuffer abstraction */
|
||||
struct pan_fb_bbox {
|
||||
/** Minimum x/y value */
|
||||
uint16_t min_x, min_y;
|
||||
|
||||
/** Maximum x/y value
|
||||
*
|
||||
* Like the hardware, the maximums here are inclusive. A pixel is
|
||||
* in-bounds if min_x <= x <= max_x and min_y <= y <= max_y.
|
||||
*/
|
||||
uint16_t max_x, max_y;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
pan_fb_bbox_is_valid(struct pan_fb_bbox b)
|
||||
{
|
||||
return b.min_x <= b.max_x && b.min_y <= b.max_y;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pan_fb_bbox_contains_bbox(struct pan_fb_bbox a, struct pan_fb_bbox b)
|
||||
{
|
||||
return a.min_x <= b.min_x && b.max_x <= a.max_x &&
|
||||
a.min_y <= b.min_y && b.max_y <= a.max_y;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pan_fb_bbox_equal(struct pan_fb_bbox a, struct pan_fb_bbox b)
|
||||
{
|
||||
return a.min_x == b.min_x && b.max_x == a.max_x &&
|
||||
a.min_y == b.min_y && b.max_y == a.max_y;
|
||||
}
|
||||
|
||||
static inline struct pan_fb_bbox
|
||||
pan_fb_bbox_clamp(struct pan_fb_bbox a, struct pan_fb_bbox b)
|
||||
{
|
||||
assert(pan_fb_bbox_is_valid(a) && pan_fb_bbox_is_valid(a));
|
||||
return (struct pan_fb_bbox) {
|
||||
.min_x = CLAMP(a.min_x, b.min_x, b.max_x),
|
||||
.min_y = CLAMP(a.min_y, b.min_y, b.max_y),
|
||||
.max_x = CLAMP(a.max_x, b.min_x, b.max_x),
|
||||
.max_y = CLAMP(a.max_y, b.min_y, b.max_y),
|
||||
};
|
||||
}
|
||||
|
||||
static inline struct pan_fb_bbox
|
||||
pan_fb_bbox_align(struct pan_fb_bbox b, uint32_t align_x, uint32_t align_y)
|
||||
{
|
||||
assert(util_is_power_of_two_nonzero(align_x));
|
||||
assert(util_is_power_of_two_nonzero(align_y));
|
||||
assert(align_x <= UINT16_MAX && align_y <= UINT16_MAX);
|
||||
|
||||
b.min_x = ROUND_DOWN_TO(b.min_x, align_x);
|
||||
b.min_y = ROUND_DOWN_TO(b.min_y, align_y);
|
||||
b.max_x = align((uint32_t)b.max_x + 1, align_x) - 1;
|
||||
b.max_y = align((uint32_t)b.max_y + 1, align_y) - 1;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static inline struct pan_fb_bbox
|
||||
pan_fb_bbox_from_xywh(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||
{
|
||||
assert(x + w > x && x + w - 1 <= UINT16_MAX);
|
||||
assert(y + h > y && y + h - 1 <= UINT16_MAX);
|
||||
return (struct pan_fb_bbox) {
|
||||
.min_x = x,
|
||||
.min_y = y,
|
||||
.max_x = x + w - 1,
|
||||
.max_y = y + h - 1,
|
||||
};
|
||||
}
|
||||
|
||||
/** Framebuffer layout
|
||||
*
|
||||
* This describes the layout of framebuffer in tile memory as well as various
|
||||
* properties that are properties of the framebuffer itself, nit any of the
|
||||
* image views attached to it.
|
||||
*/
|
||||
struct pan_fb_layout {
|
||||
/** Dimensions of the framebuffer itself, in pixels */
|
||||
uint32_t width_px, height_px;
|
||||
|
||||
/** The render area
|
||||
*
|
||||
* This is the API render area (as defined by Vulkan) and may be smaller
|
||||
* than the actual bounding box of the framebuffer. The in_bounds_load
|
||||
* and border_load members of pan_fb_load_target are relative to the
|
||||
* render area.
|
||||
*/
|
||||
struct pan_fb_bbox render_area_px;
|
||||
|
||||
/** The tiling area
|
||||
*
|
||||
* This is based on the render area but may be larger to accomodate tiling
|
||||
* restrictions.
|
||||
*/
|
||||
struct pan_fb_bbox tiling_area_px;
|
||||
|
||||
/** Sample count for this framebuffer */
|
||||
uint8_t sample_count;
|
||||
|
||||
/** Color render target formats
|
||||
*
|
||||
* If a render target is unused, set it to PIPE_FORMAT_NONE.
|
||||
*/
|
||||
uint8_t rt_count;
|
||||
enum pipe_format rt_formats[PAN_MAX_RTS];
|
||||
|
||||
/** Depth format for this framebuffer, or PIPE_FORMAT_NONE */
|
||||
enum pipe_format z_format;
|
||||
|
||||
/** Stencil format for this framebuffer, or PIPE_FORMAT_NONE */
|
||||
enum pipe_format s_format;
|
||||
|
||||
/** Amount of space reserved for PLS, in bytes.
|
||||
*
|
||||
* This may overlap the color render targets in tile memory.
|
||||
*/
|
||||
uint16_t pls_size_B;
|
||||
|
||||
uint32_t tile_rt_budget_B;
|
||||
uint32_t tile_z_budget_B;
|
||||
|
||||
/** Optimal tile buffer size, in pixels
|
||||
*
|
||||
* This must be a power of two.
|
||||
*/
|
||||
unsigned tile_size_px;
|
||||
|
||||
/** Amount of tile memory allocated for color render targets */
|
||||
unsigned tile_rt_alloc_B;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
pan_fb_has_zs(const struct pan_fb_layout *fb)
|
||||
{
|
||||
/* An intentional choice is made here to base has_zs on the formats in
|
||||
* the pan_fb_layout and not the stores being done in the end. PanVK in
|
||||
* particular relies on the size of the final framebuffer descriptor being
|
||||
* the same for all the different variants with incremental rendering.
|
||||
*/
|
||||
return fb->z_format != PIPE_FORMAT_NONE ||
|
||||
fb->s_format != PIPE_FORMAT_NONE;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pan_fb_is_fully_covered(const struct pan_fb_layout *fb)
|
||||
{
|
||||
const struct pan_fb_bbox fb_area_px =
|
||||
pan_fb_bbox_from_xywh(0, 0, fb->width_px, fb->height_px);
|
||||
return pan_fb_bbox_equal(fb->render_area_px, fb_area_px);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pan_fb_has_partial_tiles(const struct pan_fb_layout *fb)
|
||||
{
|
||||
assert(pan_fb_bbox_contains_bbox(fb->tiling_area_px, fb->render_area_px));
|
||||
return !pan_fb_bbox_equal(fb->tiling_area_px, fb->render_area_px);
|
||||
}
|
||||
|
||||
#ifdef PAN_ARCH
|
||||
void GENX(pan_select_fb_tile_size)(struct pan_fb_layout *fb);
|
||||
#endif
|
||||
|
||||
enum ENUM_PACKED pan_fb_load_op {
|
||||
PAN_FB_LOAD_NONE = 0,
|
||||
PAN_FB_LOAD_CLEAR,
|
||||
PAN_FB_LOAD_IMAGE,
|
||||
PAN_FB_LOAD_OP_COUNT,
|
||||
};
|
||||
|
||||
/** Describes how MSAA is handled when copying
|
||||
*
|
||||
* The source or destination may or may not be multisampled independently and
|
||||
* this controls how that is handled in the copy.
|
||||
*/
|
||||
enum ENUM_PACKED pan_fb_msaa_copy_op {
|
||||
/** Copies all samples of the source to the destination
|
||||
*
|
||||
* This requires that the source and destination sample counts be the same.
|
||||
* If the source and destination are both single-sampled, this is equivalent
|
||||
* as PAN_FB_MSAA_COPY_SINGLE or PAN_FB_MSAA_COPY_SAMPLE_0.
|
||||
*/
|
||||
PAN_FB_MSAA_COPY_ALL = 0,
|
||||
|
||||
/** Copies the single sample from the source to the destination
|
||||
*
|
||||
* This requires that the source be single-sampled. Semantically, this is
|
||||
* the same as PAN_FB_MSAA_COPY_SAMPLE_0, but it's useful to make this
|
||||
* distinction in shader keys so single and multi-sampled sources can be
|
||||
* differentiated.
|
||||
*/
|
||||
PAN_FB_MSAA_COPY_SINGLE,
|
||||
|
||||
/** Copies assuming all source samples are identical
|
||||
*
|
||||
* The actual copy can use any resolve mode because we know a priori that
|
||||
* all samples are identical. All resolve modes yield the same result.
|
||||
*/
|
||||
PAN_FB_MSAA_COPY_IDENTICAL,
|
||||
|
||||
/** Copies sample 0 from the source to all samples in the destination */
|
||||
PAN_FB_MSAA_COPY_SAMPLE_0,
|
||||
|
||||
/** Copies the average of the samples in the source to the destination */
|
||||
PAN_FB_MSAA_COPY_AVERAGE,
|
||||
|
||||
/** Copies the minimum of the samples in the source to the destination */
|
||||
PAN_FB_MSAA_COPY_MIN,
|
||||
|
||||
/** Copies the maximum of the samples in the source to the destination */
|
||||
PAN_FB_MSAA_COPY_MAX,
|
||||
|
||||
PAN_FB_MSAA_COPY_OP_COUNT,
|
||||
};
|
||||
|
||||
struct pan_fb_load_target {
|
||||
/** Load op for pixels inside the bounding box */
|
||||
enum pan_fb_load_op in_bounds_load;
|
||||
|
||||
/** Load op for border (out of bounds) pixels
|
||||
*
|
||||
* This should almost always be LOAD_OP_LOAD, unless you have a very good
|
||||
* reason to make a different choice.
|
||||
*/
|
||||
enum pan_fb_load_op border_load;
|
||||
|
||||
/** Always load, even if no primitives intersect the tile
|
||||
*
|
||||
* This should usually be set for clears.
|
||||
*/
|
||||
bool always;
|
||||
|
||||
/** MSAA mode used when load op is IMAGE */
|
||||
enum pan_fb_msaa_copy_op msaa;
|
||||
|
||||
/* Image view to load from, or NULL if neither load op is IMAGE */
|
||||
const struct pan_image_view *iview;
|
||||
|
||||
/** Clear value, if either load op is CLEAR */
|
||||
union {
|
||||
union pipe_color_union color;
|
||||
float depth;
|
||||
uint8_t stencil;
|
||||
} clear;
|
||||
};
|
||||
|
||||
static inline struct pan_fb_load_target
|
||||
pan_fb_load_iview(const struct pan_image_view *iview)
|
||||
{
|
||||
return (struct pan_fb_load_target) {
|
||||
.in_bounds_load = PAN_FB_LOAD_IMAGE,
|
||||
.border_load = PAN_FB_LOAD_IMAGE,
|
||||
.msaa = PAN_FB_MSAA_COPY_ALL,
|
||||
.iview = iview,
|
||||
};
|
||||
}
|
||||
|
||||
struct pan_fb_load {
|
||||
/** Color render target loads */
|
||||
struct pan_fb_load_target rts[PAN_MAX_RTS];
|
||||
|
||||
/** Depth target load */
|
||||
struct pan_fb_load_target z;
|
||||
|
||||
/** Stencil target load */
|
||||
struct pan_fb_load_target s;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
pan_fb_has_image_load(const struct pan_fb_load *load, bool include_border)
|
||||
{
|
||||
if (load->z.in_bounds_load == PAN_FB_LOAD_IMAGE ||
|
||||
load->s.in_bounds_load == PAN_FB_LOAD_IMAGE)
|
||||
return true;
|
||||
|
||||
if (include_border &&
|
||||
(load->z.border_load == PAN_FB_LOAD_IMAGE ||
|
||||
load->s.border_load == PAN_FB_LOAD_IMAGE))
|
||||
return true;
|
||||
|
||||
for (unsigned rt = 0; rt < PAN_MAX_RTS; rt++) {
|
||||
if (load->rts[rt].in_bounds_load == PAN_FB_LOAD_IMAGE)
|
||||
return true;
|
||||
if (include_border && load->rts[rt].border_load == PAN_FB_LOAD_IMAGE)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Describes a resolve operation
|
||||
*
|
||||
* This describes the source data for the resolve operation. The way in which
|
||||
* MSAA is handled in the source data is defined by the pan_fb_msaa_copy_op.
|
||||
*/
|
||||
enum ENUM_PACKED pan_fb_resolve_op {
|
||||
/** Do nothing
|
||||
*
|
||||
* In this mode, the framebuffer is left unaffected by the resolve. If
|
||||
* necessary (sometimes required for Z/S), the old value will be read and
|
||||
* written back to ensure the final value is the same.
|
||||
*/
|
||||
PAN_FB_RESOLVE_NONE = 0,
|
||||
|
||||
/** Load from the specified image view */
|
||||
PAN_FB_RESOLVE_IMAGE,
|
||||
|
||||
/** Load from color render target 0 */
|
||||
PAN_FB_RESOLVE_RT_0,
|
||||
PAN_FB_RESOLVE_RT_1,
|
||||
PAN_FB_RESOLVE_RT_2,
|
||||
PAN_FB_RESOLVE_RT_3,
|
||||
PAN_FB_RESOLVE_RT_4,
|
||||
PAN_FB_RESOLVE_RT_5,
|
||||
PAN_FB_RESOLVE_RT_6,
|
||||
PAN_FB_RESOLVE_RT_7,
|
||||
|
||||
/** Load from the depth target
|
||||
*
|
||||
* From the perspective of resolve ops, Z/S are always separate
|
||||
*/
|
||||
PAN_FB_RESOLVE_Z,
|
||||
|
||||
/** Load from the stencil target
|
||||
*
|
||||
* From the perspective of resolve ops, Z/S are always separate
|
||||
*/
|
||||
PAN_FB_RESOLVE_S,
|
||||
PAN_FB_RESOLVE_OP_COUNT,
|
||||
};
|
||||
|
||||
static_assert(PAN_FB_RESOLVE_Z == PAN_FB_RESOLVE_RT_0 + PAN_MAX_RTS,
|
||||
"There are PAN_MAX_RTS many RTs");
|
||||
|
||||
#define PAN_FB_RESOLVE_RT(rt) \
|
||||
(assert(0 <= (rt) && (rt) < PAN_MAX_RTS), (PAN_FB_RESOLVE_RT_0 + (rt)))
|
||||
|
||||
/** Describes a resovle operation on a given target
|
||||
*
|
||||
* For each side of the render area (in-bounds or border), this defines both
|
||||
* a source to copy from (the resolve op) and a MSAA copy op to apply as part
|
||||
* of the copy. In the common case, a resolve op will read from itself but
|
||||
* that is not strictly a requirement. Any resolve op can read from any
|
||||
* render target.
|
||||
*/
|
||||
struct pan_fb_resolve_target {
|
||||
struct pan_fb_resolve_op_msaa {
|
||||
enum pan_fb_resolve_op resolve;
|
||||
enum pan_fb_msaa_copy_op msaa;
|
||||
} in_bounds, border;
|
||||
|
||||
/** For PAN_FB_RESOLVE_IMAGE the image view to load from */
|
||||
const struct pan_image_view *iview;
|
||||
};
|
||||
|
||||
/** Describes a resolve operation
|
||||
*
|
||||
* A resolve operation is implemented as a post-frame shader (see
|
||||
* pan_fb_resolve_shader_key_fill) and does a copy from render targets to
|
||||
* render targets, applying MSAA copy ops along the way.
|
||||
*/
|
||||
struct pan_fb_resolve {
|
||||
struct pan_fb_resolve_target rts[PAN_MAX_RTS];
|
||||
struct pan_fb_resolve_target z, s;
|
||||
};
|
||||
|
||||
struct pan_fb_store_target {
|
||||
/** Whether or not to do a store */
|
||||
bool store;
|
||||
|
||||
/** Always store, even if no primitives intersect the tile
|
||||
*
|
||||
* clean_tile_write_enable will be set if either store.always is set or
|
||||
* load.always is set for the corresponding load[s].
|
||||
*/
|
||||
bool always;
|
||||
|
||||
/** MSAA mode to use when copying to the destination image
|
||||
*
|
||||
* This can only be set to AVERAGE for blendable color formats.
|
||||
*/
|
||||
enum pan_fb_msaa_copy_op msaa;
|
||||
|
||||
/** Image view to store to */
|
||||
const struct pan_image_view *iview;
|
||||
};
|
||||
|
||||
static inline struct pan_fb_store_target
|
||||
pan_fb_store_iview(const struct pan_image_view *iview)
|
||||
{
|
||||
return (struct pan_fb_store_target) {
|
||||
.store = true,
|
||||
.msaa = PAN_FB_MSAA_COPY_ALL,
|
||||
.iview = iview,
|
||||
};
|
||||
}
|
||||
|
||||
static inline struct pan_fb_store_target
|
||||
pan_fb_always_store_iview_s0(const struct pan_image_view *iview)
|
||||
{
|
||||
return (struct pan_fb_store_target) {
|
||||
.store = true,
|
||||
.always = true,
|
||||
.msaa = PAN_FB_MSAA_COPY_SAMPLE_0,
|
||||
.iview = iview,
|
||||
};
|
||||
}
|
||||
|
||||
struct pan_fb_store {
|
||||
/* Color render target stores */
|
||||
struct pan_fb_store_target rts[PAN_MAX_RTS];
|
||||
|
||||
/* Depth/stencil target store
|
||||
*
|
||||
* If the attached image view has a combined depth/stencil format, both
|
||||
* depth and stencil will be written.
|
||||
*/
|
||||
struct pan_fb_store_target zs;
|
||||
|
||||
/* Stencil target store */
|
||||
struct pan_fb_store_target s;
|
||||
};
|
||||
|
||||
#ifdef PAN_ARCH
|
||||
void GENX(pan_align_fb_tiling_area)(struct pan_fb_layout *fb,
|
||||
const struct pan_fb_store *store);
|
||||
|
||||
void GENX(pan_fb_fold_resolve_into_store)(const struct pan_fb_layout *fb,
|
||||
struct pan_fb_resolve *resolve,
|
||||
struct pan_fb_store *store);
|
||||
#endif
|
||||
|
||||
struct pan_fb_frame_shaders {
|
||||
uint64_t dcd_pointer;
|
||||
uint8_t modes[3];
|
||||
};
|
||||
|
||||
struct pan_fb_desc_info {
|
||||
const struct pan_fb_layout *fb;
|
||||
const struct pan_fb_load *load;
|
||||
const struct pan_fb_store *store;
|
||||
|
||||
struct pan_fb_frame_shaders frame_shaders;
|
||||
|
||||
uint64_t sample_pos_array_pointer;
|
||||
|
||||
/* Only used on Valhal */
|
||||
bool sprite_coord_origin_max_y;
|
||||
bool provoking_vertex_first;
|
||||
bool allow_hsr_prepass;
|
||||
|
||||
uint16_t layer;
|
||||
|
||||
const struct pan_tls_info *tls;
|
||||
const struct pan_tiler_context *tiler_ctx;
|
||||
};
|
||||
|
||||
#ifdef PAN_ARCH
|
||||
void GENX(pan_fill_fb_info)(const struct pan_fb_desc_info *info,
|
||||
struct pan_fb_info *fbinfo);
|
||||
|
||||
struct pan_fb_descs {
|
||||
#if PAN_ARCH <= 13
|
||||
struct mali_framebuffer_packed *fbd;
|
||||
#endif
|
||||
struct mali_zs_crc_extension_packed *zs_crc;
|
||||
struct mali_rgb_render_target_packed *rts;
|
||||
};
|
||||
|
||||
uint32_t GENX(pan_emit_fb_desc)(const struct pan_fb_desc_info *info,
|
||||
const struct pan_fb_descs *out);
|
||||
#endif
|
||||
|
||||
enum ENUM_PACKED pan_fb_shader_op {
|
||||
/** Preserves the current fragment contents
|
||||
*
|
||||
* The MSAA mode is ignored and, if a load does need to occur to preserve
|
||||
* the current fragment contents, PAN_FB_MSAA_COPY_ALL is implied.
|
||||
*
|
||||
* This is only allowed in resolve shaders so this can always be replaced
|
||||
* with a discard.
|
||||
*/
|
||||
PAN_FB_SHADER_PRESERVE = 0,
|
||||
|
||||
/** Do whatever is the fastest (lowest bandwidth)
|
||||
*
|
||||
* This could be a CLEAR or PRESERVE or just write zeros. It will never
|
||||
* write actual random data but the exact behavior may depend on other bits
|
||||
* in the shader key.
|
||||
*/
|
||||
PAN_FB_SHADER_DONT_CARE,
|
||||
|
||||
/** Loads the clear color
|
||||
*
|
||||
* This is only allowed in preload shaders and the clear will also be done
|
||||
* in hardware so it can always be replaced with a discard.
|
||||
*/
|
||||
PAN_FB_SHADER_LOAD_CLEAR,
|
||||
|
||||
/** Loads from the image bound at the corresponding gl_frag_result */
|
||||
PAN_FB_SHADER_LOAD_IMAGE,
|
||||
|
||||
PAN_FB_SHADER_COPY_RT_0,
|
||||
PAN_FB_SHADER_COPY_RT_1,
|
||||
PAN_FB_SHADER_COPY_RT_2,
|
||||
PAN_FB_SHADER_COPY_RT_3,
|
||||
PAN_FB_SHADER_COPY_RT_4,
|
||||
PAN_FB_SHADER_COPY_RT_5,
|
||||
PAN_FB_SHADER_COPY_RT_6,
|
||||
PAN_FB_SHADER_COPY_RT_7,
|
||||
PAN_FB_SHADER_COPY_Z,
|
||||
PAN_FB_SHADER_COPY_S,
|
||||
|
||||
PAN_FB_SHADER_OP_COUNT,
|
||||
};
|
||||
|
||||
static_assert(PAN_FB_SHADER_COPY_Z == PAN_FB_SHADER_COPY_RT_0 + PAN_MAX_RTS,
|
||||
"We should have one PAN_FB_SHADER_COPY_RT_N per RT");
|
||||
|
||||
#define PAN_FB_SHADER_COPY_RT(rt) \
|
||||
(assert(0 <= (rt) && (rt) < PAN_MAX_RTS), (PAN_FB_SHADER_COPY_RT_0 + (rt)))
|
||||
|
||||
static inline bool
|
||||
pan_fb_shader_op_can_discard(enum pan_fb_shader_op op)
|
||||
{
|
||||
return op == PAN_FB_SHADER_PRESERVE ||
|
||||
op == PAN_FB_SHADER_DONT_CARE ||
|
||||
op == PAN_FB_SHADER_LOAD_CLEAR;
|
||||
}
|
||||
|
||||
enum ENUM_PACKED pan_fb_shader_data_type {
|
||||
PAN_FB_SHADER_DATA_TYPE_F32 = 0,
|
||||
PAN_FB_SHADER_DATA_TYPE_I32,
|
||||
PAN_FB_SHADER_DATA_TYPE_U32,
|
||||
PAN_FB_SHADER_DATA_TYPE_COUNT,
|
||||
};
|
||||
|
||||
static_assert(PAN_FB_SHADER_OP_COUNT <= (1 << 4),
|
||||
"pan_fb_shader_op fits in 4 bits");
|
||||
static_assert(PAN_FB_MSAA_COPY_OP_COUNT <= (1 << 3),
|
||||
"pan_fb_msaa_copy_op fits in 3 bits");
|
||||
static_assert(PAN_FB_SHADER_DATA_TYPE_COUNT <= (1 << 2),
|
||||
"pan_fb_shader_data_type fits in 2 bits");
|
||||
|
||||
/* Asserts for glsl_sampler_dim glsl_base_type have to be runtime because
|
||||
* there is no MAX value we can use.
|
||||
*/
|
||||
|
||||
PRAGMA_DIAGNOSTIC_PUSH
|
||||
PRAGMA_DIAGNOSTIC_ERROR(-Wpadded)
|
||||
struct pan_fb_shader_key_target {
|
||||
uint32_t in_bounds_op : 4;
|
||||
uint32_t border_op : 4;
|
||||
uint32_t in_bounds_msaa : 3;
|
||||
uint32_t border_msaa : 3;
|
||||
uint32_t sample0_only : 1;
|
||||
uint32_t image_dim : 2;
|
||||
uint32_t image_is_array : 1;
|
||||
uint32_t image_samples_log2 : 3;
|
||||
uint32_t data_type : 2;
|
||||
uint32_t pad : 9;
|
||||
};
|
||||
PRAGMA_DIAGNOSTIC_POP
|
||||
static_assert(sizeof(struct pan_fb_shader_key_target) == 4,
|
||||
"This struct has no holes");
|
||||
|
||||
/** Whether or not the given target is written by the FB shader
|
||||
*
|
||||
* GENX(pan_get_fb_shader)() guarantees that if both in_bounds_op and
|
||||
* border_op can be discarded, that it does nothing with that target. This
|
||||
* way the full outputs_written can be known from just the shader key.
|
||||
*/
|
||||
static inline bool
|
||||
pan_fb_shader_key_target_written(const struct pan_fb_shader_key_target *target)
|
||||
{
|
||||
return !pan_fb_shader_op_can_discard(target->in_bounds_op) ||
|
||||
!pan_fb_shader_op_can_discard(target->border_op);
|
||||
}
|
||||
|
||||
PRAGMA_DIAGNOSTIC_PUSH
|
||||
PRAGMA_DIAGNOSTIC_ERROR(-Wpadded)
|
||||
struct pan_fb_shader_key {
|
||||
struct pan_fb_shader_key_target rts[PAN_MAX_RTS];
|
||||
struct pan_fb_shader_key_target z, s;
|
||||
uint16_t z_format;
|
||||
uint8_t fb_sample_count;
|
||||
uint8_t _pad;
|
||||
};
|
||||
PRAGMA_DIAGNOSTIC_POP
|
||||
static_assert(sizeof(struct pan_fb_shader_key) == 4 * (PAN_MAX_RTS + 3),
|
||||
"This struct has no holes");
|
||||
|
||||
#ifdef PAN_ARCH
|
||||
bool GENX(pan_fb_load_shader_key_fill)(struct pan_fb_shader_key *key,
|
||||
const struct pan_fb_layout *fb,
|
||||
const struct pan_fb_load *load,
|
||||
bool zs_prepass);
|
||||
|
||||
#if PAN_ARCH >= 5
|
||||
struct pan_fb_clean_tile {
|
||||
uint8_t rts;
|
||||
bool zs, s;
|
||||
};
|
||||
|
||||
struct pan_fb_clean_tile
|
||||
GENX(pan_fb_get_clean_tile)(const struct pan_fb_desc_info *info);
|
||||
|
||||
static inline bool
|
||||
pan_target_has_clear(const struct pan_fb_load_target *target)
|
||||
{
|
||||
return target->in_bounds_load == PAN_FB_LOAD_CLEAR ||
|
||||
target->border_load == PAN_FB_LOAD_CLEAR;
|
||||
}
|
||||
#endif /* PAN_ARCH >= 5 */
|
||||
|
||||
#if PAN_ARCH >= 6
|
||||
bool GENX(pan_fb_resolve_shader_key_fill)(struct pan_fb_shader_key *key,
|
||||
const struct pan_fb_layout *fb,
|
||||
const struct pan_fb_resolve *resolve);
|
||||
#endif /* PAN_ARCH >= 6 */
|
||||
|
||||
struct nir_shader *
|
||||
GENX(pan_get_fb_shader)(const struct pan_fb_shader_key *key,
|
||||
const struct nir_shader_compiler_options *nir_options);
|
||||
|
||||
#if PAN_ARCH >= 13
|
||||
/**
|
||||
* Returns true if there's enough space in the tile buffer for at least two
|
||||
* Z/S tiles.
|
||||
*/
|
||||
static inline bool
|
||||
pan_fb_can_pipeline_zs(const struct pan_fb_layout *fb)
|
||||
{
|
||||
const uint32_t z_B_per_px = sizeof(float) * fb->sample_count;
|
||||
const uint32_t z_B_per_tile = z_B_per_px * fb->tile_size_px;
|
||||
|
||||
/* The budget is already half the available Z space */
|
||||
return z_B_per_tile < fb->tile_z_budget_B;
|
||||
}
|
||||
#endif
|
||||
#endif /* PAN_ARCH */
|
||||
|
||||
#endif /* __PAN_FB_H */
|
||||
Reference in new issue
Block a user