Update libdrm to 2.4.51.

ok mpi@ kettenis@
This commit is contained in:
jsg 2014-01-18 08:29:32 +00:00
parent 8722ac84a6
commit dbee37c000
10 changed files with 786 additions and 45 deletions

View File

@ -1,6 +1,6 @@
# $OpenBSD: Makefile.inc,v 1.8 2013/11/21 13:30:07 kettenis Exp $
# $OpenBSD: Makefile.inc,v 1.9 2014/01/18 08:29:32 jsg Exp $
PACKAGE_VERSION= 2.4.47
PACKAGE_VERSION= 2.4.51
NOPROFILE=

View File

@ -248,6 +248,11 @@ int drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
uint32_t offset,
uint64_t *result);
int drm_intel_get_reset_stats(drm_intel_context *ctx,
uint32_t *reset_count,
uint32_t *active,
uint32_t *pending);
/** @{ Compatibility defines to keep old code building despite the symbol rename
* from dri_* to drm_intel_*
*/

View File

@ -151,6 +151,8 @@ struct _drm_intel_bo_gem {
/**
* Kenel-assigned global name for this object
*
* List contains both flink named and prime fd'd objects
*/
unsigned int global_name;
drmMMListHead name_list;
@ -866,10 +868,6 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
}
}
bo_gem = calloc(1, sizeof(*bo_gem));
if (!bo_gem)
return NULL;
VG_CLEAR(open_arg);
open_arg.name = handle;
ret = drmIoctl(bufmgr_gem->fd,
@ -878,9 +876,26 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
if (ret != 0) {
DBG("Couldn't reference %s handle 0x%08x: %s\n",
name, handle, strerror(errno));
free(bo_gem);
return NULL;
}
/* Now see if someone has used a prime handle to get this
* object from the kernel before by looking through the list
* again for a matching gem_handle
*/
for (list = bufmgr_gem->named.next;
list != &bufmgr_gem->named;
list = list->next) {
bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
if (bo_gem->gem_handle == open_arg.handle) {
drm_intel_gem_bo_reference(&bo_gem->bo);
return &bo_gem->bo;
}
}
bo_gem = calloc(1, sizeof(*bo_gem));
if (!bo_gem)
return NULL;
bo_gem->bo.size = open_arg.size;
bo_gem->bo.offset = 0;
bo_gem->bo.virtual = NULL;
@ -1954,12 +1969,14 @@ aub_write_trace_block(drm_intel_bo *bo, uint32_t type, uint32_t subtype,
aub_out(bufmgr_gem,
CMD_AUB_TRACE_HEADER_BLOCK |
(5 - 2));
((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
aub_out(bufmgr_gem,
AUB_TRACE_MEMTYPE_GTT | type | AUB_TRACE_OP_DATA_WRITE);
aub_out(bufmgr_gem, subtype);
aub_out(bufmgr_gem, bo_gem->aub_offset + offset);
aub_out(bufmgr_gem, size);
if (bufmgr_gem->gen >= 8)
aub_out(bufmgr_gem, 0);
aub_write_bo_data(bo, offset, size);
}
@ -2036,20 +2053,28 @@ aub_build_dump_ringbuffer(drm_intel_bufmgr_gem *bufmgr_gem,
/* Make a ring buffer to execute our batchbuffer. */
memset(ringbuffer, 0, sizeof(ringbuffer));
ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START;
ringbuffer[ring_count++] = batch_buffer;
if (bufmgr_gem->gen >= 8) {
ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START | (3 - 2);
ringbuffer[ring_count++] = batch_buffer;
ringbuffer[ring_count++] = 0;
} else {
ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START;
ringbuffer[ring_count++] = batch_buffer;
}
/* Write out the ring. This appears to trigger execution of
* the ring in the simulator.
*/
aub_out(bufmgr_gem,
CMD_AUB_TRACE_HEADER_BLOCK |
(5 - 2));
((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
aub_out(bufmgr_gem,
AUB_TRACE_MEMTYPE_GTT | ring | AUB_TRACE_OP_COMMAND_WRITE);
aub_out(bufmgr_gem, 0); /* general/surface subtype */
aub_out(bufmgr_gem, bufmgr_gem->aub_offset);
aub_out(bufmgr_gem, ring_count * 4);
if (bufmgr_gem->gen >= 8)
aub_out(bufmgr_gem, 0);
/* FIXME: Need some flush operations here? */
aub_out_data(bufmgr_gem, ringbuffer, ring_count * 4);
@ -2455,8 +2480,25 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
uint32_t handle;
drm_intel_bo_gem *bo_gem;
struct drm_i915_gem_get_tiling get_tiling;
drmMMListHead *list;
ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle);
/*
* See if the kernel has already returned this buffer to us. Just as
* for named buffers, we must not create two bo's pointing at the same
* kernel object
*/
for (list = bufmgr_gem->named.next;
list != &bufmgr_gem->named;
list = list->next) {
bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
if (bo_gem->gem_handle == handle) {
drm_intel_gem_bo_reference(&bo_gem->bo);
return &bo_gem->bo;
}
}
if (ret) {
fprintf(stderr,"ret is %d %d\n", ret, errno);
return NULL;
@ -2491,8 +2533,8 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
bo_gem->has_error = false;
bo_gem->reusable = false;
DRMINITLISTHEAD(&bo_gem->name_list);
DRMINITLISTHEAD(&bo_gem->vma_list);
DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
VG_CLEAR(get_tiling);
get_tiling.handle = bo_gem->gem_handle;
@ -2517,6 +2559,9 @@ drm_intel_bo_gem_export_to_prime(drm_intel_bo *bo, int *prime_fd)
drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
if (DRMLISTEMPTY(&bo_gem->name_list))
DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
if (drmPrimeHandleToFD(bufmgr_gem->fd, bo_gem->gem_handle,
DRM_CLOEXEC, prime_fd) != 0)
return -errno;
@ -2546,7 +2591,8 @@ drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
bo_gem->global_name = flink.name;
bo_gem->reusable = false;
DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
if (DRMLISTEMPTY(&bo_gem->name_list))
DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->named);
}
*name = bo_gem->global_name;
@ -2966,11 +3012,13 @@ drm_intel_bufmgr_gem_set_aub_dump(drm_intel_bufmgr *bufmgr, int enable)
aub_out(bufmgr_gem, 0); /* comment len */
/* Set up the GTT. The max we can handle is 256M */
aub_out(bufmgr_gem, CMD_AUB_TRACE_HEADER_BLOCK | (5 - 2));
aub_out(bufmgr_gem, CMD_AUB_TRACE_HEADER_BLOCK | ((bufmgr_gem->gen >= 8 ? 6 : 5) - 2));
aub_out(bufmgr_gem, AUB_TRACE_MEMTYPE_NONLOCAL | 0 | AUB_TRACE_OP_DATA_WRITE);
aub_out(bufmgr_gem, 0); /* subtype */
aub_out(bufmgr_gem, 0); /* offset */
aub_out(bufmgr_gem, gtt_size); /* size */
if (bufmgr_gem->gen >= 8)
aub_out(bufmgr_gem, 0);
for (i = 0x000; i < gtt_size; i += 4, entry += 0x1000) {
aub_out(bufmgr_gem, entry);
}
@ -3022,6 +3070,40 @@ drm_intel_gem_context_destroy(drm_intel_context *ctx)
free(ctx);
}
int
drm_intel_get_reset_stats(drm_intel_context *ctx,
uint32_t *reset_count,
uint32_t *active,
uint32_t *pending)
{
drm_intel_bufmgr_gem *bufmgr_gem;
struct drm_i915_reset_stats stats;
int ret;
if (ctx == NULL)
return -EINVAL;
memset(&stats, 0, sizeof(stats));
bufmgr_gem = (drm_intel_bufmgr_gem *)ctx->bufmgr;
stats.ctx_id = ctx->ctx_id;
ret = drmIoctl(bufmgr_gem->fd,
DRM_IOCTL_I915_GET_RESET_STATS,
&stats);
if (ret == 0) {
if (reset_count != NULL)
*reset_count = stats.reset_count;
if (active != NULL)
*active = stats.batch_active;
if (pending != NULL)
*pending = stats.batch_pending;
}
return ret;
}
int
drm_intel_reg_read(drm_intel_bufmgr *bufmgr,
uint32_t offset,
@ -3140,6 +3222,8 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
bufmgr_gem->gen = 6;
else if (IS_GEN7(bufmgr_gem->pci_device))
bufmgr_gem->gen = 7;
else if (IS_GEN8(bufmgr_gem->pci_device))
bufmgr_gem->gen = 8;
else {
free(bufmgr_gem);
return NULL;

View File

@ -148,6 +148,12 @@
#define PCI_CHIP_HASWELL_CRW_E_GT1 0x0D0E /* Reserved */
#define PCI_CHIP_HASWELL_CRW_E_GT2 0x0D1E
#define PCI_CHIP_HASWELL_CRW_E_GT3 0x0D2E
#define BDW_SPARE 0x2
#define BDW_ULT 0x6
#define BDW_SERVER 0xa
#define BDW_IRIS 0xb
#define BDW_WORKSTATION 0xd
#define BDW_ULX 0xe
#define PCI_CHIP_VALLEYVIEW_PO 0x0f30 /* VLV PO board */
#define PCI_CHIP_VALLEYVIEW_1 0x0f31
@ -296,10 +302,24 @@
IS_HSW_GT2(devid) || \
IS_HSW_GT3(devid))
#define IS_BROADWELL(devid) (((devid & 0xff00) != 0x1600) ? 0 : \
(((devid & 0x00f0) >> 4) > 3) ? 0 : \
((devid & 0x000f) == BDW_SPARE) ? 1 : \
((devid & 0x000f) == BDW_ULT) ? 1 : \
((devid & 0x000f) == BDW_IRIS) ? 1 : \
((devid & 0x000f) == BDW_SERVER) ? 1 : \
((devid & 0x000f) == BDW_WORKSTATION) ? 1 : \
((devid & 0x000f) == BDW_ULX) ? 1 : 0)
#define IS_GEN8(devid) IS_BROADWELL(devid)
#define IS_9XX(dev) (IS_GEN3(dev) || \
IS_GEN4(dev) || \
IS_GEN5(dev) || \
IS_GEN6(dev) || \
IS_GEN7(dev))
IS_GEN7(dev) || \
IS_GEN8(dev))
#endif /* _INTEL_CHIPSET_H */

View File

@ -257,6 +257,8 @@ decode_mi(struct drm_intel_decode *ctx)
{ 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT", decode_MI_WAIT_FOR_EVENT },
{ 0x16, 0x7f, 3, 3, "MI_SEMAPHORE_MBOX" },
{ 0x26, 0x1f, 3, 4, "MI_FLUSH_DW" },
{ 0x28, 0x3f, 3, 3, "MI_REPORT_PERF_COUNT" },
{ 0x29, 0xff, 3, 3, "MI_LOAD_REGISTER_MEM" },
{ 0x0b, 0, 1, 1, "MI_SUSPEND_FLUSH"},
}, *opcode_mi = NULL;
@ -3825,7 +3827,9 @@ drm_intel_decode_context_alloc(uint32_t devid)
ctx->devid = devid;
ctx->out = stdout;
if (IS_GEN7(devid))
if (IS_GEN8(devid))
ctx->gen = 8;
else if (IS_GEN7(devid))
ctx->gen = 7;
else if (IS_GEN6(devid))
ctx->gen = 6;

View File

@ -1,2 +1,2 @@
major=3
minor=0
minor=1

View File

@ -208,7 +208,7 @@ CHIPSET(0x9644, SUMO2_9644, SUMO2)
CHIPSET(0x9645, SUMO2_9645, SUMO2)
CHIPSET(0x9647, SUMO_9647, SUMO)
CHIPSET(0x9648, SUMO_9648, SUMO)
CHIPSET(0x9649, SUMO_9649, SUMO)
CHIPSET(0x9649, SUMO2_9649, SUMO2)
CHIPSET(0x964a, SUMO_964A, SUMO)
CHIPSET(0x964b, SUMO_964B, SUMO)
CHIPSET(0x964c, SUMO_964C, SUMO)
@ -446,3 +446,16 @@ CHIPSET(0x1317, KAVERI_1317, KAVERI)
CHIPSET(0x131B, KAVERI_131B, KAVERI)
CHIPSET(0x131C, KAVERI_131C, KAVERI)
CHIPSET(0x131D, KAVERI_131D, KAVERI)
CHIPSET(0x67A0, HAWAII_67A0, HAWAII)
CHIPSET(0x67A1, HAWAII_67A1, HAWAII)
CHIPSET(0x67A2, HAWAII_67A2, HAWAII)
CHIPSET(0x67A8, HAWAII_67A8, HAWAII)
CHIPSET(0x67A9, HAWAII_67A9, HAWAII)
CHIPSET(0x67AA, HAWAII_67AA, HAWAII)
CHIPSET(0x67B0, HAWAII_67B0, HAWAII)
CHIPSET(0x67B1, HAWAII_67B1, HAWAII)
CHIPSET(0x67B8, HAWAII_67B8, HAWAII)
CHIPSET(0x67B9, HAWAII_67B9, HAWAII)
CHIPSET(0x67BA, HAWAII_67BA, HAWAII)
CHIPSET(0x67BE, HAWAII_67BE, HAWAII)

View File

@ -26,6 +26,8 @@
* Authors:
* Jérôme Glisse <jglisse@redhat.com>
*/
#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -77,6 +79,7 @@ enum radeon_family {
CHIP_BONAIRE,
CHIP_KAVERI,
CHIP_KABINI,
CHIP_HAWAII,
CHIP_LAST,
};
@ -95,6 +98,8 @@ struct radeon_hw_info {
unsigned allow_2d;
/* apply to si */
uint32_t tile_mode_array[32];
/* apply to cik */
uint32_t macrotile_mode_array[16];
};
struct radeon_surface_manager {
@ -650,7 +655,7 @@ static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
tileb = tilew * tileh * bpe * surf->nsamples;
/* slices per tile */
slice_pt = 1;
if (tileb > tile_split) {
if (tileb > tile_split && tile_split) {
slice_pt = tileb / tile_split;
}
tileb = tileb / slice_pt;
@ -1382,16 +1387,10 @@ static int si_surface_sanity(struct radeon_surface_manager *surf_man,
break;
case RADEON_SURF_MODE_1D:
if (surf->flags & RADEON_SURF_SBUFFER) {
if (surf_man->family >= CHIP_BONAIRE)
*stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
else
*stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
*stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
}
if (surf->flags & RADEON_SURF_ZBUFFER) {
if (surf_man->family >= CHIP_BONAIRE)
*tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
else
*tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
*tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
} else if (surf->flags & RADEON_SURF_SCANOUT) {
*tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
} else {
@ -1437,16 +1436,17 @@ static void si_surf_minify(struct radeon_surface *surf,
*/
if (level == 0 && surf->last_level == 0)
/* Non-mipmap pitch padded to slice alignment */
/* Using just bpe here breaks stencil blitting; surf->bpe works. */
xalign = MAX2(xalign, slice_align / surf->bpe);
else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
/* Small rows evenly distributed across slice */
xalign = MAX2(xalign, slice_align / surf->bpe / surflevel->nblk_y);
xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
surflevel->offset = offset;
surflevel->pitch_bytes = surflevel->nblk_x * surf->bpe * surf->nsamples;
surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
@ -1540,6 +1540,7 @@ static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
uint64_t offset, unsigned start_level)
{
uint32_t xalign, yalign, zalign, slice_align;
unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
unsigned i;
/* compute alignment */
@ -1551,11 +1552,11 @@ static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
}
if (!start_level) {
surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
if (start_level <= 1) {
surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
if (offset) {
offset = ALIGN(offset, surf->bo_alignment);
offset = ALIGN(offset, alignment);
}
}
@ -1566,7 +1567,7 @@ static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
/* level0 and first mipmap need to have alignment */
offset = surf->bo_size;
if ((i == 0)) {
offset = ALIGN(offset, surf->bo_alignment);
offset = ALIGN(offset, alignment);
}
if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
if (surf->level == level) {
@ -1608,6 +1609,7 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
uint64_t offset,
unsigned start_level)
{
uint64_t aligned_offset = offset;
unsigned tilew, tileh, tileb;
unsigned mtilew, mtileh, mtileb;
unsigned slice_pt;
@ -1619,7 +1621,7 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
tileb = tilew * tileh * bpe * surf->nsamples;
/* slices per tile */
slice_pt = 1;
if (tileb > tile_split) {
if (tileb > tile_split && tile_split) {
slice_pt = tileb / tile_split;
}
tileb = tileb / slice_pt;
@ -1631,19 +1633,19 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
/* macro tile bytes */
mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
if (!start_level) {
if (start_level <= 1) {
unsigned alignment = MAX2(256, mtileb);
surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
if (offset) {
offset = ALIGN(offset, 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, offset);
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 SI_TILE_MODE_COLOR_2D_8BPP:
@ -1657,10 +1659,7 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
break;
case SI_TILE_MODE_DEPTH_STENCIL_2D:
if (surf_man->family >= CHIP_BONAIRE)
tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
else
tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
break;
default:
return -EINVAL;
@ -1668,9 +1667,9 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
}
/* level0 and first mipmap need to have alignment */
offset = surf->bo_size;
aligned_offset = offset = surf->bo_size;
if ((i == 0)) {
offset = ALIGN(offset, surf->bo_alignment);
aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
}
if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
if (surf->level == level) {
@ -1788,6 +1787,610 @@ 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__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
#define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
#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;
case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
*num_pipes = 16;
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 && 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
*/
@ -1819,12 +2422,18 @@ struct radeon_surface_manager *radeon_surface_manager_new(int fd)
}
surf_man->surface_init = &eg_surface_init;
surf_man->surface_best = &eg_surface_best;
} else {
} else if (surf_man->family < CHIP_BONAIRE) {
if (si_init_hw_info(surf_man)) {
goto out_err;
}
surf_man->surface_init = &si_surface_init;
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;

View File

@ -54,6 +54,7 @@
#define RADEON_SURF_SCANOUT (1 << 16)
#define RADEON_SURF_ZBUFFER (1 << 17)
#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_TILE_MODE_INDEX (1 << 20)
#define RADEON_SURF_FMASK (1 << 21)

View File

@ -128,6 +128,8 @@ extern "C" {
#define DRM_MODE_ENCODER_TMDS 2
#define DRM_MODE_ENCODER_LVDS 3
#define DRM_MODE_ENCODER_TVDAC 4
#define DRM_MODE_ENCODER_VIRTUAL 5
#define DRM_MODE_ENCODER_DSI 6
#define DRM_MODE_SUBCONNECTOR_Automatic 0
#define DRM_MODE_SUBCONNECTOR_Unknown 0
@ -136,6 +138,7 @@ extern "C" {
#define DRM_MODE_SUBCONNECTOR_Composite 5
#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
#define DRM_MODE_SUBCONNECTOR_Component 8
#define DRM_MODE_SUBCONNECTOR_SCART 9
#define DRM_MODE_CONNECTOR_Unknown 0
#define DRM_MODE_CONNECTOR_VGA 1
@ -152,6 +155,8 @@ extern "C" {
#define DRM_MODE_CONNECTOR_HDMIB 12
#define DRM_MODE_CONNECTOR_TV 13
#define DRM_MODE_CONNECTOR_eDP 14
#define DRM_MODE_CONNECTOR_VIRTUAL 15
#define DRM_MODE_CONNECTOR_DSI 16
#define DRM_MODE_PROP_PENDING (1<<0)
#define DRM_MODE_PROP_RANGE (1<<1)