intel_batchbuffer.h revision f75843a517bd188639e6866db2a7b04de3524e16
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
9struct intel_context;
10
11#define BATCH_SZ 16384
12#define BATCH_RESERVED 16
13
14enum 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
39struct 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
57struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
58                                                  *intel);
59
60void intel_batchbuffer_free(struct intel_batchbuffer *batch);
61
62
63void _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
69void 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 */
76void intel_batchbuffer_data(struct intel_batchbuffer *batch,
77                            const void *data, GLuint bytes,
78			    enum cliprect_mode cliprect_mode);
79
80void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
81                                     GLuint bytes);
82
83GLboolean 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 */
94static INLINE GLint
95intel_batchbuffer_space(struct intel_batchbuffer *batch)
96{
97   return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
98}
99
100
101static INLINE void
102intel_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
110static INLINE void
111intel_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	    batch->cliprect_mode = cliprect_mode;
126	 }
127      }
128   }
129}
130
131/* Here are the crusty old macros, to be removed:
132 */
133#define BATCH_LOCALS
134
135#define BEGIN_BATCH(n, cliprect_mode) do {				\
136   intel_batchbuffer_require_space(intel->batch, (n)*4, cliprect_mode); \
137} while (0)
138
139#define OUT_BATCH(d)  intel_batchbuffer_emit_dword(intel->batch, d)
140
141#define OUT_RELOC(buf, read_domains, write_domain, delta) do {		\
142   assert((delta) >= 0);						\
143   intel_batchbuffer_emit_reloc(intel->batch, buf,			\
144				read_domains, write_domain, delta);	\
145} while (0)
146
147#define ADVANCE_BATCH() do { } while(0)
148
149
150static INLINE void
151intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
152{
153   intel_batchbuffer_require_space(batch, 4, IGNORE_CLIPRECTS);
154   intel_batchbuffer_emit_dword(batch, MI_FLUSH);
155}
156
157#endif
158