mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 07:00:11 +01:00
ilo: initialize ilo_image from ilo_image_info
Convert pipe_resource to ilo_image_info for image initialization.
This commit is contained in:
parent
f825fe8e13
commit
934e4a469f
3 changed files with 244 additions and 181 deletions
|
|
@ -42,7 +42,7 @@ enum {
|
|||
|
||||
struct ilo_image_params {
|
||||
const struct ilo_dev *dev;
|
||||
const struct pipe_resource *templ;
|
||||
const struct ilo_image_info *info;
|
||||
unsigned valid_tilings;
|
||||
|
||||
bool compressed;
|
||||
|
|
@ -56,7 +56,7 @@ img_get_slice_size(const struct ilo_image *img,
|
|||
const struct ilo_image_params *params,
|
||||
unsigned level, unsigned *width, unsigned *height)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
unsigned w, h;
|
||||
|
||||
w = u_minify(img->width0, level);
|
||||
|
|
@ -112,8 +112,7 @@ img_get_slice_size(const struct ilo_image *img,
|
|||
* y = align(y, 2) * 2;
|
||||
*/
|
||||
if (img->interleaved_samples) {
|
||||
switch (templ->nr_samples) {
|
||||
case 0:
|
||||
switch (info->sample_count) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
|
|
@ -157,12 +156,12 @@ static unsigned
|
|||
img_get_num_layers(const struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
unsigned num_layers = templ->array_size;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
unsigned num_layers = info->array_size;
|
||||
|
||||
/* samples of the same index are stored in a layer */
|
||||
if (templ->nr_samples > 1 && !img->interleaved_samples)
|
||||
num_layers *= templ->nr_samples;
|
||||
if (info->sample_count > 1 && !img->interleaved_samples)
|
||||
num_layers *= info->sample_count;
|
||||
|
||||
return num_layers;
|
||||
}
|
||||
|
|
@ -171,7 +170,7 @@ static void
|
|||
img_init_layer_height(struct ilo_image *img,
|
||||
struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
unsigned num_layers;
|
||||
|
||||
if (img->walk != ILO_IMAGE_WALK_LAYER)
|
||||
|
|
@ -218,7 +217,7 @@ img_init_layer_height(struct ilo_image *img,
|
|||
img->walk_layer_height = params->h0 + params->h1 +
|
||||
((ilo_dev_gen(params->dev) >= ILO_GEN(7)) ? 12 : 11) * img->align_j;
|
||||
|
||||
if (ilo_dev_gen(params->dev) == ILO_GEN(6) && templ->nr_samples > 1 &&
|
||||
if (ilo_dev_gen(params->dev) == ILO_GEN(6) && info->sample_count > 1 &&
|
||||
img->height0 % 4 == 1)
|
||||
img->walk_layer_height += 4;
|
||||
|
||||
|
|
@ -229,13 +228,13 @@ static void
|
|||
img_init_lods(struct ilo_image *img,
|
||||
struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
unsigned cur_x, cur_y;
|
||||
unsigned lv;
|
||||
|
||||
cur_x = 0;
|
||||
cur_y = 0;
|
||||
for (lv = 0; lv <= templ->last_level; lv++) {
|
||||
for (lv = 0; lv < info->level_count; lv++) {
|
||||
unsigned lod_w, lod_h;
|
||||
|
||||
img_get_slice_size(img, params, lv, &lod_w, &lod_h);
|
||||
|
|
@ -261,7 +260,7 @@ img_init_lods(struct ilo_image *img,
|
|||
cur_y += lod_h;
|
||||
|
||||
/* every LOD begins at tile boundaries */
|
||||
if (templ->last_level > 0) {
|
||||
if (info->level_count > 1) {
|
||||
assert(img->format == PIPE_FORMAT_S8_UINT);
|
||||
cur_x = align(cur_x, 64);
|
||||
cur_y = align(cur_y, 64);
|
||||
|
|
@ -269,7 +268,7 @@ img_init_lods(struct ilo_image *img,
|
|||
break;
|
||||
case ILO_IMAGE_WALK_3D:
|
||||
{
|
||||
const unsigned num_slices = u_minify(templ->depth0, lv);
|
||||
const unsigned num_slices = u_minify(info->depth, lv);
|
||||
const unsigned num_slices_per_row = 1 << lv;
|
||||
const unsigned num_rows =
|
||||
(num_slices + num_slices_per_row - 1) / num_slices_per_row;
|
||||
|
|
@ -291,7 +290,7 @@ img_init_lods(struct ilo_image *img,
|
|||
if (img->walk == ILO_IMAGE_WALK_LAYER) {
|
||||
params->h0 = img->lods[0].slice_height;
|
||||
|
||||
if (templ->last_level > 0)
|
||||
if (info->level_count > 1)
|
||||
params->h1 = img->lods[1].slice_height;
|
||||
else
|
||||
img_get_slice_size(img, params, 1, &cur_x, ¶ms->h1);
|
||||
|
|
@ -302,7 +301,7 @@ static void
|
|||
img_init_alignments(struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
|
||||
/*
|
||||
* From the Sandy Bridge PRM, volume 1 part 1, page 113:
|
||||
|
|
@ -396,7 +395,7 @@ img_init_alignments(struct ilo_image *img,
|
|||
/* this happens to be the case */
|
||||
img->align_i = img->block_width;
|
||||
img->align_j = img->block_height;
|
||||
} else if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
|
||||
} else if (info->bind_zs) {
|
||||
if (ilo_dev_gen(params->dev) >= ILO_GEN(7)) {
|
||||
switch (img->format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
|
|
@ -426,11 +425,11 @@ img_init_alignments(struct ilo_image *img,
|
|||
}
|
||||
} else {
|
||||
const bool valign_4 =
|
||||
(templ->nr_samples > 1) ||
|
||||
(info->sample_count > 1) ||
|
||||
(ilo_dev_gen(params->dev) >= ILO_GEN(8)) ||
|
||||
(ilo_dev_gen(params->dev) >= ILO_GEN(7) &&
|
||||
img->tiling == GEN6_TILING_Y &&
|
||||
(templ->bind & PIPE_BIND_RENDER_TARGET));
|
||||
info->bind_surface_dp_render);
|
||||
|
||||
if (ilo_dev_gen(params->dev) >= ILO_GEN(7) &&
|
||||
ilo_dev_gen(params->dev) <= ILO_GEN(7.5) && valign_4)
|
||||
|
|
@ -460,14 +459,14 @@ static void
|
|||
img_init_tiling(struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
unsigned preferred_tilings = params->valid_tilings;
|
||||
|
||||
/* no fencing nor BLT support */
|
||||
if (preferred_tilings & ~IMAGE_TILING_W)
|
||||
preferred_tilings &= ~IMAGE_TILING_W;
|
||||
|
||||
if (templ->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) {
|
||||
if (info->bind_surface_dp_render || info->bind_surface_sampler) {
|
||||
/*
|
||||
* heuristically set a minimum width/height for enabling tiling
|
||||
*/
|
||||
|
|
@ -499,7 +498,7 @@ static void
|
|||
img_init_walk_gen7(struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
|
||||
/*
|
||||
* It is not explicitly states, but render targets are expected to be
|
||||
|
|
@ -508,14 +507,14 @@ img_init_walk_gen7(struct ilo_image *img,
|
|||
*
|
||||
* See "Multisampled Surface Storage Format" field of SURFACE_STATE.
|
||||
*/
|
||||
if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
|
||||
if (info->bind_zs) {
|
||||
/*
|
||||
* From the Ivy Bridge PRM, volume 1 part 1, page 111:
|
||||
*
|
||||
* "note that the depth buffer and stencil buffer have an implied
|
||||
* value of ARYSPC_FULL"
|
||||
*/
|
||||
img->walk = (templ->target == PIPE_TEXTURE_3D) ?
|
||||
img->walk = (info->target == PIPE_TEXTURE_3D) ?
|
||||
ILO_IMAGE_WALK_3D : ILO_IMAGE_WALK_LAYER;
|
||||
|
||||
img->interleaved_samples = true;
|
||||
|
|
@ -530,12 +529,12 @@ img_init_walk_gen7(struct ilo_image *img,
|
|||
* As multisampled resources are not mipmapped, we never use
|
||||
* ARYSPC_FULL for them.
|
||||
*/
|
||||
if (templ->nr_samples > 1)
|
||||
assert(templ->last_level == 0);
|
||||
if (info->sample_count > 1)
|
||||
assert(info->level_count == 1);
|
||||
|
||||
img->walk =
|
||||
(templ->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
|
||||
(templ->last_level > 0) ? ILO_IMAGE_WALK_LAYER :
|
||||
(info->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
|
||||
(info->level_count > 1) ? ILO_IMAGE_WALK_LAYER :
|
||||
ILO_IMAGE_WALK_LOD;
|
||||
|
||||
img->interleaved_samples = false;
|
||||
|
|
@ -558,7 +557,7 @@ img_init_walk_gen6(struct ilo_image *img,
|
|||
* GEN6 does not support compact spacing otherwise.
|
||||
*/
|
||||
img->walk =
|
||||
(params->templ->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
|
||||
(params->info->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
|
||||
(img->format == PIPE_FORMAT_S8_UINT) ? ILO_IMAGE_WALK_LOD :
|
||||
ILO_IMAGE_WALK_LAYER;
|
||||
|
||||
|
|
@ -580,7 +579,7 @@ static unsigned
|
|||
img_get_valid_tilings(const struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
const enum pipe_format format = img->format;
|
||||
unsigned valid_tilings = params->valid_tilings;
|
||||
|
||||
|
|
@ -590,7 +589,7 @@ img_get_valid_tilings(const struct ilo_image *img,
|
|||
* "Display/Overlay Y-Major not supported.
|
||||
* X-Major required for Async Flips"
|
||||
*/
|
||||
if (unlikely(templ->bind & PIPE_BIND_SCANOUT))
|
||||
if (unlikely(info->bind_scanout))
|
||||
valid_tilings &= IMAGE_TILING_X;
|
||||
|
||||
/*
|
||||
|
|
@ -599,7 +598,7 @@ img_get_valid_tilings(const struct ilo_image *img,
|
|||
* "The cursor surface address must be 4K byte aligned. The cursor must
|
||||
* be in linear memory, it cannot be tiled."
|
||||
*/
|
||||
if (unlikely(templ->bind & (PIPE_BIND_CURSOR | PIPE_BIND_LINEAR)))
|
||||
if (unlikely(info->bind_cursor))
|
||||
valid_tilings &= IMAGE_TILING_NONE;
|
||||
|
||||
/*
|
||||
|
|
@ -614,7 +613,7 @@ img_get_valid_tilings(const struct ilo_image *img,
|
|||
*
|
||||
* "W-Major Tile Format is used for separate stencil."
|
||||
*/
|
||||
if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
|
||||
if (info->bind_zs) {
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_S8_UINT:
|
||||
valid_tilings &= IMAGE_TILING_W;
|
||||
|
|
@ -625,7 +624,7 @@ img_get_valid_tilings(const struct ilo_image *img,
|
|||
}
|
||||
}
|
||||
|
||||
if (templ->bind & PIPE_BIND_RENDER_TARGET) {
|
||||
if (info->bind_surface_dp_render) {
|
||||
/*
|
||||
* From the Sandy Bridge PRM, volume 1 part 2, page 32:
|
||||
*
|
||||
|
|
@ -656,7 +655,7 @@ img_get_valid_tilings(const struct ilo_image *img,
|
|||
valid_tilings &= ~IMAGE_TILING_W;
|
||||
}
|
||||
|
||||
if (templ->bind & PIPE_BIND_SAMPLER_VIEW) {
|
||||
if (info->bind_surface_sampler) {
|
||||
if (ilo_dev_gen(params->dev) < ILO_GEN(8))
|
||||
valid_tilings &= ~IMAGE_TILING_W;
|
||||
}
|
||||
|
|
@ -671,17 +670,17 @@ static void
|
|||
img_init_size_and_format(struct ilo_image *img,
|
||||
struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
enum pipe_format format = templ->format;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
enum pipe_format format = info->format;
|
||||
bool require_separate_stencil = false;
|
||||
|
||||
img->target = templ->target;
|
||||
img->width0 = templ->width0;
|
||||
img->height0 = templ->height0;
|
||||
img->depth0 = templ->depth0;
|
||||
img->array_size = templ->array_size;
|
||||
img->level_count = templ->last_level + 1;
|
||||
img->sample_count = (templ->nr_samples) ? templ->nr_samples : 1;
|
||||
img->target = info->target;
|
||||
img->width0 = info->width;
|
||||
img->height0 = info->height;
|
||||
img->depth0 = info->depth;
|
||||
img->array_size = info->array_size;
|
||||
img->level_count = info->level_count;
|
||||
img->sample_count = info->sample_count;
|
||||
|
||||
/*
|
||||
* From the Sandy Bridge PRM, volume 2 part 1, page 317:
|
||||
|
|
@ -691,7 +690,7 @@ img_init_size_and_format(struct ilo_image *img,
|
|||
*
|
||||
* GEN7+ requires separate stencil buffers.
|
||||
*/
|
||||
if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
|
||||
if (info->bind_zs) {
|
||||
if (ilo_dev_gen(params->dev) >= ILO_GEN(7))
|
||||
require_separate_stencil = true;
|
||||
else
|
||||
|
|
@ -731,15 +730,14 @@ static bool
|
|||
img_want_mcs(const struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
bool want_mcs = false;
|
||||
|
||||
/* MCS is for RT on GEN7+ */
|
||||
if (ilo_dev_gen(params->dev) < ILO_GEN(7))
|
||||
return false;
|
||||
|
||||
if (templ->target != PIPE_TEXTURE_2D ||
|
||||
!(templ->bind & PIPE_BIND_RENDER_TARGET))
|
||||
if (info->target != PIPE_TEXTURE_2D || !info->bind_surface_dp_render)
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
|
@ -752,9 +750,9 @@ img_want_mcs(const struct ilo_image *img,
|
|||
* "This field must be set to 0 for all SINT MSRTs when all RT channels
|
||||
* are not written"
|
||||
*/
|
||||
if (templ->nr_samples > 1 && !util_format_is_pure_sint(templ->format)) {
|
||||
if (info->sample_count > 1 && !util_format_is_pure_sint(info->format)) {
|
||||
want_mcs = true;
|
||||
} else if (templ->nr_samples <= 1) {
|
||||
} else if (info->sample_count == 1 && !info->aux_disable) {
|
||||
/*
|
||||
* From the Ivy Bridge PRM, volume 2 part 1, page 326:
|
||||
*
|
||||
|
|
@ -770,7 +768,7 @@ img_want_mcs(const struct ilo_image *img,
|
|||
* ..."
|
||||
*/
|
||||
if (img->tiling != GEN6_TILING_NONE &&
|
||||
templ->last_level == 0 && templ->array_size == 1) {
|
||||
info->level_count == 1 && info->array_size == 1) {
|
||||
switch (img->block_size) {
|
||||
case 4:
|
||||
case 8:
|
||||
|
|
@ -790,27 +788,26 @@ static bool
|
|||
img_want_hiz(const struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(templ->format);
|
||||
util_format_description(info->format);
|
||||
|
||||
if (ilo_debug & ILO_DEBUG_NOHIZ)
|
||||
return false;
|
||||
|
||||
/* we want 8x4 aligned levels */
|
||||
if (templ->target == PIPE_TEXTURE_1D)
|
||||
if (info->aux_disable)
|
||||
return false;
|
||||
|
||||
if (!(templ->bind & PIPE_BIND_DEPTH_STENCIL))
|
||||
/* we want 8x4 aligned levels */
|
||||
if (info->target == PIPE_TEXTURE_1D)
|
||||
return false;
|
||||
|
||||
if (!info->bind_zs)
|
||||
return false;
|
||||
|
||||
if (!util_format_has_depth(desc))
|
||||
return false;
|
||||
|
||||
/* no point in having HiZ */
|
||||
if (templ->usage == PIPE_USAGE_STAGING)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* As can be seen in img_calculate_hiz_size(), HiZ may not be enabled
|
||||
* for every level. This is generally fine except on GEN6, where HiZ and
|
||||
|
|
@ -819,8 +816,8 @@ img_want_hiz(const struct ilo_image *img,
|
|||
* can result in incompatible formats.
|
||||
*/
|
||||
if (ilo_dev_gen(params->dev) == ILO_GEN(6) &&
|
||||
templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
|
||||
templ->last_level)
|
||||
info->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
|
||||
info->level_count > 1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
@ -839,7 +836,7 @@ img_init_aux(struct ilo_image *img,
|
|||
static void
|
||||
img_align(struct ilo_image *img, struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
int align_w = 1, align_h = 1, pad_h = 0;
|
||||
|
||||
/*
|
||||
|
|
@ -864,11 +861,11 @@ img_align(struct ilo_image *img, struct ilo_image_params *params)
|
|||
* padding purposes. The value of 4 for j still applies for mip level
|
||||
* alignment and QPitch calculation."
|
||||
*/
|
||||
if (templ->bind & PIPE_BIND_SAMPLER_VIEW) {
|
||||
if (info->bind_surface_sampler) {
|
||||
align_w = MAX2(align_w, img->align_i);
|
||||
align_h = MAX2(align_h, img->align_j);
|
||||
|
||||
if (templ->target == PIPE_TEXTURE_CUBE)
|
||||
if (info->target == PIPE_TEXTURE_CUBE)
|
||||
pad_h += 2;
|
||||
|
||||
if (params->compressed)
|
||||
|
|
@ -881,7 +878,7 @@ img_align(struct ilo_image *img, struct ilo_image_params *params)
|
|||
* "If the surface contains an odd number of rows of data, a final row
|
||||
* below the surface must be allocated."
|
||||
*/
|
||||
if (templ->bind & PIPE_BIND_RENDER_TARGET)
|
||||
if (info->bind_surface_dp_render)
|
||||
align_h = MAX2(align_h, 2);
|
||||
|
||||
/*
|
||||
|
|
@ -889,9 +886,9 @@ img_align(struct ilo_image *img, struct ilo_image_params *params)
|
|||
* for unaligned non-mipmapped and non-array images.
|
||||
*/
|
||||
if (img->aux.type == ILO_IMAGE_AUX_HIZ &&
|
||||
templ->last_level == 0 &&
|
||||
templ->array_size == 1 &&
|
||||
templ->depth0 == 1) {
|
||||
info->level_count == 1 &&
|
||||
info->array_size == 1 &&
|
||||
info->depth == 1) {
|
||||
align_w = MAX2(align_w, 8);
|
||||
align_h = MAX2(align_h, 4);
|
||||
}
|
||||
|
|
@ -925,7 +922,7 @@ img_calculate_bo_size(struct ilo_image *img,
|
|||
* required above."
|
||||
*/
|
||||
if (ilo_dev_gen(params->dev) >= ILO_GEN(7.5) &&
|
||||
(params->templ->bind & PIPE_BIND_SAMPLER_VIEW) &&
|
||||
params->info->bind_surface_sampler &&
|
||||
img->tiling == GEN6_TILING_NONE)
|
||||
h += (64 + img->bo_stride - 1) / img->bo_stride;
|
||||
|
||||
|
|
@ -943,7 +940,7 @@ img_calculate_bo_size(struct ilo_image *img,
|
|||
*
|
||||
* Different requirements may exist when the bo is used in different
|
||||
* places, but our alignments here should be good enough that we do not
|
||||
* need to check params->templ->bind.
|
||||
* need to check params->info->bind_x.
|
||||
*/
|
||||
switch (img->tiling) {
|
||||
case GEN6_TILING_X:
|
||||
|
|
@ -994,7 +991,7 @@ img_calculate_bo_size(struct ilo_image *img,
|
|||
img->tiling = GEN6_TILING_NONE;
|
||||
/* MCS support for non-MSRTs is limited to tiled RTs */
|
||||
if (img->aux.type == ILO_IMAGE_AUX_MCS &&
|
||||
params->templ->nr_samples <= 1)
|
||||
params->info->sample_count == 1)
|
||||
img->aux.type = ILO_IMAGE_AUX_NONE;
|
||||
|
||||
continue;
|
||||
|
|
@ -1014,7 +1011,7 @@ static void
|
|||
img_calculate_hiz_size(struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
const unsigned hz_align_j = 8;
|
||||
enum ilo_image_walk_type hz_walk;
|
||||
unsigned hz_width, hz_height, lv;
|
||||
|
|
@ -1059,7 +1056,7 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
|
||||
hz_width = align(img->lods[0].slice_width, 16);
|
||||
|
||||
hz_height = hz_qpitch * templ->array_size / 2;
|
||||
hz_height = hz_qpitch * info->array_size / 2;
|
||||
if (ilo_dev_gen(params->dev) >= ILO_GEN(7))
|
||||
hz_height = align(hz_height, 8);
|
||||
|
||||
|
|
@ -1077,7 +1074,7 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
hz_height = 0;
|
||||
cur_tx = 0;
|
||||
cur_ty = 0;
|
||||
for (lv = 0; lv <= templ->last_level; lv++) {
|
||||
for (lv = 0; lv < info->level_count; lv++) {
|
||||
unsigned tw, th;
|
||||
|
||||
lod_tx[lv] = cur_tx;
|
||||
|
|
@ -1085,7 +1082,7 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
|
||||
tw = align(img->lods[lv].slice_width, 16);
|
||||
th = align(img->lods[lv].slice_height, hz_align_j) *
|
||||
templ->array_size / 2;
|
||||
info->array_size / 2;
|
||||
/* convert to Y-tiles */
|
||||
tw = align(tw, 128) / 128;
|
||||
th = align(th, 32) / 32;
|
||||
|
|
@ -1102,7 +1099,7 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
}
|
||||
|
||||
/* convert tile offsets to memory offsets */
|
||||
for (lv = 0; lv <= templ->last_level; lv++) {
|
||||
for (lv = 0; lv < info->level_count; lv++) {
|
||||
img->aux.walk_lod_offsets[lv] =
|
||||
(lod_ty[lv] * hz_width + lod_tx[lv]) * 4096;
|
||||
}
|
||||
|
|
@ -1114,10 +1111,10 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
hz_width = align(img->lods[0].slice_width, 16);
|
||||
|
||||
hz_height = 0;
|
||||
for (lv = 0; lv <= templ->last_level; lv++) {
|
||||
for (lv = 0; lv < info->level_count; lv++) {
|
||||
const unsigned h = align(img->lods[lv].slice_height, hz_align_j);
|
||||
/* according to the formula, slices are packed together vertically */
|
||||
hz_height += h * u_minify(templ->depth0, lv);
|
||||
hz_height += h * u_minify(info->depth, lv);
|
||||
}
|
||||
hz_height /= 2;
|
||||
break;
|
||||
|
|
@ -1136,8 +1133,7 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
*/
|
||||
hz_clear_w = 8;
|
||||
hz_clear_h = 4;
|
||||
switch (templ->nr_samples) {
|
||||
case 0:
|
||||
switch (info->sample_count) {
|
||||
case 1:
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1158,7 +1154,7 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
break;
|
||||
}
|
||||
|
||||
for (lv = 0; lv <= templ->last_level; lv++) {
|
||||
for (lv = 0; lv < info->level_count; lv++) {
|
||||
if (u_minify(img->width0, lv) % hz_clear_w ||
|
||||
u_minify(img->height0, lv) % hz_clear_h)
|
||||
break;
|
||||
|
|
@ -1166,7 +1162,7 @@ img_calculate_hiz_size(struct ilo_image *img,
|
|||
}
|
||||
|
||||
/* we padded to allow this in img_align() */
|
||||
if (templ->last_level == 0 && templ->array_size == 1 && templ->depth0 == 1)
|
||||
if (info->level_count == 1 && info->array_size == 1 && info->depth == 1)
|
||||
img->aux.enables |= 0x1;
|
||||
|
||||
/* align to Y-tile */
|
||||
|
|
@ -1178,13 +1174,13 @@ static void
|
|||
img_calculate_mcs_size(struct ilo_image *img,
|
||||
const struct ilo_image_params *params)
|
||||
{
|
||||
const struct pipe_resource *templ = params->templ;
|
||||
const struct ilo_image_info *info = params->info;
|
||||
int mcs_width, mcs_height, mcs_cpp;
|
||||
int downscale_x, downscale_y;
|
||||
|
||||
assert(img->aux.type == ILO_IMAGE_AUX_MCS);
|
||||
|
||||
if (templ->nr_samples > 1) {
|
||||
if (info->sample_count > 1) {
|
||||
/*
|
||||
* From the Ivy Bridge PRM, volume 2 part 1, page 326, the clear
|
||||
* rectangle is scaled down by 8x2 for 4X MSAA and 2x2 for 8X MSAA. The
|
||||
|
|
@ -1198,7 +1194,7 @@ img_calculate_mcs_size(struct ilo_image *img,
|
|||
* RT. Similarly, we could reason that an OWord in 4X MCS maps to a 8x2
|
||||
* pixel block in the RT.
|
||||
*/
|
||||
switch (templ->nr_samples) {
|
||||
switch (info->sample_count) {
|
||||
case 2:
|
||||
case 4:
|
||||
downscale_x = 8;
|
||||
|
|
@ -1295,13 +1291,13 @@ img_calculate_mcs_size(struct ilo_image *img,
|
|||
mcs_cpp = 16; /* an OWord */
|
||||
}
|
||||
|
||||
img->aux.enables = (1 << (templ->last_level + 1)) - 1;
|
||||
img->aux.enables = (1 << info->level_count) - 1;
|
||||
/* align to Y-tile */
|
||||
img->aux.bo_stride = align(mcs_width * mcs_cpp, 128);
|
||||
img->aux.bo_height = align(mcs_height, 32);
|
||||
}
|
||||
|
||||
static void
|
||||
static bool
|
||||
img_init(struct ilo_image *img,
|
||||
struct ilo_image_params *params)
|
||||
{
|
||||
|
|
@ -1318,7 +1314,7 @@ img_init(struct ilo_image *img,
|
|||
img_align(img, params);
|
||||
img_calculate_bo_size(img, params);
|
||||
|
||||
img->scanout = (params->templ->bind & PIPE_BIND_SCANOUT);
|
||||
img->scanout = params->info->bind_scanout;
|
||||
|
||||
switch (img->aux.type) {
|
||||
case ILO_IMAGE_AUX_HIZ:
|
||||
|
|
@ -1330,6 +1326,8 @@ img_init(struct ilo_image *img,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1339,29 +1337,29 @@ img_init(struct ilo_image *img,
|
|||
static void
|
||||
img_init_for_transfer(struct ilo_image *img,
|
||||
const struct ilo_dev *dev,
|
||||
const struct pipe_resource *templ)
|
||||
const struct ilo_image_info *info)
|
||||
{
|
||||
const unsigned num_layers = (templ->target == PIPE_TEXTURE_3D) ?
|
||||
templ->depth0 : templ->array_size;
|
||||
const unsigned num_layers = (info->target == PIPE_TEXTURE_3D) ?
|
||||
info->depth : info->array_size;
|
||||
unsigned layer_width, layer_height;
|
||||
|
||||
assert(templ->last_level == 0);
|
||||
assert(templ->nr_samples <= 1);
|
||||
assert(info->level_count == 1);
|
||||
assert(info->sample_count == 1);
|
||||
|
||||
img->aux.type = ILO_IMAGE_AUX_NONE;
|
||||
|
||||
img->target = templ->target;
|
||||
img->width0 = templ->width0;
|
||||
img->height0 = templ->height0;
|
||||
img->depth0 = templ->depth0;
|
||||
img->array_size = templ->array_size;
|
||||
img->target = info->target;
|
||||
img->width0 = info->width;
|
||||
img->height0 = info->height;
|
||||
img->depth0 = info->depth;
|
||||
img->array_size = info->array_size;
|
||||
img->level_count = 1;
|
||||
img->sample_count = 1;
|
||||
|
||||
img->format = templ->format;
|
||||
img->block_width = util_format_get_blockwidth(templ->format);
|
||||
img->block_height = util_format_get_blockheight(templ->format);
|
||||
img->block_size = util_format_get_blocksize(templ->format);
|
||||
img->format = info->format;
|
||||
img->block_width = util_format_get_blockwidth(info->format);
|
||||
img->block_height = util_format_get_blockheight(info->format);
|
||||
img->block_size = util_format_get_blocksize(info->format);
|
||||
|
||||
img->walk = ILO_IMAGE_WALK_LOD;
|
||||
|
||||
|
|
@ -1374,8 +1372,8 @@ img_init_for_transfer(struct ilo_image *img,
|
|||
util_is_power_of_two(img->block_height));
|
||||
|
||||
/* use packed layout */
|
||||
layer_width = align(templ->width0, img->align_i);
|
||||
layer_height = align(templ->height0, img->align_j);
|
||||
layer_width = align(info->width, img->align_i);
|
||||
layer_height = align(info->height, img->align_j);
|
||||
|
||||
img->lods[0].slice_width = layer_width;
|
||||
img->lods[0].slice_height = layer_height;
|
||||
|
|
@ -1386,66 +1384,57 @@ img_init_for_transfer(struct ilo_image *img,
|
|||
img->bo_height = (layer_height / img->block_height) * num_layers;
|
||||
}
|
||||
|
||||
static bool
|
||||
img_is_bind_gpu(const struct ilo_image_info *info)
|
||||
{
|
||||
return (info->bind_surface_sampler ||
|
||||
info->bind_surface_dp_render ||
|
||||
info->bind_surface_dp_typed ||
|
||||
info->bind_zs ||
|
||||
info->bind_scanout ||
|
||||
info->bind_cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the image. Callers should zero-initialize \p img first.
|
||||
*/
|
||||
void ilo_image_init(struct ilo_image *img,
|
||||
const struct ilo_dev *dev,
|
||||
const struct pipe_resource *templ)
|
||||
bool
|
||||
ilo_image_init(struct ilo_image *img,
|
||||
const struct ilo_dev *dev,
|
||||
const struct ilo_image_info *info)
|
||||
{
|
||||
struct ilo_image_params params;
|
||||
bool transfer_only;
|
||||
|
||||
assert(ilo_is_zeroed(img, sizeof(*img)));
|
||||
|
||||
/* use transfer layout when the texture is never bound to GPU */
|
||||
transfer_only = !(templ->bind & ~(PIPE_BIND_TRANSFER_WRITE |
|
||||
PIPE_BIND_TRANSFER_READ));
|
||||
if (transfer_only && templ->last_level == 0 && templ->nr_samples <= 1) {
|
||||
img_init_for_transfer(img, dev, templ);
|
||||
return;
|
||||
if (!img_is_bind_gpu(info) &&
|
||||
info->level_count == 1 &&
|
||||
info->sample_count == 1) {
|
||||
img_init_for_transfer(img, dev, info);
|
||||
return true;
|
||||
}
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.dev = dev;
|
||||
params.templ = templ;
|
||||
params.valid_tilings = IMAGE_TILING_ALL;
|
||||
params.info = info;
|
||||
params.valid_tilings = (info->valid_tilings) ?
|
||||
info->valid_tilings : IMAGE_TILING_ALL;
|
||||
|
||||
img_init(img, ¶ms);
|
||||
}
|
||||
|
||||
bool
|
||||
ilo_image_init_for_imported(struct ilo_image *img,
|
||||
const struct ilo_dev *dev,
|
||||
const struct pipe_resource *templ,
|
||||
enum gen_surface_tiling tiling,
|
||||
unsigned bo_stride)
|
||||
{
|
||||
struct ilo_image_params params;
|
||||
|
||||
assert(ilo_is_zeroed(img, sizeof(*img)));
|
||||
|
||||
if ((tiling == GEN6_TILING_X && bo_stride % 512) ||
|
||||
(tiling == GEN6_TILING_Y && bo_stride % 128) ||
|
||||
(tiling == GEN8_TILING_W && bo_stride % 64))
|
||||
if (!img_init(img, ¶ms))
|
||||
return false;
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.dev = dev;
|
||||
params.templ = templ;
|
||||
params.valid_tilings = 1 << tiling;
|
||||
if (info->force_bo_stride) {
|
||||
if ((img->tiling == GEN6_TILING_X && info->force_bo_stride % 512) ||
|
||||
(img->tiling == GEN6_TILING_Y && info->force_bo_stride % 128) ||
|
||||
(img->tiling == GEN8_TILING_W && info->force_bo_stride % 64))
|
||||
return false;
|
||||
|
||||
img_init(img, ¶ms);
|
||||
if (img->bo_stride > info->force_bo_stride)
|
||||
return false;
|
||||
|
||||
assert(img->tiling == tiling);
|
||||
if (img->bo_stride > bo_stride)
|
||||
return false;
|
||||
|
||||
img->bo_stride = bo_stride;
|
||||
|
||||
/* assume imported RTs are also scanouts */
|
||||
if (!img->scanout)
|
||||
img->scanout = (templ->bind & PIPE_BIND_RENDER_TARGET);
|
||||
img->bo_stride = info->force_bo_stride;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,36 @@ enum ilo_image_walk_type {
|
|||
ILO_IMAGE_WALK_3D,
|
||||
};
|
||||
|
||||
struct ilo_image_info {
|
||||
enum pipe_texture_target target;
|
||||
|
||||
enum pipe_format format;
|
||||
|
||||
/* image size */
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint16_t depth;
|
||||
uint16_t array_size;
|
||||
uint8_t level_count;
|
||||
uint8_t sample_count;
|
||||
|
||||
/* disable optional aux */
|
||||
bool aux_disable;
|
||||
|
||||
/* tilings to consider, if any bit is set */
|
||||
uint8_t valid_tilings;
|
||||
|
||||
/* force a stride */
|
||||
uint32_t force_bo_stride;
|
||||
|
||||
bool bind_surface_sampler;
|
||||
bool bind_surface_dp_render;
|
||||
bool bind_surface_dp_typed;
|
||||
bool bind_zs;
|
||||
bool bind_scanout;
|
||||
bool bind_cursor;
|
||||
};
|
||||
|
||||
/*
|
||||
* When the walk type is ILO_IMAGE_WALK_LAYER, there is only a slice in each
|
||||
* LOD and this is used to describe LODs in the first array layer. Otherwise,
|
||||
|
|
@ -143,19 +173,10 @@ struct ilo_image {
|
|||
} aux;
|
||||
};
|
||||
|
||||
struct pipe_resource;
|
||||
|
||||
void
|
||||
bool
|
||||
ilo_image_init(struct ilo_image *img,
|
||||
const struct ilo_dev *dev,
|
||||
const struct pipe_resource *templ);
|
||||
|
||||
bool
|
||||
ilo_image_init_for_imported(struct ilo_image *img,
|
||||
const struct ilo_dev *dev,
|
||||
const struct pipe_resource *templ,
|
||||
enum gen_surface_tiling tiling,
|
||||
unsigned bo_stride);
|
||||
const struct ilo_image_info *info);
|
||||
|
||||
static inline bool
|
||||
ilo_image_can_enable_aux(const struct ilo_image *img, unsigned level)
|
||||
|
|
|
|||
|
|
@ -87,6 +87,38 @@ resource_get_cpu_init(const struct pipe_resource *templ)
|
|||
PIPE_BIND_STREAM_OUTPUT)) ? false : true;
|
||||
}
|
||||
|
||||
static void
|
||||
resource_get_image_info(const struct pipe_resource *templ,
|
||||
const struct ilo_dev *dev,
|
||||
enum pipe_format image_format,
|
||||
struct ilo_image_info *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
info->target = templ->target;
|
||||
info->format = image_format;
|
||||
|
||||
info->width = templ->width0;
|
||||
info->height = templ->height0;
|
||||
info->depth = templ->depth0;
|
||||
info->array_size = templ->array_size;
|
||||
info->level_count = templ->last_level + 1;
|
||||
info->sample_count = (templ->nr_samples) ? templ->nr_samples : 1;
|
||||
|
||||
info->aux_disable = (templ->usage == PIPE_USAGE_STAGING);
|
||||
|
||||
if (templ->bind & PIPE_BIND_LINEAR)
|
||||
info->valid_tilings = 1 << GEN6_TILING_NONE;
|
||||
|
||||
info->bind_surface_sampler = (templ->bind & PIPE_BIND_SAMPLER_VIEW);
|
||||
info->bind_surface_dp_render = (templ->bind & PIPE_BIND_RENDER_TARGET);
|
||||
info->bind_surface_dp_typed = (templ->bind &
|
||||
(PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE));
|
||||
info->bind_zs = (templ->bind & PIPE_BIND_DEPTH_STENCIL);
|
||||
info->bind_scanout = (templ->bind & PIPE_BIND_SCANOUT);
|
||||
info->bind_cursor = (templ->bind & PIPE_BIND_CURSOR);
|
||||
}
|
||||
|
||||
static enum gen_surface_tiling
|
||||
winsys_to_surface_tiling(enum intel_tiling_mode tiling)
|
||||
{
|
||||
|
|
@ -306,9 +338,10 @@ tex_alloc_bos(struct ilo_texture *tex)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
static struct intel_bo *
|
||||
tex_import_handle(struct ilo_texture *tex,
|
||||
const struct winsys_handle *handle)
|
||||
const struct winsys_handle *handle,
|
||||
struct ilo_image_info *info)
|
||||
{
|
||||
struct ilo_screen *is = ilo_screen(tex->base.screen);
|
||||
const struct pipe_resource *templ = &tex->base;
|
||||
|
|
@ -319,23 +352,24 @@ tex_import_handle(struct ilo_texture *tex,
|
|||
|
||||
bo = intel_winsys_import_handle(is->dev.winsys, name, handle,
|
||||
tex->image.bo_height, &tiling, &pitch);
|
||||
if (!bo)
|
||||
return false;
|
||||
/* modify image info */
|
||||
if (bo) {
|
||||
const uint8_t valid_tilings = 1 << winsys_to_surface_tiling(tiling);
|
||||
|
||||
if (!ilo_image_init_for_imported(&tex->image, &is->dev, templ,
|
||||
winsys_to_surface_tiling(tiling), pitch)) {
|
||||
ilo_err("failed to import handle for texture\n");
|
||||
intel_bo_unref(bo);
|
||||
return false;
|
||||
if (info->valid_tilings && !(info->valid_tilings & valid_tilings)) {
|
||||
intel_bo_unref(bo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->valid_tilings = valid_tilings;
|
||||
info->force_bo_stride = pitch;
|
||||
|
||||
/* assume imported RTs are also scanouts */
|
||||
if (!info->bind_scanout)
|
||||
info->bind_scanout = (templ->usage & PIPE_BIND_RENDER_TARGET);
|
||||
}
|
||||
|
||||
ilo_vma_init(&tex->vma, &is->dev,
|
||||
tex->image.bo_stride * tex->image.bo_height, 4096);
|
||||
ilo_vma_set_bo(&tex->vma, &is->dev, bo, 0);
|
||||
|
||||
tex->imported = true;
|
||||
|
||||
return true;
|
||||
return bo;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -345,18 +379,33 @@ tex_init_image(struct ilo_texture *tex,
|
|||
struct ilo_screen *is = ilo_screen(tex->base.screen);
|
||||
const struct pipe_resource *templ = &tex->base;
|
||||
struct ilo_image *img = &tex->image;
|
||||
struct intel_bo *imported_bo = NULL;;
|
||||
struct ilo_image_info info;
|
||||
|
||||
resource_get_image_info(templ, &is->dev, templ->format, &info);
|
||||
|
||||
if (handle) {
|
||||
if (!tex_import_handle(tex, handle))
|
||||
imported_bo = tex_import_handle(tex, handle, &info);
|
||||
if (!imported_bo)
|
||||
return false;
|
||||
} else {
|
||||
ilo_image_init(img, &is->dev, templ);
|
||||
ilo_vma_init(&tex->vma, &is->dev,
|
||||
img->bo_stride * img->bo_height, 4096);
|
||||
}
|
||||
|
||||
if (img->bo_height > ilo_max_resource_size / img->bo_stride)
|
||||
if (!ilo_image_init(img, &is->dev, &info)) {
|
||||
intel_bo_unref(imported_bo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (img->bo_height > ilo_max_resource_size / img->bo_stride ||
|
||||
!ilo_vma_init(&tex->vma, &is->dev, img->bo_stride * img->bo_height,
|
||||
4096)) {
|
||||
intel_bo_unref(imported_bo);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (imported_bo) {
|
||||
ilo_vma_set_bo(&tex->vma, &is->dev, imported_bo, 0);
|
||||
tex->imported = true;
|
||||
}
|
||||
|
||||
if (templ->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) {
|
||||
/* require on-the-fly tiling/untiling or format conversion */
|
||||
|
|
@ -500,13 +549,17 @@ static boolean
|
|||
ilo_can_create_resource(struct pipe_screen *screen,
|
||||
const struct pipe_resource *templ)
|
||||
{
|
||||
struct ilo_screen *is = ilo_screen(screen);
|
||||
struct ilo_image_info info;
|
||||
struct ilo_image img;
|
||||
|
||||
if (templ->target == PIPE_BUFFER)
|
||||
return (templ->width0 <= ilo_max_resource_size);
|
||||
|
||||
resource_get_image_info(templ, &is->dev, templ->format, &info);
|
||||
|
||||
memset(&img, 0, sizeof(img));
|
||||
ilo_image_init(&img, &ilo_screen(screen)->dev, templ);
|
||||
ilo_image_init(&img, &ilo_screen(screen)->dev, &info);
|
||||
|
||||
return (img.bo_height <= ilo_max_resource_size / img.bo_stride);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue