vrend_renderer.c 349 KB
Newer Older
Dave Airlie's avatar
Dave Airlie committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**************************************************************************
 *
 * Copyright (C) 2014 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/
24
25
26
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Dave Airlie's avatar
Dave Airlie committed
27

28
#include <unistd.h>
29
#include <stdio.h>
Dave Airlie's avatar
Dave Airlie committed
30
#include <errno.h>
31
32
33
34
35
36
37
38
#include "pipe/p_shader_tokens.h"

#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
Dave Airlie's avatar
Dave Airlie committed
39
40
#include "util/u_dual_blend.h"

41
#include "os/os_thread.h"
42
43
44
45
46
#include "util/u_double_list.h"
#include "util/u_format.h"
#include "tgsi/tgsi_parse.h"

#include "vrend_object.h"
Dave Airlie's avatar
Dave Airlie committed
47
#include "vrend_shader.h"
48

Dave Airlie's avatar
Dave Airlie committed
49
#include "vrend_renderer.h"
50
#include "vrend_debug.h"
51
52

#include "virgl_hw.h"
53
#include "virglrenderer.h"
Dave Airlie's avatar
Dave Airlie committed
54

55
#include "tgsi/tgsi_text.h"
56
57
58
59
60

#ifdef HAVE_EVENTFD
#include <sys/eventfd.h>
#endif

61
62
63
64
65
66
67
#ifdef HAVE_EPOXY_EGL_H
#include "virgl_gbm.h"
#include "virgl_egl.h"
extern struct virgl_gbm *gbm;
extern struct virgl_egl *egl;
#endif

68
69
70
/* debugging via KHR_debug extension */
int vrend_use_debug_cb = 0;

71
72
int use_context = CONTEXT_NONE;

73
74
static const uint32_t fake_occlusion_query_samples_passed_default = 1024;

Dave Airlie's avatar
Dave Airlie committed
75
struct vrend_if_cbs *vrend_clicbs;
76

Dave Airlie's avatar
Dave Airlie committed
77
struct vrend_fence {
78
79
80
81
82
83
   uint32_t fence_id;
   uint32_t ctx_id;
   GLsync syncobj;
   struct list_head fences;
};

Dave Airlie's avatar
Dave Airlie committed
84
struct vrend_query {
85
86
   struct list_head waiting_queries;

87
   GLuint id;
88
   GLuint type;
89
   GLuint index;
90
91
   GLuint gltype;
   int ctx_id;
Dave Airlie's avatar
Dave Airlie committed
92
   struct vrend_resource *res;
93
   uint64_t current_total;
94
   bool fake_samples_passed;
95
96
97
98
99
100
};

struct global_error_state {
   enum virgl_errors last_error;
};

101
102
103
104
enum features_id
{
   feat_arb_or_gles_ext_texture_buffer,
   feat_arb_robustness,
105
   feat_arrays_of_arrays,
106
   feat_atomic_counters,
107
   feat_base_instance,
108
   feat_barrier,
109
   feat_bind_vertex_buffers,
110
   feat_bit_encoding,
111
   feat_clip_control,
112
   feat_compute_shader,
113
   feat_copy_image,
114
   feat_conditional_render_inverted,
115
   feat_conservative_depth,
116
   feat_cube_map_array,
117
   feat_debug_cb,
118
   feat_depth_clamp,
119
   feat_draw_instance,
120
   feat_dual_src_blend,
121
   feat_fb_no_attach,
122
   feat_enhanced_layouts,
123
   feat_framebuffer_fetch,
124
   feat_framebuffer_fetch_non_coherent,
125
   feat_geometry_shader,
126
127
128
   feat_gl_conditional_render,
   feat_gl_prim_restart,
   feat_gles_khr_robustness,
129
   feat_gles31_compatibility,
130
   feat_gles31_vertex_attrib_binding,
131
   feat_gpu_shader5,
132
   feat_images,
133
   feat_indep_blend,
134
   feat_indep_blend_func,
135
   feat_indirect_draw,
136
   feat_indirect_params,
137
138
139
   feat_mesa_invert,
   feat_ms_scaled_blit,
   feat_multisample,
140
   feat_multi_draw_indirect,
141
142
143
   feat_nv_conditional_render,
   feat_nv_prim_restart,
   feat_polygon_offset_clamp,
144
145
   feat_occlusion_query,
   feat_occlusion_query_boolean,
146
   feat_qbo,
147
   feat_robust_buffer_access,
148
   feat_sample_mask,
149
150
   feat_sample_shading,
   feat_samplers,
Dave Airlie's avatar
Dave Airlie committed
151
   feat_shader_clock,
152
   feat_separate_shader_objects,
153
   feat_ssbo,
154
   feat_ssbo_barrier,
155
   feat_srgb_write_control,
156
   feat_stencil_texturing,
157
   feat_storage_multisample,
158
   feat_tessellation,
159
   feat_texture_array,
160
   feat_texture_barrier,
161
   feat_texture_buffer_range,
162
   feat_texture_gather,
163
   feat_texture_multisample,
164
   feat_texture_query_lod,
165
   feat_texture_srgb_decode,
166
167
   feat_texture_storage,
   feat_texture_view,
168
   feat_timer_query,
169
   feat_transform_feedback,
170
   feat_transform_feedback2,
171
   feat_transform_feedback3,
172
   feat_transform_feedback_overflow_query,
173
   feat_txqs,
Dave Airlie's avatar
Dave Airlie committed
174
   feat_ubo,
175
   feat_viewport_array,
176
177
178
   feat_last,
};

179
180
181
#define FEAT_MAX_EXTS 4
#define UNAVAIL INT_MAX

