Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / gallium / winsys / egl_drm / intel / intel_batchbuffer.h
1 #ifndef INTEL_BATCHBUFFER_H
2 #define INTEL_BATCHBUFFER_H
3
4 #include "mtypes.h"
5 #include "ws_dri_bufmgr.h"
6
7 struct intel_screen;
8
9 #define BATCH_SZ 16384
10 #define BATCH_RESERVED 16
11
12 #define INTEL_DEFAULT_RELOCS 100
13 #define INTEL_MAX_RELOCS 400
14
15 #define INTEL_BATCH_NO_CLIPRECTS 0x1
16 #define INTEL_BATCH_CLIPRECTS 0x2
17
18 struct intel_batchbuffer
19 {
20 struct bufmgr *bm;
21 struct intel_screen *intel_screen;
22
23 struct _DriBufferObject *buffer;
24 struct _DriFenceObject *last_fence;
25 GLuint flags;
26
27 struct _DriBufferList *list;
28 GLuint list_count;
29 GLubyte *map;
30 GLubyte *ptr;
31
32 uint32_t *reloc;
33 GLuint reloc_size;
34 GLuint nr_relocs;
35
36 GLuint size;
37
38 GLuint dirty_state;
39 GLuint id;
40
41 uint32_t poolOffset;
42 uint8_t *drmBOVirtual;
43 struct _drmBONode *node; /* Validation list node for this buffer */
44 int dest_location; /* Validation list sequence for this buffer */
45 };
46
47 struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_screen
48 *intel);
49
50 void intel_batchbuffer_free(struct intel_batchbuffer *batch);
51
52
53 void intel_batchbuffer_finish(struct intel_batchbuffer *batch);
54
55 struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer
56 *batch);
57
58 void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
59
60
61 /* Unlike bmBufferData, this currently requires the buffer be mapped.
62 * Consider it a convenience function wrapping multple
63 * intel_buffer_dword() calls.
64 */
65 void intel_batchbuffer_data(struct intel_batchbuffer *batch,
66 const void *data, GLuint bytes, GLuint flags);
67
68 void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
69 GLuint bytes);
70
71 void
72 intel_offset_relocation(struct intel_batchbuffer *batch,
73 unsigned pre_add,
74 struct _DriBufferObject *driBO,
75 uint64_t val_flags,
76 uint64_t val_mask);
77
78 /* Inline functions - might actually be better off with these
79 * non-inlined. Certainly better off switching all command packets to
80 * be passed as structs rather than dwords, but that's a little bit of
81 * work...
82 */
83 static INLINE GLuint
84 intel_batchbuffer_space(struct intel_batchbuffer *batch)
85 {
86 return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
87 }
88
89
90 static INLINE void
91 intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
92 {
93 assert(batch->map);
94 assert(intel_batchbuffer_space(batch) >= 4);
95 *(GLuint *) (batch->ptr) = dword;
96 batch->ptr += 4;
97 }
98
99 static INLINE void
100 intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
101 GLuint sz, GLuint flags)
102 {
103 struct _DriFenceObject *fence;
104
105 assert(sz < batch->size - 8);
106 if (intel_batchbuffer_space(batch) < sz ||
107 (batch->flags != 0 && flags != 0 && batch->flags != flags)) {
108 fence = intel_batchbuffer_flush(batch);
109 driFenceUnReference(&fence);
110 }
111
112 batch->flags |= flags;
113 }
114
115 /* Here are the crusty old macros, to be removed:
116 */
117 #define BATCH_LOCALS
118
119 #define BEGIN_BATCH(n, flags) do { \
120 assert(!intel->prim.flush); \
121 intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \
122 } while (0)
123
124 #define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
125
126 #define OUT_RELOC(buf,flags,mask,delta) do { \
127 assert((delta) >= 0); \
128 intel_offset_relocation(intel->batch, delta, buf, flags, mask); \
129 } while (0)
130
131 #define ADVANCE_BATCH() do { } while(0)
132
133 #endif