[intel] intel_batchbuffer_flush using uninit 'used' to check for buffer empty
[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 "dri_bufmgr.h"
7
8 struct intel_context;
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 *map;
45 GLubyte *ptr;
46
47 enum cliprect_mode cliprect_mode;
48
49 GLuint size;
50
51 GLuint dirty_state;
52 };
53
54 struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
55 *intel);
56
57 void intel_batchbuffer_free(struct intel_batchbuffer *batch);
58
59
60 void _intel_batchbuffer_flush(struct intel_batchbuffer *batch,
61 const char *file, int line);
62
63 #define intel_batchbuffer_flush(batch) \
64 _intel_batchbuffer_flush(batch, __FILE__, __LINE__)
65
66 void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
67
68
69 /* Unlike bmBufferData, this currently requires the buffer be mapped.
70 * Consider it a convenience function wrapping multple
71 * intel_buffer_dword() calls.
72 */
73 void intel_batchbuffer_data(struct intel_batchbuffer *batch,
74 const void *data, GLuint bytes,
75 enum cliprect_mode cliprect_mode);
76
77 void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
78 GLuint bytes);
79
80 GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
81 dri_bo *buffer,
82 uint32_t read_domains,
83 uint32_t write_domain,
84 uint32_t offset);
85
86 /* Inline functions - might actually be better off with these
87 * non-inlined. Certainly better off switching all command packets to
88 * be passed as structs rather than dwords, but that's a little bit of
89 * work...
90 */
91 static INLINE GLint
92 intel_batchbuffer_space(struct intel_batchbuffer *batch)
93 {
94 return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
95 }
96
97
98 static INLINE void
99 intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
100 {
101 assert(batch->map);
102 assert(intel_batchbuffer_space(batch) >= 4);
103 *(GLuint *) (batch->ptr) = dword;
104 batch->ptr += 4;
105 }
106
107 static INLINE void
108 intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
109 GLuint sz,
110 enum cliprect_mode cliprect_mode)
111 {
112 assert(sz < batch->size - 8);
113 if (intel_batchbuffer_space(batch) < sz)
114 intel_batchbuffer_flush(batch);
115
116 if (cliprect_mode != IGNORE_CLIPRECTS) {
117 if (batch->cliprect_mode == IGNORE_CLIPRECTS) {
118 batch->cliprect_mode = cliprect_mode;
119 } else {
120 if (batch->cliprect_mode != cliprect_mode)
121 intel_batchbuffer_flush(batch);
122 }
123 }
124 }
125
126 /* Here are the crusty old macros, to be removed:
127 */
128 #define BATCH_LOCALS
129
130 #define BEGIN_BATCH(n, cliprect_mode) do { \
131 intel_batchbuffer_require_space(intel->batch, (n)*4, cliprect_mode); \
132 } while (0)
133
134 #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
135
136 #define OUT_RELOC(buf, read_domains, write_domain, delta) do { \
137 assert((delta) >= 0); \
138 intel_batchbuffer_emit_reloc(intel->batch, buf, \
139 read_domains, write_domain, delta); \
140 } while (0)
141
142 #define ADVANCE_BATCH() do { } while(0)
143
144
145 #endif