intel_batchbuffer.h revision 70be48dff6bb68c61285641e4d976bfd53e0f00c
16b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#ifndef INTEL_BATCHBUFFER_H
26b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define INTEL_BATCHBUFFER_H
36b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
4ecadb51bbcb972a79f3ed79e65a7986b9396e757Brian Paul#include "main/mtypes.h"
54cd3ef58a989f61ff22669648e4117426c6e603cDave Airlie
635fd72756a05463568d94862f4fcd234903e1204Eric Anholt#include "intel_context.h"
73628185f566e178a12b493fb89abf52b4b281f99Eric Anholt#include "intel_bufmgr.h"
8f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#include "intel_reg.h"
96b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
108e21bb516f87bfdde90d0f469ede4192435b9235Dave Airlie#define BATCH_SZ 16384
116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define BATCH_RESERVED 16
126b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
146b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellstruct intel_batchbuffer
156b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
166b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   struct intel_context *intel;
176b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
18cfc21190af1038f204d38ab4764a9c731b0323a5Eric Anholt   dri_bo *buf;
19f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie
20f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   GLubyte *buffer;
21145523ba3acb95a9ff390430a9e0a3fa958cae1bKeith Packard
226b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLubyte *map;
236b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLubyte *ptr;
246b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
256b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   GLuint size;
26a8fee3a498c8c4966d57a5273408477f3aa3ce73Keith Whitwell
27bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   /** Tracking of BEGIN_BATCH()/OUT_BATCH()/ADVANCE_BATCH() debugging */
28bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   struct {
29bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt      GLuint total;
30bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt      GLubyte *start_ptr;
31bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   } emit;
32bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt
33a8fee3a498c8c4966d57a5273408477f3aa3ce73Keith Whitwell   GLuint dirty_state;
348e0f40d28777f1ae599a95312788fe29a0515a0dEric Anholt   GLuint reserved_space;
356b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell};
366b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
376b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellstruct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
386b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                                                  *intel);
396b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
406b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid intel_batchbuffer_free(struct intel_batchbuffer *batch);
416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
43ab2933df65628d8f1f0a3f49129442bc8d2c3a2bEric Anholtvoid _intel_batchbuffer_flush(struct intel_batchbuffer *batch,
44ab2933df65628d8f1f0a3f49129442bc8d2c3a2bEric Anholt			      const char *file, int line);
45ab2933df65628d8f1f0a3f49129442bc8d2c3a2bEric Anholt
46ab2933df65628d8f1f0a3f49129442bc8d2c3a2bEric Anholt#define intel_batchbuffer_flush(batch) \
47ab2933df65628d8f1f0a3f49129442bc8d2c3a2bEric Anholt	_intel_batchbuffer_flush(batch, __FILE__, __LINE__)
486b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
496b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid intel_batchbuffer_reset(struct intel_batchbuffer *batch);
506b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
516b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
526b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* Unlike bmBufferData, this currently requires the buffer be mapped.
536b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * Consider it a convenience function wrapping multple
546b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * intel_buffer_dword() calls.
556b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
566b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid intel_batchbuffer_data(struct intel_batchbuffer *batch,
575203b7227ccb6b618fa42f08434d4a3cf123dca2Kristian Høgsberg                            const void *data, GLuint bytes);
586b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
596b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellvoid intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
606b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell                                     GLuint bytes);
616b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
626b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith WhitwellGLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
63cfc21190af1038f204d38ab4764a9c731b0323a5Eric Anholt                                       dri_bo *buffer,
64f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				       uint32_t read_domains,
65f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				       uint32_t write_domain,
66f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				       uint32_t offset);
678e0f40d28777f1ae599a95312788fe29a0515a0dEric Anholtvoid intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch);
686b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
696b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* Inline functions - might actually be better off with these
706b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * non-inlined.  Certainly better off switching all command packets to
716b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * be passed as structs rather than dwords, but that's a little bit of
726b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * work...
736b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
74f75843a517bd188639e6866db2a7b04de3524e16Dave Airliestatic INLINE GLint
756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellintel_batchbuffer_space(struct intel_batchbuffer *batch)
766b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
778e0f40d28777f1ae599a95312788fe29a0515a0dEric Anholt   return (batch->size - batch->reserved_space) - (batch->ptr - batch->map);
786b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
796b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
806b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
816b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellstatic INLINE void
826b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellintel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
836b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
846b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   assert(batch->map);
856b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   assert(intel_batchbuffer_space(batch) >= 4);
866b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   *(GLuint *) (batch->ptr) = dword;
876b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   batch->ptr += 4;
886b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
896b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
906b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellstatic INLINE void
916b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellintel_batchbuffer_require_space(struct intel_batchbuffer *batch,
925203b7227ccb6b618fa42f08434d4a3cf123dca2Kristian Høgsberg                                GLuint sz)
936b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
946b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell   assert(sz < batch->size - 8);
95beddf653a914903156712aa472b5deaddb7bbaedEric Anholt   if (intel_batchbuffer_space(batch) < sz)
966b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell      intel_batchbuffer_flush(batch);
976b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
986b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
9970be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholtstatic INLINE uint32_t float_as_int(float f)
10070be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt{
10170be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt   union {
10270be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt      float f;
10370be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt      uint32_t d;
10470be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt   } fi;
10570be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt
10670be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt   fi.f = f;
10770be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt   return fi.d;
10870be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt}
10970be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt
1106b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* Here are the crusty old macros, to be removed:
1116b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
1126b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define BATCH_LOCALS
1136b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1145203b7227ccb6b618fa42f08434d4a3cf123dca2Kristian Høgsberg#define BEGIN_BATCH(n) do {				\
1155203b7227ccb6b618fa42f08434d4a3cf123dca2Kristian Høgsberg   intel_batchbuffer_require_space(intel->batch, (n)*4); \
116bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   assert(intel->batch->emit.start_ptr == NULL);			\
117bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   intel->batch->emit.total = (n) * 4;					\
118bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   intel->batch->emit.start_ptr = intel->batch->ptr;			\
1196b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell} while (0)
1206b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
121bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
12270be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt#define OUT_BATCH_F(f) intel_batchbuffer_emit_dword(intel->batch,	\
12370be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt						    float_as_int(f))
1246b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
125f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#define OUT_RELOC(buf, read_domains, write_domain, delta) do {		\
12660a39b6799c72430851d92f93758e2f25487a0f4Chris Wilson   assert((unsigned) (delta) < buf->size);				\
127f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie   intel_batchbuffer_emit_reloc(intel->batch, buf,			\
128f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				read_domains, write_domain, delta);	\
1296b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell} while (0)
1306b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
131bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt#define ADVANCE_BATCH() do {						\
132bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   unsigned int _n = intel->batch->ptr - intel->batch->emit.start_ptr;	\
133bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   assert(intel->batch->emit.start_ptr != NULL);			\
134bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   if (_n != intel->batch->emit.total) {				\
135bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt      fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n",	\
136bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt	      _n, intel->batch->emit.total);				\
137bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt      abort();								\
138bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   }									\
139bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt   intel->batch->emit.start_ptr = NULL;					\
140bc3b8a39a7090d95942faf378e776e89c490e250Eric Anholt} while(0)
1416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#endif
143