i965g: add lots of error checks and early returns
[mesa.git] / src / gallium / drivers / i965 / brw_batchbuffer.h
1 #ifndef BRW_BATCHBUFFER_H
2 #define BRW_BATCHBUFFER_H
3
4 #include "util/u_debug.h"
5
6 #include "brw_types.h"
7 #include "brw_winsys.h"
8 #include "brw_reg.h"
9
10 #define BATCH_SZ 16384
11 #define BATCH_RESERVED 16
12
13 /* All ignored:
14 */
15 enum cliprect_mode {
16 IGNORE_CLIPRECTS,
17 LOOP_CLIPRECTS,
18 NO_LOOP_CLIPRECTS,
19 REFERENCES_CLIPRECTS
20 };
21
22
23
24
25 struct brw_batchbuffer {
26
27 struct brw_winsys_screen *sws;
28 struct brw_winsys_buffer *buf;
29 struct brw_chipset chipset;
30
31 /* Main-memory copy of the batch-buffer, built up incrementally &
32 * then copied as one to the true buffer.
33 *
34 * XXX: is this still necessary?
35 * XXX: if so, can this be hidden inside the GEM-specific winsys code?
36 */
37 boolean use_malloc_buffer;
38 uint8_t *malloc_buffer;
39
40 /**
41 * Values exported to speed up the writing the batchbuffer,
42 * instead of having to go trough a accesor function for
43 * each dword written.
44 */
45 /*{@*/
46 uint8_t *map;
47 uint8_t *ptr;
48 size_t size;
49 struct {
50 uint8_t *end_ptr;
51 } emit;
52
53
54 size_t relocs;
55 size_t max_relocs;
56 /*@}*/
57 };
58
59 struct brw_batchbuffer *brw_batchbuffer_alloc( struct brw_winsys_screen *sws,
60 struct brw_chipset chipset );
61
62 void brw_batchbuffer_free(struct brw_batchbuffer *batch);
63
64 void _brw_batchbuffer_flush(struct brw_batchbuffer *batch,
65 const char *file, int line);
66
67
68 enum pipe_error
69 brw_batchbuffer_reset(struct brw_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 int brw_batchbuffer_data(struct brw_batchbuffer *batch,
77 const void *data, GLuint bytes,
78 enum cliprect_mode cliprect_mode);
79
80
81 int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
82 struct brw_winsys_buffer *buffer,
83 enum brw_buffer_usage usage,
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 brw_batchbuffer_space(struct brw_batchbuffer *batch)
93 {
94 return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
95 }
96
97
98 static INLINE void
99 brw_batchbuffer_emit_dword(struct brw_batchbuffer *batch, GLuint dword)
100 {
101 assert(batch->map);
102 assert(brw_batchbuffer_space(batch) >= 4);
103 *(GLuint *) (batch->ptr) = dword;
104 batch->ptr += 4;
105 }
106
107 static INLINE enum pipe_error
108 brw_batchbuffer_require_space(struct brw_batchbuffer *batch,
109 GLuint sz)
110 {
111 assert(sz < batch->size - 8);
112 if (brw_batchbuffer_space(batch) < sz) {
113 assert(0);
114 return PIPE_ERROR_OUT_OF_MEMORY;
115 }
116 #ifdef DEBUG
117 batch->emit.end_ptr = batch->ptr + sz;
118 #endif
119 return 0;
120 }
121
122 /* Here are the crusty old macros, to be removed:
123 */
124 #define BEGIN_BATCH(n, cliprect_mode) do { \
125 brw_batchbuffer_require_space(brw->batch, (n)*4); \
126 } while (0)
127
128 #define OUT_BATCH(d) brw_batchbuffer_emit_dword(brw->batch, d)
129
130 #define OUT_RELOC(buf, usage, delta) do { \
131 assert((unsigned) (delta) < buf->size); \
132 brw_batchbuffer_emit_reloc(brw->batch, buf, \
133 usage, delta); \
134 } while (0)
135
136 #ifdef DEBUG
137 #define ADVANCE_BATCH() do { \
138 unsigned int _n = brw->batch->ptr - brw->batch->emit.end_ptr; \
139 if (_n != 0) { \
140 debug_printf("%s: %d too many bytes emitted to batch\n", \
141 __FUNCTION__, _n); \
142 abort(); \
143 } \
144 brw->batch->emit.end_ptr = NULL; \
145 } while(0)
146 #else
147 #define ADVANCE_BATCH()
148 #endif
149
150 static INLINE void
151 brw_batchbuffer_emit_mi_flush(struct brw_batchbuffer *batch)
152 {
153 brw_batchbuffer_require_space(batch, 4);
154 brw_batchbuffer_emit_dword(batch, MI_FLUSH);
155 }
156
157 #endif