From: Glenn Kennard Date: Sat, 13 Dec 2014 02:32:37 +0000 (+0100) Subject: drm/radeon: evergreen/cayman indirect draw support (v2) X-Git-Tag: v4.0-rc1~74^2~28^2~44 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=16613743adaf7989151da2e58fef2a71624875ab;p=karo-tx-linux.git drm/radeon: evergreen/cayman indirect draw support (v2) Add the necessary set of commands to support OpenGL indirect draw calls on evergreen/cayman devices that do not have VM. v2: agd5f: fix warning on 32-bit Reviewed-by: Marek Olšák Signed-off-by: Glenn Kennard Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 924b1b7ab455..c9e0fbbf76a3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -83,6 +83,7 @@ struct evergreen_cs_track { u32 htile_offset; u32 htile_surface; struct radeon_bo *htile_bo; + unsigned long indirect_draw_buffer_size; }; static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) @@ -1896,6 +1897,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, } break; } + case PACKET3_INDEX_BUFFER_SIZE: + { + if (pkt->count != 0) { + DRM_ERROR("bad INDEX_BUFFER_SIZE\n"); + return -EINVAL; + } + break; + } case PACKET3_DRAW_INDEX: { uint64_t offset; @@ -2006,6 +2015,67 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, return r; } break; + case PACKET3_SET_BASE: + { + /* + DW 1 HEADER Header of the packet. Shader_Type in bit 1 of the Header will correspond to the shader type of the Load, see Type-3 Packet. + 2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies which base address is specified in the last two DWs. + 0001: DX11 Draw_Index_Indirect Patch Table Base: Base address for Draw_Index_Indirect data. + 3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned Address. Bits [2:0] - Reserved + 4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits of Address [47:32] + */ + if (pkt->count != 2) { + DRM_ERROR("bad SET_BASE\n"); + return -EINVAL; + } + + /* currently only supporting setting indirect draw buffer base address */ + if (idx_value != 1) { + DRM_ERROR("bad SET_BASE\n"); + return -EINVAL; + } + + r = radeon_cs_packet_next_reloc(p, &reloc, 0); + if (r) { + DRM_ERROR("bad SET_BASE\n"); + return -EINVAL; + } + + track->indirect_draw_buffer_size = radeon_bo_size(reloc->robj); + + ib[idx+1] = reloc->gpu_offset; + ib[idx+2] = upper_32_bits(reloc->gpu_offset) & 0xff; + + break; + } + case PACKET3_DRAW_INDIRECT: + case PACKET3_DRAW_INDEX_INDIRECT: + { + u64 size = pkt->opcode == PACKET3_DRAW_INDIRECT ? 16 : 20; + + /* + DW 1 HEADER + 2 DATA_OFFSET Bits [31:0] + byte aligned offset where the required data structure starts. Bits 1:0 are zero + 3 DRAW_INITIATOR Draw Initiator Register. Written to the VGT_DRAW_INITIATOR register for the assigned context + */ + if (pkt->count != 1) { + DRM_ERROR("bad DRAW_INDIRECT\n"); + return -EINVAL; + } + + if (idx_value + size > track->indirect_draw_buffer_size) { + dev_warn(p->dev, "DRAW_INDIRECT buffer too small %u + %llu > %lu\n", + idx_value, size, track->indirect_draw_buffer_size); + return -EINVAL; + } + + r = evergreen_cs_track_check(p); + if (r) { + dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); + return r; + } + break; + } case PACKET3_DISPATCH_DIRECT: if (pkt->count != 3) { DRM_ERROR("bad DISPATCH_DIRECT\n"); @@ -3243,7 +3313,13 @@ static int evergreen_vm_packet3_check(struct radeon_device *rdev, switch (pkt->opcode) { case PACKET3_NOP: + break; case PACKET3_SET_BASE: + if (idx_value != 1) { + DRM_ERROR("bad SET_BASE"); + return -EINVAL; + } + break; case PACKET3_CLEAR_STATE: case PACKET3_INDEX_BUFFER_SIZE: case PACKET3_DISPATCH_DIRECT: diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4f50fb0e3d93..5d684beb48d3 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -88,9 +88,10 @@ * 2.39.0 - Add INFO query for number of active CUs * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting * CS to GPU on >= r600 + * 2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing support */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 40 +#define KMS_DRIVER_MINOR 41 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev);