radeon: implement 2D tiling for CIK
Bug fixes and simplification by Marek. We have to use the tile index of 0 for non-MSAA depth-stencil after all. Signed-off-by: Marek Olšák <marek.olsak@amd.com> Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>main
parent
ce8af45425
commit
67d92404d6
|
@ -979,6 +979,10 @@ struct drm_radeon_cs {
|
||||||
#define RADEON_INFO_RING_WORKING 0x15
|
#define RADEON_INFO_RING_WORKING 0x15
|
||||||
/* SI tile mode array */
|
/* SI tile mode array */
|
||||||
#define RADEON_INFO_SI_TILE_MODE_ARRAY 0x16
|
#define RADEON_INFO_SI_TILE_MODE_ARRAY 0x16
|
||||||
|
/* query if CP DMA is supported on the compute ring */
|
||||||
|
#define RADEON_INFO_SI_CP_DMA_COMPUTE 0x17
|
||||||
|
/* CIK macrotile mode array */
|
||||||
|
#define RADEON_INFO_CIK_MACROTILE_MODE_ARRAY 0x18
|
||||||
|
|
||||||
struct drm_radeon_info {
|
struct drm_radeon_info {
|
||||||
uint32_t request;
|
uint32_t request;
|
||||||
|
@ -1004,6 +1008,13 @@ struct drm_radeon_info {
|
||||||
#define SI_TILE_MODE_DEPTH_STENCIL_2D_4AA 3
|
#define SI_TILE_MODE_DEPTH_STENCIL_2D_4AA 3
|
||||||
#define SI_TILE_MODE_DEPTH_STENCIL_2D_8AA 2
|
#define SI_TILE_MODE_DEPTH_STENCIL_2D_8AA 2
|
||||||
|
|
||||||
|
#define CIK_TILE_MODE_COLOR_2D 14
|
||||||
|
#define CIK_TILE_MODE_COLOR_2D_SCANOUT 10
|
||||||
|
#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64 0
|
||||||
|
#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128 1
|
||||||
|
#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256 2
|
||||||
|
#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512 3
|
||||||
|
#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE 4
|
||||||
#define CIK_TILE_MODE_DEPTH_STENCIL_1D 5
|
#define CIK_TILE_MODE_DEPTH_STENCIL_1D 5
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
* Authors:
|
* Authors:
|
||||||
* Jérôme Glisse <jglisse@redhat.com>
|
* Jérôme Glisse <jglisse@redhat.com>
|
||||||
*/
|
*/
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -96,6 +98,8 @@ struct radeon_hw_info {
|
||||||
unsigned allow_2d;
|
unsigned allow_2d;
|
||||||
/* apply to si */
|
/* apply to si */
|
||||||
uint32_t tile_mode_array[32];
|
uint32_t tile_mode_array[32];
|
||||||
|
/* apply to cik */
|
||||||
|
uint32_t macrotile_mode_array[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radeon_surface_manager {
|
struct radeon_surface_manager {
|
||||||
|
@ -1383,16 +1387,10 @@ static int si_surface_sanity(struct radeon_surface_manager *surf_man,
|
||||||
break;
|
break;
|
||||||
case RADEON_SURF_MODE_1D:
|
case RADEON_SURF_MODE_1D:
|
||||||
if (surf->flags & RADEON_SURF_SBUFFER) {
|
if (surf->flags & RADEON_SURF_SBUFFER) {
|
||||||
if (surf_man->family >= CHIP_BONAIRE)
|
*stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
|
||||||
*stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
|
|
||||||
else
|
|
||||||
*stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
|
|
||||||
}
|
}
|
||||||
if (surf->flags & RADEON_SURF_ZBUFFER) {
|
if (surf->flags & RADEON_SURF_ZBUFFER) {
|
||||||
if (surf_man->family >= CHIP_BONAIRE)
|
*tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
|
||||||
*tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
|
|
||||||
else
|
|
||||||
*tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
|
|
||||||
} else if (surf->flags & RADEON_SURF_SCANOUT) {
|
} else if (surf->flags & RADEON_SURF_SCANOUT) {
|
||||||
*tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
|
*tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1660,10 +1658,7 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
|
||||||
tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
|
tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
|
||||||
break;
|
break;
|
||||||
case SI_TILE_MODE_DEPTH_STENCIL_2D:
|
case SI_TILE_MODE_DEPTH_STENCIL_2D:
|
||||||
if (surf_man->family >= CHIP_BONAIRE)
|
tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
|
||||||
tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
|
|
||||||
else
|
|
||||||
tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1791,6 +1786,604 @@ static int si_surface_best(struct radeon_surface_manager *surf_man,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ===========================================================================
|
||||||
|
* Sea Islands family
|
||||||
|
*/
|
||||||
|
#define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
|
||||||
|
#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
|
||||||
|
#define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
|
||||||
|
#define CIK__TILE_SPLIT__64B 0
|
||||||
|
#define CIK__TILE_SPLIT__128B 1
|
||||||
|
#define CIK__TILE_SPLIT__256B 2
|
||||||
|
#define CIK__TILE_SPLIT__512B 3
|
||||||
|
#define CIK__TILE_SPLIT__1024B 4
|
||||||
|
#define CIK__TILE_SPLIT__2048B 5
|
||||||
|
#define CIK__TILE_SPLIT__4096B 6
|
||||||
|
#define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
|
||||||
|
#define CIK__SAMPLE_SPLIT__1 0
|
||||||
|
#define CIK__SAMPLE_SPLIT__2 1
|
||||||
|
#define CIK__SAMPLE_SPLIT__4 2
|
||||||
|
#define CIK__SAMPLE_SPLIT__8 3
|
||||||
|
#define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
|
||||||
|
#define CIK__BANK_WIDTH__1 0
|
||||||
|
#define CIK__BANK_WIDTH__2 1
|
||||||
|
#define CIK__BANK_WIDTH__4 2
|
||||||
|
#define CIK__BANK_WIDTH__8 3
|
||||||
|
#define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
|
||||||
|
#define CIK__BANK_HEIGHT__1 0
|
||||||
|
#define CIK__BANK_HEIGHT__2 1
|
||||||
|
#define CIK__BANK_HEIGHT__4 2
|
||||||
|
#define CIK__BANK_HEIGHT__8 3
|
||||||
|
#define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
|
||||||
|
#define CIK__MACRO_TILE_ASPECT__1 0
|
||||||
|
#define CIK__MACRO_TILE_ASPECT__2 1
|
||||||
|
#define CIK__MACRO_TILE_ASPECT__4 2
|
||||||
|
#define CIK__MACRO_TILE_ASPECT__8 3
|
||||||
|
#define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
|
||||||
|
#define CIK__NUM_BANKS__2_BANK 0
|
||||||
|
#define CIK__NUM_BANKS__4_BANK 1
|
||||||
|
#define CIK__NUM_BANKS__8_BANK 2
|
||||||
|
#define CIK__NUM_BANKS__16_BANK 3
|
||||||
|
|
||||||
|
|
||||||
|
static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
|
||||||
|
unsigned bpe, unsigned nsamples, bool is_color,
|
||||||
|
unsigned tile_mode,
|
||||||
|
uint32_t *num_pipes,
|
||||||
|
uint32_t *tile_split_ptr,
|
||||||
|
uint32_t *num_banks,
|
||||||
|
uint32_t *macro_tile_aspect,
|
||||||
|
uint32_t *bank_w,
|
||||||
|
uint32_t *bank_h)
|
||||||
|
{
|
||||||
|
uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
|
||||||
|
unsigned tileb_1x, tileb;
|
||||||
|
unsigned gb_macrotile_mode;
|
||||||
|
unsigned macrotile_index;
|
||||||
|
unsigned tile_split, sample_split;
|
||||||
|
|
||||||
|
if (num_pipes) {
|
||||||
|
switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P2:
|
||||||
|
default:
|
||||||
|
*num_pipes = 2;
|
||||||
|
break;
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
|
||||||
|
*num_pipes = 4;
|
||||||
|
break;
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
|
||||||
|
case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
|
||||||
|
*num_pipes = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
|
||||||
|
default:
|
||||||
|
case CIK__TILE_SPLIT__64B:
|
||||||
|
tile_split = 64;
|
||||||
|
break;
|
||||||
|
case CIK__TILE_SPLIT__128B:
|
||||||
|
tile_split = 128;
|
||||||
|
break;
|
||||||
|
case CIK__TILE_SPLIT__256B:
|
||||||
|
tile_split = 256;
|
||||||
|
break;
|
||||||
|
case CIK__TILE_SPLIT__512B:
|
||||||
|
tile_split = 512;
|
||||||
|
break;
|
||||||
|
case CIK__TILE_SPLIT__1024B:
|
||||||
|
tile_split = 1024;
|
||||||
|
break;
|
||||||
|
case CIK__TILE_SPLIT__2048B:
|
||||||
|
tile_split = 2048;
|
||||||
|
break;
|
||||||
|
case CIK__TILE_SPLIT__4096B:
|
||||||
|
tile_split = 4096;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
|
||||||
|
default:
|
||||||
|
case CIK__SAMPLE_SPLIT__1:
|
||||||
|
sample_split = 1;
|
||||||
|
break;
|
||||||
|
case CIK__SAMPLE_SPLIT__2:
|
||||||
|
sample_split = 1;
|
||||||
|
break;
|
||||||
|
case CIK__SAMPLE_SPLIT__4:
|
||||||
|
sample_split = 4;
|
||||||
|
break;
|
||||||
|
case CIK__SAMPLE_SPLIT__8:
|
||||||
|
sample_split = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust the tile split. */
|
||||||
|
tileb_1x = 8 * 8 * bpe;
|
||||||
|
if (is_color) {
|
||||||
|
tile_split = MAX2(256, sample_split * tileb_1x);
|
||||||
|
}
|
||||||
|
tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
|
||||||
|
|
||||||
|
/* Determine the macrotile index. */
|
||||||
|
tileb = MIN2(tile_split, nsamples * tileb_1x);
|
||||||
|
|
||||||
|
for (macrotile_index = 0; tileb > 64; macrotile_index++) {
|
||||||
|
tileb >>= 1;
|
||||||
|
}
|
||||||
|
gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
|
||||||
|
|
||||||
|
if (tile_split_ptr) {
|
||||||
|
*tile_split_ptr = tile_split;
|
||||||
|
}
|
||||||
|
if (num_banks) {
|
||||||
|
switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
|
||||||
|
default:
|
||||||
|
case CIK__NUM_BANKS__2_BANK:
|
||||||
|
*num_banks = 2;
|
||||||
|
break;
|
||||||
|
case CIK__NUM_BANKS__4_BANK:
|
||||||
|
*num_banks = 4;
|
||||||
|
break;
|
||||||
|
case CIK__NUM_BANKS__8_BANK:
|
||||||
|
*num_banks = 8;
|
||||||
|
break;
|
||||||
|
case CIK__NUM_BANKS__16_BANK:
|
||||||
|
*num_banks = 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (macro_tile_aspect) {
|
||||||
|
switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
|
||||||
|
default:
|
||||||
|
case CIK__MACRO_TILE_ASPECT__1:
|
||||||
|
*macro_tile_aspect = 1;
|
||||||
|
break;
|
||||||
|
case CIK__MACRO_TILE_ASPECT__2:
|
||||||
|
*macro_tile_aspect = 2;
|
||||||
|
break;
|
||||||
|
case CIK__MACRO_TILE_ASPECT__4:
|
||||||
|
*macro_tile_aspect = 4;
|
||||||
|
break;
|
||||||
|
case CIK__MACRO_TILE_ASPECT__8:
|
||||||
|
*macro_tile_aspect = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bank_w) {
|
||||||
|
switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
|
||||||
|
default:
|
||||||
|
case CIK__BANK_WIDTH__1:
|
||||||
|
*bank_w = 1;
|
||||||
|
break;
|
||||||
|
case CIK__BANK_WIDTH__2:
|
||||||
|
*bank_w = 2;
|
||||||
|
break;
|
||||||
|
case CIK__BANK_WIDTH__4:
|
||||||
|
*bank_w = 4;
|
||||||
|
break;
|
||||||
|
case CIK__BANK_WIDTH__8:
|
||||||
|
*bank_w = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bank_h) {
|
||||||
|
switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
|
||||||
|
default:
|
||||||
|
case CIK__BANK_HEIGHT__1:
|
||||||
|
*bank_h = 1;
|
||||||
|
break;
|
||||||
|
case CIK__BANK_HEIGHT__2:
|
||||||
|
*bank_h = 2;
|
||||||
|
break;
|
||||||
|
case CIK__BANK_HEIGHT__4:
|
||||||
|
*bank_h = 4;
|
||||||
|
break;
|
||||||
|
case CIK__BANK_HEIGHT__8:
|
||||||
|
*bank_h = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
|
||||||
|
{
|
||||||
|
uint32_t tiling_config;
|
||||||
|
drmVersionPtr version;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
|
||||||
|
&tiling_config);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
surf_man->hw_info.allow_2d = 0;
|
||||||
|
version = drmGetVersion(surf_man->fd);
|
||||||
|
if (version && version->version_minor >= 35) {
|
||||||
|
if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
|
||||||
|
!radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
|
||||||
|
surf_man->hw_info.allow_2d = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drmFreeVersion(version);
|
||||||
|
|
||||||
|
switch (tiling_config & 0xf) {
|
||||||
|
case 0:
|
||||||
|
surf_man->hw_info.num_pipes = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
surf_man->hw_info.num_pipes = 2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
surf_man->hw_info.num_pipes = 4;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
surf_man->hw_info.num_pipes = 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
surf_man->hw_info.num_pipes = 8;
|
||||||
|
surf_man->hw_info.allow_2d = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((tiling_config & 0xf0) >> 4) {
|
||||||
|
case 0:
|
||||||
|
surf_man->hw_info.num_banks = 4;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
surf_man->hw_info.num_banks = 8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
surf_man->hw_info.num_banks = 16;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
surf_man->hw_info.num_banks = 8;
|
||||||
|
surf_man->hw_info.allow_2d = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((tiling_config & 0xf00) >> 8) {
|
||||||
|
case 0:
|
||||||
|
surf_man->hw_info.group_bytes = 256;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
surf_man->hw_info.group_bytes = 512;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
surf_man->hw_info.group_bytes = 256;
|
||||||
|
surf_man->hw_info.allow_2d = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((tiling_config & 0xf000) >> 12) {
|
||||||
|
case 0:
|
||||||
|
surf_man->hw_info.row_size = 1024;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
surf_man->hw_info.row_size = 2048;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
surf_man->hw_info.row_size = 4096;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
surf_man->hw_info.row_size = 4096;
|
||||||
|
surf_man->hw_info.allow_2d = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
|
||||||
|
struct radeon_surface *surf,
|
||||||
|
unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
|
||||||
|
{
|
||||||
|
/* check surface dimension */
|
||||||
|
if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check mipmap last_level */
|
||||||
|
if (surf->last_level > 15) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* force 1d on kernel that can't do 2d */
|
||||||
|
if (mode > RADEON_SURF_MODE_1D &&
|
||||||
|
(!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
|
||||||
|
if (surf->nsamples > 1) {
|
||||||
|
fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
mode = RADEON_SURF_MODE_1D;
|
||||||
|
surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
|
||||||
|
surf->flags |= RADEON_SURF_SET(mode, MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!surf->tile_split) {
|
||||||
|
/* default value */
|
||||||
|
surf->mtilea = 1;
|
||||||
|
surf->bankw = 1;
|
||||||
|
surf->bankw = 1;
|
||||||
|
surf->tile_split = 64;
|
||||||
|
surf->stencil_tile_split = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case RADEON_SURF_MODE_2D: {
|
||||||
|
if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
|
||||||
|
switch (surf->nsamples) {
|
||||||
|
case 1:
|
||||||
|
*tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
*tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
*tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (surf->flags & RADEON_SURF_SBUFFER) {
|
||||||
|
*stencil_tile_mode = *tile_mode;
|
||||||
|
|
||||||
|
cik_get_2d_params(surf_man, 1, surf->nsamples, false,
|
||||||
|
*stencil_tile_mode, NULL,
|
||||||
|
&surf->stencil_tile_split,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
} else if (surf->flags & RADEON_SURF_SCANOUT) {
|
||||||
|
*tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
|
||||||
|
} else {
|
||||||
|
*tile_mode = CIK_TILE_MODE_COLOR_2D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* retrieve tiling mode values */
|
||||||
|
cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
|
||||||
|
!(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
|
||||||
|
NULL, &surf->tile_split, NULL, &surf->mtilea,
|
||||||
|
&surf->bankw, &surf->bankh);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case RADEON_SURF_MODE_1D:
|
||||||
|
if (surf->flags & RADEON_SURF_SBUFFER) {
|
||||||
|
*stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
|
||||||
|
}
|
||||||
|
if (surf->flags & RADEON_SURF_ZBUFFER) {
|
||||||
|
*tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
|
||||||
|
} else if (surf->flags & RADEON_SURF_SCANOUT) {
|
||||||
|
*tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
|
||||||
|
} else {
|
||||||
|
*tile_mode = SI_TILE_MODE_COLOR_1D;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RADEON_SURF_MODE_LINEAR_ALIGNED:
|
||||||
|
default:
|
||||||
|
*tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
|
||||||
|
struct radeon_surface *surf,
|
||||||
|
struct radeon_surface_level *level,
|
||||||
|
unsigned bpe, unsigned tile_mode,
|
||||||
|
unsigned tile_split,
|
||||||
|
unsigned num_pipes, unsigned num_banks,
|
||||||
|
uint64_t offset,
|
||||||
|
unsigned start_level)
|
||||||
|
{
|
||||||
|
uint64_t aligned_offset = offset;
|
||||||
|
unsigned tilew, tileh, tileb_1x, tileb;
|
||||||
|
unsigned mtilew, mtileh, mtileb;
|
||||||
|
unsigned slice_pt;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* compute tile values */
|
||||||
|
tilew = 8;
|
||||||
|
tileh = 8;
|
||||||
|
tileb_1x = tilew * tileh * bpe;
|
||||||
|
|
||||||
|
tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
|
||||||
|
|
||||||
|
tileb = surf->nsamples * tileb_1x;
|
||||||
|
|
||||||
|
/* slices per tile */
|
||||||
|
slice_pt = 1;
|
||||||
|
if (tileb > tile_split) {
|
||||||
|
slice_pt = tileb / tile_split;
|
||||||
|
tileb = tileb / slice_pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* macro tile width & height */
|
||||||
|
mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
|
||||||
|
mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
|
||||||
|
|
||||||
|
/* macro tile bytes */
|
||||||
|
mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
|
||||||
|
|
||||||
|
if (start_level <= 1) {
|
||||||
|
unsigned alignment = MAX2(256, mtileb);
|
||||||
|
surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
|
||||||
|
|
||||||
|
if (aligned_offset) {
|
||||||
|
aligned_offset = ALIGN(aligned_offset, alignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build mipmap tree */
|
||||||
|
for (i = start_level; i <= surf->last_level; i++) {
|
||||||
|
level[i].mode = RADEON_SURF_MODE_2D;
|
||||||
|
si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
|
||||||
|
if (level[i].mode == RADEON_SURF_MODE_1D) {
|
||||||
|
switch (tile_mode) {
|
||||||
|
case CIK_TILE_MODE_COLOR_2D:
|
||||||
|
tile_mode = SI_TILE_MODE_COLOR_1D;
|
||||||
|
break;
|
||||||
|
case CIK_TILE_MODE_COLOR_2D_SCANOUT:
|
||||||
|
tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
|
||||||
|
break;
|
||||||
|
case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
|
||||||
|
case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
|
||||||
|
case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
|
||||||
|
case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
|
||||||
|
case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
|
||||||
|
tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
|
||||||
|
}
|
||||||
|
/* level0 and first mipmap need to have alignment */
|
||||||
|
aligned_offset = offset = surf->bo_size;
|
||||||
|
if (i == 0) {
|
||||||
|
aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
|
||||||
|
}
|
||||||
|
if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
|
||||||
|
if (surf->level == level) {
|
||||||
|
surf->tiling_index[i] = tile_mode;
|
||||||
|
/* it's ok because stencil is done after */
|
||||||
|
surf->stencil_tiling_index[i] = tile_mode;
|
||||||
|
} else {
|
||||||
|
surf->stencil_tiling_index[i] = tile_mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
|
||||||
|
struct radeon_surface *surf,
|
||||||
|
unsigned tile_mode, unsigned stencil_tile_mode)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
uint32_t num_pipes, num_banks;
|
||||||
|
|
||||||
|
cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
|
||||||
|
!(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
|
||||||
|
&num_pipes, NULL, &num_banks, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
|
||||||
|
surf->tile_split, num_pipes, num_banks, 0, 0);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (surf->flags & RADEON_SURF_SBUFFER) {
|
||||||
|
r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
|
||||||
|
surf->stencil_tile_split, num_pipes, num_banks,
|
||||||
|
surf->bo_size, 0);
|
||||||
|
surf->stencil_offset = surf->stencil_level[0].offset;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cik_surface_init(struct radeon_surface_manager *surf_man,
|
||||||
|
struct radeon_surface *surf)
|
||||||
|
{
|
||||||
|
unsigned mode, tile_mode, stencil_tile_mode;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* MSAA surfaces support the 2D mode only. */
|
||||||
|
if (surf->nsamples > 1) {
|
||||||
|
surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
|
||||||
|
surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tiling mode */
|
||||||
|
mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
|
||||||
|
|
||||||
|
if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
|
||||||
|
/* zbuffer only support 1D or 2D tiled surface */
|
||||||
|
switch (mode) {
|
||||||
|
case RADEON_SURF_MODE_1D:
|
||||||
|
case RADEON_SURF_MODE_2D:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mode = RADEON_SURF_MODE_1D;
|
||||||
|
surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
|
||||||
|
surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
|
||||||
|
if (r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
surf->stencil_offset = 0;
|
||||||
|
surf->bo_alignment = 0;
|
||||||
|
|
||||||
|
/* check tiling mode */
|
||||||
|
switch (mode) {
|
||||||
|
case RADEON_SURF_MODE_LINEAR:
|
||||||
|
r = r6_surface_init_linear(surf_man, surf, 0, 0);
|
||||||
|
break;
|
||||||
|
case RADEON_SURF_MODE_LINEAR_ALIGNED:
|
||||||
|
r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
|
||||||
|
break;
|
||||||
|
case RADEON_SURF_MODE_1D:
|
||||||
|
r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
|
||||||
|
break;
|
||||||
|
case RADEON_SURF_MODE_2D:
|
||||||
|
r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* depending on surface
|
||||||
|
*/
|
||||||
|
static int cik_surface_best(struct radeon_surface_manager *surf_man,
|
||||||
|
struct radeon_surface *surf)
|
||||||
|
{
|
||||||
|
unsigned mode, tile_mode, stencil_tile_mode;
|
||||||
|
|
||||||
|
/* tiling mode */
|
||||||
|
mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
|
||||||
|
|
||||||
|
if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
|
||||||
|
!(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
|
||||||
|
/* depth/stencil force 1d tiling for old mesa */
|
||||||
|
surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
|
||||||
|
surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* public API
|
* public API
|
||||||
*/
|
*/
|
||||||
|
@ -1822,12 +2415,18 @@ struct radeon_surface_manager *radeon_surface_manager_new(int fd)
|
||||||
}
|
}
|
||||||
surf_man->surface_init = &eg_surface_init;
|
surf_man->surface_init = &eg_surface_init;
|
||||||
surf_man->surface_best = &eg_surface_best;
|
surf_man->surface_best = &eg_surface_best;
|
||||||
} else {
|
} else if (surf_man->family < CHIP_BONAIRE) {
|
||||||
if (si_init_hw_info(surf_man)) {
|
if (si_init_hw_info(surf_man)) {
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
surf_man->surface_init = &si_surface_init;
|
surf_man->surface_init = &si_surface_init;
|
||||||
surf_man->surface_best = &si_surface_best;
|
surf_man->surface_best = &si_surface_best;
|
||||||
|
} else {
|
||||||
|
if (cik_init_hw_info(surf_man)) {
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
surf_man->surface_init = &cik_surface_init;
|
||||||
|
surf_man->surface_best = &cik_surface_best;
|
||||||
}
|
}
|
||||||
|
|
||||||
return surf_man;
|
return surf_man;
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#define RADEON_SURF_SCANOUT (1 << 16)
|
#define RADEON_SURF_SCANOUT (1 << 16)
|
||||||
#define RADEON_SURF_ZBUFFER (1 << 17)
|
#define RADEON_SURF_ZBUFFER (1 << 17)
|
||||||
#define RADEON_SURF_SBUFFER (1 << 18)
|
#define RADEON_SURF_SBUFFER (1 << 18)
|
||||||
|
#define RADEON_SURF_Z_OR_SBUFFER (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)
|
||||||
#define RADEON_SURF_HAS_SBUFFER_MIPTREE (1 << 19)
|
#define RADEON_SURF_HAS_SBUFFER_MIPTREE (1 << 19)
|
||||||
#define RADEON_SURF_HAS_TILE_MODE_INDEX (1 << 20)
|
#define RADEON_SURF_HAS_TILE_MODE_INDEX (1 << 20)
|
||||||
#define RADEON_SURF_FMASK (1 << 21)
|
#define RADEON_SURF_FMASK (1 << 21)
|
||||||
|
|
Loading…
Reference in New Issue