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
10434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berry#ifdef __cplusplus
11434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berryextern "C" {
12434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berry#endif
13434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berry
144e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke/**
154e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke * Number of bytes to reserve for commands necessary to complete a batch.
164e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke *
174e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke * This includes:
184e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke * - MI_BATCHBUFFER_END (4 bytes)
194e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke * - Optional MI_NOOP for ensuring the batch length is qword aligned (4 bytes)
204e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke * - Any state emitted by vtbl->finish_batch()
214e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke *   - On 965+, this means ending occlusion queries (on Gen6, which has the
224e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke *     most workaround flushes, this can be as much as (4+4+5)*4 = 52 bytes)
234e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke */
244e087de51ad0e7ba4a7199d3664e1d096f8dc510Kenneth Graunke#define BATCH_RESERVED 60
256b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
26f28a7d0e77ffbeb2a27bda132d4334b3649be3a2Paul Berrystruct intel_batchbuffer;
27f28a7d0e77ffbeb2a27bda132d4334b3649be3a2Paul Berry
28dfada714f8db3deea2fea3583c3c166a78db1117Eric Anholtvoid intel_batchbuffer_init(struct intel_context *intel);
298d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonvoid intel_batchbuffer_reset(struct intel_context *intel);
308d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonvoid intel_batchbuffer_free(struct intel_context *intel);
313faf56ffbdebef04345ebb1fa8e0d50b4beeedb2Eric Anholtvoid intel_batchbuffer_save_state(struct intel_context *intel);
323faf56ffbdebef04345ebb1fa8e0d50b4beeedb2Eric Anholtvoid intel_batchbuffer_reset_to_saved(struct intel_context *intel);
336b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
34da8f052560120010b7f37a300f03c0847cca3aa5Eric Anholtint _intel_batchbuffer_flush(struct intel_context *intel,
35da8f052560120010b7f37a300f03c0847cca3aa5Eric Anholt			     const char *file, int line);
36ab2933df65628d8f1f0a3f49129442bc8d2c3a2bEric Anholt
378d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson#define intel_batchbuffer_flush(intel) \
388d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson	_intel_batchbuffer_flush(intel, __FILE__, __LINE__)
396b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
406b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
416b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
426b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* Unlike bmBufferData, this currently requires the buffer be mapped.
436b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * Consider it a convenience function wrapping multple
446b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * intel_buffer_dword() calls.
456b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
468d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonvoid intel_batchbuffer_data(struct intel_context *intel,
47c27285610c9f9b50d06bf0f2725da195937cb48dEric Anholt                            const void *data, GLuint bytes, bool is_blit);
486b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
492e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkebool intel_batchbuffer_emit_reloc(struct intel_context *intel,
5034474fa4119378ef9fbb9fb557cc19c0a1ca1f7eEric Anholt                                       drm_intel_bo *buffer,
51f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				       uint32_t read_domains,
52f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				       uint32_t write_domain,
53f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				       uint32_t offset);
542e5a1a254ed81b1d3efa6064f48183eefac784d0Kenneth Graunkebool intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
5506d1472ffa0648efa9374fa227894fbf0b0be054Eric Anholt					      drm_intel_bo *buffer,
5606d1472ffa0648efa9374fa227894fbf0b0be054Eric Anholt					      uint32_t read_domains,
5706d1472ffa0648efa9374fa227894fbf0b0be054Eric Anholt					      uint32_t write_domain,
5806d1472ffa0648efa9374fa227894fbf0b0be054Eric Anholt					      uint32_t offset);
598d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonvoid intel_batchbuffer_emit_mi_flush(struct intel_context *intel);
60f6e5230b2614cc91e4c849c07781b2230878d274Eric Anholtvoid intel_emit_post_sync_nonzero_flush(struct intel_context *intel);
61b095b683f8451b54cca52593dc331f82844c9c30Eric Anholtvoid intel_emit_depth_stall_flushes(struct intel_context *intel);
62709f50928e1d4df755ffb90ec9f33ba6c9605a32Kenneth Graunkevoid gen7_emit_vs_workaround_flush(struct intel_context *intel);
636b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
647392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholtstatic INLINE uint32_t float_as_int(float f)
657392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt{
667392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt   union {
677392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt      float f;
687392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt      uint32_t d;
697392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt   } fi;
707392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt
717392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt   fi.f = f;
727392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt   return fi.d;
737392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt}
747392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt
756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* Inline functions - might actually be better off with these
766b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * non-inlined.  Certainly better off switching all command packets to
776b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * be passed as structs rather than dwords, but that's a little bit of
786b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell * work...
796b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
802a6a1c4bc291b76674f62bd989d1487f10268ef0Ian Romanickstatic INLINE unsigned
818d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonintel_batchbuffer_space(struct intel_context *intel)
826b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
832a6a1c4bc291b76674f62bd989d1487f10268ef0Ian Romanick   return (intel->batch.state_batch_offset - intel->batch.reserved_space)
842a6a1c4bc291b76674f62bd989d1487f10268ef0Ian Romanick      - intel->batch.used*4;
856b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
866b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
876b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
886b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellstatic INLINE void
898d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonintel_batchbuffer_emit_dword(struct intel_context *intel, GLuint dword)
906b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
91855515859ec1d94737ea91167220ba7b568c144dEric Anholt#ifdef DEBUG
928d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   assert(intel_batchbuffer_space(intel) >= 4);
93855515859ec1d94737ea91167220ba7b568c144dEric Anholt#endif
948d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   intel->batch.map[intel->batch.used++] = dword;
956b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
966b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
976b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwellstatic INLINE void
988d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonintel_batchbuffer_emit_float(struct intel_context *intel, float f)
997392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt{
1008d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   intel_batchbuffer_emit_dword(intel, float_as_int(f));
1017392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt}
1027392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt
1037392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholtstatic INLINE void
1048d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonintel_batchbuffer_require_space(struct intel_context *intel,
105c27285610c9f9b50d06bf0f2725da195937cb48dEric Anholt                                GLuint sz, int is_blit)
1066b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell{
107c27285610c9f9b50d06bf0f2725da195937cb48dEric Anholt
1088d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   if (intel->gen >= 6 &&
1098d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson       intel->batch.is_blit != is_blit && intel->batch.used) {
1108d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson      intel_batchbuffer_flush(intel);
111c27285610c9f9b50d06bf0f2725da195937cb48dEric Anholt   }
112c27285610c9f9b50d06bf0f2725da195937cb48dEric Anholt
1138d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   intel->batch.is_blit = is_blit;
114c27285610c9f9b50d06bf0f2725da195937cb48dEric Anholt
115855515859ec1d94737ea91167220ba7b568c144dEric Anholt#ifdef DEBUG
1168d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   assert(sz < sizeof(intel->batch.map) - BATCH_RESERVED);
117855515859ec1d94737ea91167220ba7b568c144dEric Anholt#endif
1188d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   if (intel_batchbuffer_space(intel) < sz)
1198d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson      intel_batchbuffer_flush(intel);
1206b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell}
1216b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1227392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholtstatic INLINE void
1238d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonintel_batchbuffer_begin(struct intel_context *intel, int n, bool is_blit)
12470be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt{
1258d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   intel_batchbuffer_require_space(intel, n * 4, is_blit);
126c27285610c9f9b50d06bf0f2725da195937cb48dEric Anholt
127aac120977d1ead319141d48d65c9bba626ec03b8Chris Wilson   intel->batch.emit = intel->batch.used;
128855515859ec1d94737ea91167220ba7b568c144dEric Anholt#ifdef DEBUG
129aac120977d1ead319141d48d65c9bba626ec03b8Chris Wilson   intel->batch.total = n;
130855515859ec1d94737ea91167220ba7b568c144dEric Anholt#endif
1317392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt}
13270be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt
1337392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholtstatic INLINE void
1348d68a90e225d831a395ba788e425cb717eec1f9aChris Wilsonintel_batchbuffer_advance(struct intel_context *intel)
1357392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt{
136855515859ec1d94737ea91167220ba7b568c144dEric Anholt#ifdef DEBUG
1378d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   struct intel_batchbuffer *batch = &intel->batch;
1388d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   unsigned int _n = batch->used - batch->emit;
1398d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   assert(batch->total != 0);
1408d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   if (_n != batch->total) {
1417392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt      fprintf(stderr, "ADVANCE_BATCH: %d of %d dwords emitted\n",
1428d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson	      _n, batch->total);
1437392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt      abort();
1447392002041f6c7ac6eb788d7b154f2b44eb6f403Eric Anholt   }
1458d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   batch->total = 0;
146855515859ec1d94737ea91167220ba7b568c144dEric Anholt#endif
14770be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt}
14870be48dff6bb68c61285641e4d976bfd53e0f00cEric Anholt
149aac120977d1ead319141d48d65c9bba626ec03b8Chris Wilsonvoid intel_batchbuffer_cached_advance(struct intel_context *intel);
150aac120977d1ead319141d48d65c9bba626ec03b8Chris Wilson
1516b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell/* Here are the crusty old macros, to be removed:
1526b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell */
1536b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#define BATCH_LOCALS
1546b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1558d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson#define BEGIN_BATCH(n) intel_batchbuffer_begin(intel, n, false)
1568d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson#define BEGIN_BATCH_BLT(n) intel_batchbuffer_begin(intel, n, true)
1578d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel, d)
1588d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson#define OUT_BATCH_F(f) intel_batchbuffer_emit_float(intel,f)
159f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie#define OUT_RELOC(buf, read_domains, write_domain, delta) do {		\
1608d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   intel_batchbuffer_emit_reloc(intel, buf,			\
161f75843a517bd188639e6866db2a7b04de3524e16Dave Airlie				read_domains, write_domain, delta);	\
1626b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell} while (0)
16306d1472ffa0648efa9374fa227894fbf0b0be054Eric Anholt#define OUT_RELOC_FENCED(buf, read_domains, write_domain, delta) do {	\
1648d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson   intel_batchbuffer_emit_reloc_fenced(intel, buf,		\
16506d1472ffa0648efa9374fa227894fbf0b0be054Eric Anholt				       read_domains, write_domain, delta); \
16606d1472ffa0648efa9374fa227894fbf0b0be054Eric Anholt} while (0)
1676b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
1688d68a90e225d831a395ba788e425cb717eec1f9aChris Wilson#define ADVANCE_BATCH() intel_batchbuffer_advance(intel);
169aac120977d1ead319141d48d65c9bba626ec03b8Chris Wilson#define CACHED_BATCH() intel_batchbuffer_cached_advance(intel);
1706b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell
171434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berry#ifdef __cplusplus
172434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berry}
173434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berry#endif
174434fc8bde41f07687ad8941ceba03c4b3e0e75bbPaul Berry
1756b9e31f3eb3dbe20cbc8493b963bbc6530e392c6Keith Whitwell#endif
176