vrend_renderer.c 352 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

Gurchetan Singh's avatar
Gurchetan Singh committed
52
53
#include "vrend_util.h"

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

57
#include "tgsi/tgsi_text.h"
58
59
60
61
62

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

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

70
71
int use_context = CONTEXT_NONE;

72
73
static const uint32_t fake_occlusion_query_samples_passed_default = 1024;

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

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

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

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

struct global_error_state {
   enum virgl_errors last_error;
};

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

180
181
182
#define FEAT_MAX_EXTS 4
#define UNAVAIL INT_MAX

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

186
187
188
189
static const  struct {
   int gl_ver;
   int gles_ver;
   const char *gl_ext[FEAT_MAX_EXTS];
190
   const char *log_name;
191
} feature_list[] = {
192
193
   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" ),
194
   FEAT(arrays_of_arrays, 43, 31, "GL_ARB_arrays_of_arrays"),
195
196
197
   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),
198
   FEAT(bind_vertex_buffers, 44, UNAVAIL, NULL),
199
   FEAT(bit_encoding, 33, UNAVAIL,  "GL_ARB_shader_bit_encoding" ),
200
   FEAT(clip_control, 45, UNAVAIL, "GL_ARB_clip_control", "GL_EXT_clip_control"),
201
202
203
   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" ),
204
   FEAT(conservative_depth, 42, UNAVAIL, "GL_ARB_conservative_depth", "GL_EXT_conservative_depth" ),
205
206
207
   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" ),
208
   FEAT(dual_src_blend, 33, UNAVAIL,  "GL_ARB_blend_func_extended", "GL_EXT_blend_func_extended" ),
209
   FEAT(depth_clamp, 32, UNAVAIL, "GL_ARB_depth_clamp", "GL_EXT_depth_clamp", "GL_NV_depth_clamp"),
210
   FEAT(enhanced_layouts, 44, UNAVAIL, "GL_ARB_enhanced_layouts"),
211
212
   FEAT(egl_image_external, UNAVAIL, UNAVAIL, "GL_OES_EGL_image_external"),
   FEAT(egl_image_storage, UNAVAIL, UNAVAIL, "GL_EXT_EGL_image_storage"),
213
214
   FEAT(fb_no_attach, 43, 31,  "GL_ARB_framebuffer_no_attachments" ),
   FEAT(framebuffer_fetch, UNAVAIL, UNAVAIL,  "GL_EXT_shader_framebuffer_fetch" ),
215
   FEAT(framebuffer_fetch_non_coherent, UNAVAIL, UNAVAIL,  "GL_EXT_shader_framebuffer_fetch_non_coherent" ),
216
217
218
219
   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" ),
220
   FEAT(gles31_compatibility, 45, 31, "ARB_ES3_1_compatibility" ),
221
222
223
224
225
226
   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" ),
227
   FEAT(indirect_params, 46, UNAVAIL,  "GL_ARB_indirect_parameters" ),
228
229
230
   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" ),
231
   FEAT(multi_draw_indirect, 43, UNAVAIL,  "GL_ARB_multi_draw_indirect", "GL_EXT_multi_draw_indirect" ),
232
233
   FEAT(nv_conditional_render, UNAVAIL, UNAVAIL,  "GL_NV_conditional_render" ),
   FEAT(nv_prim_restart, UNAVAIL, UNAVAIL,  "GL_NV_primitive_restart" ),
234
   FEAT(polygon_offset_clamp, 46, UNAVAIL,  "GL_ARB_polygon_offset_clamp", "GL_EXT_polygon_offset_clamp"),
235
236
   FEAT(occlusion_query, 15, UNAVAIL, "GL_ARB_occlusion_query"),
   FEAT(occlusion_query_boolean, 33, 30, "GL_EXT_occlusion_query_boolean", "GL_ARB_occlusion_query2"),
237
   FEAT(qbo, 44, UNAVAIL, "GL_ARB_query_buffer_object" ),
238
239
240
241
   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" ),
242
   FEAT(separate_shader_objects, 41, 31, "GL_ARB_seperate_shader_objects"),
243
244
245
   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),
246
   FEAT(srgb_write_control, 30, UNAVAIL, "GL_EXT_sRGB_write_control"),
247
248
249
250
251
252
253
254
   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" ),
255
   FEAT(texture_query_lod, 40, UNAVAIL, "GL_ARB_texture_query_lod", "GL_EXT_texture_query_lod"),
256
257
   FEAT(texture_srgb_decode, UNAVAIL, UNAVAIL,  "GL_EXT_texture_sRGB_decode" ),
   FEAT(texture_storage, 42, 30,  "GL_ARB_texture_storage" ),
258
   FEAT(texture_view, 43, UNAVAIL,  "GL_ARB_texture_view", "GL_OES_texture_view" ),
259
   FEAT(timer_query, 33, UNAVAIL, "GL_ARB_timer_query", "GL_EXT_disjoint_timer_query"),
260
261
262
263
264
265
   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" ),
266
   FEAT(viewport_array, 41, UNAVAIL,  "GL_ARB_viewport_array", "GL_OES_viewport_array"),
267
268
};

269
struct global_renderer_state {
270
271
272
   int gl_major_ver;
   int gl_minor_ver;

Dave Airlie's avatar
Dave Airlie committed
273
274
   struct vrend_context *current_ctx;
   struct vrend_context *current_hw_ctx;
275
276
   struct list_head waiting_query_list;

277
   bool inited;
278
   bool use_gles;
279
280
   bool use_core_profile;

281
   bool features[feat_last];
282

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

   /* 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;
302
303
304

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

307
308
};

Dave Airlie's avatar
Dave Airlie committed
309
static struct global_renderer_state vrend_state;
310

311
312
static inline bool has_feature(enum features_id feature_id)
{
313
314
315
   VREND_DEBUG(dbg_feature_use, NULL, "Try using feature %s:%d\n",
               feature_list[feature_id].log_name,
               vrend_state.features[feature_id]);
316
317
318
319
320
321
322
323
   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
324
struct vrend_linked_shader_program {
325
326
327
   struct list_head head;
   struct list_head sl[PIPE_SHADER_TYPES];
   GLuint id;
328

329
330
   bool dual_src_linked;
   struct vrend_shader *ss[PIPE_SHADER_TYPES];
331

332
   uint32_t ubo_used_mask[PIPE_SHADER_TYPES];
333
   uint32_t samplers_used_mask[PIPE_SHADER_TYPES];
334

335
336
   GLuint *shadow_samp_mask_locs[PIPE_SHADER_TYPES];
   GLuint *shadow_samp_add_locs[PIPE_SHADER_TYPES];
337

338
   GLint const_location[PIPE_SHADER_TYPES];
339

340
341
   GLuint *attrib_locs;
   uint32_t shadow_samp_mask[PIPE_SHADER_TYPES];
342

343
   GLuint vs_ws_adjust_loc;
344
   float viewport_neg_val;
Dave Airlie's avatar
Dave Airlie committed
345

Gert Wollny's avatar
Gert Wollny committed
346
   GLint fs_stipple_loc;
Dave Airlie's avatar
Dave Airlie committed
347

348
   GLuint clip_locs[8];
349

350
351
352
   uint32_t images_used_mask[PIPE_SHADER_TYPES];
   GLint *img_locs[PIPE_SHADER_TYPES];

353
354
   uint32_t ssbo_used_mask[PIPE_SHADER_TYPES];
   GLuint *ssbo_locs[PIPE_SHADER_TYPES];
355
356

   struct vrend_sub_context *ref_context;
357
358
};

Dave Airlie's avatar
Dave Airlie committed
359
360
361
struct vrend_shader {
   struct vrend_shader *next_variant;
   struct vrend_shader_selector *sel;
362

363
   struct vrend_strarray glsl_strings;
364
365
366
   GLuint id;
   GLuint compiled_fs_id;
   struct vrend_shader_key key;
367
   struct list_head programs;
368
369
};

Dave Airlie's avatar
Dave Airlie committed
370
struct vrend_shader_selector {
371
372
373
374
   struct pipe_reference reference;

   unsigned num_shaders;
   unsigned type;
375
376
377
378
   struct vrend_shader_info sinfo;

   struct vrend_shader *current;
   struct tgsi_token *tokens;
379

380
   uint32_t req_local_mem;
381
382
383
   char *tmp_buf;
   uint32_t buf_len;
   uint32_t buf_offset;
384
385
};

Dave Airlie's avatar
Dave Airlie committed
386
387
struct vrend_texture {
   struct vrend_resource base;
388
   struct pipe_sampler_state state;
389
390
391
392
393
394
   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;
395
396
};

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

Dave Airlie's avatar
Dave Airlie committed
406
407
struct vrend_sampler_state {
   struct pipe_sampler_state base;
408
   GLuint ids[2];
409
410
};

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

Dave Airlie's avatar
Dave Airlie committed
420
struct vrend_sampler_view {
421
422
   struct pipe_reference reference;
   GLuint id;
423
   enum virgl_formats format;
424
   GLenum target;
425
426
427
428
429
430
431
   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;
432
   struct vrend_resource *texture;
433
434
};

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
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;
};

453
454
455
456
457
458
struct vrend_ssbo {
   struct vrend_resource *res;
   unsigned buffer_size;
   unsigned buffer_offset;
};

459
460
461
462
463
464
struct vrend_abo {
   struct vrend_resource *res;
   unsigned buffer_size;
   unsigned buffer_offset;
};

Dave Airlie's avatar
Dave Airlie committed
465
struct vrend_vertex_element {
466
467
468
469
470
471
   struct pipe_vertex_element base;
   GLenum type;
   GLboolean norm;
   GLuint nr_chan;
};

Dave Airlie's avatar
Dave Airlie committed
472
struct vrend_vertex_element_array {
473
   unsigned count;
Dave Airlie's avatar
Dave Airlie committed
474
   struct vrend_vertex_element elements[PIPE_MAX_ATTRIBS];
475
   GLuint id;
476
477
};

Dave Airlie's avatar
Dave Airlie committed
478
479
struct vrend_constants {
   unsigned int *consts;
480
   uint32_t num_consts;
481
   uint32_t num_allocated_consts;
482
483
};

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

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

497
498
499
500
501
502
503
504
505
506
/* 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];
};

507
508
509
510
511
#define XFB_STATE_OFF 0
#define XFB_STATE_STARTED_NEED_BEGIN 1
#define XFB_STATE_STARTED 2
#define XFB_STATE_PAUSED 3

512
struct vrend_sub_context {
Dave Airlie's avatar
Dave Airlie committed
513
   struct list_head head;
514
515
516

   virgl_gl_context gl_context;

Dave Airlie's avatar
Dave Airlie committed
517
   int sub_ctx_id;
518

Dave Airlie's avatar
Dave Airlie committed
519
   GLuint vaoid;
520
521
   uint32_t enabled_attribs_bitmask;

Dave Airlie's avatar
Dave Airlie committed
522
   struct list_head programs;
523
   struct util_hash_table *object_hash;
Dave Airlie's avatar
Dave Airlie committed
524
525

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

   struct pipe_index_buffer ib;
   uint32_t index_buffer_res_id;

534
   bool vbo_dirty;
535
   bool shader_dirty;
536
   bool cs_shader_dirty;
537
   bool stencil_state_dirty;
538
   bool image_state_dirty;
539
   bool blend_state_dirty;
540

541
542
   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
543
   struct vrend_linked_shader_program *prog;
544

545
   int prog_ids[PIPE_SHADER_TYPES];
Dave Airlie's avatar
Dave Airlie committed
546
   struct vrend_shader_view views[PIPE_SHADER_TYPES];
547

Dave Airlie's avatar
Dave Airlie committed
548
   struct vrend_constants consts[PIPE_SHADER_TYPES];
549
   bool const_dirty[PIPE_SHADER_TYPES];
Dave Airlie's avatar
Dave Airlie committed
550
551
552
553
   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];
554
   uint32_t const_bufs_dirty[PIPE_SHADER_TYPES];
555
556
557

   int num_sampler_states[PIPE_SHADER_TYPES];

558
559
   uint32_t sampler_views_dirty[PIPE_SHADER_TYPES];

Dave Airlie's avatar
Dave Airlie committed
560
561
562
   uint32_t fb_id;
   int nr_cbufs, old_nr_cbufs;
   struct vrend_surface *zsurf;
563
   struct vrend_surface *surf[PIPE_MAX_COLOR_BUFS];
564

565
   struct vrend_viewport vps[PIPE_MAX_VIEWPORTS];
566
   /* viewport is negative */
567
568
   uint32_t scissor_state_dirty;
   uint32_t viewport_state_dirty;
569
   uint32_t viewport_state_initialized;
570

571
572
   uint32_t fb_height;

573
   struct pipe_scissor_state ss[PIPE_MAX_VIEWPORTS];
574
575
576
577
578

   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
579
   uint8_t stencil_refs[2];
580
581
582
583
   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
584
585
586
587
588
589

   GLuint blit_fb_ids[2];

   struct pipe_depth_stencil_alpha_state *dsa;

   struct pipe_clip_state ucp_state;
590

591
592
593
   bool depth_test_enabled;
   bool alpha_test_enabled;
   bool stencil_test_enabled;
594
   bool framebuffer_srgb_enabled;
595

596
   GLuint program_id;
597
   int last_shader_idx;
598

599
600
   GLint draw_indirect_buffer;

601
602
   GLint draw_indirect_params_buffer;

603
604
   struct pipe_rasterizer_state hw_rs_state;
   struct pipe_blend_state hw_blend_state;
605

606
   struct list_head streamout_list;
607
   struct vrend_streamout_object *current_so;
608
609

   struct pipe_blend_color blend_color;
610
611
612

   uint32_t cond_render_q_id;
   GLenum cond_render_gl_mode;
613

614
615
616
   struct vrend_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
   uint32_t images_used_mask[PIPE_SHADER_TYPES];

617
618
   struct vrend_ssbo ssbo[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
   uint32_t ssbo_used_mask[PIPE_SHADER_TYPES];
619
620
621

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

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;
636
   /* has this ctx gotten an error? */
637
638
639
   bool in_error;
   bool ctx_switch_pending;
   bool pstip_inited;
640

Dave Airlie's avatar
Dave Airlie committed
641
642
   GLuint pstipple_tex_id;

643
644
645
646
   enum virgl_ctx_errors last_error;

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

648
   struct list_head active_nontimer_query_list;
649
   struct list_head ctx_entry;
650
651

   struct vrend_shader_cfg shader_cfg;
652
653

   unsigned debug_flags;
654
655
};

Dave Airlie's avatar
Dave Airlie committed
656
static struct vrend_resource *vrend_renderer_ctx_res_lookup(struct vrend_context *ctx, int res_handle);
657
static void vrend_pause_render_condition(struct vrend_context *ctx, bool pause);
Dave Airlie's avatar
Dave Airlie committed
658
659
660
661
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);
662
static void vrend_patch_blend_state(struct vrend_context *ctx);
Dave Airlie's avatar
Dave Airlie committed
663
664
665
666
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);
667
static void vrend_destroy_program(struct vrend_linked_shader_program *ent);
Dave Airlie's avatar
Dave Airlie committed
668
669
670
static void vrend_apply_sampler_state(struct vrend_context *ctx,
                                      struct vrend_resource *res,
                                      uint32_t shader_type,
671
672
                                      int id, int sampler_id,
                                      struct vrend_sampler_view *tview);
673
674
static GLenum tgsitargettogltarget(const enum pipe_texture_target target, int nr_samples);

Dave Airlie's avatar
Dave Airlie committed
675
void vrend_update_stencil_state(struct vrend_context *ctx);
676

677
static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX_EXTENDED];
678

679
static inline bool vrend_format_can_sample(enum virgl_formats format)
Dave Airlie's avatar
Dave Airlie committed
680
{
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
   if (tex_conv_table[format].bindings & VIRGL_BIND_SAMPLER_VIEW)
      return true;

#ifdef ENABLE_GBM_ALLOCATION
   uint32_t gbm_format = 0;
   if (virgl_gbm_convert_format(&format, &gbm_format))
      return false;

   if (!gbm || !gbm->device || !gbm_format)
      return false;

   return gbm_device_is_format_supported(gbm->device, gbm_format, GBM_BO_USE_TEXTURING);
#else
   return false;
#endif
Dave Airlie's avatar
Dave Airlie committed
696
}
697
698
699
700
701
702

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

703
static inline bool vrend_format_can_render(enum virgl_formats format)
704
{
705
   return tex_conv_table[format].bindings & VIRGL_BIND_RENDER_TARGET;
706
707
}

708
static inline bool vrend_format_is_ds(enum virgl_formats format)
709
{
710
   return tex_conv_table[format].bindings & VIRGL_BIND_DEPTH_STENCIL;
711
712
}

713
714
715
static inline bool vrend_format_can_scanout(enum virgl_formats format)
{
#ifdef ENABLE_GBM_ALLOCATION
716
717
718
719
   uint32_t gbm_format = 0;
   if (virgl_gbm_convert_format(&format, &gbm_format))
      return false;

720
   if (!gbm || !gbm->device || !gbm_format)
721
722
723
724
      return false;

   return gbm_device_is_format_supported(gbm->device, gbm_format, GBM_BO_USE_SCANOUT);
#else
725
   (void)format;
726
727
728
729
   return true;
#endif
}

730
731
732
733
734
struct vrend_context_tweaks *vrend_get_context_tweaks(struct vrend_context *ctx)
{
   return &ctx->sub->tweaks;
}

Dave Airlie's avatar
Dave Airlie committed
735
bool vrend_format_is_emulated_alpha(enum virgl_formats format)
736
{
737
   if (vrend_state.use_gles || !vrend_state.use_core_profile)
738
739
740
741
742
      return false;
   return (format == VIRGL_FORMAT_A8_UNORM ||
           format == VIRGL_FORMAT_A16_UNORM);
}

743
744
static bool vrend_blit_needs_swizzle(enum virgl_formats src,
                                     enum virgl_formats dst)
745
{
746
747
748
749
750
   for (int i = 0; i < 4; ++i) {
      if (tex_conv_table[src].swizzle[i] != tex_conv_table[dst].swizzle[i])
         return true;
   }
   return false;
751
752
}

Dave Airlie's avatar
Dave Airlie committed
753
754
755
756
757
758
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";
759
760
   case PIPE_SHADER_TESS_CTRL: return "tc";
   case PIPE_SHADER_TESS_EVAL: return "te";
761
   case PIPE_SHADER_COMPUTE: return "cs";
Marc-André Lureau's avatar
Marc-André Lureau committed
762
763
   default:
      return NULL;
Dave Airlie's avatar
Dave Airlie committed
764
765
766
   };
}

767
768
769
770
771
772
773
774
775
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",
776
777
   [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",
778
   [VIRGL_ERROR_CTX_ILLEGAL_FORMAT]        = "Illegal format ID",
779
   [VIRGL_ERROR_CTX_ILLEGAL_SAMPLER_VIEW_TARGET] = "Illegat target for sampler view",
780
   [VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS]   = "IOV data size exceeds resource capacity",
781
};
782

783
784
static void __report_context_error(const char *fname, struct vrend_context *ctx,
                                   enum virgl_ctx_errors error, uint32_t value)
785
{
786
   ctx->in_error = true;
787
   ctx->last_error = error;
788
789
790
   vrend_printf("%s: context error reported %d \"%s\" %s %d\n", fname,
                ctx->ctx_id, ctx->debug_name, vrend_ctx_error_strings[error],
                value);
791
792
793
}
#define report_context_error(ctx, error, value) __report_context_error(__func__, ctx, error, value)

Dave Airlie's avatar
Dave Airlie committed
794
795
796
797
798
799
800
801
802
803
804
805
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

806
807
808
809
810
811
812
813
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
814

815
816
static void __report_core_warn(const char *fname, struct vrend_context *ctx,
                               enum virgl_ctx_errors error)
Dave Airlie's avatar
Dave Airlie committed
817
{
818
819
820
   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
821
}
822
#define report_core_warn(ctx, error) __report_core_warn(__func__, ctx, error)
823
824
825
826
827


#define GLES_WARN_NONE 0
#define GLES_WARN_STIPPLE 1
#define GLES_WARN_POLYGON_MODE 2
828
#define GLES_WARN_DEPTH_RANGE 3
829
#define GLES_WARN_POINT_SIZE 4
830
#define GLES_WARN_SEAMLESS_CUBE_MAP 5
831
#define GLES_WARN_LOD_BIAS 6
832
#define GLES_WARN_TEXTURE_RECT 7
833
834
#define GLES_WARN_OFFSET_LINE 8
#define GLES_WARN_OFFSET_POINT 9
835
//#define GLES_WARN_ free slot 10
836
837
838
839
840
841
842
#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

843
MAYBE_UNUSED
844
static const char *vrend_gles_warn_strings[] = {
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
   [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",
861
};
862

863
864
865
static void __report_gles_warn(MAYBE_UNUSED const char *fname,
                               MAYBE_UNUSED struct vrend_context *ctx,
                               MAYBE_UNUSED enum virgl_ctx_errors error)
866
{
867
   VREND_DEBUG(dbg_gles, ctx, "%s: GLES violation - %s\n", fname, vrend_gles_warn_strings[error]);
868
}
869
#define report_gles_warn(ctx, error) __report_gles_warn(__func__, ctx, error)
870

871
872
873
static void __report_gles_missing_func(MAYBE_UNUSED const char *fname,
                                       MAYBE_UNUSED struct vrend_context *ctx,
                                       MAYBE_UNUSED const char *missf)
874
{
875
   VREND_DEBUG(dbg_gles, ctx, "%s: GLES function %s is missing\n", fname, missf);
876
}
877

878
879
#define report_gles_missing_func(ctx, missf) __report_gles_missing_func(__func__, ctx, missf)

880
881
882
883
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 ||
884
          gles_ver >= feature_list[id].gles_ver) {
885
         set_feature(id);
886
887
888
889
         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 {
890
891
892
893
894
         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);
895
896
897
               VREND_DEBUG(dbg_features, NULL,
                           "Host feature %s provide by %s\n", feature_list[id].log_name,
                           feature_list[id].gl_ext[i]);
898
899
900
901
902
903
904
               break;
            }
         }
      }
   }
}

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

913
static inline void
Dave Airlie's avatar
Dave Airlie committed
914
vrend_surface_reference(struct vrend_surface **ptr, struct vrend_surface *surf)
915
{
Dave Airlie's avatar
Dave Airlie committed
916
   struct vrend_surface *old_surf = *ptr;
917
918

   if (pipe_reference(&(*ptr)->reference, &surf->reference))
Dave Airlie's avatar
Dave Airlie committed
919
      vrend_destroy_surface(old_surf);
920
921
922
   *ptr = surf;
}

Dave Airlie's avatar
Dave Airlie committed
923
static void vrend_destroy_sampler_view(struct vrend_sampler_view *samp)
924
{
925
926
   if (samp->texture->id != samp->id)
      glDeleteTextures(1, &samp->id);
Dave Airlie's avatar
Dave Airlie committed
927
   vrend_resource_reference(&samp->texture, NULL);
928
929
930
   free(samp);
}

931
static inline void
Dave Airlie's avatar
Dave Airlie committed
932
vrend_sampler_view_reference(struct vrend_sampler_view **ptr, struct vrend_sampler_view *view)
933
{
Dave Airlie's avatar
Dave Airlie committed
934
   struct vrend_sampler_view *old_view = *ptr;
935
936

   if (pipe_reference(&(*ptr)->reference, &view->reference))
Dave Airlie's avatar
Dave Airlie committed
937
      vrend_destroy_sampler_view(old_view);
938
939
940
   *ptr = view;
}

Dave Airlie's avatar
Dave Airlie committed
941
static void vrend_destroy_so_target(struct vrend_so_target *target)
942
{
Dave Airlie's avatar
Dave Airlie committed
943
   vrend_resource_reference(&target->buffer, NULL);
944
945
946
   free(target);
}

947
static inline void
Dave Airlie's avatar
Dave Airlie committed
948
vrend_so_target_reference(struct vrend_so_target **ptr, struct vrend_so_target *target)
949
{
Dave Airlie's avatar
Dave Airlie committed
950
   struct vrend_so_target *old_target = *p