* Jérôme Glisse <glisse@freedesktop.org>
*/
#include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+#include "drm.h"
+#include "radeon_drm.h"
#include "radeon_bocs_wrapper.h"
-
+#include "radeon_common.h"
+#ifdef HAVE_LIBDRM_RADEON
+#include "radeon_cs_int.h"
+#else
+#include "radeon_cs_int_drm.h"
+#endif
struct cs_manager_legacy {
struct radeon_cs_manager base;
struct radeon_context *ctx;
};
-static struct radeon_cs *cs_create(struct radeon_cs_manager *csm,
- uint32_t ndw)
+static struct radeon_cs_int *cs_create(struct radeon_cs_manager *csm,
+ uint32_t ndw)
{
- struct radeon_cs *cs;
+ struct radeon_cs_int *csi;
- cs = (struct radeon_cs*)calloc(1, sizeof(struct radeon_cs));
- if (cs == NULL) {
+ csi = (struct radeon_cs_int*)calloc(1, sizeof(struct radeon_cs_int));
+ if (csi == NULL) {
return NULL;
}
- cs->csm = csm;
- cs->ndw = (ndw + 0x3FF) & (~0x3FF);
- cs->packets = (uint32_t*)malloc(4*cs->ndw);
- if (cs->packets == NULL) {
- free(cs);
+ csi->csm = csm;
+ csi->ndw = (ndw + 0x3FF) & (~0x3FF);
+ csi->packets = (uint32_t*)malloc(4*csi->ndw);
+ if (csi->packets == NULL) {
+ free(csi);
return NULL;
}
- cs->relocs_total_size = 0;
- return cs;
+ csi->relocs_total_size = 0;
+ return csi;
}
-static int cs_write_reloc(struct radeon_cs *cs,
+static int cs_write_reloc(struct radeon_cs_int *cs,
struct radeon_bo *bo,
uint32_t read_domain,
uint32_t write_domain,
return 0;
}
-static int cs_begin(struct radeon_cs *cs,
+static int cs_begin(struct radeon_cs_int *cs,
uint32_t ndw,
const char *file,
const char *func,
int line)
{
- if (cs->section) {
+ if (cs->section_ndw) {
fprintf(stderr, "CS already in a section(%s,%s,%d)\n",
cs->section_file, cs->section_func, cs->section_line);
fprintf(stderr, "CS can't start section(%s,%s,%d)\n",
file, func, line);
return -EPIPE;
}
- cs->section = 1;
cs->section_ndw = ndw;
cs->section_cdw = 0;
cs->section_file = file;
if (cs->cdw + ndw > cs->ndw) {
uint32_t tmp, *ptr;
- int num = (ndw > 0x3FF) ? ndw : 0x3FF;
- tmp = (cs->cdw + 1 + num) & (~num);
+ tmp = (cs->cdw + ndw + 0x3ff) & (~0x3ff);
ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
if (ptr == NULL) {
return -ENOMEM;
return 0;
}
-static int cs_end(struct radeon_cs *cs,
+static int cs_end(struct radeon_cs_int *cs,
const char *file,
const char *func,
int line)
{
- if (!cs->section) {
+ if (!cs->section_ndw) {
fprintf(stderr, "CS no section to end at (%s,%s,%d)\n",
file, func, line);
return -EPIPE;
}
- cs->section = 0;
if (cs->section_ndw != cs->section_cdw) {
fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
file, func, line);
return -EPIPE;
}
+ cs->section_ndw = 0;
+
return 0;
}
-static int cs_process_relocs(struct radeon_cs *cs)
+static int cs_process_relocs(struct radeon_cs_int *cs)
{
- struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
struct cs_reloc_legacy *relocs;
int i, j, r;
- csm = (struct cs_manager_legacy*)cs->csm;
relocs = (struct cs_reloc_legacy *)cs->relocs;
- restart:
- for (i = 0; i < cs->crelocs; i++) {
- for (j = 0; j < relocs[i].cindices; j++) {
+restart:
+ for (i = 0; i < cs->crelocs; i++)
+ {
+ for (j = 0; j < relocs[i].cindices; j++)
+ {
uint32_t soffset, eoffset;
r = radeon_bo_legacy_validate(relocs[i].base.bo,
&soffset, &eoffset);
- if (r == -EAGAIN)
- goto restart;
- if (r) {
+ if (r == -EAGAIN)
+ {
+ goto restart;
+ }
+ if (r)
+ {
fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
relocs[i].base.bo, soffset, eoffset);
return r;
}
cs->packets[relocs[i].indices[j]] += soffset;
- if (cs->packets[relocs[i].indices[j]] >= eoffset) {
+ if (cs->packets[relocs[i].indices[j]] >= eoffset)
+ {
/* radeon_bo_debug(relocs[i].base.bo, 12); */
fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
relocs[i].base.bo, soffset, eoffset);
return 0;
}
-static int cs_set_age(struct radeon_cs *cs)
+static int cs_set_age(struct radeon_cs_int *cs)
{
struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
struct cs_reloc_legacy *relocs;
return 0;
}
-static int cs_emit(struct radeon_cs *cs)
+static int cs_emit(struct radeon_cs_int *cs)
{
struct cs_manager_legacy *csm = (struct cs_manager_legacy*)cs->csm;
drm_radeon_cmd_buffer_t cmd;
uint64_t ull;
int r;
- csm->ctx->vtbl.emit_cs_header(cs, csm->ctx);
+ csm->ctx->vtbl.emit_cs_header((struct radeon_cs *)cs, csm->ctx);
/* append buffer age */
- if (IS_R300_CLASS(csm->ctx->radeonScreen)) {
+ if ( IS_R300_CLASS(csm->ctx->radeonScreen) )
+ {
age.scratch.cmd_type = R300_CMD_SCRATCH;
/* Scratch register 2 corresponds to what radeonGetAge polls */
csm->pending_age = 0;
age.scratch.reg = 2;
age.scratch.n_bufs = 1;
age.scratch.flags = 0;
- radeon_cs_write_dword(cs, age.u);
- radeon_cs_write_qword(cs, ull);
- radeon_cs_write_dword(cs, 0);
+ radeon_cs_write_dword((struct radeon_cs *)cs, age.u);
+ radeon_cs_write_qword((struct radeon_cs *)cs, ull);
+ radeon_cs_write_dword((struct radeon_cs *)cs, 0);
}
r = cs_process_relocs(cs);
if (r) {
return r;
}
- if (!IS_R300_CLASS(csm->ctx->radeonScreen)) {
+ if ((!IS_R300_CLASS(csm->ctx->radeonScreen)) &&
+ (!IS_R600_CLASS(csm->ctx->radeonScreen))) { /* +r6/r7 : No irq for r6/r7 yet. */
drm_radeon_irq_emit_t emit_cmd;
- emit_cmd.irq_seq = &csm->pending_age;
- r = drmCommandWrite(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd));
+ emit_cmd.irq_seq = (int*)&csm->pending_age;
+ r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd));
if (r) {
return r;
}
free(relocs[i].indices);
}
-static int cs_destroy(struct radeon_cs *cs)
+static int cs_destroy(struct radeon_cs_int *cs)
{
cs_free_reloc(cs->relocs, cs->crelocs);
free(cs->relocs);
return 0;
}
-static int cs_erase(struct radeon_cs *cs)
+static int cs_erase(struct radeon_cs_int *cs)
{
cs_free_reloc(cs->relocs, cs->crelocs);
free(cs->relocs);
cs->relocs = NULL;
cs->crelocs = 0;
cs->cdw = 0;
- cs->section = 0;
+ cs->section_ndw = 0;
return 0;
}
-static int cs_need_flush(struct radeon_cs *cs)
+static int cs_need_flush(struct radeon_cs_int *cs)
{
/* this function used to flush when the BO usage got to
* a certain size, now the higher levels handle this better */
return 0;
}
-static void cs_print(struct radeon_cs *cs, FILE *file)
+static void cs_print(struct radeon_cs_int *cs, FILE *file)
{
}
-static int cs_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;
-
- /* pinned bos don't count */
- if (radeon_legacy_bo_is_static(bo))
- continue;
-
- /* 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_legacy_funcs = {
cs_create,
cs_write_reloc,
cs_erase,
cs_need_flush,
cs_print,
- cs_check_space
};
struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx)