Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2013 LunarG, Inc.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors:
25
 *    Chia-I Wu 
26
 */
27
 
28
#include "util/u_prim.h"
29
#include "intel_winsys.h"
30
 
31
#include "ilo_context.h"
32
#include "ilo_cp.h"
33
#include "ilo_state.h"
34
#include "ilo_3d_pipeline_gen6.h"
35
#include "ilo_3d_pipeline_gen7.h"
36
#include "ilo_3d_pipeline.h"
37
 
38
/* in U0.4 */
39
struct sample_position {
40
   uint8_t x, y;
41
};
42
 
43
/* \see gen6_get_sample_position() */
44
static const struct sample_position sample_position_1x[1] = {
45
   {  8,  8 },
46
};
47
 
48
static const struct sample_position sample_position_4x[4] = {
49
   {  6,  2 }, /* distance from the center is sqrt(40) */
50
   { 14,  6 }, /* distance from the center is sqrt(40) */
51
   {  2, 10 }, /* distance from the center is sqrt(40) */
52
   { 10, 14 }, /* distance from the center is sqrt(40) */
53
};
54
 
55
static const struct sample_position sample_position_8x[8] = {
56
   {  7,  9 }, /* distance from the center is sqrt(2) */
57
   {  9, 13 }, /* distance from the center is sqrt(26) */
58
   { 11,  3 }, /* distance from the center is sqrt(34) */
59
   { 13, 11 }, /* distance from the center is sqrt(34) */
60
   {  1,  7 }, /* distance from the center is sqrt(50) */
61
   {  5,  1 }, /* distance from the center is sqrt(58) */
62
   { 15,  5 }, /* distance from the center is sqrt(58) */
63
   {  3, 15 }, /* distance from the center is sqrt(74) */
64
};
65
 
66
struct ilo_3d_pipeline *
67
ilo_3d_pipeline_create(struct ilo_cp *cp, const struct ilo_dev_info *dev)
68
{
69
   struct ilo_3d_pipeline *p;
70
   int i;
71
 
72
   p = CALLOC_STRUCT(ilo_3d_pipeline);
73
   if (!p)
74
      return NULL;
75
 
76
   p->cp = cp;
77
   p->dev = dev;
78
 
79
   switch (p->dev->gen) {
80
   case ILO_GEN(6):
81
      ilo_3d_pipeline_init_gen6(p);
82
      break;
83
   case ILO_GEN(7):
84
      ilo_3d_pipeline_init_gen7(p);
85
      break;
86
   default:
87
      assert(!"unsupported GEN");
88
      FREE(p);
89
      return NULL;
90
      break;
91
   }
92
 
93
   p->invalidate_flags = ILO_3D_PIPELINE_INVALIDATE_ALL;
94
 
95
   p->workaround_bo = intel_winsys_alloc_buffer(p->cp->winsys,
96
         "PIPE_CONTROL workaround", 4096, 0);
97
   if (!p->workaround_bo) {
98
      ilo_warn("failed to allocate PIPE_CONTROL workaround bo\n");
99
      FREE(p);
100
      return NULL;
101
   }
102
 
103
   p->packed_sample_position_1x =
104
      sample_position_1x[0].x << 4 |
105
      sample_position_1x[0].y;
106
 
107
   /* pack into dwords */
108
   for (i = 0; i < 4; i++) {
109
      p->packed_sample_position_4x |=
110
         sample_position_4x[i].x << (8 * i + 4) |
111
         sample_position_4x[i].y << (8 * i);
112
 
113
      p->packed_sample_position_8x[0] |=
114
         sample_position_8x[i].x << (8 * i + 4) |
115
         sample_position_8x[i].y << (8 * i);
116
 
117
      p->packed_sample_position_8x[1] |=
118
         sample_position_8x[4 + i].x << (8 * i + 4) |
119
         sample_position_8x[4 + i].y << (8 * i);
120
   }
121
 
122
   return p;
123
}
124
 
125
void
126
ilo_3d_pipeline_destroy(struct ilo_3d_pipeline *p)
127
{
128
   if (p->workaround_bo)
129
      intel_bo_unreference(p->workaround_bo);
130
 
131
   FREE(p);
132
}
133
 
134
static void
135
handle_invalid_batch_bo(struct ilo_3d_pipeline *p, bool unset)
136
{
137
   if (p->invalidate_flags & ILO_3D_PIPELINE_INVALIDATE_BATCH_BO) {
138
      if (p->dev->gen == ILO_GEN(6))
139
         p->state.has_gen6_wa_pipe_control = false;
140
 
141
      if (unset)
142
         p->invalidate_flags &= ~ILO_3D_PIPELINE_INVALIDATE_BATCH_BO;
143
   }
144
}
145
 
146
/**
147
 * Emit context states and 3DPRIMITIVE.
148
 */
149
bool
150
ilo_3d_pipeline_emit_draw(struct ilo_3d_pipeline *p,
151
                          const struct ilo_context *ilo,
152
                          int *prim_generated, int *prim_emitted)
153
{
154
   bool success;
155
 
156
   if (ilo->dirty & ILO_DIRTY_SO &&
157
       ilo->so.enabled && !ilo->so.append_bitmask) {
158
      /*
159
       * We keep track of the SVBI in the driver, so that we can restore it
160
       * when the HW context is invalidated (by another process).  The value
161
       * needs to be reset when stream output is enabled and the targets are
162
       * changed.
163
       */
164
      p->state.so_num_vertices = 0;
165
 
166
      /* on GEN7+, we need SOL_RESET to reset the SO write offsets */
167
      if (p->dev->gen >= ILO_GEN(7))
168
         ilo_cp_set_one_off_flags(p->cp, INTEL_EXEC_GEN7_SOL_RESET);
169
   }
170
 
171
 
172
   while (true) {
173
      struct ilo_cp_jmp_buf jmp;
174
      int err;
175
 
176
      /* we will rewind if aperture check below fails */
177
      ilo_cp_setjmp(p->cp, &jmp);
178
 
179
      handle_invalid_batch_bo(p, false);
180
 
181
      /* draw! */
182
      ilo_cp_assert_no_implicit_flush(p->cp, true);
183
      p->emit_draw(p, ilo);
184
      ilo_cp_assert_no_implicit_flush(p->cp, false);
185
 
186
      err = intel_winsys_check_aperture_space(ilo->winsys, &p->cp->bo, 1);
187
      if (!err) {
188
         success = true;
189
         break;
190
      }
191
 
192
      /* rewind */
193
      ilo_cp_longjmp(p->cp, &jmp);
194
 
195
      if (ilo_cp_empty(p->cp)) {
196
         success = false;
197
         break;
198
      }
199
      else {
200
         /* flush and try again */
201
         ilo_cp_flush(p->cp);
202
      }
203
   }
204
 
205
   if (success) {
206
      const int num_verts =
207
         u_vertices_per_prim(u_reduced_prim(ilo->draw->mode));
208
      const int max_emit =
209
         (p->state.so_max_vertices - p->state.so_num_vertices) / num_verts;
210
      const int generated =
211
         u_reduced_prims_for_vertices(ilo->draw->mode, ilo->draw->count);
212
      const int emitted = MIN2(generated, max_emit);
213
 
214
      p->state.so_num_vertices += emitted * num_verts;
215
 
216
      if (prim_generated)
217
         *prim_generated = generated;
218
 
219
      if (prim_emitted)
220
         *prim_emitted = emitted;
221
   }
222
 
223
   p->invalidate_flags = 0x0;
224
 
225
   return success;
226
}
227
 
228
/**
229
 * Emit PIPE_CONTROL to flush all caches.
230
 */
231
void
232
ilo_3d_pipeline_emit_flush(struct ilo_3d_pipeline *p)
233
{
234
   handle_invalid_batch_bo(p, true);
235
   p->emit_flush(p);
236
}
237
 
238
/**
239
 * Emit PIPE_CONTROL with PIPE_CONTROL_WRITE_TIMESTAMP post-sync op.
240
 */
241
void
242
ilo_3d_pipeline_emit_write_timestamp(struct ilo_3d_pipeline *p,
243
                                     struct intel_bo *bo, int index)
244
{
245
   handle_invalid_batch_bo(p, true);
246
   p->emit_write_timestamp(p, bo, index);
247
}
248
 
249
/**
250
 * Emit PIPE_CONTROL with PIPE_CONTROL_WRITE_DEPTH_COUNT post-sync op.
251
 */
252
void
253
ilo_3d_pipeline_emit_write_depth_count(struct ilo_3d_pipeline *p,
254
                                       struct intel_bo *bo, int index)
255
{
256
   handle_invalid_batch_bo(p, true);
257
   p->emit_write_depth_count(p, bo, index);
258
}
259
 
260
void
261
ilo_3d_pipeline_get_sample_position(struct ilo_3d_pipeline *p,
262
                                    unsigned sample_count,
263
                                    unsigned sample_index,
264
                                    float *x, float *y)
265
{
266
   const struct sample_position *pos;
267
 
268
   switch (sample_count) {
269
   case 1:
270
      assert(sample_index < Elements(sample_position_1x));
271
      pos = sample_position_1x;
272
      break;
273
   case 4:
274
      assert(sample_index < Elements(sample_position_4x));
275
      pos = sample_position_4x;
276
      break;
277
   case 8:
278
      assert(sample_index < Elements(sample_position_8x));
279
      pos = sample_position_8x;
280
      break;
281
   default:
282
      assert(!"unknown sample count");
283
      *x = 0.5f;
284
      *y = 0.5f;
285
      return;
286
      break;
287
   }
288
 
289
   *x = (float) pos[sample_index].x / 16.0f;
290
   *y = (float) pos[sample_index].y / 16.0f;
291
}