182
183
184
#define FEAT(NAME, GLVER, GLESVER, ...) \
   [feat_ ## NAME ] = {GLVER, GLESVER, { __VA_ARGS__ }, #NAME}

185
186
187
188
static const  struct {
   int gl_ver;
   int gles_ver;
   const char *gl_ext[FEAT_MAX_EXTS];
189
   const char *log_name;
190
} feature_list[] = {
191
192
   FEAT(arb_or_gles_ext_texture_buffer, 31, UNAVAIL, "GL_ARB_texture_buffer_object", "GL_EXT_texture_buffer", NULL),
   FEAT(arb_robustness, UNAVAIL, UNAVAIL,  "GL_ARB_robustness" ),
193
   FEAT(arrays_of_arrays, 43, 31, "GL_ARB_arrays_of_arrays"),
194
195
196
   FEAT(atomic_counters, 42, 31,  "GL_ARB_shader_atomic_counters" ),
   FEAT(base_instance, 42, UNAVAIL,  "GL_ARB_base_instance", "GL_EXT_base_instance" ),
   FEAT(barrier, 42, 31, NULL),
197
   FEAT(bind_vertex_buffers, 44, UNAVAIL, NULL),
198
   FEAT(bit_encoding, 33, UNAVAIL,  "GL_ARB_shader_bit_encoding" ),
199
   FEAT(clip_control, 45, UNAVAIL, "GL_ARB_clip_control", "GL_EXT_clip_control"),
200
201
202
   FEAT(compute_shader, 43, 31,  "GL_ARB_compute_shader" ),
   FEAT(copy_image, 43, 32,  "GL_ARB_copy_image", "GL_EXT_copy_image", "GL_OES_copy_image" ),
   FEAT(conditional_render_inverted, 45, UNAVAIL,  "GL_ARB_conditional_render_inverted" ),
203
   FEAT(conservative_depth, 42, UNAVAIL, "GL_ARB_conservative_depth", "GL_EXT_conservative_depth" ),
204
205
206
   FEAT(cube_map_array, 40, 32,  "GL_ARB_texture_cube_map_array", "GL_EXT_texture_cube_map_array", "GL_OES_texture_cube_map_array" ),
   FEAT(debug_cb, UNAVAIL, UNAVAIL, NULL), /* special case */
   FEAT(draw_instance, 31, 30,  "GL_ARB_draw_instanced" ),
207
   FEAT(dual_src_blend, 33, UNAVAIL,  "GL_ARB_blend_func_extended", "GL_EXT_blend_func_extended" ),
208
   FEAT(depth_clamp, 32, UNAVAIL, "GL_ARB_depth_clamp", "GL_EXT_depth_clamp", "GL_NV_depth_clamp"),
209
   FEAT(enhanced_layouts, 44, UNAVAIL, "GL_ARB_enhanced_layouts"),
210
211
   FEAT(fb_no_attach, 43, 31,  "GL_ARB_framebuffer_no_attachments" ),
   FEAT(framebuffer_fetch, UNAVAIL, UNAVAIL,  "GL_EXT_shader_framebuffer_fetch" ),
212
   FEAT(framebuffer_fetch_non_coherent, UNAVAIL, UNAVAIL,  "GL_EXT_shader_framebuffer_fetch_non_coherent" ),
213
214
215
216
   FEAT(geometry_shader, 32, 32, "GL_EXT_geometry_shader", "GL_OES_geometry_shader"),
   FEAT(gl_conditional_render, 30, UNAVAIL, NULL),
   FEAT(gl_prim_restart, 31, 30, NULL),
   FEAT(gles_khr_robustness, UNAVAIL, UNAVAIL,  "GL_KHR_robustness" ),
217
   FEAT(gles31_compatibility, 45, 31, "ARB_ES3_1_compatibility" ),
218
219
220
221
222
223
   FEAT(gles31_vertex_attrib_binding, 43, 31,  "GL_ARB_vertex_attrib_binding" ),
   FEAT(gpu_shader5, 40, 32, "GL_ARB_gpu_shader5", "GL_EXT_gpu_shader5", "GL_OES_gpu_shader5" ),
   FEAT(images, 42, 31,  "GL_ARB_shader_image_load_store" ),
   FEAT(indep_blend, 30, 32,  "GL_EXT_draw_buffers2", "GL_OES_draw_buffers_indexed" ),
   FEAT(indep_blend_func, 40, 32,  "GL_ARB_draw_buffers_blend", "GL_OES_draw_buffers_indexed"),
   FEAT(indirect_draw, 40, 31,  "GL_ARB_draw_indirect" ),
224
   FEAT(indirect_params, 46, UNAVAIL,  "GL_ARB_indirect_parameters" ),
225
226
227
   FEAT(mesa_invert, UNAVAIL, UNAVAIL,  "GL_MESA_pack_invert" ),
   FEAT(ms_scaled_blit, UNAVAIL, UNAVAIL,  "GL_EXT_framebuffer_multisample_blit_scaled" ),
   FEAT(multisample, 32, 30,  "GL_ARB_texture_multisample" ),
228
   FEAT(multi_draw_indirect, 43, UNAVAIL,  "GL_ARB_multi_draw_indirect", "GL_EXT_multi_draw_indirect" ),
229
230
   FEAT(nv_conditional_render, UNAVAIL, UNAVAIL,  "GL_NV_conditional_render" ),
   FEAT(nv_prim_restart, UNAVAIL, UNAVAIL,  "GL_NV_primitive_restart" ),
231
   FEAT(polygon_offset_clamp, 46, UNAVAIL,  "GL_ARB_polygon_offset_clamp", "GL_EXT_polygon_offset_clamp"),
232
233
   FEAT(occlusion_query, 15, UNAVAIL, "GL_ARB_occlusion_query"),
   FEAT(occlusion_query_boolean, 33, 30, "GL_EXT_occlusion_query_boolean", "GL_ARB_occlusion_query2"),
234
   FEAT(qbo, 44, UNAVAIL, "GL_ARB_query_buffer_object" ),
235
236
237
238
   FEAT(robust_buffer_access, 43, UNAVAIL,  "GL_ARB_robust_buffer_access_behavior", "GL_KHR_robust_buffer_access_behavior" ),
   FEAT(sample_mask, 32, 31,  "GL_ARB_texture_multisample" ),
   FEAT(sample_shading, 40, 32,  "GL_ARB_sample_shading", "GL_OES_sample_shading" ),
   FEAT(samplers, 33, 30,  "GL_ARB_sampler_objects" ),
239
   FEAT(separate_shader_objects, 41, 31, "GL_ARB_seperate_shader_objects"),
240
241
242
   FEAT(shader_clock, UNAVAIL, UNAVAIL,  "GL_ARB_shader_clock" ),
   FEAT(ssbo, 43, 31,  "GL_ARB_shader_storage_buffer_object" ),
   FEAT(ssbo_barrier, 43, 31, NULL),
243
   FEAT(srgb_write_control, 30, UNAVAIL, "GL_EXT_sRGB_write_control"),
244
245
246
247
248
249
250
251
   FEAT(stencil_texturing, 43, 31,  "GL_ARB_stencil_texturing" ),
   FEAT(storage_multisample, 43, 31,  "GL_ARB_texture_storage_multisample" ),
   FEAT(tessellation, 40, 32,  "GL_ARB_tessellation_shader", "GL_OES_tessellation_shader", "GL_EXT_tessellation_shader" ),
   FEAT(texture_array, 30, 30,  "GL_EXT_texture_array" ),
   FEAT(texture_barrier, 45, UNAVAIL,  "GL_ARB_texture_barrier" ),
   FEAT(texture_buffer_range, 43, 32,  "GL_ARB_texture_buffer_range" ),
   FEAT(texture_gather, 40, 31,  "GL_ARB_texture_gather" ),
   FEAT(texture_multisample, 32, 30,  "GL_ARB_texture_multisample" ),
252
   FEAT(texture_query_lod, 40, UNAVAIL, "GL_ARB_texture_query_lod", "GL_EXT_texture_query_lod"),
253
254
   FEAT(texture_srgb_decode, UNAVAIL, UNAVAIL,  "GL_EXT_texture_sRGB_decode" ),
   FEAT(texture_storage, 42, 30,  "GL_ARB_texture_storage" ),
255
   FEAT(texture_view, 43, UNAVAIL,  "GL_ARB_texture_view", "GL_OES_texture_view" ),
256
   FEAT(timer_query, 33, UNAVAIL, "GL_ARB_timer_query", "GL_EXT_disjoint_timer_query"),
257
258
259
260
261
262
   FEAT(transform_feedback, 30, 30,  "GL_EXT_transform_feedback" ),
   FEAT(transform_feedback2, 40, 30,  "GL_ARB_transform_feedback2" ),
   FEAT(transform_feedback3, 40, UNAVAIL,  "GL_ARB_transform_feedback3" ),
   FEAT(transform_feedback_overflow_query, 46, UNAVAIL,  "GL_ARB_transform_feedback_overflow_query" ),
   FEAT(txqs, 45, UNAVAIL,  "GL_ARB_shader_texture_image_samples" ),
   FEAT(ubo, 31, 30,  "GL_ARB_uniform_buffer_object" ),
263
   FEAT(viewport_array, 41, UNAVAIL,  "GL_ARB_viewport_array", "GL_OES_viewport_array"),
264
265
};

266
struct global_renderer_state {
267
268
269
   int gl_major_ver;
   int gl_minor_ver;

Dave Airlie's avatar
Dave Airlie committed
270
271
   struct vrend_context *current_ctx;
   struct vrend_context *current_hw_ctx;
272
273
   struct list_head waiting_query_list;

274
   bool inited;
275
   bool use_gles;
276
277
   bool use_core_profile;

278
   bool features[feat_last];
279

280
281
   /* these appeared broken on at least one driver */
   bool use_explicit_locations;
282
   uint32_t max_draw_buffers;
283
284
285
   uint32_t max_texture_2d_size;
   uint32_t max_texture_3d_size;
   uint32_t max_texture_cube_size;
286
   struct list_head active_ctx_list;
287
288
289
290
291
292
293
294
295
296
297
298

   /* threaded sync */
   bool stop_sync_thread;
   int eventfd;

   pipe_mutex fence_mutex;
   struct list_head fence_list;
   struct list_head fence_wait_list;
   pipe_condvar fence_cond;

   pipe_thread sync_thread;
   virgl_gl_context sync_context;
299
300
301

   /* Needed on GLES to inject a TCS */
   float tess_factors[6];
302
303
   bool bgra_srgb_emulation_loaded;

304
305
};

Dave Airlie's avatar
Dave Airlie committed
306
static struct global_renderer_state vrend_state;
307

308
309
static inline bool has_feature(enum features_id feature_id)
{
310
311
312
   VREND_DEBUG(dbg_feature_use, NULL, "Try using feature %s:%d\n",
               feature_list[feature_id].log_name,
               vrend_state.features[feature_id]);
313
314
315
316
317
318
319
320
   return vrend_state.features[feature_id];
}

static inline void set_feature(enum features_id feature_id)
{
   vrend_state.features[feature_id] = true;
}

Dave Airlie's avatar
Dave Airlie committed
321
struct vrend_linked_shader_program {
322
323
324
   struct list_head head;
   struct list_head sl[PIPE_SHADER_TYPES];
   GLuint id;
325

326
327
   bool dual_src_linked;
   struct vrend_shader *ss[PIPE_SHADER_TYPES];
328

329
   uint32_t ubo_used_mask[PIPE_SHADER_TYPES];
330
   uint32_t samplers_used_mask[PIPE_SHADER_TYPES];
331

332
333
   GLuint *shadow_samp_mask_locs[PIPE_SHADER_TYPES];
   GLuint *shadow_samp_add_locs[PIPE_SHADER_TYPES];
334

335
   GLint const_location[PIPE_SHADER_TYPES];
336

337
338
   GLuint *attrib_locs;
   uint32_t shadow_samp_mask[PIPE_SHADER_TYPES];
339

340
   GLuint vs_ws_adjust_loc;
341
   float viewport_neg_val;
Dave Airlie's avatar
Dave Airlie committed
342

Gert Wollny's avatar
Gert Wollny committed
343
   GLint fs_stipple_loc;
Dave Airlie's avatar
Dave Airlie committed
344

345
   GLuint clip_locs[8];
346

347
348
349
   uint32_t images_used_mask[PIPE_SHADER_TYPES];
   GLint *img_locs[PIPE_SHADER_TYPES];

350
351
   uint32_t ssbo_used_mask[PIPE_SHADER_TYPES];
   GLuint *ssbo_locs[PIPE_SHADER_TYPES];
352
353

   struct vrend_sub_context *ref_context;
354
355
};

Dave Airlie's avatar
Dave Airlie committed
356
357
358
struct vrend_shader {
   struct vrend_shader *next_variant;
   struct vrend_shader_selector *sel;
359

360
   struct vrend_strarray glsl_strings;
361
362
363
   GLuint id;
   GLuint compiled_fs_id;
   struct vrend_shader_key key;
364
   struct list_head programs;
365
366
};

Dave Airlie's avatar
Dave Airlie committed
367
struct vrend_shader_selector {
368
369
370
371
   struct pipe_reference reference;

   unsigned num_shaders;
   unsigned type;
372
373
374
375
   struct vrend_shader_info sinfo;

   struct vrend_shader *current;
   struct tgsi_token *tokens;
376

377
   uint32_t req_local_mem;
378
379
380
   char *tmp_buf;
   uint32_t buf_len;
   uint32_t buf_offset;
381
382
};

Dave Airlie's avatar
Dave Airlie committed
383
384
struct vrend_texture {
   struct vrend_resource base;
385
   struct pipe_sampler_state state;
386
387
388
389
390
391
   GLenum cur_swizzle_r;
   GLenum cur_swizzle_g;
   GLenum cur_swizzle_b;
   GLenum cur_swizzle_a;
   GLuint cur_srgb_decode;
   GLuint cur_base, cur_max;
392
393
};

Dave Airlie's avatar
Dave Airlie committed
394
struct vrend_surface {
395
396
397
398
399
   struct pipe_reference reference;
   GLuint id;
   GLuint res_handle;
   GLuint format;
   GLuint val0, val1;
Dave Airlie's avatar
Dave Airlie committed
400
   struct vrend_resource *texture;
401
402
};

Dave Airlie's avatar
Dave Airlie committed
403
404
struct vrend_sampler_state {
   struct pipe_sampler_state base;
405
   GLuint ids[2];
406
407
};

Dave Airlie's avatar
Dave Airlie committed
408
struct vrend_so_target {
409
410
411
412
   struct pipe_reference reference;
   GLuint res_handle;
   unsigned buffer_offset;
   unsigned buffer_size;
Dave Airlie's avatar
Dave Airlie committed
413
   struct vrend_resource *buffer;
414
   struct vrend_sub_context *sub_ctx;
415
416
};

Dave Airlie's avatar
Dave Airlie committed
417
struct vrend_sampler_view {
418
419
   struct pipe_reference reference;
   GLuint id;
420
   enum pipe_format format;
421
   GLenum target;
422
423
424
425
426
427
428
   GLuint val0, val1;
   GLuint gl_swizzle_r;
   GLuint gl_swizzle_g;
   GLuint gl_swizzle_b;
   GLuint gl_swizzle_a;
   GLenum depth_texture_mode;
   GLuint srgb_decode;
429
   struct vrend_resource *texture;
430
431
};

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
struct vrend_image_view {
   GLuint id;
   GLenum access;
   GLenum format;
   union {
      struct {
         unsigned first_layer:16;     /**< first layer to use for array textures */
         unsigned last_layer:16;      /**< last layer to use for array textures */
         unsigned level:8;            /**< mipmap level to use */
      } tex;
      struct {
         unsigned offset;   /**< offset in bytes */
         unsigned size;     /**< size of the accessible sub-range in bytes */
      } buf;
   } u;
   struct vrend_resource *texture;
};

450
451
452
453
454
455
struct vrend_ssbo {
   struct vrend_resource *res;
   unsigned buffer_size;
   unsigned buffer_offset;
};

456
457
458
459
460
461
struct vrend_abo {
   struct vrend_resource *res;
   unsigned buffer_size;
   unsigned buffer_offset;
};

Dave Airlie's avatar
Dave Airlie committed
462
struct vrend_vertex_element {
463
464
465
466
467
468
   struct pipe_vertex_element base;
   GLenum type;
   GLboolean norm;
   GLuint nr_chan;
};

Dave Airlie's avatar
Dave Airlie committed
469
struct vrend_vertex_element_array {
470
   unsigned count;
Dave Airlie's avatar
Dave Airlie committed
471
   struct vrend_vertex_element elements[PIPE_MAX_ATTRIBS];
472
   GLuint id;
473
474
};

Dave Airlie's avatar
Dave Airlie committed
475
476
struct vrend_constants {
   unsigned int *consts;
477
   uint32_t num_consts;
478
   uint32_t num_allocated_consts;
479
480
};

Dave Airlie's avatar
Dave Airlie committed
481
struct vrend_shader_view {
482
   int num_views;
Dave Airlie's avatar
Dave Airlie committed
483
   struct vrend_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
484
485
486
487
   uint32_t res_id[PIPE_MAX_SHADER_SAMPLER_VIEWS];
   uint32_t old_ids[PIPE_MAX_SHADER_SAMPLER_VIEWS];
};

488
489
490
491
492
struct vrend_viewport {
   GLint cur_x, cur_y;
   GLsizei width, height;
   GLclampd near_val, far_val;
};
Dave Airlie's avatar
Dave Airlie committed
493

494
495
496
497
498
499
500
501
502
503
/* create a streamout object to support pause/resume */
struct vrend_streamout_object {
   GLuint id;
   uint32_t num_targets;
   uint32_t handles[16];
   struct list_head head;
   int xfb_state;
   struct vrend_so_target *so_targets[16];
};

504
505
506
507
508
#define XFB_STATE_OFF 0
#define XFB_STATE_STARTED_NEED_BEGIN 1
#define XFB_STATE_STARTED 2
#define XFB_STATE_PAUSED 3

509
struct vrend_sub_context {
Dave Airlie's avatar
Dave Airlie committed
510
   struct list_head head;
511
512
513

   virgl_gl_context gl_context;

Dave Airlie's avatar
Dave Airlie committed
514
   int sub_ctx_id;
515

Dave Airlie's avatar
Dave Airlie committed
516
   GLuint vaoid;
517
518
   uint32_t enabled_attribs_bitmask;

Dave Airlie's avatar
Dave Airlie committed
519
   struct list_head programs;
520
   struct util_hash_table *object_hash;
Dave Airlie's avatar
Dave Airlie committed
521
522

   struct vrend_vertex_element_array *ve;
523
   int num_vbos;
524
   int old_num_vbos; /* for cleaning up */
525
526
   struct pipe_vertex_buffer vbo[PIPE_MAX_ATTRIBS];
   uint32_t vbo_res_ids[PIPE_MAX_ATTRIBS];
527
528
529
530

   struct pipe_index_buffer ib;
   uint32_t index_buffer_res_id;

531
   bool vbo_dirty;
532
   bool shader_dirty;
533
   bool cs_shader_dirty;
534
   bool stencil_state_dirty;
535
   bool image_state_dirty;
536
   bool blend_state_dirty;
537

538
539
   uint32_t long_shader_in_progress_handle[PIPE_SHADER_TYPES];
   struct vrend_shader_selector *shaders[PIPE_SHADER_TYPES];
Dave Airlie's avatar
Dave Airlie committed
540
   struct vrend_linked_shader_program *prog;
541

542
   int prog_ids[PIPE_SHADER_TYPES];
Dave Airlie's avatar
Dave Airlie committed
543
   struct vrend_shader_view views[PIPE_SHADER_TYPES];
544

Dave Airlie's avatar
Dave Airlie committed
545
   struct vrend_constants consts[PIPE_SHADER_TYPES];
546
   bool const_dirty[PIPE_SHADER_TYPES];
Dave Airlie's avatar
Dave Airlie committed
547
548
549
550
   struct vrend_sampler_state *sampler_state[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];

   struct pipe_constant_buffer cbs[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
   uint32_t const_bufs_used_mask[PIPE_SHADER_TYPES];
551
   uint32_t const_bufs_dirty[PIPE_SHADER_TYPES];
552
553
554

   int num_sampler_states[PIPE_SHADER_TYPES];

555
556
   uint32_t sampler_views_dirty[PIPE_SHADER_TYPES];

Dave Airlie's avatar
Dave Airlie committed
557
558
559
   uint32_t fb_id;
   int nr_cbufs, old_nr_cbufs;
   struct vrend_surface *zsurf;
560
   struct vrend_surface *surf[PIPE_MAX_COLOR_BUFS];
561

562
   struct vrend_viewport vps[PIPE_MAX_VIEWPORTS];
563
   /* viewport is negative */
564
565
   uint32_t scissor_state_dirty;
   uint32_t viewport_state_dirty;
566
   uint32_t viewport_state_initialized;
567

568
569
   uint32_t fb_height;

570
   struct pipe_scissor_state ss[PIPE_MAX_VIEWPORTS];
571
572
573
574
575

   struct pipe_blend_state blend_state;
   struct pipe_depth_stencil_alpha_state dsa_state;
   struct pipe_rasterizer_state rs_state;

Dave Airlie's avatar
Dave Airlie committed
576
   uint8_t stencil_refs[2];
577
578
579
580
   bool viewport_is_negative;
   /* this is set if the contents of the FBO look upside down when viewed
      with 0,0 as the bottom corner */
   bool inverted_fbo_content;
Dave Airlie's avatar
Dave Airlie committed
581
582
583
584
585
586

   GLuint blit_fb_ids[2];

   struct pipe_depth_stencil_alpha_state *dsa;

   struct pipe_clip_state ucp_state;
587

588
589
590
   bool depth_test_enabled;
   bool alpha_test_enabled;
   bool stencil_test_enabled;
591
   bool framebuffer_srgb_enabled;
592

593
   GLuint program_id;
594
   int last_shader_idx;
595

596
597
   GLint draw_indirect_buffer;

598
599
   GLint draw_indirect_params_buffer;

600
601
   struct pipe_rasterizer_state hw_rs_state;
   struct pipe_blend_state hw_blend_state;
602

603
   struct list_head streamout_list;
604
   struct vrend_streamout_object *current_so;
605
606

   struct pipe_blend_color blend_color;
607
608
609

   uint32_t cond_render_q_id;
   GLenum cond_render_gl_mode;
610

611
612
613
   struct vrend_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
   uint32_t images_used_mask[PIPE_SHADER_TYPES];

614
615
   struct vrend_ssbo ssbo[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
   uint32_t ssbo_used_mask[PIPE_SHADER_TYPES];
616
617
618

   struct vrend_abo abo[PIPE_MAX_HW_ATOMIC_BUFFERS];
   uint32_t abo_used_mask;
619
   struct vrend_context_tweaks tweaks;
620
   uint8_t swizzle_output_rgb_to_bgr;
621
   int fake_occlusion_query_samples_passed_multiplier;
Dave Airlie's avatar
Dave Airlie committed
622
623
624
625
626
627
628
629
630
631
632
};

struct vrend_context {
   char debug_name[64];

   struct list_head sub_ctxs;

   struct vrend_sub_context *sub;
   struct vrend_sub_context *sub0;

   int ctx_id;
633
   /* has this ctx gotten an error? */
634
635
636
   bool in_error;
   bool ctx_switch_pending;
   bool pstip_inited;
637

Dave Airlie's avatar
Dave Airlie committed
638
639
   GLuint pstipple_tex_id;

640
641
642
643
   enum virgl_ctx_errors last_error;

   /* resource bounds to this context */
   struct util_hash_table *res_hash;
644

645
   struct list_head active_nontimer_query_list;
646
   struct list_head ctx_entry;
647
648

   struct vrend_shader_cfg shader_cfg;
649
650

   unsigned debug_flags;
651
652
};

Dave Airlie's avatar
Dave Airlie committed
653
static struct vrend_resource *vrend_renderer_ctx_res_lookup(struct vrend_context *ctx, int res_handle);
654
static void vrend_pause_render_condition(struct vrend_context *ctx, bool pause);
Dave Airlie's avatar
Dave Airlie committed
655
656
657
658
static void vrend_update_viewport_state(struct vrend_context *ctx);
static void vrend_update_scissor_state(struct vrend_context *ctx);
static void vrend_destroy_query_object(void *obj_ptr);
static void vrend_finish_context_switch(struct vrend_context *ctx);
659
static void vrend_patch_blend_state(struct vrend_context *ctx);
Dave Airlie's avatar
Dave Airlie committed
660
661
662
663
static void vrend_update_frontface_state(struct vrend_context *ctx);
static void vrender_get_glsl_version(int *glsl_version);
static void vrend_destroy_resource_object(void *obj_ptr);
static void vrend_renderer_detach_res_ctx_p(struct vrend_context *ctx, int res_handle);
664
static void vrend_destroy_program(struct vrend_linked_shader_program *ent);
Dave Airlie's avatar
Dave Airlie committed
665
666
667
static void vrend_apply_sampler_state(struct vrend_context *ctx,
                                      struct vrend_resource *res,
                                      uint32_t shader_type,
668
669
                                      int id, int sampler_id,
                                      struct vrend_sampler_view *tview);
670
671
static GLenum tgsitargettogltarget(const enum pipe_texture_target target, int nr_samples);

Dave Airlie's avatar
Dave Airlie committed
672
void vrend_update_stencil_state(struct vrend_context *ctx);
673

674
static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX_EXTENDED];
675

676
static inline bool vrend_format_can_sample(enum virgl_formats format)
Dave Airlie's avatar
Dave Airlie committed
677
{
678
   return tex_conv_table[format].bindings & VIRGL_BIND_SAMPLER_VIEW;
Dave Airlie's avatar
Dave Airlie committed
679
}
680
681
682
683
684
685

static inline bool vrend_format_can_readback(enum virgl_formats format)
{
   return tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_READBACK;
}

686
static inline bool vrend_format_can_render(enum virgl_formats format)
687
{
688
   return tex_conv_table[format].bindings & VIRGL_BIND_RENDER_TARGET;
689
690
}

691
static inline bool vrend_format_is_ds(enum virgl_formats format)
692
{
693
   return tex_conv_table[format].bindings & VIRGL_BIND_DEPTH_STENCIL;
694
695
}

696
697
698
static inline bool vrend_format_can_scanout(enum virgl_formats format)
{
#ifdef ENABLE_GBM_ALLOCATION
699
700
701
702
   uint32_t gbm_format = 0;
   if (virgl_gbm_convert_format(&format, &gbm_format))
      return false;

703
   if (!gbm || !gbm->device || !gbm_format)
704
705
706
707
      return false;

   return gbm_device_is_format_supported(gbm->device, gbm_format, GBM_BO_USE_SCANOUT);
#else
708
   (void)format;
709
710
711
712
   return true;
#endif
}

713
714
715
716
717
struct vrend_context_tweaks *vrend_get_context_tweaks(struct vrend_context *ctx)
{
   return &ctx->sub->tweaks;
}

Dave Airlie's avatar
Dave Airlie committed
718
bool vrend_format_is_emulated_alpha(enum virgl_formats format)
719
{
720
   if (vrend_state.use_gles || !vrend_state.use_core_profile)
721
722
723
724
725
      return false;
   return (format == VIRGL_FORMAT_A8_UNORM ||
           format == VIRGL_FORMAT_A16_UNORM);
}

726
727
static bool vrend_blit_needs_swizzle(enum virgl_formats src,
                                     enum virgl_formats dst)
728
{
729
730
731
732
733
   for (int i = 0; i < 4; ++i) {
      if (tex_conv_table[src].swizzle[i] != tex_conv_table[dst].swizzle[i])
         return true;
   }
   return false;
734
735
}

Dave Airlie's avatar
Dave Airlie committed
736
737
738
739
740
741
static inline const char *pipe_shader_to_prefix(int shader_type)
{
   switch (shader_type) {
   case PIPE_SHADER_VERTEX: return "vs";
   case PIPE_SHADER_FRAGMENT: return "fs";
   case PIPE_SHADER_GEOMETRY: return "gs";
742
743
   case PIPE_SHADER_TESS_CTRL: return "tc";
   case PIPE_SHADER_TESS_EVAL: return "te";
744
   case PIPE_SHADER_COMPUTE: return "cs";
Marc-André Lureau's avatar
Marc-André Lureau committed
745
746
   default:
      return NULL;
Dave Airlie's avatar
Dave Airlie committed
747
748
749
   };
}

750
751
752
753
754
755
756
757
758
static const char *vrend_ctx_error_strings[] = {
   [VIRGL_ERROR_CTX_NONE]                  = "None",
   [VIRGL_ERROR_CTX_UNKNOWN]               = "Unknown",
   [VIRGL_ERROR_CTX_ILLEGAL_SHADER]        = "Illegal shader",
   [VIRGL_ERROR_CTX_ILLEGAL_HANDLE]        = "Illegal handle",
   [VIRGL_ERROR_CTX_ILLEGAL_RESOURCE]      = "Illegal resource",
   [VIRGL_ERROR_CTX_ILLEGAL_SURFACE]       = "Illegal surface",
   [VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT] = "Illegal vertex format",
   [VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER]    = "Illegal command buffer",
759
760
   [VIRGL_ERROR_CTX_GLES_HAVE_TES_BUT_MISS_TCS] = "On GLES context and shader program has tesselation evaluation shader but no tesselation control shader",
   [VIRGL_ERROR_GL_ANY_SAMPLES_PASSED] = "Query for ANY_SAMPLES_PASSED not supported",
761
   [VIRGL_ERROR_CTX_ILLEGAL_FORMAT]        = "Illegal format ID",
762
   [VIRGL_ERROR_CTX_ILLEGAL_SAMPLER_VIEW_TARGET] = "Illegat target for sampler view",
763
   [VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS]   = "IOV data size exceeds resource capacity",
764
};
765

766
767
static void __report_context_error(const char *fname, struct vrend_context *ctx,
                                   enum virgl_ctx_errors error, uint32_t value)
768
{
769
   ctx->in_error = true;
770
   ctx->last_error = error;
771
772
773
   vrend_printf("%s: context error reported %d \"%s\" %s %d\n", fname,
                ctx->ctx_id, ctx->debug_name, vrend_ctx_error_strings[error],
                value);
774
775
776
}
#define report_context_error(ctx, error, value) __report_context_error(__func__, ctx, error, value)

Dave Airlie's avatar
Dave Airlie committed
777
778
779
780
781
782
783
784
785
786
787
788
void vrend_report_buffer_error(struct vrend_context *ctx, int cmd)
{
   report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, cmd);
}

#define CORE_PROFILE_WARN_NONE 0
#define CORE_PROFILE_WARN_STIPPLE 1
#define CORE_PROFILE_WARN_POLYGON_MODE 2
#define CORE_PROFILE_WARN_TWO_SIDE 3
#define CORE_PROFILE_WARN_CLAMP 4
#define CORE_PROFILE_WARN_SHADE_MODEL 5

789
790
791
792
793
794
795
796
static const char *vrend_core_profile_warn_strings[] = {
   [CORE_PROFILE_WARN_NONE]         = "None",
   [CORE_PROFILE_WARN_STIPPLE]      = "Stipple",
   [CORE_PROFILE_WARN_POLYGON_MODE] = "Polygon Mode",
   [CORE_PROFILE_WARN_TWO_SIDE]     = "Two Side",
   [CORE_PROFILE_WARN_CLAMP]        = "Clamping",
   [CORE_PROFILE_WARN_SHADE_MODEL]  = "Shade Model",
};
Dave Airlie's avatar
Dave Airlie committed
797

798
799
static void __report_core_warn(const char *fname, struct vrend_context *ctx,
                               enum virgl_ctx_errors error)
Dave Airlie's avatar
Dave Airlie committed
800
{
801
802
803
   vrend_printf("%s: core profile violation reported %d \"%s\" %s\n", fname,
                ctx->ctx_id, ctx->debug_name,
                vrend_core_profile_warn_strings[error]);
Dave Airlie's avatar
Dave Airlie committed
804
}
805
#define report_core_warn(ctx, error) __report_core_warn(__func__, ctx, error)
806
807
808
809
810


#define GLES_WARN_NONE 0
#define GLES_WARN_STIPPLE 1
#define GLES_WARN_POLYGON_MODE 2
811
#define GLES_WARN_DEPTH_RANGE 3
812
#define GLES_WARN_POINT_SIZE 4
813
#define GLES_WARN_SEAMLESS_CUBE_MAP 5
814
#define GLES_WARN_LOD_BIAS 6
815
#define GLES_WARN_TEXTURE_RECT 7
816
817
#define GLES_WARN_OFFSET_LINE 8
#define GLES_WARN_OFFSET_POINT 9
818
//#define GLES_WARN_ free slot 10
819
820
821
822
823
824
825
#define GLES_WARN_FLATSHADE_FIRST 11
#define GLES_WARN_LINE_SMOOTH 12
#define GLES_WARN_POLY_SMOOTH 13
#define GLES_WARN_DEPTH_CLEAR 14
#define GLES_WARN_LOGIC_OP 15
#define GLES_WARN_TIMESTAMP 16

826
MAYBE_UNUSED
827
static const char *vrend_gles_warn_strings[] = {
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
   [GLES_WARN_NONE]             = "None",
   [GLES_WARN_STIPPLE]          = "Stipple",
   [GLES_WARN_POLYGON_MODE]     = "Polygon Mode",
   [GLES_WARN_DEPTH_RANGE]      = "Depth Range",
   [GLES_WARN_POINT_SIZE]       = "Point Size",
   [GLES_WARN_SEAMLESS_CUBE_MAP] = "Seamless Cube Map",
   [GLES_WARN_LOD_BIAS]         = "Lod Bias",
   [GLES_WARN_TEXTURE_RECT]     = "Texture Rect",
   [GLES_WARN_OFFSET_LINE]      = "Offset Line",
   [GLES_WARN_OFFSET_POINT]     = "Offset Point",
   [GLES_WARN_FLATSHADE_FIRST]  = "Flatshade First",
   [GLES_WARN_LINE_SMOOTH]      = "Line Smooth",
   [GLES_WARN_POLY_SMOOTH]      = "Poly Smooth",
   [GLES_WARN_DEPTH_CLEAR]      = "Depth Clear",
   [GLES_WARN_LOGIC_OP]         = "LogicOp",
   [GLES_WARN_TIMESTAMP]        = "GL_TIMESTAMP",
844
};
845

846
847
848
static void __report_gles_warn(MAYBE_UNUSED const char *fname,
                               MAYBE_UNUSED struct vrend_context *ctx,
                               MAYBE_UNUSED enum virgl_ctx_errors error)
849
{
850
   VREND_DEBUG(dbg_gles, ctx, "%s: GLES violation - %s\n", fname, vrend_gles_warn_strings[error]);
851
}
852
#define report_gles_warn(ctx, error) __report_gles_warn(__func__, ctx, error)
853

854
855
856
static void __report_gles_missing_func(MAYBE_UNUSED const char *fname,
                                       MAYBE_UNUSED struct vrend_context *ctx,
                                       MAYBE_UNUSED const char *missf)
857
{
858
   VREND_DEBUG(dbg_gles, ctx, "%s: GLES function %s is missing\n", fname, missf);
859
}
860

861
862
#define report_gles_missing_func(ctx, missf) __report_gles_missing_func(__func__, ctx, missf)

863
864
865
866
static void init_features(int gl_ver, int gles_ver)
{
   for (enum features_id id = 0; id < feat_last; id++) {
      if (gl_ver >= feature_list[id].gl_ver ||
867
          gles_ver >= feature_list[id].gles_ver) {
868
         set_feature(id);
869
870
871
872
         VREND_DEBUG(dbg_features, NULL, "Host feature %s provided by %s %3.1f\n",
                     feature_list[id].log_name, (gl_ver > 0 ? "GL" : "GLES"),
                     0.1f * (gl_ver > 0 ? gl_ver : gles_ver));
      } else {
873
874
875
876
877
         for (uint32_t i = 0; i < FEAT_MAX_EXTS; i++) {
            if (!feature_list[id].gl_ext[i])
               break;
            if (epoxy_has_gl_extension(feature_list[id].gl_ext[i])) {
               set_feature(id);
878
879
880
               VREND_DEBUG(dbg_features, NULL,
                           "Host feature %s provide by %s\n", feature_list[id].log_name,
                           feature_list[id].gl_ext[i]);
881
882
883
884
885
886
887
               break;
            }
         }
      }
   }
}

Dave Airlie's avatar
Dave Airlie committed
888
static void vrend_destroy_surface(struct vrend_surface *surf)
889
{
890
891
   if (surf->id != surf->texture->id)
      glDeleteTextures(1, &surf->id);
Dave Airlie's avatar
Dave Airlie committed
892
   vrend_resource_reference(&surf->texture, NULL);
893
894
895
   free(surf);
}

896
static inline void
Dave Airlie's avatar
Dave Airlie committed
897
vrend_surface_reference(struct vrend_surface **ptr, struct vrend_surface *surf)
898
{
Dave Airlie's avatar
Dave Airlie committed
899
   struct vrend_surface *old_surf = *ptr;
900
901

   if (pipe_reference(&(*ptr)->reference, &surf->reference))
Dave Airlie's avatar
Dave Airlie committed
902
      vrend_destroy_surface(old_surf);
903
904
905
   *ptr = surf;
}

Dave Airlie's avatar
Dave Airlie committed
906
static void vrend_destroy_sampler_view(struct vrend_sampler_view *samp)
907
{
908
909
   if (samp->texture->id != samp->id)
      glDeleteTextures(1, &samp->id);
Dave Airlie's avatar
Dave Airlie committed
910
   vrend_resource_reference(&samp->texture, NULL);
911
912
913
   free(samp);
}

914
static inline void
Dave Airlie's avatar
Dave Airlie committed
915
vrend_sampler_view_reference(struct vrend_sampler_view **ptr, struct vrend_sampler_view *view)
916
{
Dave Airlie's avatar
Dave Airlie committed
917
   struct vrend_sampler_view *old_view = *ptr;
918
919

   if (pipe_reference(&(*ptr)->reference, &view->reference))
Dave Airlie's avatar
Dave Airlie committed
920
      vrend_destroy_sampler_view(old_view);
921
922
923
   *ptr = view;
}

Dave Airlie's avatar
Dave Airlie committed
924
static void vrend_destroy_so_target(struct vrend_so_target *target)
925
{
Dave Airlie's avatar
Dave Airlie committed
926
   vrend_resource_reference(&target->buffer, NULL);
927
928
929
   free(target);
}

930
static inline void
Dave Airlie's avatar
Dave Airlie committed
931
vrend_so_target_reference(struct vrend_so_target **ptr, struct vrend_so_target *target)
932
{
Dave Airlie's avatar
Dave Airlie committed
933
   struct vrend_so_target *old_target = *ptr;
934
935

   if (pipe_reference(&(*ptr)->reference, &target->reference))
Dave Airlie's avatar
Dave Airlie committed
936
      vrend_destroy_so_target(old_target);
937
938
939
   *ptr = target;
}

940
941
942
static void vrend_shader_dump(struct vrend_shader *shader)
{
   const char *prefix = pipe_shader_to_prefix(shader->sel->type);