Reviewed-by: Marek Olšák <marek.olsak@xxxxxxx> Marek On Sat, Dec 13, 2014 at 3:32 AM, Glenn Kennard <glenn.kennard@xxxxxxxxx> wrote: > Add the necessary set of commands to support OpenGL > indirect draw calls on evergreen/cayman devices that > do not have VM. > > Signed-off-by: Glenn Kennard <glenn.kennard@xxxxxxxxx> > --- > Changes since patch V1: > * Removed multi draw indirect, not used by current userspace which instead > decomposes multi into separate draw indirect calls > * Added validation to reject cs if indirect draw buffer is too small for address+offset > * Removed useless calls to evergreen_cs_track_check > * Reject attempt to call PACKET3_SET_BASE with other value than indirect draw buffer base for chips using VM. > > I've left the index buffer logic unchanged, outside of scope for this feature, > additional checking of that would be part of support for GL_ARB/KHR_robust_buffer_access_behavior. > > drivers/gpu/drm/radeon/evergreen_cs.c | 76 +++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/radeon/radeon_drv.c | 3 +- > 2 files changed, 78 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c > index 924b1b7..5152c1f 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 %llu + %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 4f50fb0..5d684be 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); > -- > 1.9.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel