freedreno/layout: layout simplifications and pitch from level 0 pitch

This updates a3xx/a4xx/a5xx to fix the fetchsize to "PITCHALIGN" (called
"MINLINEOFFSET" by the a3xx docs), and some simplifications to make things
more like a6xx. Also similar simplifications for a2xx layout code.

The pitch can always be determined using a simple calculation from the base
level pitch, so don't pre-calculate a pitch for each mipmap level.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5796>
This commit is contained in:
Jonathan Marek 2020-07-07 18:27:32 -04:00 committed by Marge Bot
parent 4b290b759a
commit 979e7e3680
33 changed files with 177 additions and 320 deletions

View file

@ -29,29 +29,12 @@
#include "freedreno_layout.h" #include "freedreno_layout.h"
/* indexed by cpp: */
static const struct {
unsigned pitchalign;
unsigned heightalign;
} tile_alignment[] = {
[1] = { 128, 32 },
[2] = { 128, 16 },
[3] = { 128, 16 },
[4] = { 64, 16 },
[8] = { 64, 16 },
[12] = { 64, 16 },
[16] = { 64, 16 },
};
void void
fdl5_layout(struct fdl_layout *layout, fdl5_layout(struct fdl_layout *layout,
enum pipe_format format, uint32_t nr_samples, enum pipe_format format, uint32_t nr_samples,
uint32_t width0, uint32_t height0, uint32_t depth0, uint32_t width0, uint32_t height0, uint32_t depth0,
uint32_t mip_levels, uint32_t array_size, bool is_3d) uint32_t mip_levels, uint32_t array_size, bool is_3d)
{ {
const struct util_format_description *format_desc =
util_format_description(format);
assert(nr_samples > 0); assert(nr_samples > 0);
layout->width0 = width0; layout->width0 = width0;
layout->height0 = height0; layout->height0 = height0;
@ -65,30 +48,27 @@ fdl5_layout(struct fdl_layout *layout,
layout->nr_samples = nr_samples; layout->nr_samples = nr_samples;
layout->layer_first = !is_3d; layout->layer_first = !is_3d;
uint32_t pitchalign; uint32_t heightalign = layout->cpp == 1 ? 32 : 16;
uint32_t heightalign;
uint32_t width = width0;
uint32_t height = height0;
uint32_t depth = depth0;
/* in layer_first layout, the level (slice) contains just one /* in layer_first layout, the level (slice) contains just one
* layer (since in fact the layer contains the slices) * layer (since in fact the layer contains the slices)
*/ */
uint32_t layers_in_level = layout->layer_first ? 1 : array_size; uint32_t layers_in_level = layout->layer_first ? 1 : array_size;
heightalign = tile_alignment[layout->cpp].heightalign; /* use 128 pixel alignment for cpp=1 and cpp=2 */
if (layout->cpp < 4 && layout->tile_mode)
fdl_set_pitchalign(layout, fdl_cpp_shift(layout) + 7);
else
fdl_set_pitchalign(layout, fdl_cpp_shift(layout) + 6);
for (uint32_t level = 0; level < mip_levels; level++) { for (uint32_t level = 0; level < mip_levels; level++) {
struct fdl_slice *slice = &layout->slices[level]; struct fdl_slice *slice = &layout->slices[level];
uint32_t tile_mode = fdl_tile_mode(layout, level); uint32_t tile_mode = fdl_tile_mode(layout, level);
uint32_t aligned_height = height; uint32_t pitch = fdl_pitch(layout, level);
uint32_t blocks; uint32_t nblocksy = util_format_get_nblocksy(format, u_minify(height0, level));
if (tile_mode) { if (tile_mode) {
pitchalign = tile_alignment[layout->cpp].pitchalign; nblocksy = align(nblocksy, heightalign);
aligned_height = align(aligned_height, heightalign);
} else { } else {
pitchalign = 64;
/* The blits used for mem<->gmem work at a granularity of /* The blits used for mem<->gmem work at a granularity of
* 32x32, which can cause faults due to over-fetch on the * 32x32, which can cause faults due to over-fetch on the
* last level. The simple solution is to over-allocate a * last level. The simple solution is to over-allocate a
@ -97,20 +77,10 @@ fdl5_layout(struct fdl_layout *layout,
* may not be: * may not be:
*/ */
if (level == mip_levels - 1) if (level == mip_levels - 1)
aligned_height = align(aligned_height, 32); nblocksy = align(nblocksy, 32);
} }
unsigned pitch_pixels;
if (format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC)
pitch_pixels =
util_align_npot(width, pitchalign * util_format_get_blockwidth(format));
else
pitch_pixels = align(width, pitchalign);
slice->offset = layout->size; slice->offset = layout->size;
blocks = util_format_get_nblocks(format, pitch_pixels, aligned_height);
slice->pitch = util_format_get_nblocksx(format, pitch_pixels) *
layout->cpp;
const int alignment = is_3d ? 4096 : 1; const int alignment = is_3d ? 4096 : 1;
@ -123,17 +93,13 @@ fdl5_layout(struct fdl_layout *layout,
if (is_3d && ( if (is_3d && (
level == 1 || level == 1 ||
(level > 1 && layout->slices[level - 1].size0 > 0xf000))) (level > 1 && layout->slices[level - 1].size0 > 0xf000)))
slice->size0 = align(blocks * layout->cpp, alignment); slice->size0 = align(nblocksy * pitch, alignment);
else if (level == 0 || layout->layer_first || alignment == 1) else if (level == 0 || layout->layer_first || alignment == 1)
slice->size0 = align(blocks * layout->cpp, alignment); slice->size0 = align(nblocksy * pitch, alignment);
else else
slice->size0 = layout->slices[level - 1].size0; slice->size0 = layout->slices[level - 1].size0;
layout->size += slice->size0 * depth * layers_in_level; layout->size += slice->size0 * u_minify(depth0, level) * layers_in_level;
width = u_minify(width, 1);
height = u_minify(height, 1);
depth = u_minify(depth, 1);
} }
} }

View file

@ -29,10 +29,6 @@
#include "freedreno_layout.h" #include "freedreno_layout.h"
#define RGB_TILE_WIDTH_ALIGNMENT 64
#define RGB_TILE_HEIGHT_ALIGNMENT 16
#define UBWC_PLANE_SIZE_ALIGNMENT 4096
static bool static bool
is_r8g8(struct fdl_layout *layout) is_r8g8(struct fdl_layout *layout)
{ {
@ -103,10 +99,9 @@ fdl6_layout(struct fdl_layout *layout,
enum pipe_format format, uint32_t nr_samples, enum pipe_format format, uint32_t nr_samples,
uint32_t width0, uint32_t height0, uint32_t depth0, uint32_t width0, uint32_t height0, uint32_t depth0,
uint32_t mip_levels, uint32_t array_size, bool is_3d, uint32_t mip_levels, uint32_t array_size, bool is_3d,
struct fdl_slice *plane_layout) struct fdl_explicit_layout *explicit_layout)
{ {
uint32_t offset, pitch0; uint32_t offset = 0, heightalign;
uint32_t pitchalign, heightalign;
uint32_t ubwc_blockwidth, ubwc_blockheight; uint32_t ubwc_blockwidth, ubwc_blockheight;
assert(nr_samples > 0); assert(nr_samples > 0);
@ -152,24 +147,20 @@ fdl6_layout(struct fdl_layout *layout,
/* when possible, use a bit more alignment than necessary /* when possible, use a bit more alignment than necessary
* presumably this is better for performance? * presumably this is better for performance?
*/ */
if (!plane_layout) if (!explicit_layout)
layout->pitchalign = fdl_cpp_shift(layout); layout->pitchalign = fdl_cpp_shift(layout);
/* not used, avoid "may be used uninitialized" warning */ /* not used, avoid "may be used uninitialized" warning */
heightalign = 1; heightalign = 1;
} }
pitchalign = 64 << layout->pitchalign; fdl_set_pitchalign(layout, layout->pitchalign + 6);
if (plane_layout) { if (explicit_layout) {
offset = plane_layout->offset; offset = explicit_layout->offset;
pitch0 = plane_layout->pitch; layout->pitch0 = explicit_layout->pitch;
if (align(pitch0, pitchalign) != pitch0) if (align(layout->pitch0, 1 << layout->pitchalign) != layout->pitch0)
return false; return false;
} else {
uint32_t nblocksx = util_format_get_nblocksx(format, width0);
offset = 0;
pitch0 = util_align_npot(nblocksx * layout->cpp, pitchalign);
} }
uint32_t ubwc_width0 = width0; uint32_t ubwc_width0 = width0;
@ -185,8 +176,8 @@ fdl6_layout(struct fdl_layout *layout,
ubwc_height0 = util_next_power_of_two(height0); ubwc_height0 = util_next_power_of_two(height0);
ubwc_tile_height_alignment = 64; ubwc_tile_height_alignment = 64;
} }
ubwc_width0 = align(DIV_ROUND_UP(ubwc_width0, ubwc_blockwidth), layout->ubwc_width0 = align(DIV_ROUND_UP(ubwc_width0, ubwc_blockwidth),
RGB_TILE_WIDTH_ALIGNMENT); RGB_TILE_WIDTH_ALIGNMENT);
ubwc_height0 = align(DIV_ROUND_UP(ubwc_height0, ubwc_blockheight), ubwc_height0 = align(DIV_ROUND_UP(ubwc_height0, ubwc_blockheight),
ubwc_tile_height_alignment); ubwc_tile_height_alignment);
@ -195,6 +186,7 @@ fdl6_layout(struct fdl_layout *layout,
struct fdl_slice *slice = &layout->slices[level]; struct fdl_slice *slice = &layout->slices[level];
struct fdl_slice *ubwc_slice = &layout->ubwc_slices[level]; struct fdl_slice *ubwc_slice = &layout->ubwc_slices[level];
uint32_t tile_mode = fdl_tile_mode(layout, level); uint32_t tile_mode = fdl_tile_mode(layout, level);
uint32_t pitch = fdl_pitch(layout, level);
uint32_t height; uint32_t height;
/* tiled levels of 3D textures are rounded up to PoT dimensions: */ /* tiled levels of 3D textures are rounded up to PoT dimensions: */
@ -219,7 +211,6 @@ fdl6_layout(struct fdl_layout *layout,
height = align(nblocksy, 4); height = align(nblocksy, 4);
slice->offset = offset + layout->size; slice->offset = offset + layout->size;
slice->pitch = align(u_minify(pitch0, level), pitchalign);
/* 1d array and 2d array textures must all have the same layer size /* 1d array and 2d array textures must all have the same layer size
* for each miplevel on a6xx. 3d textures can have different layer * for each miplevel on a6xx. 3d textures can have different layer
@ -229,12 +220,12 @@ fdl6_layout(struct fdl_layout *layout,
*/ */
if (is_3d) { if (is_3d) {
if (level < 1 || layout->slices[level - 1].size0 > 0xf000) { if (level < 1 || layout->slices[level - 1].size0 > 0xf000) {
slice->size0 = align(nblocksy * slice->pitch, 4096); slice->size0 = align(nblocksy * pitch, 4096);
} else { } else {
slice->size0 = layout->slices[level - 1].size0; slice->size0 = layout->slices[level - 1].size0;
} }
} else { } else {
slice->size0 = nblocksy * slice->pitch; slice->size0 = nblocksy * pitch;
} }
layout->size += slice->size0 * depth * layers_in_level; layout->size += slice->size0 * depth * layers_in_level;
@ -243,13 +234,11 @@ fdl6_layout(struct fdl_layout *layout,
/* with UBWC every level is aligned to 4K */ /* with UBWC every level is aligned to 4K */
layout->size = align(layout->size, 4096); layout->size = align(layout->size, 4096);
uint32_t meta_pitch = align(u_minify(ubwc_width0, level), uint32_t meta_pitch = fdl_ubwc_pitch(layout, level);
RGB_TILE_WIDTH_ALIGNMENT);
uint32_t meta_height = align(u_minify(ubwc_height0, level), uint32_t meta_height = align(u_minify(ubwc_height0, level),
ubwc_tile_height_alignment); ubwc_tile_height_alignment);
ubwc_slice->size0 = align(meta_pitch * meta_height, UBWC_PLANE_SIZE_ALIGNMENT); ubwc_slice->size0 = align(meta_pitch * meta_height, UBWC_PLANE_SIZE_ALIGNMENT);
ubwc_slice->pitch = meta_pitch;
ubwc_slice->offset = offset + layout->ubwc_layer_size; ubwc_slice->offset = offset + layout->ubwc_layer_size;
layout->ubwc_layer_size += ubwc_slice->size0; layout->ubwc_layer_size += ubwc_slice->size0;
} }

View file

@ -89,12 +89,12 @@ bool fdl_test_layout(const struct testcase *testcase, int gpu_id)
testcase->layout.slices[l].offset); testcase->layout.slices[l].offset);
ok = false; ok = false;
} }
if (layout.slices[l].pitch != testcase->layout.slices[l].pitch) { if (fdl_pitch(&layout, l) != testcase->layout.slices[l].pitch) {
fprintf(stderr, "%s %dx%dx%d@%dx lvl%d: pitch %d != %d\n", fprintf(stderr, "%s %dx%dx%d@%dx lvl%d: pitch %d != %d\n",
util_format_short_name(testcase->format), util_format_short_name(testcase->format),
layout.width0, layout.height0, layout.depth0, layout.width0, layout.height0, layout.depth0,
layout.nr_samples, l, layout.nr_samples, l,
layout.slices[l].pitch, fdl_pitch(&layout, l),
testcase->layout.slices[l].pitch); testcase->layout.slices[l].pitch);
ok = false; ok = false;
} }
@ -108,12 +108,12 @@ bool fdl_test_layout(const struct testcase *testcase, int gpu_id)
testcase->layout.ubwc_slices[l].offset); testcase->layout.ubwc_slices[l].offset);
ok = false; ok = false;
} }
if (layout.ubwc_slices[l].pitch != testcase->layout.ubwc_slices[l].pitch) { if (fdl_ubwc_pitch(&layout, l) != testcase->layout.ubwc_slices[l].pitch) {
fprintf(stderr, "%s %dx%dx%d@%dx lvl%d: UBWC pitch %d != %d\n", fprintf(stderr, "%s %dx%dx%d@%dx lvl%d: UBWC pitch %d != %d\n",
util_format_short_name(testcase->format), util_format_short_name(testcase->format),
layout.width0, layout.height0, layout.depth0, layout.width0, layout.height0, layout.depth0,
layout.nr_samples, l, layout.nr_samples, l,
layout.ubwc_slices[l].pitch, fdl_ubwc_pitch(&layout, l),
testcase->layout.ubwc_slices[l].pitch); testcase->layout.ubwc_slices[l].pitch);
ok = false; ok = false;
} }

View file

@ -28,7 +28,20 @@ struct testcase {
bool is_3d; bool is_3d;
/* Partially filled layout of input parameters and expected results. */ /* Partially filled layout of input parameters and expected results. */
struct fdl_layout layout; struct {
uint32_t tile_mode : 2;
bool ubwc : 1;
uint32_t width0, height0, depth0;
uint32_t nr_samples;
struct {
uint32_t offset;
uint32_t pitch;
} slices[FDL_MAX_MIP_LEVELS];
struct {
uint32_t offset;
uint32_t pitch;
} ubwc_slices[FDL_MAX_MIP_LEVELS];
} layout;
}; };
bool fdl_test_layout(const struct testcase *testcase, int gpu_id); bool fdl_test_layout(const struct testcase *testcase, int gpu_id);

View file

@ -56,9 +56,9 @@ fdl_dump_layout(struct fdl_layout *layout)
u_minify(layout->depth0, level), u_minify(layout->depth0, level),
layout->cpp, layout->nr_samples, layout->cpp, layout->nr_samples,
level, level,
slice->pitch, fdl_pitch(layout, level),
slice->size0, ubwc_slice->size0, slice->size0, ubwc_slice->size0,
slice->size0 / slice->pitch, slice->size0 / fdl_pitch(layout, level),
slice->offset, ubwc_slice->offset, slice->offset, ubwc_slice->offset,
layout->layer_size, layout->ubwc_layer_size, layout->layer_size, layout->ubwc_layer_size,
fdl_tile_mode(layout, level)); fdl_tile_mode(layout, level));

View file

@ -79,10 +79,15 @@
struct fdl_slice { struct fdl_slice {
uint32_t offset; /* offset of first layer in slice */ uint32_t offset; /* offset of first layer in slice */
uint32_t pitch; /* pitch in bytes between rows. */
uint32_t size0; /* size of first layer in slice */ uint32_t size0; /* size of first layer in slice */
}; };
/* parameters for explicit (imported) layout */
struct fdl_explicit_layout {
uint32_t offset;
uint32_t pitch;
};
/** /**
* Encapsulates the layout of a resource, including position of given 2d * Encapsulates the layout of a resource, including position of given 2d
* surface (layer, level) within. Or rather all the information needed * surface (layer, level) within. Or rather all the information needed
@ -91,6 +96,8 @@ struct fdl_slice {
struct fdl_layout { struct fdl_layout {
struct fdl_slice slices[FDL_MAX_MIP_LEVELS]; struct fdl_slice slices[FDL_MAX_MIP_LEVELS];
struct fdl_slice ubwc_slices[FDL_MAX_MIP_LEVELS]; struct fdl_slice ubwc_slices[FDL_MAX_MIP_LEVELS];
uint32_t pitch0;
uint32_t ubwc_width0;
uint32_t layer_size; uint32_t layer_size;
uint32_t ubwc_layer_size; /* in bytes */ uint32_t ubwc_layer_size; /* in bytes */
bool ubwc : 1; bool ubwc : 1;
@ -121,7 +128,7 @@ struct fdl_layout {
uint32_t size; /* Size of the whole image, in bytes. */ uint32_t size; /* Size of the whole image, in bytes. */
uint32_t base_align; /* Alignment of the base address, in bytes. */ uint32_t base_align; /* Alignment of the base address, in bytes. */
uint8_t pitchalign; /* log2(pitchalign / 64) */ uint8_t pitchalign; /* log2(pitchalign) */
}; };
static inline uint32_t static inline uint32_t
@ -131,6 +138,24 @@ fdl_cpp_shift(const struct fdl_layout *layout)
return layout->cpp_shift; return layout->cpp_shift;
} }
static inline uint32_t
fdl_pitch(const struct fdl_layout *layout, unsigned level)
{
return align(u_minify(layout->pitch0, level), 1 << layout->pitchalign);
}
#define RGB_TILE_WIDTH_ALIGNMENT 64
#define RGB_TILE_HEIGHT_ALIGNMENT 16
#define UBWC_PLANE_SIZE_ALIGNMENT 4096
static inline uint32_t
fdl_ubwc_pitch(const struct fdl_layout *layout, unsigned level)
{
if (!layout->ubwc)
return 0;
return align(u_minify(layout->ubwc_width0, level), RGB_TILE_WIDTH_ALIGNMENT);
}
static inline uint32_t static inline uint32_t
fdl_layer_stride(const struct fdl_layout *layout, unsigned level) fdl_layer_stride(const struct fdl_layout *layout, unsigned level)
{ {
@ -140,6 +165,22 @@ fdl_layer_stride(const struct fdl_layout *layout, unsigned level)
return layout->slices[level].size0; return layout->slices[level].size0;
} }
/* a2xx is special and needs PoT alignment for mipmaps: */
static inline uint32_t
fdl2_pitch(const struct fdl_layout *layout, unsigned level)
{
uint32_t pitch = fdl_pitch(layout, level);
if (level)
pitch = util_next_power_of_two(pitch);
return pitch;
}
static inline uint32_t
fdl2_pitch_pixels(const struct fdl_layout *layout, unsigned level)
{
return fdl2_pitch(layout, level) >> fdl_cpp_shift(layout);
}
static inline uint32_t static inline uint32_t
fdl_surface_offset(const struct fdl_layout *layout, unsigned level, unsigned layer) fdl_surface_offset(const struct fdl_layout *layout, unsigned level, unsigned layer)
{ {
@ -196,7 +237,15 @@ fdl6_layout(struct fdl_layout *layout,
enum pipe_format format, uint32_t nr_samples, enum pipe_format format, uint32_t nr_samples,
uint32_t width0, uint32_t height0, uint32_t depth0, uint32_t width0, uint32_t height0, uint32_t depth0,
uint32_t mip_levels, uint32_t array_size, bool is_3d, uint32_t mip_levels, uint32_t array_size, bool is_3d,
struct fdl_slice *plane_layout); struct fdl_explicit_layout *plane_layout);
static inline void
fdl_set_pitchalign(struct fdl_layout *layout, unsigned pitchalign)
{
uint32_t nblocksx = util_format_get_nblocksx(layout->format, layout->width0);
layout->pitchalign = pitchalign;
layout->pitch0 = align(nblocksx * layout->cpp, 1 << pitchalign);
}
void void
fdl_dump_layout(struct fdl_layout *layout); fdl_dump_layout(struct fdl_layout *layout);

View file

@ -216,19 +216,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
<value name="TFMT_NONE" value="0xff"/> <value name="TFMT_NONE" value="0xff"/>
</enum> </enum>
<enum name="a3xx_tex_fetchsize">
<doc>
Size pixel to fetch, in bytes. Doesn't seem to be required, setting
it to 0x0 seems to work ok, but may be less optimal.
</doc>
<value name="TFETCH_DISABLE" value="0"/>
<value name="TFETCH_1_BYTE" value="1"/>
<value name="TFETCH_2_BYTE" value="2"/>
<value name="TFETCH_4_BYTE" value="3"/>
<value name="TFETCH_8_BYTE" value="4"/>
<value name="TFETCH_16_BYTE" value="5"/>
</enum>
<enum name="a3xx_color_fmt"> <enum name="a3xx_color_fmt">
<value name="RB_R5G6B5_UNORM" value="0x00"/> <value name="RB_R5G6B5_UNORM" value="0x00"/>
<value name="RB_R5G5B5A1_UNORM" value="0x01"/> <value name="RB_R5G5B5A1_UNORM" value="0x01"/>
@ -1736,7 +1723,8 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
<reg32 offset="1" name="1"> <reg32 offset="1" name="1">
<bitfield name="HEIGHT" low="0" high="13" type="uint"/> <bitfield name="HEIGHT" low="0" high="13" type="uint"/>
<bitfield name="WIDTH" low="14" high="27" type="uint"/> <bitfield name="WIDTH" low="14" high="27" type="uint"/>
<bitfield name="FETCHSIZE" low="28" high="31" type="a3xx_tex_fetchsize"/> <!-- minimum pitch (for mipmap levels): log2(pitchalign / 16) -->
<bitfield name="PITCHALIGN" low="28" high="31" type="uint"/>
</reg32> </reg32>
<reg32 offset="2" name="2"> <reg32 offset="2" name="2">
<doc>INDX is index of texture address(es) in MIPMAP state block</doc> <doc>INDX is index of texture address(es) in MIPMAP state block</doc>

View file

@ -268,18 +268,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
<value name="TFMT4_NONE" value="0xff"/> <value name="TFMT4_NONE" value="0xff"/>
</enum> </enum>
<enum name="a4xx_tex_fetchsize">
<doc>
Size pixel to fetch, in bytes. Doesn't seem to be required, setting
it to 0x0 seems to work ok, but may be less optimal.
</doc>
<value name="TFETCH4_1_BYTE" value="0"/>
<value name="TFETCH4_2_BYTE" value="1"/>
<value name="TFETCH4_4_BYTE" value="2"/>
<value name="TFETCH4_8_BYTE" value="3"/>
<value name="TFETCH4_16_BYTE" value="4"/>
</enum>
<enum name="a4xx_depth_format"> <enum name="a4xx_depth_format">
<value name="DEPTH4_NONE" value="0"/> <value name="DEPTH4_NONE" value="0"/>
<value name="DEPTH4_16" value="1"/> <value name="DEPTH4_16" value="1"/>
@ -2346,7 +2334,8 @@ perhaps they should be taken with a grain of salt
<bitfield name="WIDTH" low="15" high="29" type="uint"/> <bitfield name="WIDTH" low="15" high="29" type="uint"/>
</reg32> </reg32>
<reg32 offset="2" name="2"> <reg32 offset="2" name="2">
<bitfield name="FETCHSIZE" low="0" high="3" type="a4xx_tex_fetchsize"/> <!-- minimum pitch (for mipmap levels): log2(pitchalign / 32) -->
<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
<doc>Pitch in bytes (so actually stride)</doc> <doc>Pitch in bytes (so actually stride)</doc>
<bitfield name="PITCH" low="9" high="29" type="uint"/> <bitfield name="PITCH" low="9" high="29" type="uint"/>
<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/> <bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>

View file

@ -232,18 +232,6 @@ xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
<value value="0xff" name="TFMT5_NONE"/> <value value="0xff" name="TFMT5_NONE"/>
</enum> </enum>
<enum name="a5xx_tex_fetchsize">
<doc>
Size pixel to fetch, in bytes. Doesn't seem to be required, setting
it to 0x0 seems to work ok, but may be less optimal.
</doc>
<value name="TFETCH5_1_BYTE" value="0"/>
<value name="TFETCH5_2_BYTE" value="1"/>
<value name="TFETCH5_4_BYTE" value="2"/>
<value name="TFETCH5_8_BYTE" value="3"/>
<value name="TFETCH5_16_BYTE" value="4"/>
</enum>
<enum name="a5xx_depth_format"> <enum name="a5xx_depth_format">
<value name="DEPTH5_NONE" value="0"/> <value name="DEPTH5_NONE" value="0"/>
<value name="DEPTH5_16" value="1"/> <value name="DEPTH5_16" value="1"/>
@ -2914,7 +2902,8 @@ different border-color states per texture.. Looks something like:
<bitfield name="HEIGHT" low="15" high="29" type="uint"/> <bitfield name="HEIGHT" low="15" high="29" type="uint"/>
</reg32> </reg32>
<reg32 offset="2" name="2"> <reg32 offset="2" name="2">
<bitfield name="FETCHSIZE" low="0" high="3" type="a5xx_tex_fetchsize"/> <!-- minimum pitch (for mipmap levels): log2(pitchalign / 64) -->
<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
<doc>Pitch in bytes (so actually stride)</doc> <doc>Pitch in bytes (so actually stride)</doc>
<bitfield name="PITCH" low="7" high="28" type="uint"/> <bitfield name="PITCH" low="7" high="28" type="uint"/>
<bitfield name="TYPE" low="29" high="30" type="a5xx_tex_type"/> <bitfield name="TYPE" low="29" high="30" type="a5xx_tex_type"/>

View file

@ -210,7 +210,7 @@ tu_image_create(VkDevice _device,
} }
} }
struct fdl_slice plane_layout; struct fdl_explicit_layout plane_layout;
if (plane_layouts) { if (plane_layouts) {
/* only expect simple 2D images for now */ /* only expect simple 2D images for now */
@ -412,8 +412,8 @@ tu_image_view_init(struct tu_image_view *iview,
uint64_t ubwc_addr = image->bo->iova + image->bo_offset + uint64_t ubwc_addr = image->bo->iova + image->bo_offset +
fdl_ubwc_offset(layout, range->baseMipLevel, range->baseArrayLayer); fdl_ubwc_offset(layout, range->baseMipLevel, range->baseArrayLayer);
uint32_t pitch = layout->slices[range->baseMipLevel].pitch; uint32_t pitch = fdl_pitch(layout, range->baseMipLevel);
uint32_t ubwc_pitch = layout->ubwc_slices[range->baseMipLevel].pitch; uint32_t ubwc_pitch = fdl_ubwc_pitch(layout, range->baseMipLevel);
uint32_t layer_size = fdl_layer_stride(layout, range->baseMipLevel); uint32_t layer_size = fdl_layer_stride(layout, range->baseMipLevel);
struct tu_native_format fmt = tu6_format_texture(format, layout->tile_mode); struct tu_native_format fmt = tu6_format_texture(format, layout->tile_mode);
@ -443,7 +443,7 @@ tu_image_view_init(struct tu_image_view *iview,
A6XX_TEX_CONST_0_MIPLVLS(tu_get_levelCount(image, range) - 1); A6XX_TEX_CONST_0_MIPLVLS(tu_get_levelCount(image, range) - 1);
iview->descriptor[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height); iview->descriptor[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height);
iview->descriptor[2] = iview->descriptor[2] =
A6XX_TEX_CONST_2_PITCHALIGN(layout->pitchalign) | A6XX_TEX_CONST_2_PITCHALIGN(layout->pitchalign - 6) |
A6XX_TEX_CONST_2_PITCH(pitch) | A6XX_TEX_CONST_2_PITCH(pitch) |
A6XX_TEX_CONST_2_TYPE(tu6_tex_type(pCreateInfo->viewType, false)); A6XX_TEX_CONST_2_TYPE(tu6_tex_type(pCreateInfo->viewType, false));
iview->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(layer_size); iview->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(layer_size);
@ -481,7 +481,7 @@ tu_image_view_init(struct tu_image_view *iview,
iview->descriptor[4] = base_addr[0]; iview->descriptor[4] = base_addr[0];
iview->descriptor[5] |= base_addr[0] >> 32; iview->descriptor[5] |= base_addr[0] >> 32;
iview->descriptor[6] = iview->descriptor[6] =
A6XX_TEX_CONST_6_PLANE_PITCH(image->layout[1].slices[range->baseMipLevel].pitch); A6XX_TEX_CONST_6_PLANE_PITCH(fdl_pitch(&image->layout[1], range->baseMipLevel));
iview->descriptor[7] = base_addr[1]; iview->descriptor[7] = base_addr[1];
iview->descriptor[8] = base_addr[1] >> 32; iview->descriptor[8] = base_addr[1] >> 32;
iview->descriptor[9] = base_addr[2]; iview->descriptor[9] = base_addr[2];
@ -685,7 +685,7 @@ tu_GetImageSubresourceLayout(VkDevice _device,
pLayout->offset = pLayout->offset =
fdl_surface_offset(layout, pSubresource->mipLevel, pSubresource->arrayLayer); fdl_surface_offset(layout, pSubresource->mipLevel, pSubresource->arrayLayer);
pLayout->size = slice->size0; pLayout->size = slice->size0;
pLayout->rowPitch = slice->pitch; pLayout->rowPitch = fdl_pitch(layout, pSubresource->mipLevel);
pLayout->arrayPitch = fdl_layer_stride(layout, pSubresource->mipLevel); pLayout->arrayPitch = fdl_layer_stride(layout, pSubresource->mipLevel);
pLayout->depthPitch = slice->size0; pLayout->depthPitch = slice->size0;

View file

@ -89,11 +89,10 @@ emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base,
{ {
struct fd_ringbuffer *ring = batch->tile_fini; struct fd_ringbuffer *ring = batch->tile_fini;
struct fd_resource *rsc = fd_resource(psurf->texture); struct fd_resource *rsc = fd_resource(psurf->texture);
struct fdl_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level);
uint32_t offset = uint32_t offset =
fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer);
enum pipe_format format = fd_gmem_restore_format(psurf->format); enum pipe_format format = fd_gmem_restore_format(psurf->format);
uint32_t pitch = slice->pitch >> fdl_cpp_shift(&rsc->layout); uint32_t pitch = fdl2_pitch_pixels(&rsc->layout, psurf->u.tex.level);
assert((pitch & 31) == 0); assert((pitch & 31) == 0);
assert((offset & 0xfff) == 0); assert((offset & 0xfff) == 0);
@ -230,11 +229,11 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base,
{ {
struct fd_ringbuffer *ring = batch->gmem; struct fd_ringbuffer *ring = batch->gmem;
struct fd_resource *rsc = fd_resource(psurf->texture); struct fd_resource *rsc = fd_resource(psurf->texture);
struct fdl_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level);
uint32_t offset = uint32_t offset =
fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer);
enum pipe_format format = fd_gmem_restore_format(psurf->format); enum pipe_format format = fd_gmem_restore_format(psurf->format);
OUT_PKT3(ring, CP_SET_CONSTANT, 2); OUT_PKT3(ring, CP_SET_CONSTANT, 2);
OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO)); OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO));
OUT_RING(ring, A2XX_RB_COLOR_INFO_BASE(base) | OUT_RING(ring, A2XX_RB_COLOR_INFO_BASE(base) |
@ -246,7 +245,7 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base,
OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) | OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) |
A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) | A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) |
A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) | A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) |
A2XX_SQ_TEX_0_PITCH(slice->pitch >> fdl_cpp_shift(&rsc->layout))); A2XX_SQ_TEX_0_PITCH(fdl2_pitch_pixels(&rsc->layout, psurf->u.tex.level)));
OUT_RELOC(ring, rsc->bo, offset, OUT_RELOC(ring, rsc->bo, offset,
A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(format).format) | A2XX_SQ_TEX_1_FORMAT(fd2_pipe2surface(format).format) |
A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL), 0); A2XX_SQ_TEX_1_CLAMP_POLICY(SQ_TEX_CLAMP_POLICY_OGL), 0);
@ -436,10 +435,9 @@ fd2_emit_sysmem_prep(struct fd_batch *batch)
return; return;
struct fd_resource *rsc = fd_resource(psurf->texture); struct fd_resource *rsc = fd_resource(psurf->texture);
struct fdl_slice *slice = fd_resource_slice(rsc, psurf->u.tex.level);
uint32_t offset = uint32_t offset =
fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer);
uint32_t pitch = slice->pitch >> fdl_cpp_shift(&rsc->layout); uint32_t pitch = fdl2_pitch_pixels(&rsc->layout, psurf->u.tex.level);
assert((pitch & 31) == 0); assert((pitch & 31) == 0);
assert((offset & 0xfff) == 0); assert((offset & 0xfff) == 0);

