1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef INTEL_BATCHBUFFER_H
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INTEL_BATCHBUFFER_H
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h"
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_context.h"
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_bufmgr.h"
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "intel_reg.h"
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __cplusplus
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern "C" {
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Number of bytes to reserve for commands necessary to complete a batch.
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This includes:
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - MI_BATCHBUFFER_END (4 bytes)
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - Optional MI_NOOP for ensuring the batch length is qword aligned (4 bytes)
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - Any state emitted by vtbl->finish_batch()
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *   - On 965+, this means ending occlusion queries (on Gen6, which has the
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *     most workaround flushes, this can be as much as (4+4+5)*4 = 52 bytes)
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BATCH_RESERVED 60
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct intel_batchbuffer;
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_init(struct intel_context *intel);
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_reset(struct intel_context *intel);
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_free(struct intel_context *intel);
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_save_state(struct intel_context *intel);
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_reset_to_saved(struct intel_context *intel);
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint _intel_batchbuffer_flush(struct intel_context *intel,
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			     const char *file, int line);
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define intel_batchbuffer_flush(intel) \
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	_intel_batchbuffer_flush(intel, __FILE__, __LINE__)
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Unlike bmBufferData, this currently requires the buffer be mapped.
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Consider it a convenience function wrapping multple
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * intel_buffer_dword() calls.
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_data(struct intel_context *intel,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            const void *data, GLuint bytes, bool is_blit);
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool intel_batchbuffer_emit_reloc(struct intel_context *intel,
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       drm_intel_bo *buffer,
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       uint32_t read_domains,
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       uint32_t write_domain,
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       uint32_t offset);
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      drm_intel_bo *buffer,
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      uint32_t read_domains,
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      uint32_t write_domain,
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					      uint32_t offset);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_emit_mi_flush(struct intel_context *intel);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_emit_post_sync_nonzero_flush(struct intel_context *intel);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_emit_depth_stall_flushes(struct intel_context *intel);
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid gen7_emit_vs_workaround_flush(struct intel_context *intel);
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE uint32_t float_as_int(float f)
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   union {
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      float f;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      uint32_t d;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } fi;
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   fi.f = f;
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return fi.d;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Inline functions - might actually be better off with these
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * non-inlined.  Certainly better off switching all command packets to
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * be passed as structs rather than dwords, but that's a little bit of
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * work...
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_batchbuffer_space(struct intel_context *intel)
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (intel->batch.state_batch_offset - intel->batch.reserved_space)
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      - intel->batch.used*4;
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_batchbuffer_emit_dword(struct intel_context *intel, GLuint dword)
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(intel_batchbuffer_space(intel) >= 4);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel->batch.map[intel->batch.used++] = dword;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_batchbuffer_emit_float(struct intel_context *intel, float f)
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel_batchbuffer_emit_dword(intel, float_as_int(f));
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_batchbuffer_require_space(struct intel_context *intel,
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                GLuint sz, int is_blit)
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel->gen >= 6 &&
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       intel->batch.is_blit != is_blit && intel->batch.used) {
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      intel_batchbuffer_flush(intel);
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel->batch.is_blit = is_blit;
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(sz < sizeof(intel->batch.map) - BATCH_RESERVED);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (intel_batchbuffer_space(intel) < sz)
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      intel_batchbuffer_flush(intel);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_batchbuffer_begin(struct intel_context *intel, int n, bool is_blit)
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel_batchbuffer_require_space(intel, n * 4, is_blit);
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel->batch.emit = intel->batch.used;
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel->batch.total = n;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgintel_batchbuffer_advance(struct intel_context *intel)
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct intel_batchbuffer *batch = &intel->batch;
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int _n = batch->used - batch->emit;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(batch->total != 0);
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (_n != batch->total) {
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n",
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	      _n, batch->total);
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      abort();
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   batch->total = 0;
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid intel_batchbuffer_cached_advance(struct intel_context *intel);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Here are the crusty old macros, to be removed:
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BATCH_LOCALS
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel, n, false)
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel, n, true)
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel, d)
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel,f)
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define OUT_RELOC(buf, read_domains, write_domain, delta) do {		\
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel_batchbuffer_emit_reloc(intel, buf,			\
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				read_domains, write_domain, delta);	\
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0)
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do {	\
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   intel_batchbuffer_emit_reloc_fenced(intel, buf,		\
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				       read_domains, write_domain, delta); \
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} while (0)
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define ADVANCE_BATCH() intel_batchbuffer_advance(intel);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CACHED_BATCH() intel_batchbuffer_cached_advance(intel);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef __cplusplus
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
176