~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
#include "i915_drm_winsys.h"
3
 
#include "util/u_memory.h"
4
 
 
5
 
#include "drm-uapi/i915_drm.h"
6
 
#include "i915/i915_debug.h"
7
 
#include <xf86drm.h>
8
 
#include <stdio.h>
9
 
 
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
 
#undef INTEL_RUN_SYNC
19
 
 
20
 
struct i915_drm_batchbuffer
21
 
{
22
 
   struct i915_winsys_batchbuffer base;
23
 
 
24
 
   size_t actual_size;
25
 
 
26
 
   drm_intel_bo *bo;
27
 
};
28
 
 
29
 
static inline struct i915_drm_batchbuffer *
30
 
i915_drm_batchbuffer(struct i915_winsys_batchbuffer *batch)
31
 
{
32
 
   return (struct i915_drm_batchbuffer *)batch;
33
 
}
34
 
 
35
 
static void
36
 
i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer *batch)
37
 
{
38
 
   struct i915_drm_winsys *idws = i915_drm_winsys(batch->base.iws);
39
 
 
40
 
   if (batch->bo)
41
 
      drm_intel_bo_unreference(batch->bo);
42
 
   batch->bo = drm_intel_bo_alloc(idws->gem_manager,
43
 
                                  "gallium3d_batchbuffer",
44
 
                                  batch->actual_size,
45
 
                                  4096);
46
 
 
47
 
   memset(batch->base.map, 0, batch->actual_size);
48
 
   batch->base.ptr = batch->base.map;
49
 
   batch->base.size = batch->actual_size - BATCH_RESERVED;
50
 
   batch->base.relocs = 0;
51
 
}
52
 
 
53
 
static struct i915_winsys_batchbuffer *
54
 
i915_drm_batchbuffer_create(struct i915_winsys *iws)
55
 
{
56
 
   struct i915_drm_winsys *idws = i915_drm_winsys(iws);
57
 
   struct i915_drm_batchbuffer *batch = CALLOC_STRUCT(i915_drm_batchbuffer);
58
 
 
59
 
   batch->actual_size = idws->max_batch_size;
60
 
 
61
 
   batch->base.map = MALLOC(batch->actual_size);
62
 
   batch->base.ptr = NULL;
63
 
   batch->base.size = 0;
64
 
 
65
 
   batch->base.relocs = 0;
66
 
 
67
 
   batch->base.iws = iws;
68
 
 
69
 
   i915_drm_batchbuffer_reset(batch);
70
 
 
71
 
   return &batch->base;
72
 
}
73
 
 
74
 
static bool
75
 
i915_drm_batchbuffer_validate_buffers(struct i915_winsys_batchbuffer *batch,
76
 
                                      struct i915_winsys_buffer **buffer,
77
 
                                      int num_of_buffers)
78
 
{
79
 
   struct i915_drm_batchbuffer *drm_batch = i915_drm_batchbuffer(batch);
80
 
   drm_intel_bo *bos[num_of_buffers + 1];
81
 
   int i, ret;
82
 
 
83
 
   bos[0] = drm_batch->bo;
84
 
   for (i = 0; i < num_of_buffers; i++)
85
 
      bos[i+1] = intel_bo(buffer[i]);
86
 
 
87
 
   ret = drm_intel_bufmgr_check_aperture_space(bos, num_of_buffers);
88
 
   if (ret != 0)
89
 
      return false;
90
 
 
91
 
   return true;
92
 
}
93
 
 
94
 
static int
95
 
i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
96
 
                            struct i915_winsys_buffer *buffer,
97
 
                            enum i915_winsys_buffer_usage usage,
98
 
                            unsigned pre_add, bool fenced)
99
 
{
100
 
   struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
101
 
   unsigned write_domain = 0;
102
 
   unsigned read_domain = 0;
103
 
   unsigned offset;
104
 
   int ret = 0;
105
 
 
106
 
   switch (usage) {
107
 
   case I915_USAGE_SAMPLER:
108
 
      write_domain = 0;
109
 
      read_domain = I915_GEM_DOMAIN_SAMPLER;
110
 
      break;
111
 
   case I915_USAGE_RENDER:
112
 
      write_domain = I915_GEM_DOMAIN_RENDER;
113
 
      read_domain = I915_GEM_DOMAIN_RENDER;
114
 
      break;
115
 
   case I915_USAGE_2D_TARGET:
116
 
      write_domain = I915_GEM_DOMAIN_RENDER;
117
 
      read_domain = I915_GEM_DOMAIN_RENDER;
118
 
      break;
119
 
   case I915_USAGE_2D_SOURCE:
120
 
      write_domain = 0;
121
 
      read_domain = I915_GEM_DOMAIN_RENDER;
122
 
      break;
123
 
   case I915_USAGE_VERTEX:
124
 
      write_domain = 0;
125
 
      read_domain = I915_GEM_DOMAIN_VERTEX;
126
 
      break;
127
 
   default:
128
 
      assert(0);
129
 
      return -1;
130
 
   }
131
 
 
132
 
   offset = (unsigned)(batch->base.ptr - batch->base.map);
133
 
 
134
 
   if (fenced)
135
 
      ret = drm_intel_bo_emit_reloc_fence(batch->bo, offset,
136
 
                                    intel_bo(buffer), pre_add,
137
 
                                    read_domain,
138
 
                                    write_domain);
139
 
   else
140
 
      ret = drm_intel_bo_emit_reloc(batch->bo, offset,
141
 
                                    intel_bo(buffer), pre_add,
142
 
                                    read_domain,
143
 
                                    write_domain);
144
 
 
145
 
   ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
146
 
   batch->base.ptr += 4;
147
 
 
148
 
   if (!ret)
149
 
      batch->base.relocs++;
150
 
 
151
 
   return ret;
152
 
}
153
 
 
154
 
static void
155
 
i915_drm_throttle(struct i915_drm_winsys *idws)
156
 
{
157
 
   drmIoctl(idws->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL);
158
 
}
159
 
 
160
 
static void
161
 
i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
162
 
                           struct pipe_fence_handle **fence,
163
 
                           enum i915_winsys_flush_flags flags)
164
 
{
165
 
   struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
166
 
   unsigned used;
167
 
   int ret;
168
 
 
169
 
   /* MI_BATCH_BUFFER_END */
170
 
   i915_winsys_batchbuffer_dword_unchecked(ibatch, (0xA<<23));
171
 
 
172
 
   used = batch->base.ptr - batch->base.map;
173
 
   if (used & 4) {
174
 
      /* MI_NOOP */
175
 
      i915_winsys_batchbuffer_dword_unchecked(ibatch, 0);
176
 
      used += 4;
177
 
   }
178
 
 
179
 
   /* Do the sending to HW */
180
 
   ret = drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
181
 
   if (ret == 0 && i915_drm_winsys(ibatch->iws)->send_cmd)
182
 
      ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
183
 
 
184
 
   if (flags & I915_FLUSH_END_OF_FRAME)
185
 
      i915_drm_throttle(i915_drm_winsys(ibatch->iws));
186
 
 
187
 
   if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) {
188
 
      i915_dump_batchbuffer(ibatch);
189
 
      assert(ret == 0);
190
 
   }
191
 
 
192
 
   if (i915_drm_winsys(ibatch->iws)->dump_raw_file) {
193
 
      FILE *file = fopen(i915_drm_winsys(ibatch->iws)->dump_raw_file, "a");
194
 
      if (file) {
195
 
         fwrite(batch->base.map, used, 1, file);
196
 
         fclose(file);
197
 
      }
198
 
   }
199
 
 
200
 
#ifdef INTEL_RUN_SYNC
201
 
   drm_intel_bo_wait_rendering(batch->bo);
202
 
#endif
203
 
 
204
 
   if (fence) {
205
 
      ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
206
 
 
207
 
#ifdef INTEL_RUN_SYNC
208
 
      /* we run synced to GPU so just pass null */
209
 
      (*fence) = i915_drm_fence_create(NULL);
210
 
#else
211
 
      (*fence) = i915_drm_fence_create(batch->bo);
212
 
#endif
213
 
   }
214
 
 
215
 
   i915_drm_batchbuffer_reset(batch);
216
 
}
217
 
 
218
 
static void
219
 
i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
220
 
{
221
 
   struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
222
 
 
223
 
   if (batch->bo)
224
 
      drm_intel_bo_unreference(batch->bo);
225
 
 
226
 
   FREE(batch->base.map);
227
 
   FREE(batch);
228
 
}
229
 
 
230
 
void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws)
231
 
{
232
 
   idws->base.batchbuffer_create = i915_drm_batchbuffer_create;
233
 
   idws->base.validate_buffers = i915_drm_batchbuffer_validate_buffers;
234
 
   idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc;
235
 
   idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush;
236
 
   idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy;
237
 
}