View file

@ -31,50 +31,27 @@ fd2_setup_slices(struct fd_resource *rsc)
{ {
struct pipe_resource *prsc = &rsc->base; struct pipe_resource *prsc = &rsc->base;
enum pipe_format format = rsc->base.format; enum pipe_format format = rsc->base.format;
uint32_t height0 = util_format_get_nblocksy(format, prsc->height0);
uint32_t level, size = 0; uint32_t level, size = 0;
uint32_t width = prsc->width0;
uint32_t height = prsc->height0; /* 32 pixel alignment */
uint32_t depth = prsc->depth0; fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5);
for (level = 0; level <= prsc->last_level; level++) { for (level = 0; level <= prsc->last_level; level++) {
struct fdl_slice *slice = fd_resource_slice(rsc, level); struct fdl_slice *slice = fd_resource_slice(rsc, level);
uint32_t blocks; uint32_t pitch = fdl2_pitch(&rsc->layout, level);
uint32_t nblocksy = align(u_minify(height0, level), 32);
/* 32 * 32 block alignment */
switch (prsc->target) {
default: assert(0);
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_2D_ARRAY:
case PIPE_TEXTURE_RECT:
case PIPE_TEXTURE_CUBE:
height = align(height, 32 * util_format_get_blockheight(format));
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_1D_ARRAY:
width = align(width, 32 * util_format_get_blockwidth(format));
case PIPE_BUFFER:
break;
}
/* mipmaps have power of two sizes in memory */ /* mipmaps have power of two sizes in memory */
if (level) { if (level)
width = util_next_power_of_two(width); nblocksy = util_next_power_of_two(nblocksy);
height = util_next_power_of_two(height);
}
slice->pitch = util_format_get_nblocksx(format, width) * rsc->layout.cpp;
slice->offset = size; slice->offset = size;
slice->size0 = align(pitch * nblocksy, 4096);
blocks = util_format_get_nblocks(format, width, height); size += slice->size0 * u_minify(prsc->depth0, level) * prsc->array_size;
/* 4k aligned size */
slice->size0 = align(blocks * rsc->layout.cpp, 4096);
size += slice->size0 * depth * prsc->array_size;
width = u_minify(width, 1);
height = u_minify(height, 1);
depth = u_minify(depth, 1);
} }
return size; return size;
} }

View file

@ -181,13 +181,12 @@ fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
so->base.reference.count = 1; so->base.reference.count = 1;
so->base.context = pctx; so->base.context = pctx;
struct fdl_slice *slice0 = fd_resource_slice(rsc, 0);
so->tex0 = so->tex0 =
A2XX_SQ_TEX_0_SIGN_X(fmt.sign) | A2XX_SQ_TEX_0_SIGN_X(fmt.sign) |
A2XX_SQ_TEX_0_SIGN_Y(fmt.sign) | A2XX_SQ_TEX_0_SIGN_Y(fmt.sign) |
A2XX_SQ_TEX_0_SIGN_Z(fmt.sign) | A2XX_SQ_TEX_0_SIGN_Z(fmt.sign) |
A2XX_SQ_TEX_0_SIGN_W(fmt.sign) | A2XX_SQ_TEX_0_SIGN_W(fmt.sign) |
A2XX_SQ_TEX_0_PITCH((slice0->pitch >> fdl_cpp_shift(&rsc->layout)) * A2XX_SQ_TEX_0_PITCH(fdl2_pitch_pixels(&rsc->layout, 0) *
util_format_get_blockwidth(prsc->format)) | util_format_get_blockwidth(prsc->format)) |
COND(rsc->layout.tile_mode, A2XX_SQ_TEX_0_TILED); COND(rsc->layout.tile_mode, A2XX_SQ_TEX_0_TILED);
so->tex1 = so->tex1 =

View file

@ -344,9 +344,8 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring,
A3XX_TEX_CONST_0_TYPE(A3XX_TEX_2D) | A3XX_TEX_CONST_0_TYPE(A3XX_TEX_2D) |
fd3_tex_swiz(format, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, fd3_tex_swiz(format, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W)); PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W));
OUT_RING(ring, A3XX_TEX_CONST_1_FETCHSIZE(TFETCH_DISABLE) | OUT_RING(ring, A3XX_TEX_CONST_1_WIDTH(psurf[i]->width) |
A3XX_TEX_CONST_1_WIDTH(psurf[i]->width) | A3XX_TEX_CONST_1_HEIGHT(psurf[i]->height));
A3XX_TEX_CONST_1_HEIGHT(psurf[i]->height));
OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)) | OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)) |
A3XX_TEX_CONST_2_INDX(BASETABLE_SZ * i)); A3XX_TEX_CONST_2_INDX(BASETABLE_SZ * i));
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);

View file

@ -321,27 +321,6 @@ fd3_pipe2swap(enum pipe_format format)
return formats[format].swap; return formats[format].swap;
} }
enum a3xx_tex_fetchsize
fd3_pipe2fetchsize(enum pipe_format format)
{
if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
format = PIPE_FORMAT_Z32_FLOAT;
else if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
format = PIPE_FORMAT_R8G8B8A8_UNORM;
switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) {
case 8: return TFETCH_1_BYTE;
case 16: return TFETCH_2_BYTE;
case 32: return TFETCH_4_BYTE;
case 64: return TFETCH_8_BYTE;
case 128: return TFETCH_16_BYTE;
default:
debug_printf("Unknown block size for format %s: %d\n",
util_format_name(format),
util_format_get_blocksizebits(format));
return TFETCH_DISABLE;
}
}
enum a3xx_color_fmt enum a3xx_color_fmt
fd3_fs_output_format(enum pipe_format format) fd3_fs_output_format(enum pipe_format format)
{ {

View file

@ -32,7 +32,6 @@
enum a3xx_vtx_fmt fd3_pipe2vtx(enum pipe_format format); enum a3xx_vtx_fmt fd3_pipe2vtx(enum pipe_format format);
enum a3xx_tex_fmt fd3_pipe2tex(enum pipe_format format); enum a3xx_tex_fmt fd3_pipe2tex(enum pipe_format format);
enum a3xx_tex_fetchsize fd3_pipe2fetchsize(enum pipe_format format);
enum a3xx_color_fmt fd3_pipe2color(enum pipe_format format); enum a3xx_color_fmt fd3_pipe2color(enum pipe_format format);
enum a3xx_color_fmt fd3_fs_output_format(enum pipe_format format); enum a3xx_color_fmt fd3_fs_output_format(enum pipe_format format);
enum a3xx_color_swap fd3_pipe2swap(enum pipe_format format); enum a3xx_color_swap fd3_pipe2swap(enum pipe_format format);

View file

@ -29,42 +29,26 @@ static uint32_t
setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format format) setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format format)
{ {
struct pipe_resource *prsc = &rsc->base; struct pipe_resource *prsc = &rsc->base;
struct fd_screen *screen = fd_screen(prsc->screen);
uint32_t pitchalign = screen->gmem_alignw;
uint32_t level, size = 0; uint32_t level, size = 0;
uint32_t width = prsc->width0; uint32_t width0 = prsc->width0;
uint32_t height = prsc->height0;
uint32_t depth = prsc->depth0; if (rsc->layout.tile_mode && prsc->target != PIPE_TEXTURE_CUBE)
width0 = util_next_power_of_two(width0);
/* 32 pixel alignment */
fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5);
for (level = 0; level <= prsc->last_level; level++) { for (level = 0; level <= prsc->last_level; level++) {
struct fdl_slice *slice = fd_resource_slice(rsc, level); struct fdl_slice *slice = fd_resource_slice(rsc, level);
uint32_t blocks; uint32_t pitch = fdl_pitch(&rsc->layout, level);
uint32_t height = u_minify(prsc->height0, level);
if (rsc->layout.tile_mode) { if (rsc->layout.tile_mode) {
if (prsc->target != PIPE_TEXTURE_CUBE) { height = align(height, 4);
if (level == 0) { if (prsc->target != PIPE_TEXTURE_CUBE)
width = util_next_power_of_two(width); height = util_next_power_of_two(height);
height = util_next_power_of_two(height);
}
width = MAX2(width, 8);
height = MAX2(height, 4);
// Multiplying by 4 is the result of the 4x4 tiling pattern.
slice->pitch = width * 4;
blocks = util_format_get_nblocks(format, width, height);
} else {
uint32_t twidth, theight;
twidth = align(width, 8);
theight = align(height, 4);
// Multiplying by 4 is the result of the 4x4 tiling pattern.
slice->pitch = twidth * 4;
blocks = util_format_get_nblocks(format, twidth, theight);
}
} else {
slice->pitch = width = align(width, pitchalign);
blocks = util_format_get_nblocks(format, slice->pitch, height);
} }
slice->pitch = util_format_get_nblocksx(format, slice->pitch) *
rsc->layout.cpp; uint32_t nblocksy = util_format_get_nblocksy(format, height);
slice->offset = size; slice->offset = size;
/* 1d array and 2d array textures must all have the same layer size /* 1d array and 2d array textures must all have the same layer size
@ -76,17 +60,13 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format forma
if (prsc->target == PIPE_TEXTURE_3D && ( if (prsc->target == PIPE_TEXTURE_3D && (
level == 1 || level == 1 ||
(level > 1 && fd_resource_slice(rsc, level - 1)->size0 > 0xf000))) (level > 1 && fd_resource_slice(rsc, level - 1)->size0 > 0xf000)))
slice->size0 = align(blocks * rsc->layout.cpp, alignment); slice->size0 = align(nblocksy * pitch, alignment);
else if (level == 0 || alignment == 1) else if (level == 0 || alignment == 1)
slice->size0 = align(blocks * rsc->layout.cpp, alignment); slice->size0 = align(nblocksy * pitch, alignment);
else else
slice->size0 = fd_resource_slice(rsc, level - 1)->size0; slice->size0 = fd_resource_slice(rsc, level - 1)->size0;
size += slice->size0 * depth * prsc->array_size; size += slice->size0 * u_minify(prsc->depth0, level) * prsc->array_size;
width = u_minify(width, 1);
height = u_minify(height, 1);
depth = u_minify(depth, 1);
} }
return size; return size;

View file

@ -247,7 +247,6 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
if (prsc->target == PIPE_BUFFER) { if (prsc->target == PIPE_BUFFER) {
lvl = 0; lvl = 0;
so->texconst1 = so->texconst1 =
A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
A3XX_TEX_CONST_1_WIDTH(cso->u.buf.size / util_format_get_blocksize(cso->format)) | A3XX_TEX_CONST_1_WIDTH(cso->u.buf.size / util_format_get_blocksize(cso->format)) |
A3XX_TEX_CONST_1_HEIGHT(1); A3XX_TEX_CONST_1_HEIGHT(1);
} else { } else {
@ -258,7 +257,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
so->texconst0 |= A3XX_TEX_CONST_0_MIPLVLS(miplevels); so->texconst0 |= A3XX_TEX_CONST_0_MIPLVLS(miplevels);
so->texconst1 = so->texconst1 =
A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) | A3XX_TEX_CONST_1_PITCHALIGN(rsc->layout.pitchalign - 4) |
A3XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A3XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
A3XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); A3XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
} }

View file

@ -348,8 +348,7 @@ fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, unsigned nr_bufs,
PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W)); PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W));
OUT_RING(ring, A4XX_TEX_CONST_1_WIDTH(bufs[i]->width) | OUT_RING(ring, A4XX_TEX_CONST_1_WIDTH(bufs[i]->width) |
A4XX_TEX_CONST_1_HEIGHT(bufs[i]->height)); A4XX_TEX_CONST_1_HEIGHT(bufs[i]->height));
OUT_RING(ring, A4XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)) | OUT_RING(ring, A4XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)));
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format)));
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RELOC(ring, rsc->bo, offset, 0, 0); OUT_RELOC(ring, rsc->bo, offset, 0, 0);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);

View file

@ -369,30 +369,6 @@ fd4_pipe2swap(enum pipe_format format)
return formats[format].swap; return formats[format].swap;
} }
enum a4xx_tex_fetchsize
fd4_pipe2fetchsize(enum pipe_format format)
{
if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
format = PIPE_FORMAT_Z32_FLOAT;
if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_ASTC)
return TFETCH4_16_BYTE;
switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) {
case 8: return TFETCH4_1_BYTE;
case 16: return TFETCH4_2_BYTE;
case 32: return TFETCH4_4_BYTE;
case 64: return TFETCH4_8_BYTE;
case 96: return TFETCH4_1_BYTE; /* Does this matter? */
case 128: return TFETCH4_16_BYTE;
default:
debug_printf("Unknown block size for format %s: %d\n",
util_format_name(format),
util_format_get_blocksizebits(format));
return TFETCH4_1_BYTE;
}
}
enum a4xx_depth_format enum a4xx_depth_format
fd4_pipe2depth(enum pipe_format format) fd4_pipe2depth(enum pipe_format format)
{ {

View file

@ -35,7 +35,6 @@ enum a4xx_vtx_fmt fd4_pipe2vtx(enum pipe_format format);
enum a4xx_tex_fmt fd4_pipe2tex(enum pipe_format format); enum a4xx_tex_fmt fd4_pipe2tex(enum pipe_format format);
enum a4xx_color_fmt fd4_pipe2color(enum pipe_format format); enum a4xx_color_fmt fd4_pipe2color(enum pipe_format format);
enum a3xx_color_swap fd4_pipe2swap(enum pipe_format format); enum a3xx_color_swap fd4_pipe2swap(enum pipe_format format);
enum a4xx_tex_fetchsize fd4_pipe2fetchsize(enum pipe_format format);
enum a4xx_depth_format fd4_pipe2depth(enum pipe_format format); enum a4xx_depth_format fd4_pipe2depth(enum pipe_format format);
uint32_t fd4_tex_swiz(enum pipe_format format, unsigned swizzle_r, uint32_t fd4_tex_swiz(enum pipe_format format, unsigned swizzle_r,

View file

@ -32,7 +32,6 @@ fd4_setup_slices(struct fd_resource *rsc)
{ {
struct pipe_resource *prsc = &rsc->base; struct pipe_resource *prsc = &rsc->base;
enum pipe_format format = prsc->format; enum pipe_format format = prsc->format;
enum util_format_layout layout = util_format_description(format)->layout;
uint32_t level, size = 0; uint32_t level, size = 0;
uint32_t width = prsc->width0; uint32_t width = prsc->width0;
uint32_t height = prsc->height0; uint32_t height = prsc->height0;
@ -52,17 +51,16 @@ fd4_setup_slices(struct fd_resource *rsc)
alignment = 1; alignment = 1;
} }
/* 32 pixel alignment */
fdl_set_pitchalign(&rsc->layout, fdl_cpp_shift(&rsc->layout) + 5);
for (level = 0; level <= prsc->last_level; level++) { for (level = 0; level <= prsc->last_level; level++) {
struct fdl_slice *slice = fd_resource_slice(rsc, level); struct fdl_slice *slice = fd_resource_slice(rsc, level);
uint32_t blocks; uint32_t pitch = fdl_pitch(&rsc->layout, level);
uint32_t nblocksy = util_format_get_nblocksy(format, height);
if (layout == UTIL_FORMAT_LAYOUT_ASTC)
width = util_align_npot(width, 32 * util_format_get_blockwidth(format));
else
width = align(width, 32);
slice->pitch = util_format_get_nblocksx(format, width) * rsc->layout.cpp;
slice->offset = size; slice->offset = size;
blocks = util_format_get_nblocks(format, width, height);
/* 3d textures can have different layer sizes for high levels, but the /* 3d textures can have different layer sizes for high levels, but the
* hw auto-sizer is buggy (or at least different than what this code * hw auto-sizer is buggy (or at least different than what this code
* does), so as soon as the layer size range gets into range, we stop * does), so as soon as the layer size range gets into range, we stop
@ -72,7 +70,7 @@ fd4_setup_slices(struct fd_resource *rsc)
(level > 1 && fd_resource_slice(rsc, level - 1)->size0 <= 0xf000)) (level > 1 && fd_resource_slice(rsc, level - 1)->size0 <= 0xf000))
slice->size0 = fd_resource_slice(rsc, level - 1)->size0; slice->size0 = fd_resource_slice(rsc, level - 1)->size0;
else else
slice->size0 = align(blocks * rsc->layout.cpp, alignment); slice->size0 = align(nblocksy * pitch, alignment);
size += slice->size0 * depth * layers_in_level; size += slice->size0 * depth * layers_in_level;

View file

@ -259,7 +259,6 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
A4XX_TEX_CONST_1_WIDTH(elements) | A4XX_TEX_CONST_1_WIDTH(elements) |
A4XX_TEX_CONST_1_HEIGHT(1); A4XX_TEX_CONST_1_HEIGHT(1);
so->texconst2 = so->texconst2 =
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format)) |
A4XX_TEX_CONST_2_PITCH(elements * rsc->layout.cpp); A4XX_TEX_CONST_2_PITCH(elements * rsc->layout.cpp);
so->offset = cso->u.buf.offset; so->offset = cso->u.buf.offset;
} else { } else {
@ -274,7 +273,7 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
so->texconst2 = so->texconst2 =
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format)) | A4XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign - 5) |
A4XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)); A4XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl));
so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer);
} }

View file

@ -372,31 +372,6 @@ fd5_pipe2swap(enum pipe_format format)
return formats[format].swap; return formats[format].swap;
} }
// XXX possibly same as a4xx..
enum a5xx_tex_fetchsize
fd5_pipe2fetchsize(enum pipe_format format)
{
if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
format = PIPE_FORMAT_Z32_FLOAT;
if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_ASTC)
return TFETCH5_16_BYTE;
switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) {
case 8: return TFETCH5_1_BYTE;
case 16: return TFETCH5_2_BYTE;
case 32: return TFETCH5_4_BYTE;
case 64: return TFETCH5_8_BYTE;
case 96: return TFETCH5_1_BYTE; /* Does this matter? */
case 128: return TFETCH5_16_BYTE;
default:
debug_printf("Unknown block size for format %s: %d\n",
util_format_name(format),
util_format_get_blocksizebits(format));
return TFETCH5_1_BYTE;
}
}
enum a5xx_depth_format enum a5xx_depth_format
fd5_pipe2depth(enum pipe_format format) fd5_pipe2depth(enum pipe_format format)
{ {

View file

@ -35,7 +35,6 @@ enum a5xx_vtx_fmt fd5_pipe2vtx(enum pipe_format format);
enum a5xx_tex_fmt fd5_pipe2tex(enum pipe_format format); enum a5xx_tex_fmt fd5_pipe2tex(enum pipe_format format);
enum a5xx_color_fmt fd5_pipe2color(enum pipe_format format); enum a5xx_color_fmt fd5_pipe2color(enum pipe_format format);
enum a3xx_color_swap fd5_pipe2swap(enum pipe_format format); enum a3xx_color_swap fd5_pipe2swap(enum pipe_format format);
enum a5xx_tex_fetchsize fd5_pipe2fetchsize(enum pipe_format format);
enum a5xx_depth_format fd5_pipe2depth(enum pipe_format format); enum a5xx_depth_format fd5_pipe2depth(enum pipe_format format);
uint32_t fd5_tex_swiz(enum pipe_format format, unsigned swizzle_r, uint32_t fd5_tex_swiz(enum pipe_format format, unsigned swizzle_r,

View file

@ -44,7 +44,6 @@ static enum a4xx_state_block imgsb[] = {
struct fd5_image { struct fd5_image {
enum pipe_format pfmt; enum pipe_format pfmt;
enum a5xx_tex_fmt fmt; enum a5xx_tex_fmt fmt;
enum a5xx_tex_fetchsize fetchsize;
enum a5xx_tex_type type; enum a5xx_tex_type type;
bool srgb; bool srgb;
uint32_t cpp; uint32_t cpp;
@ -71,7 +70,6 @@ static void translate_image(struct fd5_image *img, struct pipe_image_view *pimg)
img->pfmt = format; img->pfmt = format;
img->fmt = fd5_pipe2tex(format); img->fmt = fd5_pipe2tex(format);
img->fetchsize = fd5_pipe2fetchsize(format);
img->type = fd5_tex_type(prsc->target); img->type = fd5_tex_type(prsc->target);
img->srgb = util_format_is_srgb(format); img->srgb = util_format_is_srgb(format);
img->cpp = rsc->layout.cpp; img->cpp = rsc->layout.cpp;
@ -138,8 +136,7 @@ static void emit_image_tex(struct fd_ringbuffer *ring, unsigned slot,
COND(img->srgb, A5XX_TEX_CONST_0_SRGB)); COND(img->srgb, A5XX_TEX_CONST_0_SRGB));
OUT_RING(ring, A5XX_TEX_CONST_1_WIDTH(img->width) | OUT_RING(ring, A5XX_TEX_CONST_1_WIDTH(img->width) |
A5XX_TEX_CONST_1_HEIGHT(img->height)); A5XX_TEX_CONST_1_HEIGHT(img->height));
OUT_RING(ring, A5XX_TEX_CONST_2_FETCHSIZE(img->fetchsize) | OUT_RING(ring, A5XX_TEX_CONST_2_TYPE(img->type) |
A5XX_TEX_CONST_2_TYPE(img->type) |
A5XX_TEX_CONST_2_PITCH(img->pitch)); A5XX_TEX_CONST_2_PITCH(img->pitch));
OUT_RING(ring, A5XX_TEX_CONST_3_ARRAY_PITCH(img->array_pitch)); OUT_RING(ring, A5XX_TEX_CONST_3_ARRAY_PITCH(img->array_pitch));
if (img->bo) { if (img->bo) {

View file

@ -257,7 +257,6 @@ fd5_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
A5XX_TEX_CONST_1_WIDTH(elements) | A5XX_TEX_CONST_1_WIDTH(elements) |
A5XX_TEX_CONST_1_HEIGHT(1); A5XX_TEX_CONST_1_HEIGHT(1);
so->texconst2 = so->texconst2 =
A5XX_TEX_CONST_2_FETCHSIZE(fd5_pipe2fetchsize(format)) |
A5XX_TEX_CONST_2_PITCH(elements * rsc->layout.cpp); A5XX_TEX_CONST_2_PITCH(elements * rsc->layout.cpp);
so->offset = cso->u.buf.offset; so->offset = cso->u.buf.offset;
} else { } else {
@ -272,7 +271,7 @@ fd5_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
A5XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A5XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
A5XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); A5XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
so->texconst2 = so->texconst2 =
A5XX_TEX_CONST_2_FETCHSIZE(fd5_pipe2fetchsize(format)) | A5XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign - 6) |
A5XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)); A5XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl));
so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer);
} }

View file

@ -60,7 +60,7 @@ fd6_emit_flag_reference(struct fd_ringbuffer *ring, struct fd_resource *rsc,
if (fd_resource_ubwc_enabled(rsc, level)) { if (fd_resource_ubwc_enabled(rsc, level)) {
OUT_RELOC(ring, rsc->bo, fd_resource_ubwc_offset(rsc, level, layer), 0, 0); OUT_RELOC(ring, rsc->bo, fd_resource_ubwc_offset(rsc, level, layer), 0, 0);
OUT_RING(ring, OUT_RING(ring,
A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(rsc->layout.ubwc_slices[level].pitch) | A6XX_RB_MRT_FLAG_BUFFER_PITCH_PITCH(fdl_ubwc_pitch(&rsc->layout, level)) |
A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2)); A6XX_RB_MRT_FLAG_BUFFER_PITCH_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2));
} else { } else {
OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */ OUT_RING(ring, 0x00000000); /* RB_MRT_FLAG_BUFFER[i].ADDR_LO */

View file

@ -192,15 +192,13 @@ static void emit_image_tex(struct fd_ringbuffer *ring, struct fd6_image *img)
OUT_RING(ring, 0x00000000); /* texconst6 */ OUT_RING(ring, 0x00000000); /* texconst6 */
if (ubwc_enabled) { if (ubwc_enabled) {
struct fdl_slice *ubwc_slice = &rsc->layout.ubwc_slices[img->level];
uint32_t block_width, block_height; uint32_t block_width, block_height;
fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height); fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height);
OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0); OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0);
OUT_RING(ring, A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2)); OUT_RING(ring, A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2));
OUT_RING(ring, OUT_RING(ring,
A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(ubwc_slice->pitch) | A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(fdl_ubwc_pitch(&rsc->layout, img->level)) |
A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(img->width, block_width))) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(img->width, block_width))) |
A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(img->height, block_height)))); A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(img->height, block_height))));
} else { } else {
@ -267,10 +265,9 @@ static void emit_image_ssbo(struct fd_ringbuffer *ring, struct fd6_image *img)
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
if (ubwc_enabled) { if (ubwc_enabled) {
struct fdl_slice *ubwc_slice = &rsc->layout.ubwc_slices[img->level];
OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0); OUT_RELOC(ring, rsc->bo, img->ubwc_offset, 0, 0);
OUT_RING(ring, A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2)); OUT_RING(ring, A6XX_IBO_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2));
OUT_RING(ring, A6XX_IBO_10_FLAG_BUFFER_PITCH(ubwc_slice->pitch)); OUT_RING(ring, A6XX_IBO_10_FLAG_BUFFER_PITCH(fdl_ubwc_pitch(&rsc->layout, img->level)));
} else { } else {
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);
OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000000);

View file

@ -163,7 +163,10 @@ static int
fill_ubwc_buffer_sizes(struct fd_resource *rsc) fill_ubwc_buffer_sizes(struct fd_resource *rsc)
{ {
struct pipe_resource *prsc = &rsc->base; struct pipe_resource *prsc = &rsc->base;
struct fdl_slice slice = *fd_resource_slice(rsc, 0); struct fdl_explicit_layout explicit = {
.offset = rsc->layout.slices[0].offset,
.pitch = rsc->layout.pitch0,
};
/* limit things to simple single level 2d for now: */ /* limit things to simple single level 2d for now: */
if ((prsc->depth0 != 1) || (prsc->array_size != 1) || (prsc->last_level != 0)) if ((prsc->depth0 != 1) || (prsc->array_size != 1) || (prsc->last_level != 0))
@ -178,7 +181,7 @@ fill_ubwc_buffer_sizes(struct fd_resource *rsc)
if (!fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc), if (!fdl6_layout(&rsc->layout, prsc->format, fd_resource_nr_samples(prsc),
prsc->width0, prsc->height0, prsc->depth0, prsc->width0, prsc->height0, prsc->depth0,
prsc->last_level + 1, prsc->array_size, false, &slice)) prsc->last_level + 1, prsc->array_size, false, &explicit))
return -1; return -1;
if (rsc->layout.size > fd_bo_size(rsc->bo)) if (rsc->layout.size > fd_bo_size(rsc->bo))

View file

@ -263,7 +263,7 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
A6XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) | A6XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
A6XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl)); A6XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
so->texconst2 = so->texconst2 =
A6XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign) | A6XX_TEX_CONST_2_PITCHALIGN(rsc->layout.pitchalign - 6) |
A6XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl)); A6XX_TEX_CONST_2_PITCH(fd_resource_pitch(rsc, lvl));
so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer); so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer);
so->ubwc_offset = fd_resource_ubwc_offset(rsc, lvl, cso->u.tex.first_layer); so->ubwc_offset = fd_resource_ubwc_offset(rsc, lvl, cso->u.tex.first_layer);
@ -312,15 +312,13 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
} }
if (so->ubwc_enabled) { if (so->ubwc_enabled) {
struct fdl_slice *ubwc_base_slice = &rsc->layout.ubwc_slices[lvl];
uint32_t block_width, block_height; uint32_t block_width, block_height;
fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height); fdl6_get_ubwc_blockwidth(&rsc->layout, &block_width, &block_height);
so->texconst3 |= A6XX_TEX_CONST_3_FLAG | A6XX_TEX_CONST_3_TILE_ALL; so->texconst3 |= A6XX_TEX_CONST_3_FLAG | A6XX_TEX_CONST_3_TILE_ALL;
so->texconst9 |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2); so->texconst9 |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(rsc->layout.ubwc_layer_size >> 2);
so->texconst10 |= so->texconst10 |=
A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(ubwc_base_slice->pitch) | A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(fdl_ubwc_pitch(&rsc->layout, lvl)) |
A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->width0, lvl), block_width))) | A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->width0, lvl), block_width))) |
A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->height0, lvl), block_height))); A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(u_minify(prsc->height0, lvl), block_height)));
} }

View file

@ -821,6 +821,8 @@ fd_resource_layout_init(struct pipe_resource *prsc)
struct fd_resource *rsc = fd_resource(prsc); struct fd_resource *rsc = fd_resource(prsc);
struct fdl_layout *layout = &rsc->layout; struct fdl_layout *layout = &rsc->layout;
layout->format = prsc->format;
layout->width0 = prsc->width0; layout->width0 = prsc->width0;
layout->height0 = prsc->height0; layout->height0 = prsc->height0;
layout->depth0 = prsc->depth0; layout->depth0 = prsc->depth0;
@ -1021,7 +1023,7 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
goto fail; goto fail;
rsc->internal_format = tmpl->format; rsc->internal_format = tmpl->format;
slice->pitch = handle->stride; rsc->layout.pitch0 = handle->stride;
slice->offset = handle->offset; slice->offset = handle->offset;
slice->size0 = handle->stride * prsc->height0; slice->size0 = handle->stride * prsc->height0;
@ -1033,8 +1035,8 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
if (is_a6xx(screen)) if (is_a6xx(screen))
pitchalign = 64; pitchalign = 64;
if ((slice->pitch < align(prsc->width0 * rsc->layout.cpp, pitchalign)) || if ((rsc->layout.pitch0 < align(prsc->width0 * rsc->layout.cpp, pitchalign)) ||
(slice->pitch & (pitchalign - 1))) (rsc->layout.pitch0 & (pitchalign - 1)))
goto fail; goto fail;
assert(rsc->layout.cpp); assert(rsc->layout.cpp);

View file

@ -201,7 +201,10 @@ fd_resource_layer_stride(struct fd_resource *rsc, unsigned level)
static inline uint32_t static inline uint32_t
fd_resource_pitch(struct fd_resource *rsc, unsigned level) fd_resource_pitch(struct fd_resource *rsc, unsigned level)
{ {
return fd_resource_slice(rsc, level)->pitch; if (is_a2xx(fd_screen(rsc->base.screen)))
return fdl2_pitch(&rsc->layout, level);
return fdl_pitch(&rsc->layout, level);
} }
/* get offset for specified mipmap level and texture/array layer */ /* get offset for specified mipmap level and texture/array layer */