Merge branch 'mesa_7_5_branch'
[mesa.git] / src / gallium / winsys / drm / intel / gem / intel_be_batchbuffer.c
1
2 #include "i915simple/i915_debug.h"
3 #include "intel_be_batchbuffer.h"
4 #include "intel_be_context.h"
5 #include "intel_be_device.h"
6 #include "intel_be_fence.h"
7 #include <errno.h>
8
9 #include "util/u_memory.h"
10
11 struct intel_be_batchbuffer *
12 intel_be_batchbuffer_alloc(struct intel_be_context *intel)
13 {
14 struct intel_be_batchbuffer *batch = CALLOC_STRUCT(intel_be_batchbuffer);
15
16
17 batch->base.buffer = NULL;
18 batch->base.winsys = &intel->base;
19 batch->base.map = NULL;
20 batch->base.ptr = NULL;
21 batch->base.size = 0;
22 batch->base.actual_size = intel->device->max_batch_size;
23 batch->base.relocs = 0;
24 batch->base.max_relocs = 500;/*INTEL_DEFAULT_RELOCS;*/
25
26 batch->base.map = malloc(batch->base.actual_size);
27 memset(batch->base.map, 0, batch->base.actual_size);
28
29 batch->base.ptr = batch->base.map;
30
31 intel_be_batchbuffer_reset(batch);
32
33 return batch;
34 }
35
36 void
37 intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
38 {
39 struct intel_be_context *intel = intel_be_context(batch->base.winsys);
40 struct intel_be_device *dev = intel->device;
41
42 if (batch->bo)
43 drm_intel_bo_unreference(batch->bo);
44
45 memset(batch->base.map, 0, batch->base.actual_size);
46 batch->base.ptr = batch->base.map;
47 batch->base.size = batch->base.actual_size - BATCH_RESERVED;
48
49 batch->base.relocs = 0;
50
51 batch->bo = drm_intel_bo_alloc(dev->pools.gem,
52 "gallium3d_batch_buffer",
53 batch->base.actual_size, 0);
54 }
55
56 int
57 intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
58 unsigned pre_add,
59 drm_intel_bo *bo,
60 uint32_t read_domains,
61 uint32_t write_domain)
62 {
63 unsigned offset;
64 int ret = 0;
65
66 assert(batch->base.relocs < batch->base.max_relocs);
67
68 offset = (unsigned)(batch->base.ptr - batch->base.map);
69
70 ret = drm_intel_bo_emit_reloc(batch->bo, offset,
71 bo, pre_add,
72 read_domains,
73 write_domain);
74
75 ((uint32_t*)batch->base.ptr)[0] = bo->offset + pre_add;
76 batch->base.ptr += 4;
77
78 if (!ret)
79 batch->base.relocs++;
80
81 return ret;
82 }
83
84 void
85 intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
86 struct intel_be_fence **fence)
87 {
88 struct i915_batchbuffer *i915 = &batch->base;
89 unsigned used = 0;
90 int ret = 0;
91
92 assert(i915_batchbuffer_space(i915) >= 0);
93
94 used = batch->base.ptr - batch->base.map;
95 assert((used & 3) == 0);
96
97 if (used & 4) {
98 i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); // MI_FLUSH | FLUSH_MAP_CACHE;
99 i915_batchbuffer_dword(i915, (0x0<<29)|(0x0<<23)); // MI_NOOP
100 i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
101 } else {
102 i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); //MI_FLUSH | FLUSH_MAP_CACHE;
103 i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
104 }
105
106 used = batch->base.ptr - batch->base.map;
107
108 drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
109 ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
110
111 assert(ret == 0);
112
113 intel_be_batchbuffer_reset(batch);
114
115 if (fence) {
116 if (*fence)
117 intel_be_fence_reference(fence, NULL);
118
119 (*fence) = CALLOC_STRUCT(intel_be_fence);
120 pipe_reference_init(&(*fence)->reference, 1);
121 (*fence)->bo = NULL;
122 }
123 }
124
125 void
126 intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch)
127 {
128
129 }
130
131 void
132 intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
133 {
134 if (batch->bo)
135 drm_intel_bo_unreference(batch->bo);
136
137 free(batch->base.map);
138 free(batch);
139 }