mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 09:00:10 +01:00
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:
parent
4b290b759a
commit
979e7e3680
33 changed files with 177 additions and 320 deletions
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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"/>
|
||||||
|
|
|
||||||
|
|
@ -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"/>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue