mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-25 01:20:11 +01:00
radeon: CS2 make it all work with new relocs style
This commit is contained in:
parent
35f0805592
commit
6000fa6862
2 changed files with 74 additions and 25 deletions
|
|
@ -1242,21 +1242,58 @@ static int radeon_gem_ib_destroy(struct drm_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_gem_find_reloc(struct drm_radeon_cs_parser *parser,
|
||||
uint32_t offset, uint32_t *handle,
|
||||
uint32_t *read_domains, uint32_t *write_domain)
|
||||
{
|
||||
struct drm_device *dev = parser->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
struct drm_radeon_kernel_chunk *reloc_chunk = &parser->chunks[parser->reloc_index];
|
||||
|
||||
if (!reloc_chunk->kdata)
|
||||
return -EINVAL;
|
||||
|
||||
if (offset > reloc_chunk->length_dw){
|
||||
DRM_ERROR("Offset larger than chunk %d %d\n", offset, reloc_chunk->length_dw);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*handle = reloc_chunk->kdata[offset];
|
||||
*read_domains = reloc_chunk->kdata[offset + 1];
|
||||
*write_domain = reloc_chunk->kdata[offset + 2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_gem_relocate(struct drm_radeon_cs_parser *parser,
|
||||
uint32_t *reloc, uint32_t *offset)
|
||||
{
|
||||
struct drm_device *dev = parser->dev;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
/* relocate the handle */
|
||||
uint32_t read_domains = reloc[2];
|
||||
uint32_t write_domain = reloc[3];
|
||||
uint32_t read_domains, write_domain;
|
||||
struct drm_gem_object *obj;
|
||||
int flags = 0;
|
||||
int ret;
|
||||
struct drm_radeon_gem_object *obj_priv;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
if (parser->reloc_index == -1) {
|
||||
obj = drm_gem_object_lookup(dev, parser->file_priv, reloc[1]);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
read_domains = reloc[2];
|
||||
write_domain = reloc[3];
|
||||
} else {
|
||||
uint32_t handle;
|
||||
|
||||
/* have to lookup handle in other chunk */
|
||||
ret = radeon_gem_find_reloc(parser, reloc[1], &handle, &read_domains, &write_domain);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
obj = drm_gem_object_lookup(dev, parser->file_priv, handle);
|
||||
if (!obj)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
obj_priv = obj->driver_private;
|
||||
radeon_gem_set_domain(obj, read_domains, write_domain, &flags, false);
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
|
|||
goto out;
|
||||
}
|
||||
|
||||
parser.dev = dev;
|
||||
parser.file_priv = fpriv;
|
||||
parser.reloc_index = -1;
|
||||
parser.ib_index = -1;
|
||||
parser.num_chunks = cs->num_chunks;
|
||||
|
|
@ -103,24 +105,29 @@ int radeon_cs2_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
|
|||
parser.chunks[i].chunk_data = (uint32_t *)(unsigned long)user_chunk.chunk_data;
|
||||
|
||||
parser.chunks[i].kdata = NULL;
|
||||
size = parser.chunks[i].length_dw * sizeof(uint32_t);
|
||||
|
||||
switch(parser.chunks[i].chunk_id) {
|
||||
case RADEON_CHUNK_ID_RELOCS:
|
||||
case RADEON_CHUNK_ID_IB:
|
||||
case RADEON_CHUNK_ID_OLD: {
|
||||
/* copy from user the relocs chunk */
|
||||
int size = parser.chunks[i].length_dw * sizeof(uint32_t);
|
||||
parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER);
|
||||
if (!parser.chunks[i].kdata) {
|
||||
r = -ENOMEM;
|
||||
case RADEON_CHUNK_ID_OLD:
|
||||
if (size == 0) {
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) {
|
||||
r = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
case RADEON_CHUNK_ID_RELOCS:
|
||||
if (size) {
|
||||
parser.chunks[i].kdata = drm_alloc(size, DRM_MEM_DRIVER);
|
||||
if (!parser.chunks[i].kdata) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (DRM_COPY_FROM_USER(parser.chunks[i].kdata, parser.chunks[i].chunk_data, size)) {
|
||||
r = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
parser.chunks[i].kdata = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -266,6 +273,7 @@ static int radeon_nomm_relocate(struct drm_radeon_cs_parser *parser, uint32_t *r
|
|||
return 0;
|
||||
}
|
||||
#define RELOC_SIZE 2
|
||||
#define RELOC_SIZE_NEW 0
|
||||
#define RADEON_2D_OFFSET_MASK 0x3fffff
|
||||
|
||||
static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
|
||||
|
|
@ -288,9 +296,17 @@ static __inline__ int radeon_cs_relocate_packet0(struct drm_radeon_cs_parser *pa
|
|||
|
||||
/* this is too strict we may want to expand the length in the future and have
|
||||
old kernels ignore it. */
|
||||
if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
|
||||
DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg);
|
||||
return -EINVAL;
|
||||
if (parser->reloc_index == -1) {
|
||||
if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16))) {
|
||||
DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE << 16), reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (packet3_hdr != (RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16))) {
|
||||
DRM_ERROR("Packet 3 was %x should have been %x: reg is %x\n", packet3_hdr, RADEON_CP_PACKET3 | RADEON_CP_NOP | (RELOC_SIZE_NEW << 16), reg);
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
switch(reg) {
|
||||
|
|
@ -371,9 +387,7 @@ static int radeon_cs_relocate_packet3(struct drm_radeon_cs_parser *parser,
|
|||
|
||||
int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = parser->dev->dev_private;
|
||||
uint32_t hdr, num_dw, reg;
|
||||
int need_reloc = 0;
|
||||
int count_dw = 1;
|
||||
int ret;
|
||||
|
||||
|
|
@ -422,8 +436,6 @@ int radeon_cs_packet0(struct drm_radeon_cs_parser *parser, uint32_t offset_dw)
|
|||
|
||||
int radeon_cs_parse(struct drm_radeon_cs_parser *parser)
|
||||
{
|
||||
struct drm_device *dev = parser->dev;
|
||||
drm_radeon_private_t *dev_priv = parser->dev->dev_private;
|
||||
volatile int rb;
|
||||
struct drm_radeon_kernel_chunk *ib_chunk;
|
||||
/* scan the packet for various things */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue