Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/mesa into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / intel / intel_batchbuffer.h
1 #ifndef INTEL_BATCHBUFFER_H
2 #define INTEL_BATCHBUFFER_H
3
4 #include "mtypes.h"
5
6 #include "intel_context.h"
7 #include "intel_bufmgr.h"
8 #include "intel_reg.h"
9
10 #define BATCH_SZ 16384
11 #define BATCH_RESERVED 16
12
13 enum cliprect_mode {
14 /**
15 * Batchbuffer contents may be looped over per cliprect, but do not
16 * require it.
17 */
18 IGNORE_CLIPRECTS,
19 /**
20 * Batchbuffer contents require looping over per cliprect at batch submit
21 * time.
22 */
23 LOOP_CLIPRECTS,
24 /**
25 * Batchbuffer contents contain drawing that should not be executed multiple
26 * times.
27 */
28 NO_LOOP_CLIPRECTS,
29 /**
30 * Batchbuffer contents contain drawing that already handles cliprects, such
31 * as 2D drawing to front/back/depth that doesn't respect DRAWING_RECTANGLE.
32 * Equivalent behavior to NO_LOOP_CLIPRECTS, but may not persist in batch
33 * outside of LOCK/UNLOCK.
34 */
35 REFERENCES_CLIPRECTS
36 };
37
38 struct intel_batchbuffer
39 {
40 struct intel_context *intel;
41
42 dri_bo *buf;
43
44 GLubyte *buffer;
45
46 GLubyte *map;
47 GLubyte *ptr;
48
49 enum cliprect_mode cliprect_mode;
50
51 GLuint size;
52
53 GLuint dirty_state;
54 };
55
56 struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
57 *intel);
58
59 void intel_batchbuffer_free(struct intel_batchbuffer *batch);
60
61
62 void _intel_batchbuffer_flush(struct intel_batchbuffer *batch,
63 const char *file, int line);
64
65 #define intel_batchbuffer_flush(batch) \
66 _intel_batchbuffer_flush(batch, __FILE__, __LINE__)
67
68 void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
69
70
71 /* Unlike bmBufferData, this currently requires the buffer be mapped.
72 * Consider it a convenience function wrapping multple
73 * intel_buffer_dword() calls.
74 */
75 void intel_batchbuffer_data(struct intel_batchbuffer *batch,
76 const void *data, GLuint bytes,
77 enum cliprect_mode cliprect_mode);
78
79 void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
80 GLuint bytes);
81
82 GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
83 dri_bo *buffer,
84 uint32_t read_domains,
85 uint32_t write_domain,
86 uint32_t offset);
87
88 /* Inline functions - might actually be better off with these
89 * non-inlined. Certainly better off switching all command packets to
90 * be passed as structs rather than dwords, but that's a little bit of
91 * work...
92 */
93 static INLINE GLint
94 intel_batchbuffer_space(struct intel_batchbuffer *batch)
95 {
96 return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
97 }
98
99
100 static INLINE void
101 intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
102 {
103 assert(batch->map);
104 assert(intel_batchbuffer_space(batch) >= 4);
105 *(GLuint *) (batch->ptr) = dword;
106 batch->ptr += 4;
107 }
108
109 static INLINE void
110 intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
111 GLuint sz,
112 enum cliprect_mode cliprect_mode)
113 {
114 assert(sz < batch->size - 8);
115 if (intel_batchbuffer_space(batch) < sz)
116 intel_batchbuffer_flush(batch);
117
118 if (cliprect_mode != IGNORE_CLIPRECTS) {
119 if (batch->cliprect_mode == IGNORE_CLIPRECTS) {
120 batch->cliprect_mode = cliprect_mode;
121 } else {
122 if (batch->cliprect_mode != cliprect_mode) {
123 intel_batchbuffer_flush(batch);
124 batch->cliprect_mode = cliprect_mode;
125 }
126 }
127 }
128 }
129
130 /* Here are the crusty old macros, to be removed:
131 */
132 #define BATCH_LOCALS
133
134 #define BEGIN_BATCH(n, cliprect_mode) do { \
135 intel_batchbuffer_require_space(intel->batch, (n)*4, cliprect_mode); \
136 } while (0)
137
138 #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
139
140 #define OUT_RELOC(buf, read_domains, write_domain, delta) do { \
141 assert((delta) >= 0); \
142 intel_batchbuffer_emit_reloc(intel->batch, buf, \
143 read_domains, write_domain, delta); \
144 } while (0)
145
146 #define ADVANCE_BATCH() do { } while(0)
147
148
149 static INLINE void
150 intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
151 {
152 intel_batchbuffer_require_space(batch, 4, IGNORE_CLIPRECTS);
153 intel_batchbuffer_emit_dword(batch, MI_FLUSH);
154 }
155
156 #endif