summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-07-05 18:35:19 +1000
committerDave Airlie <airlied@redhat.com>2010-07-06 09:06:25 +1000
commitd8ef7c15dedd6cbb48a6866131f6a9a15e627e12 (patch)
tree7f84e4ce3cc0459cfeb9e0bd474b972d685dafd4
parentb803918f3f77c62edf22e78cb2095be399753423 (diff)
radeon: add support to libdrm for alternative start buffer.
-rw-r--r--include/drm/radeon_drm.h4
-rw-r--r--radeon/radeon_cs_gem.c48
-rw-r--r--radeon/radeon_cs_gem.h3
3 files changed, 50 insertions, 5 deletions
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index ff97e484..42409daa 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -874,6 +874,7 @@ struct drm_radeon_gem_pwrite {
#define RADEON_CHUNK_ID_RELOCS 0x01
#define RADEON_CHUNK_ID_IB 0x02
+#define RADEON_CHUNK_ID_IB_SETUP 0x03
struct drm_radeon_cs_chunk {
uint32_t chunk_id;
@@ -902,6 +903,9 @@ struct drm_radeon_cs {
#define RADEON_INFO_NUM_GB_PIPES 0x01
#define RADEON_INFO_NUM_Z_PIPES 0x02
#define RADEON_INFO_ACCEL_WORKING 0x03
+#define RADEON_INFO_CRTC_FROM_ID 0x04
+#define RADEON_INFO_ACCEL_WORKING2 0x05
+#define RADEON_INFO_HAVE_IB_SETUP 0x06
struct drm_radeon_info {
uint32_t request;
diff --git a/radeon/radeon_cs_gem.c b/radeon/radeon_cs_gem.c
index 81bd3939..e0cdbaa2 100644
--- a/radeon/radeon_cs_gem.c
+++ b/radeon/radeon_cs_gem.c
@@ -69,10 +69,11 @@ struct cs_reloc_gem {
struct cs_gem {
struct radeon_cs_int base;
struct drm_radeon_cs cs;
- struct drm_radeon_cs_chunk chunks[2];
+ struct drm_radeon_cs_chunk chunks[3];
unsigned nrelocs;
uint32_t *relocs;
struct radeon_bo_int **relocs_bo;
+ struct radeon_cs alt;
};
static pthread_mutex_t id_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -119,8 +120,19 @@ static void free_id(uint32_t id)
pthread_mutex_unlock( &id_mutex );
}
-static struct radeon_cs_int *cs_gem_create(struct radeon_cs_manager *csm,
- uint32_t ndw)
+void radeon_cs_gem_switch_alt(struct radeon_cs *cs)
+{
+ struct cs_gem *csg = (struct cs_gem*)cs;
+ struct radeon_cs tmp;
+
+ /* swap alt and tmp */
+ tmp = *cs;
+ *cs = csg->alt;
+ csg->alt = tmp;
+}
+
+struct radeon_cs *radeon_cs_gem_create_setup(struct radeon_cs_manager *csm,
+ uint32_t ndw, uint32_t setup_ndw)
{
struct cs_gem *csg;
@@ -157,13 +169,28 @@ static struct radeon_cs_int *cs_gem_create(struct radeon_cs_manager *csm,
free(csg);
return NULL;
}
+ csg->alt.ndw = setup_ndw;
+ csg->alt.packets = (uint32_t*)calloc(1, 4*1024);
+ if (csg->alt.packets == NULL) {
+ free(csg);
+ return NULL;
+ }
csg->chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
csg->chunks[0].length_dw = 0;
csg->chunks[0].chunk_data = (uint64_t)(uintptr_t)csg->base.packets;
csg->chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
csg->chunks[1].length_dw = 0;
csg->chunks[1].chunk_data = (uint64_t)(uintptr_t)csg->relocs;
- return (struct radeon_cs_int*)csg;
+ csg->chunks[2].chunk_id = RADEON_CHUNK_ID_IB_SETUP;
+ csg->chunks[2].length_dw = 0;
+ csg->chunks[2].chunk_data = (uint64_t)(uintptr_t)csg->alt.packets;
+ return (struct radeon_cs*)csg;
+}
+
+static struct radeon_cs_int *cs_gem_create(struct radeon_cs_manager *csm,
+ uint32_t ndw)
+{
+ return (struct radeon_cs_int *)radeon_cs_gem_create_setup(csm, ndw, 0);
}
static int cs_gem_write_reloc(struct radeon_cs_int *cs,
@@ -419,7 +446,7 @@ out_err:
static int cs_gem_emit(struct radeon_cs_int *cs)
{
struct cs_gem *csg = (struct cs_gem*)cs;
- uint64_t chunk_array[2];
+ uint64_t chunk_array[3];
unsigned i;
int r;
@@ -432,6 +459,13 @@ static int cs_gem_emit(struct radeon_cs_int *cs)
chunk_array[1] = (uint64_t)(uintptr_t)&csg->chunks[1];
csg->cs.num_chunks = 2;
+
+ if (csg->alt.cdw > 0) {
+ csg->chunks[2].length_dw = csg->alt.cdw;
+ chunk_array[2] = (uint64_t)(uintptr_t)&csg->chunks[2];
+ csg->cs.num_chunks++;
+ }
+
csg->cs.chunks = (uint64_t)(uintptr_t)chunk_array;
r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_CS,
@@ -458,6 +492,7 @@ static int cs_gem_destroy(struct radeon_cs_int *cs)
free(csg->relocs_bo);
free(cs->relocs);
free(cs->packets);
+ free(csg->alt.packets);
free(cs);
return 0;
}
@@ -479,10 +514,13 @@ static int cs_gem_erase(struct radeon_cs_int *cs)
}
cs->relocs_total_size = 0;
cs->cdw = 0;
+ csg->alt.cdw = 0;
cs->section_ndw = 0;
+ csg->alt.section_ndw = 0;
cs->crelocs = 0;
csg->chunks[0].length_dw = 0;
csg->chunks[1].length_dw = 0;
+ csg->chunks[2].length_dw = 0;
return 0;
}
diff --git a/radeon/radeon_cs_gem.h b/radeon/radeon_cs_gem.h
index 5dea38ad..fb51cd5d 100644
--- a/radeon/radeon_cs_gem.h
+++ b/radeon/radeon_cs_gem.h
@@ -38,4 +38,7 @@
struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd);
void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm);
+void radeon_cs_gem_switch_alt(struct radeon_cs *cs);
+struct radeon_cs *radeon_cs_gem_create_setup(struct radeon_cs_manager *csm,
+ uint32_t ndw, uint32_t setup_ndw);
#endif