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