summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/intel/intel_batchbuffer.h
blob: a0a5c9841c6a854e063a4ae73c2fc4ed5549d917 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef INTEL_BATCHBUFFER_H
#define INTEL_BATCHBUFFER_H

#include "main/mtypes.h"

#include "intel_context.h"
#include "intel_bufmgr.h"
#include "intel_reg.h"

#define BATCH_RESERVED 16

void intel_batchbuffer_reset(struct intel_context *intel);
void intel_batchbuffer_free(struct intel_context *intel);

void _intel_batchbuffer_flush(struct intel_context *intel,
			      const char *file, int line);

#define intel_batchbuffer_flush(intel) \
	_intel_batchbuffer_flush(intel, __FILE__, __LINE__)



/* Unlike bmBufferData, this currently requires the buffer be mapped.
 * Consider it a convenience function wrapping multple
 * intel_buffer_dword() calls.
 */
void intel_batchbuffer_data(struct intel_context *intel,
                            const void *data, GLuint bytes, bool is_blit);

GLboolean intel_batchbuffer_emit_reloc(struct intel_context *intel,
                                       drm_intel_bo *buffer,
				       uint32_t read_domains,
				       uint32_t write_domain,
				       uint32_t offset);
GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
					      drm_intel_bo *buffer,
					      uint32_t read_domains,
					      uint32_t write_domain,
					      uint32_t offset);
void intel_batchbuffer_emit_mi_flush(struct intel_context *intel);

static INLINE uint32_t float_as_int(float f)
{
   union {
      float f;
      uint32_t d;
   } fi;

   fi.f = f;
   return fi.d;
}

/* Inline functions - might actually be better off with these
 * non-inlined.  Certainly better off switching all command packets to
 * be passed as structs rather than dwords, but that's a little bit of
 * work...
 */
static INLINE GLint
intel_batchbuffer_space(struct intel_context *intel)
{
   return (intel->batch.state_batch_offset - intel->batch.reserved_space) - intel->batch.used*4;
}


static INLINE void
intel_batchbuffer_emit_dword(struct intel_context *intel, GLuint dword)
{
#ifdef DEBUG
   assert(intel_batchbuffer_space(intel) >= 4);
#endif
   intel->batch.map[intel->batch.used++] = dword;
}

static INLINE void
intel_batchbuffer_emit_float(struct intel_context *intel, float f)
{
   intel_batchbuffer_emit_dword(intel, float_as_int(f));
}

static INLINE void
intel_batchbuffer_require_space(struct intel_context *intel,
                                GLuint sz, int is_blit)
{

   if (intel->gen >= 6 &&
       intel->batch.is_blit != is_blit && intel->batch.used) {
      intel_batchbuffer_flush(intel);
   }

   intel->batch.is_blit = is_blit;

#ifdef DEBUG
   assert(sz < sizeof(intel->batch.map) - BATCH_RESERVED);
#endif
   if (intel_batchbuffer_space(intel) < sz)
      intel_batchbuffer_flush(intel);
}

static INLINE void
intel_batchbuffer_begin(struct intel_context *intel, int n, bool is_blit)
{
   intel_batchbuffer_require_space(intel, n * 4, is_blit);

   intel->batch.emit = intel->batch.used;
#ifdef DEBUG
   intel->batch.total = n;
#endif
}

static INLINE void
intel_batchbuffer_advance(struct intel_context *intel)
{
#ifdef DEBUG
   struct intel_batchbuffer *batch = &intel->batch;
   unsigned int _n = batch->used - batch->emit;
   assert(batch->total != 0);
   if (_n != batch->total) {
      fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n",
	      _n, batch->total);
      abort();
   }
   batch->total = 0;
#endif
}

void intel_batchbuffer_cached_advance(struct intel_context *intel);

/* Here are the crusty old macros, to be removed:
 */
#define BATCH_LOCALS

#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel, n, false)
#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel, n, true)
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel, d)
#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel,f)
#define OUT_RELOC(buf, read_domains, write_domain, delta) do {		\
   intel_batchbuffer_emit_reloc(intel, buf,			\
				read_domains, write_domain, delta);	\
} while (0)
#define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do {	\
   intel_batchbuffer_emit_reloc_fenced(intel, buf,		\
				       read_domains, write_domain, delta); \
} while (0)

#define ADVANCE_BATCH() intel_batchbuffer_advance(intel);
#define CACHED_BATCH() intel_batchbuffer_cached_advance(intel);

#endif