mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-09 08:38:23 +02:00
radeon: add space accounting to cs code
This commit is contained in:
parent
2e3f86c2a0
commit
aa5612d308
3 changed files with 140 additions and 1 deletions
|
|
@ -52,6 +52,7 @@ struct radeon_bo {
|
|||
#endif
|
||||
void *ptr;
|
||||
struct radeon_bo_manager *bom;
|
||||
uint32_t space_accounted;
|
||||
};
|
||||
|
||||
/* bo functions */
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#define RADEON_CS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "drm.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon_bo.h"
|
||||
|
||||
struct radeon_cs_reloc {
|
||||
|
|
@ -42,6 +44,18 @@ struct radeon_cs_reloc {
|
|||
uint32_t flags;
|
||||
};
|
||||
|
||||
|
||||
#define RADEON_CS_SPACE_OK 0
|
||||
#define RADEON_CS_SPACE_OP_TO_BIG 1
|
||||
#define RADEON_CS_SPACE_FLUSH 2
|
||||
|
||||
struct radeon_cs_space_check {
|
||||
struct radeon_bo *bo;
|
||||
uint32_t read_domains;
|
||||
uint32_t write_domain;
|
||||
uint32_t new_accounted;
|
||||
};
|
||||
|
||||
struct radeon_cs_manager;
|
||||
|
||||
struct radeon_cs {
|
||||
|
|
@ -58,6 +72,7 @@ struct radeon_cs {
|
|||
const char *section_file;
|
||||
const char *section_func;
|
||||
int section_line;
|
||||
|
||||
};
|
||||
|
||||
/* cs functions */
|
||||
|
|
@ -84,11 +99,16 @@ struct radeon_cs_funcs {
|
|||
int (*cs_erase)(struct radeon_cs *cs);
|
||||
int (*cs_need_flush)(struct radeon_cs *cs);
|
||||
void (*cs_print)(struct radeon_cs *cs, FILE *file);
|
||||
int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos,
|
||||
int num_bo);
|
||||
};
|
||||
|
||||
struct radeon_cs_manager {
|
||||
struct radeon_cs_funcs *funcs;
|
||||
int fd;
|
||||
uint32_t vram_limit, gart_limit;
|
||||
uint32_t vram_write_used, gart_write_used;
|
||||
uint32_t read_used;
|
||||
};
|
||||
|
||||
static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
|
||||
|
|
@ -157,4 +177,19 @@ static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file)
|
|||
cs->csm->funcs->cs_print(cs, file);
|
||||
}
|
||||
|
||||
static inline int radeon_cs_space_check(struct radeon_cs *cs,
|
||||
struct radeon_cs_space_check *bos,
|
||||
int num_bo)
|
||||
{
|
||||
return cs->csm->funcs->cs_space_check(cs, bos, num_bo);
|
||||
}
|
||||
|
||||
static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
|
||||
{
|
||||
|
||||
if (domain == RADEON_GEM_DOMAIN_VRAM)
|
||||
cs->csm->vram_limit = limit;
|
||||
else
|
||||
cs->csm->gart_limit = limit;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -229,6 +229,16 @@ static int cs_gem_end(struct radeon_cs *cs,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void dump_cmdbuf(struct radeon_cs *cs)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < cs->cdw; i++){
|
||||
fprintf(stderr,"%x: %08x\n", i, cs->packets[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int cs_gem_emit(struct radeon_cs *cs)
|
||||
{
|
||||
struct cs_gem *csg = (struct cs_gem*)cs;
|
||||
|
|
@ -236,6 +246,7 @@ static int cs_gem_emit(struct radeon_cs *cs)
|
|||
unsigned i;
|
||||
int r;
|
||||
|
||||
dump_cmdbuf(cs);
|
||||
csg->chunks[0].length_dw = cs->cdw;
|
||||
|
||||
chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0];
|
||||
|
|
@ -387,6 +398,97 @@ static void cs_gem_print(struct radeon_cs *cs, FILE *file)
|
|||
}
|
||||
}
|
||||
|
||||
static int cs_gem_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo)
|
||||
{
|
||||
struct radeon_cs_manager *csm = cs->csm;
|
||||
int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0;
|
||||
uint32_t read_domains, write_domain;
|
||||
int i;
|
||||
struct radeon_bo *bo;
|
||||
|
||||
/* check the totals for this operation */
|
||||
|
||||
if (num_bo == 0)
|
||||
return 0;
|
||||
|
||||
/* prepare */
|
||||
for (i = 0; i < num_bo; i++) {
|
||||
bo = bos[i].bo;
|
||||
|
||||
bos[i].new_accounted = 0;
|
||||
read_domains = bos[i].read_domains;
|
||||
write_domain = bos[i].write_domain;
|
||||
|
||||
/* already accounted this bo */
|
||||
if (write_domain && (write_domain == bo->space_accounted))
|
||||
continue;
|
||||
|
||||
if (read_domains && ((read_domains << 16) == bo->space_accounted))
|
||||
continue;
|
||||
|
||||
if (bo->space_accounted == 0) {
|
||||
if (write_domain == RADEON_GEM_DOMAIN_VRAM)
|
||||
this_op_vram_write += bo->size;
|
||||
else if (write_domain == RADEON_GEM_DOMAIN_GTT)
|
||||
this_op_gart_write += bo->size;
|
||||
else
|
||||
this_op_read += bo->size;
|
||||
bos[i].new_accounted = (read_domains << 16) | write_domain;
|
||||
} else {
|
||||
uint16_t old_read, old_write;
|
||||
|
||||
old_read = bo->space_accounted >> 16;
|
||||
old_write = bo->space_accounted & 0xffff;
|
||||
|
||||
if (write_domain && (old_read & write_domain)) {
|
||||
bos[i].new_accounted = write_domain;
|
||||
/* moving from read to a write domain */
|
||||
if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
|
||||
this_op_read -= bo->size;
|
||||
this_op_vram_write += bo->size;
|
||||
} else if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
|
||||
this_op_read -= bo->size;
|
||||
this_op_gart_write += bo->size;
|
||||
}
|
||||
} else if (read_domains & old_write) {
|
||||
bos[i].new_accounted = bo->space_accounted & 0xffff;
|
||||
} else {
|
||||
/* rewrite the domains */
|
||||
if (write_domain != old_write)
|
||||
fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
|
||||
if (read_domains != old_read)
|
||||
fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
|
||||
return RADEON_CS_SPACE_FLUSH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this_op_read < 0)
|
||||
this_op_read = 0;
|
||||
|
||||
/* check sizes - operation first */
|
||||
if ((this_op_read + this_op_gart_write > csm->gart_limit) ||
|
||||
(this_op_vram_write > csm->vram_limit)) {
|
||||
return RADEON_CS_SPACE_OP_TO_BIG;
|
||||
}
|
||||
|
||||
if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) ||
|
||||
((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) {
|
||||
return RADEON_CS_SPACE_FLUSH;
|
||||
}
|
||||
|
||||
csm->gart_write_used += this_op_gart_write;
|
||||
csm->vram_write_used += this_op_vram_write;
|
||||
csm->read_used += this_op_read;
|
||||
/* commit */
|
||||
for (i = 0; i < num_bo; i++) {
|
||||
bo = bos[i].bo;
|
||||
bo->space_accounted = bos[i].new_accounted;
|
||||
}
|
||||
|
||||
return RADEON_CS_SPACE_OK;
|
||||
}
|
||||
|
||||
static struct radeon_cs_funcs radeon_cs_gem_funcs = {
|
||||
cs_gem_create,
|
||||
cs_gem_write_dword,
|
||||
|
|
@ -397,7 +499,8 @@ static struct radeon_cs_funcs radeon_cs_gem_funcs = {
|
|||
cs_gem_destroy,
|
||||
cs_gem_erase,
|
||||
cs_gem_need_flush,
|
||||
cs_gem_print
|
||||
cs_gem_print,
|
||||
cs_gem_check_space,
|
||||
};
|
||||
|
||||
struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue