summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/r600/drm/radeon_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/r600/drm/radeon_draw.c')
-rw-r--r--src/gallium/winsys/r600/drm/radeon_draw.c92
1 files changed, 85 insertions, 7 deletions
diff --git a/src/gallium/winsys/r600/drm/radeon_draw.c b/src/gallium/winsys/r600/drm/radeon_draw.c
index 53699eb0b1..4413ed79fb 100644
--- a/src/gallium/winsys/r600/drm/radeon_draw.c
+++ b/src/gallium/winsys/r600/drm/radeon_draw.c
@@ -31,33 +31,111 @@
/*
* draw functions
*/
-int radeon_draw_init(struct radeon_draw *draw, struct radeon *radeon)
+struct radeon_draw *radeon_draw(struct radeon *radeon)
{
- memset(draw, 0, sizeof(struct radeon_draw));
+ struct radeon_draw *draw;
+
+ draw = calloc(1, sizeof(*draw));
+ if (draw == NULL)
+ return NULL;
draw->nstate = radeon->nstate;
draw->radeon = radeon;
- return 0;
+ draw->refcount = 1;
+ draw->state = calloc(1, sizeof(void*) * draw->nstate);
+ if (draw->state == NULL) {
+ free(draw);
+ return NULL;
+ }
+ return draw;
}
-int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state)
+struct radeon_draw *radeon_draw_incref(struct radeon_draw *draw)
+{
+ draw->refcount++;
+ return draw;
+}
+
+struct radeon_draw *radeon_draw_decref(struct radeon_draw *draw)
+{
+ unsigned i;
+
+ if (draw == NULL)
+ return NULL;
+ if (--draw->refcount > 0)
+ return NULL;
+ for (i = 0; i < draw->nstate; i++) {
+ draw->state[i] = radeon_state_decref(draw->state[i]);
+ }
+ free(draw->state);
+ memset(draw, 0, sizeof(*draw));
+ free(draw);
+ return NULL;
+}
+
+int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state)
{
if (state == NULL)
return 0;
if (state->type >= draw->radeon->ntype)
return -EINVAL;
- draw->state[state->id] = *state;
+ draw->state[state->id] = radeon_state_decref(draw->state[state->id]);
+ draw->state[state->id] = state;
return 0;
}
+int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state)
+{
+ if (state == NULL)
+ return 0;
+ radeon_state_incref(state);
+ return radeon_draw_set_new(draw, state);
+}
+
int radeon_draw_check(struct radeon_draw *draw)
{
unsigned i;
int r;
+ r = radeon_draw_pm4(draw);
+ if (r)
+ return r;
for (i = 0, draw->cpm4 = 0; i < draw->nstate; i++) {
- if (draw->state[i].valid) {
- draw->cpm4 += draw->state[i].cpm4;
+ if (draw->state[i]) {
+ draw->cpm4 += draw->state[i]->cpm4;
}
}
return 0;
}
+
+struct radeon_draw *radeon_draw_duplicate(struct radeon_draw *draw)
+{
+ struct radeon_draw *ndraw;
+ unsigned i;
+
+ if (draw == NULL)
+ return NULL;
+ ndraw = radeon_draw(draw->radeon);
+ if (ndraw == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < draw->nstate; i++) {
+ if (radeon_draw_set(ndraw, draw->state[i])) {
+ radeon_draw_decref(ndraw);
+ return NULL;
+ }
+ }
+ return ndraw;
+}
+
+int radeon_draw_pm4(struct radeon_draw *draw)
+{
+ unsigned i;
+ int r;
+
+ for (i = 0; i < draw->nstate; i++) {
+ r = radeon_state_pm4(draw->state[i]);
+ if (r)
+ return r;
+ }
+ return 0;
+}