xref: /aosp_15_r20/external/mesa3d/src/mesa/state_tracker/st_context.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 
29 #include "main/accum.h"
30 #include "main/context.h"
31 #include "main/debug_output.h"
32 #include "main/framebuffer.h"
33 #include "main/glthread.h"
34 #include "main/shaderobj.h"
35 #include "main/state.h"
36 #include "main/version.h"
37 #include "main/hash.h"
38 #include "program/prog_cache.h"
39 #include "vbo/vbo.h"
40 #include "glapi/glapi.h"
41 #include "st_manager.h"
42 #include "st_context.h"
43 #include "st_debug.h"
44 #include "st_cb_bitmap.h"
45 #include "st_cb_clear.h"
46 #include "st_cb_drawpixels.h"
47 #include "st_cb_drawtex.h"
48 #include "st_cb_eglimage.h"
49 #include "st_cb_feedback.h"
50 #include "st_cb_flush.h"
51 #include "st_atom.h"
52 #include "st_draw.h"
53 #include "st_extensions.h"
54 #include "st_gen_mipmap.h"
55 #include "st_pbo.h"
56 #include "st_program.h"
57 #include "st_sampler_view.h"
58 #include "st_shader_cache.h"
59 #include "st_texcompress_compute.h"
60 #include "st_texture.h"
61 #include "st_util.h"
62 #include "pipe/p_context.h"
63 #include "util/u_cpu_detect.h"
64 #include "util/u_inlines.h"
65 #include "util/u_upload_mgr.h"
66 #include "util/u_vbuf.h"
67 #include "util/u_memory.h"
68 #include "util/hash_table.h"
69 #include "util/thread_sched.h"
70 #include "cso_cache/cso_context.h"
71 #include "compiler/glsl/glsl_parser_extras.h"
72 
73 DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", false)
74 
75 void
st_invalidate_buffers(struct st_context * st)76 st_invalidate_buffers(struct st_context *st)
77 {
78    st->ctx->NewDriverState |= ST_NEW_BLEND |
79                               ST_NEW_DSA |
80                               ST_NEW_FB_STATE |
81                               ST_NEW_SAMPLE_STATE |
82                               ST_NEW_SAMPLE_SHADING |
83                               ST_NEW_FS_STATE |
84                               ST_NEW_POLY_STIPPLE |
85                               ST_NEW_VIEWPORT |
86                               ST_NEW_RASTERIZER |
87                               ST_NEW_SCISSOR |
88                               ST_NEW_WINDOW_RECTANGLES;
89 }
90 
91 
92 static inline bool
st_vp_uses_current_values(const struct gl_context * ctx)93 st_vp_uses_current_values(const struct gl_context *ctx)
94 {
95    const uint64_t inputs = ctx->VertexProgram._Current->info.inputs_read;
96 
97    return ~_mesa_get_enabled_vertex_arrays(ctx) & inputs;
98 }
99 
100 
101 void
st_invalidate_state(struct gl_context * ctx)102 st_invalidate_state(struct gl_context *ctx)
103 {
104    GLbitfield new_state = ctx->NewState;
105    struct st_context *st = st_context(ctx);
106 
107    if (new_state & _NEW_BUFFERS) {
108       st_invalidate_buffers(st);
109    } else {
110       /* These set a subset of flags set by _NEW_BUFFERS, so we only have to
111        * check them when _NEW_BUFFERS isn't set.
112        */
113       if (new_state & _NEW_FOG)
114          ctx->NewDriverState |= ST_NEW_FS_STATE;
115    }
116 
117    if (new_state & (_NEW_LIGHT_STATE |
118                     _NEW_POINT))
119       ctx->NewDriverState |= ST_NEW_RASTERIZER;
120 
121    if ((new_state & _NEW_LIGHT_STATE) &&
122        (st->lower_flatshade || st->lower_two_sided_color))
123       ctx->NewDriverState |= ST_NEW_FS_STATE;
124 
125    if (new_state & _NEW_PROJECTION &&
126        st_user_clip_planes_enabled(ctx))
127       ctx->NewDriverState |= ST_NEW_CLIP_STATE;
128 
129    if (new_state & _NEW_PIXEL)
130       ctx->NewDriverState |= ST_NEW_PIXEL_TRANSFER;
131 
132    if (new_state & _NEW_CURRENT_ATTRIB && st_vp_uses_current_values(ctx)) {
133       ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS;
134       /* glColor3f -> glColor4f changes the vertex format. */
135       ctx->Array.NewVertexElements = true;
136    }
137 
138    /* Update the vertex shader if ctx->Light._ClampVertexColor was changed. */
139    if (st->clamp_vert_color_in_shader && (new_state & _NEW_LIGHT_STATE)) {
140       ctx->NewDriverState |= ST_NEW_VS_STATE;
141       if (_mesa_is_desktop_gl_compat(st->ctx) && ctx->Version >= 32) {
142          ctx->NewDriverState |= ST_NEW_GS_STATE | ST_NEW_TES_STATE;
143       }
144    }
145 
146    /* Update the vertex shader if ctx->Point was changed. */
147    if (st->lower_point_size && new_state & _NEW_POINT) {
148       if (ctx->GeometryProgram._Current)
149          ctx->NewDriverState |= ST_NEW_GS_STATE | ST_NEW_GS_CONSTANTS;
150       else if (ctx->TessEvalProgram._Current)
151          ctx->NewDriverState |= ST_NEW_TES_STATE | ST_NEW_TES_CONSTANTS;
152       else
153          ctx->NewDriverState |= ST_NEW_VS_STATE | ST_NEW_VS_CONSTANTS;
154    }
155 
156    if (new_state & _NEW_TEXTURE_OBJECT) {
157       ctx->NewDriverState |= st->active_states &
158                              (ST_NEW_SAMPLER_VIEWS |
159                               ST_NEW_SAMPLERS |
160                               ST_NEW_IMAGE_UNITS);
161       if (ctx->FragmentProgram._Current) {
162          struct gl_program *fp = ctx->FragmentProgram._Current;
163 
164          if (fp->ExternalSamplersUsed || fp->ati_fs ||
165             (!fp->shader_program && fp->ShadowSamplers))
166             ctx->NewDriverState |= ST_NEW_FS_STATE;
167       }
168    }
169 }
170 
171 
172 /*
173  * In some circumstances (such as running google-chrome) the state
174  * tracker may try to delete a resource view from a context different
175  * than when it was created.  We don't want to do that.
176  *
177  * In that situation, st_texture_release_all_sampler_views() calls this
178  * function to transfer the sampler view reference to this context (expected
179  * to be the context which created the view.)
180  */
181 void
st_save_zombie_sampler_view(struct st_context * st,struct pipe_sampler_view * view)182 st_save_zombie_sampler_view(struct st_context *st,
183                             struct pipe_sampler_view *view)
184 {
185    struct st_zombie_sampler_view_node *entry;
186 
187    assert(view->context == st->pipe);
188 
189    entry = MALLOC_STRUCT(st_zombie_sampler_view_node);
190    if (!entry)
191       return;
192 
193    entry->view = view;
194 
195    /* We need a mutex since this function may be called from one thread
196     * while free_zombie_resource_views() is called from another.
197     */
198    simple_mtx_lock(&st->zombie_sampler_views.mutex);
199    list_addtail(&entry->node, &st->zombie_sampler_views.list.node);
200    simple_mtx_unlock(&st->zombie_sampler_views.mutex);
201 }
202 
203 
204 /*
205  * Since OpenGL shaders may be shared among contexts, we can wind up
206  * with variants of a shader created with different contexts.
207  * When we go to destroy a gallium shader, we want to free it with the
208  * same context that it was created with, unless the driver reports
209  * PIPE_CAP_SHAREABLE_SHADERS = TRUE.
210  */
211 void
st_save_zombie_shader(struct st_context * st,enum pipe_shader_type type,struct pipe_shader_state * shader)212 st_save_zombie_shader(struct st_context *st,
213                       enum pipe_shader_type type,
214                       struct pipe_shader_state *shader)
215 {
216    struct st_zombie_shader_node *entry;
217 
218    /* we shouldn't be here if the driver supports shareable shaders */
219    assert(!st->has_shareable_shaders);
220 
221    entry = MALLOC_STRUCT(st_zombie_shader_node);
222    if (!entry)
223       return;
224 
225    entry->shader = shader;
226    entry->type = type;
227 
228    /* We need a mutex since this function may be called from one thread
229     * while free_zombie_shaders() is called from another.
230     */
231    simple_mtx_lock(&st->zombie_shaders.mutex);
232    list_addtail(&entry->node, &st->zombie_shaders.list.node);
233    simple_mtx_unlock(&st->zombie_shaders.mutex);
234 }
235 
236 
237 /*
238  * Free any zombie sampler views that may be attached to this context.
239  */
240 static void
free_zombie_sampler_views(struct st_context * st)241 free_zombie_sampler_views(struct st_context *st)
242 {
243    struct st_zombie_sampler_view_node *entry, *next;
244 
245    if (list_is_empty(&st->zombie_sampler_views.list.node)) {
246       return;
247    }
248 
249    simple_mtx_lock(&st->zombie_sampler_views.mutex);
250 
251    LIST_FOR_EACH_ENTRY_SAFE(entry, next,
252                             &st->zombie_sampler_views.list.node, node) {
253       list_del(&entry->node);  // remove this entry from the list
254 
255       assert(entry->view->context == st->pipe);
256       pipe_sampler_view_reference(&entry->view, NULL);
257 
258       free(entry);
259    }
260 
261    assert(list_is_empty(&st->zombie_sampler_views.list.node));
262 
263    simple_mtx_unlock(&st->zombie_sampler_views.mutex);
264 }
265 
266 
267 /*
268  * Free any zombie shaders that may be attached to this context.
269  */
270 static void
free_zombie_shaders(struct st_context * st)271 free_zombie_shaders(struct st_context *st)
272 {
273    struct st_zombie_shader_node *entry, *next;
274 
275    if (list_is_empty(&st->zombie_shaders.list.node)) {
276       return;
277    }
278 
279    simple_mtx_lock(&st->zombie_shaders.mutex);
280 
281    LIST_FOR_EACH_ENTRY_SAFE(entry, next,
282                             &st->zombie_shaders.list.node, node) {
283       list_del(&entry->node);  // remove this entry from the list
284 
285       switch (entry->type) {
286       case PIPE_SHADER_VERTEX:
287          st->ctx->NewDriverState |= ST_NEW_VS_STATE;
288          st->pipe->delete_vs_state(st->pipe, entry->shader);
289          break;
290       case PIPE_SHADER_FRAGMENT:
291          st->ctx->NewDriverState |= ST_NEW_FS_STATE;
292          st->pipe->delete_fs_state(st->pipe, entry->shader);
293          break;
294       case PIPE_SHADER_GEOMETRY:
295          st->ctx->NewDriverState |= ST_NEW_GS_STATE;
296          st->pipe->delete_gs_state(st->pipe, entry->shader);
297          break;
298       case PIPE_SHADER_TESS_CTRL:
299          st->ctx->NewDriverState |= ST_NEW_TCS_STATE;
300          st->pipe->delete_tcs_state(st->pipe, entry->shader);
301          break;
302       case PIPE_SHADER_TESS_EVAL:
303          st->ctx->NewDriverState |= ST_NEW_TES_STATE;
304          st->pipe->delete_tes_state(st->pipe, entry->shader);
305          break;
306       case PIPE_SHADER_COMPUTE:
307          st->ctx->NewDriverState |= ST_NEW_CS_STATE;
308          st->pipe->delete_compute_state(st->pipe, entry->shader);
309          break;
310       default:
311          unreachable("invalid shader type in free_zombie_shaders()");
312       }
313       free(entry);
314    }
315 
316    assert(list_is_empty(&st->zombie_shaders.list.node));
317 
318    simple_mtx_unlock(&st->zombie_shaders.mutex);
319 }
320 
321 
322 /*
323  * This function is called periodically to free any zombie objects
324  * which are attached to this context.
325  */
326 void
st_context_free_zombie_objects(struct st_context * st)327 st_context_free_zombie_objects(struct st_context *st)
328 {
329    free_zombie_sampler_views(st);
330    free_zombie_shaders(st);
331 }
332 
333 
334 static void
st_destroy_context_priv(struct st_context * st,bool destroy_pipe)335 st_destroy_context_priv(struct st_context *st, bool destroy_pipe)
336 {
337    st_destroy_draw(st);
338    st_destroy_clear(st);
339    st_destroy_bitmap(st);
340    st_destroy_drawpix(st);
341    st_destroy_drawtex(st);
342    st_destroy_pbo_helpers(st);
343 
344    if (_mesa_has_compute_shaders(st->ctx) && st->transcode_astc)
345       st_destroy_texcompress_compute(st);
346 
347    st_destroy_bound_texture_handles(st);
348    st_destroy_bound_image_handles(st);
349 
350    /* free glReadPixels cache data */
351    st_invalidate_readpix_cache(st);
352    util_throttle_deinit(st->screen, &st->throttle);
353 
354    cso_destroy_context(st->cso_context);
355 
356    if (st->pipe && destroy_pipe)
357       st->pipe->destroy(st->pipe);
358 
359    st->ctx->st = NULL;
360    FREE(st);
361 }
362 
363 
364 static void
st_init_driver_flags(struct st_context * st)365 st_init_driver_flags(struct st_context *st)
366 {
367    struct gl_driver_flags *f = &st->ctx->DriverFlags;
368 
369    /* Shader resources */
370    if (st->has_hw_atomics)
371       f->NewAtomicBuffer = ST_NEW_HW_ATOMICS | ST_NEW_CS_ATOMICS;
372    else
373       f->NewAtomicBuffer = ST_NEW_ATOMIC_BUFFER;
374 
375    f->NewShaderConstants[MESA_SHADER_VERTEX] = ST_NEW_VS_CONSTANTS;
376    f->NewShaderConstants[MESA_SHADER_TESS_CTRL] = ST_NEW_TCS_CONSTANTS;
377    f->NewShaderConstants[MESA_SHADER_TESS_EVAL] = ST_NEW_TES_CONSTANTS;
378    f->NewShaderConstants[MESA_SHADER_GEOMETRY] = ST_NEW_GS_CONSTANTS;
379    f->NewShaderConstants[MESA_SHADER_FRAGMENT] = ST_NEW_FS_CONSTANTS;
380    f->NewShaderConstants[MESA_SHADER_COMPUTE] = ST_NEW_CS_CONSTANTS;
381 
382    if (st->lower_alpha_test)
383       f->NewAlphaTest = ST_NEW_FS_STATE | ST_NEW_FS_CONSTANTS;
384    else
385       f->NewAlphaTest = ST_NEW_DSA;
386 
387    f->NewMultisampleEnable = ST_NEW_BLEND | ST_NEW_RASTERIZER |
388                              ST_NEW_SAMPLE_STATE | ST_NEW_SAMPLE_SHADING;
389    f->NewSampleShading = ST_NEW_SAMPLE_SHADING;
390 
391    /* This depends on what the gallium driver wants. */
392    if (st->force_persample_in_shader) {
393       f->NewMultisampleEnable |= ST_NEW_FS_STATE;
394       f->NewSampleShading |= ST_NEW_FS_STATE;
395    } else {
396       f->NewSampleShading |= ST_NEW_RASTERIZER;
397    }
398 
399    if (st->clamp_frag_color_in_shader) {
400       f->NewFragClamp = ST_NEW_FS_STATE;
401    } else {
402       f->NewFragClamp = ST_NEW_RASTERIZER;
403    }
404 
405    f->NewClipPlaneEnable = ST_NEW_RASTERIZER;
406    if (st->lower_ucp)
407       f->NewClipPlaneEnable |= ST_NEW_VS_STATE | ST_NEW_GS_STATE | ST_NEW_TES_STATE;
408 
409    if (st->emulate_gl_clamp)
410       f->NewSamplersWithClamp = ST_NEW_SAMPLERS |
411                                 ST_NEW_VS_STATE | ST_NEW_TCS_STATE |
412                                 ST_NEW_TES_STATE | ST_NEW_GS_STATE |
413                                 ST_NEW_FS_STATE | ST_NEW_CS_STATE;
414 
415    if (!st->has_hw_atomics && st->ctx->Const.ShaderStorageBufferOffsetAlignment > 4)
416       f->NewAtomicBuffer |= ST_NEW_CONSTANTS;
417 }
418 
419 static bool
st_have_perfquery(struct st_context * ctx)420 st_have_perfquery(struct st_context *ctx)
421 {
422    struct pipe_context *pipe = ctx->pipe;
423 
424    return pipe->init_intel_perf_query_info && pipe->get_intel_perf_query_info &&
425           pipe->get_intel_perf_query_counter_info &&
426           pipe->new_intel_perf_query_obj && pipe->begin_intel_perf_query &&
427           pipe->end_intel_perf_query && pipe->delete_intel_perf_query &&
428           pipe->wait_intel_perf_query && pipe->is_intel_perf_query_ready &&
429           pipe->get_intel_perf_query_data;
430 }
431 
432 static struct st_context *
st_create_context_priv(struct gl_context * ctx,struct pipe_context * pipe,const struct st_config_options * options)433 st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe,
434                        const struct st_config_options *options)
435 {
436    struct pipe_screen *screen = pipe->screen;
437    struct st_context *st = CALLOC_STRUCT( st_context);
438 
439    st->options = *options;
440 
441    ctx->st_opts = &st->options;
442    ctx->st = st;
443 
444    st->ctx = ctx;
445    st->screen = screen;
446    st->pipe = pipe;
447 
448    st->can_bind_const_buffer_as_vertex =
449       screen->get_param(screen, PIPE_CAP_CAN_BIND_CONST_BUFFER_AS_VERTEX);
450 
451    /* st/mesa always uploads zero-stride vertex attribs, and other user
452     * vertex buffers are only possible with a compatibility profile.
453     * So tell the u_vbuf module that user VBOs are not possible with the Core
454     * profile, so that u_vbuf is bypassed completely if there is nothing else
455     * to do.
456     */
457    unsigned cso_flags;
458    switch (ctx->API) {
459    case API_OPENGL_CORE:
460       cso_flags = CSO_NO_USER_VERTEX_BUFFERS;
461       break;
462    case API_OPENGLES:
463    case API_OPENGLES2:
464       cso_flags = CSO_NO_64B_VERTEX_BUFFERS;
465       break;
466    default:
467       cso_flags = 0;
468       break;
469    }
470 
471    st->cso_context = cso_create_context(pipe, cso_flags);
472    ctx->cso_context = st->cso_context;
473 
474    STATIC_ASSERT(ARRAY_SIZE(st->update_functions) <= 64);
475 
476 #define ST_STATE(FLAG, st_update) st->update_functions[FLAG##_INDEX] = st_update;
477 #include "st_atom_list.h"
478 #undef ST_STATE
479 
480    st_init_clear(st);
481    {
482       enum pipe_texture_transfer_mode val = screen->get_param(screen, PIPE_CAP_TEXTURE_TRANSFER_MODES);
483       st->prefer_blit_based_texture_transfer = (val & PIPE_TEXTURE_TRANSFER_BLIT) != 0;
484       st->allow_compute_based_texture_transfer = (val & PIPE_TEXTURE_TRANSFER_COMPUTE) != 0;
485    }
486    st_init_pbo_helpers(st);
487 
488    /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */
489    if (screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES))
490       st->internal_target = PIPE_TEXTURE_2D;
491    else
492       st->internal_target = PIPE_TEXTURE_RECT;
493 
494    /* Setup vertex element info for 'struct st_util_vertex'.
495     */
496    {
497       STATIC_ASSERT(sizeof(struct st_util_vertex) == 9 * sizeof(float));
498 
499       memset(&st->util_velems, 0, sizeof(st->util_velems));
500       st->util_velems.velems[0].src_offset = 0;
501       st->util_velems.velems[0].vertex_buffer_index = 0;
502       st->util_velems.velems[0].src_format = PIPE_FORMAT_R32G32B32_FLOAT;
503       st->util_velems.velems[0].src_stride = sizeof(struct st_util_vertex);
504       st->util_velems.velems[1].src_offset = 3 * sizeof(float);
505       st->util_velems.velems[1].vertex_buffer_index = 0;
506       st->util_velems.velems[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
507       st->util_velems.velems[1].src_stride = sizeof(struct st_util_vertex);
508       st->util_velems.velems[2].src_offset = 7 * sizeof(float);
509       st->util_velems.velems[2].vertex_buffer_index = 0;
510       st->util_velems.velems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
511       st->util_velems.velems[2].src_stride = sizeof(struct st_util_vertex);
512    }
513 
514    ctx->Const.PackedDriverUniformStorage =
515       screen->get_param(screen, PIPE_CAP_PACKED_UNIFORMS);
516 
517    ctx->Const.BitmapUsesRed =
518       screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM,
519                                   PIPE_TEXTURE_2D, 0, 0,
520                                   PIPE_BIND_SAMPLER_VIEW);
521 
522    ctx->Const.QueryCounterBits.Timestamp =
523       screen->get_param(screen, PIPE_CAP_QUERY_TIMESTAMP_BITS);
524 
525    st->has_stencil_export =
526       screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
527    st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8,
528                                               PIPE_TEXTURE_2D, 0, 0,
529                                               PIPE_BIND_SAMPLER_VIEW);
530    st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8,
531                                               PIPE_TEXTURE_2D, 0, 0,
532                                               PIPE_BIND_SAMPLER_VIEW);
533    st->transcode_etc = options->transcode_etc &&
534                        screen->is_format_supported(screen, PIPE_FORMAT_DXT1_SRGBA,
535                                                    PIPE_TEXTURE_2D, 0, 0,
536                                                    PIPE_BIND_SAMPLER_VIEW);
537    st->transcode_astc = options->transcode_astc &&
538                         screen->is_format_supported(screen, PIPE_FORMAT_DXT5_SRGBA,
539                                                     PIPE_TEXTURE_2D, 0, 0,
540                                                     PIPE_BIND_SAMPLER_VIEW) &&
541                         screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
542                                                     PIPE_TEXTURE_2D, 0, 0,
543                                                     PIPE_BIND_SAMPLER_VIEW);
544    st->has_astc_2d_ldr =
545       screen->is_format_supported(screen, PIPE_FORMAT_ASTC_4x4_SRGB,
546                                   PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW);
547    st->has_astc_5x5_ldr =
548       screen->is_format_supported(screen, PIPE_FORMAT_ASTC_5x5_SRGB,
549                                   PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW);
550    st->astc_void_extents_need_denorm_flush =
551       screen->get_param(screen, PIPE_CAP_ASTC_VOID_EXTENTS_NEED_DENORM_FLUSH);
552 
553    st->has_s3tc = screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
554                                               PIPE_TEXTURE_2D, 0, 0,
555                                               PIPE_BIND_SAMPLER_VIEW);
556    st->has_rgtc = screen->is_format_supported(screen, PIPE_FORMAT_RGTC2_UNORM,
557                                               PIPE_TEXTURE_2D, 0, 0,
558                                               PIPE_BIND_SAMPLER_VIEW);
559    st->has_latc = screen->is_format_supported(screen, PIPE_FORMAT_LATC2_UNORM,
560                                               PIPE_TEXTURE_2D, 0, 0,
561                                               PIPE_BIND_SAMPLER_VIEW);
562    st->has_bptc = screen->is_format_supported(screen, PIPE_FORMAT_BPTC_SRGBA,
563                                               PIPE_TEXTURE_2D, 0, 0,
564                                               PIPE_BIND_SAMPLER_VIEW);
565    st->force_persample_in_shader =
566       screen->get_param(screen, PIPE_CAP_SAMPLE_SHADING) &&
567       !screen->get_param(screen, PIPE_CAP_FORCE_PERSAMPLE_INTERP);
568    st->has_shareable_shaders = screen->get_param(screen,
569                                                  PIPE_CAP_SHAREABLE_SHADERS);
570    st->needs_texcoord_semantic =
571       screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
572    st->apply_texture_swizzle_to_border_color =
573       !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) &
574          (PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 |
575           PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600));
576    st->use_format_with_border_color =
577       !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) &
578          PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_FREEDRENO);
579    st->alpha_border_color_is_not_w =
580       !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) &
581          PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_ALPHA_NOT_W);
582    st->emulate_gl_clamp =
583       !screen->get_param(screen, PIPE_CAP_GL_CLAMP);
584    st->has_time_elapsed =
585       screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED);
586    ctx->Const.GLSLHasHalfFloatPacking =
587       screen->get_param(screen, PIPE_CAP_SHADER_PACK_HALF_FLOAT);
588    st->has_multi_draw_indirect =
589       screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT);
590    st->has_indirect_partial_stride =
591       screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE);
592    st->has_occlusion_query =
593       screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY);
594    st->has_single_pipe_stat =
595       screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE);
596    st->has_pipeline_stat =
597       screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS);
598    st->has_indep_blend_enable =
599       screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE);
600    st->has_indep_blend_func =
601       screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC);
602    st->can_dither =
603       screen->get_param(screen, PIPE_CAP_DITHERING);
604    st->lower_flatshade =
605       !screen->get_param(screen, PIPE_CAP_FLATSHADE);
606    st->lower_alpha_test =
607       !screen->get_param(screen, PIPE_CAP_ALPHA_TEST);
608    switch (screen->get_param(screen, PIPE_CAP_POINT_SIZE_FIXED)) {
609    case PIPE_POINT_SIZE_LOWER_ALWAYS:
610       st->lower_point_size = true;
611       st->add_point_size = true;
612       break;
613    case PIPE_POINT_SIZE_LOWER_USER_ONLY:
614       st->lower_point_size = true;
615       break;
616    default: break;
617    }
618    st->lower_two_sided_color =
619       !screen->get_param(screen, PIPE_CAP_TWO_SIDED_COLOR);
620    st->lower_ucp =
621       !screen->get_param(screen, PIPE_CAP_CLIP_PLANES);
622    st->prefer_real_buffer_in_constbuf0 =
623       screen->get_param(screen, PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0);
624    st->has_conditional_render =
625       screen->get_param(screen, PIPE_CAP_CONDITIONAL_RENDER);
626    st->lower_rect_tex =
627       !screen->get_param(screen, PIPE_CAP_TEXRECT);
628    st->allow_st_finalize_nir_twice = screen->finalize_nir != NULL;
629 
630    st->has_hw_atomics =
631       screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
632                                PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS)
633       ? true : false;
634 
635    st->validate_all_dirty_states =
636       screen->get_param(screen, PIPE_CAP_VALIDATE_ALL_DIRTY_STATES)
637       ? true : false;
638    st->can_null_texture =
639       screen->get_param(screen, PIPE_CAP_NULL_TEXTURES)
640       ? true : false;
641 
642    util_throttle_init(&st->throttle,
643                       screen->get_param(screen,
644                                         PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET));
645 
646    /* GL limits and extensions */
647    st_init_limits(screen, &ctx->Const, &ctx->Extensions, ctx->API);
648    st_init_extensions(screen, &ctx->Const,
649                       &ctx->Extensions, &st->options, ctx->API);
650 
651    if (st_have_perfquery(st)) {
652       ctx->Extensions.INTEL_performance_query = GL_TRUE;
653    }
654 
655    /* Enable shader-based fallbacks for ARB_color_buffer_float if needed. */
656    if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) {
657       if (!screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_CLAMPED)) {
658          st->clamp_vert_color_in_shader = GL_TRUE;
659       }
660 
661       if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) {
662          st->clamp_frag_color_in_shader = GL_TRUE;
663       }
664 
665       /* For drivers which cannot do color clamping, it's better to just
666        * disable ARB_color_buffer_float in the core profile, because
667        * the clamping is deprecated there anyway. */
668       if (_mesa_is_desktop_gl_core(ctx) &&
669           (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) {
670          st->clamp_vert_color_in_shader = GL_FALSE;
671          st->clamp_frag_color_in_shader = GL_FALSE;
672          ctx->Extensions.ARB_color_buffer_float = GL_FALSE;
673       }
674    }
675 
676    /* called after _mesa_create_context/_mesa_init_point, fix default user
677     * settable max point size up
678     */
679    ctx->Point.MaxSize = MAX2(ctx->Const.MaxPointSize,
680                              ctx->Const.MaxPointSizeAA);
681 
682    ctx->Const.NoClippingOnCopyTex = screen->get_param(screen,
683                                                       PIPE_CAP_NO_CLIP_ON_COPY_TEX);
684 
685    ctx->Const.ForceFloat32TexNearest =
686       !screen->get_param(screen, PIPE_CAP_TEXTURE_FLOAT_LINEAR);
687 
688    ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].PositionAlwaysInvariant = options->vs_position_always_invariant;
689 
690    ctx->Const.ShaderCompilerOptions[MESA_SHADER_TESS_EVAL].PositionAlwaysPrecise = options->vs_position_always_precise;
691 
692    /* Set which shader types can be compiled at link time. */
693    st->shader_has_one_variant[MESA_SHADER_VERTEX] =
694          st->has_shareable_shaders &&
695          !st->clamp_vert_color_in_shader &&
696          !st->lower_point_size &&
697          !st->lower_ucp;
698 
699    st->shader_has_one_variant[MESA_SHADER_FRAGMENT] =
700          st->has_shareable_shaders &&
701          !st->lower_flatshade &&
702          !st->lower_alpha_test &&
703          !st->clamp_frag_color_in_shader &&
704          !st->force_persample_in_shader &&
705          !st->lower_two_sided_color;
706 
707    st->shader_has_one_variant[MESA_SHADER_TESS_CTRL] = st->has_shareable_shaders;
708    st->shader_has_one_variant[MESA_SHADER_TESS_EVAL] =
709          st->has_shareable_shaders &&
710          !st->clamp_vert_color_in_shader &&
711          !st->lower_point_size &&
712          !st->lower_ucp;
713 
714    st->shader_has_one_variant[MESA_SHADER_GEOMETRY] =
715          st->has_shareable_shaders &&
716          !st->clamp_vert_color_in_shader &&
717          !st->lower_point_size &&
718          !st->lower_ucp;
719    st->shader_has_one_variant[MESA_SHADER_COMPUTE] = st->has_shareable_shaders;
720 
721    if (!st->pipe->set_context_param || !util_thread_scheduler_enabled())
722       st->pin_thread_counter = ST_THREAD_SCHEDULER_DISABLED;
723 
724    st->bitmap.cache.empty = true;
725 
726    if (ctx->Const.ForceGLNamesReuse && ctx->Shared->RefCount == 1) {
727       _mesa_HashEnableNameReuse(&ctx->Shared->TexObjects);
728       _mesa_HashEnableNameReuse(&ctx->Shared->ShaderObjects);
729       _mesa_HashEnableNameReuse(&ctx->Shared->BufferObjects);
730       _mesa_HashEnableNameReuse(&ctx->Shared->SamplerObjects);
731       _mesa_HashEnableNameReuse(&ctx->Shared->FrameBuffers);
732       _mesa_HashEnableNameReuse(&ctx->Shared->RenderBuffers);
733       _mesa_HashEnableNameReuse(&ctx->Shared->MemoryObjects);
734       _mesa_HashEnableNameReuse(&ctx->Shared->SemaphoreObjects);
735    }
736    /* SPECviewperf13/sw-04 crashes since a56849ddda6 if Mesa is build with
737     * -O3 on gcc 7.5, which doesn't happen with ForceGLNamesReuse, which is
738     * the default setting for SPECviewperf because it simulates glGen behavior
739     * of closed source drivers.
740     */
741    if (ctx->Const.ForceGLNamesReuse)
742       _mesa_HashEnableNameReuse(&ctx->Query.QueryObjects);
743 
744    _mesa_override_extensions(ctx);
745    _mesa_compute_version(ctx);
746 
747    if (ctx->Version == 0 ||
748        !_mesa_initialize_dispatch_tables(ctx)) {
749       /* This can happen when a core profile was requested, but the driver
750        * does not support some features of GL 3.1 or later.
751        */
752       st_destroy_context_priv(st, false);
753       return NULL;
754    }
755 
756    if (_mesa_has_compute_shaders(ctx) &&
757        st->transcode_astc && !st_init_texcompress_compute(st)) {
758       /* Transcoding ASTC to DXT5 using compute shaders can provide a
759        * significant performance benefit over the CPU path. It isn't strictly
760        * necessary to fail if we can't use the compute shader path, but it's
761        * very convenient to do so. This should be rare.
762        */
763       st_destroy_context_priv(st, false);
764       return NULL;
765    }
766 
767    /* This must be done after extensions are initialized to enable persistent
768     * mappings immediately.
769     */
770    _vbo_CreateContext(ctx);
771 
772    st_init_driver_flags(st);
773    st_init_update_array(st);
774 
775    /* Initialize context's winsys buffers list */
776    list_inithead(&st->winsys_buffers);
777 
778    list_inithead(&st->zombie_sampler_views.list.node);
779    simple_mtx_init(&st->zombie_sampler_views.mutex, mtx_plain);
780    list_inithead(&st->zombie_shaders.list.node);
781    simple_mtx_init(&st->zombie_shaders.mutex, mtx_plain);
782 
783    ctx->Const.DriverSupportedPrimMask = screen->get_param(screen, PIPE_CAP_SUPPORTED_PRIM_MODES) |
784                                         /* patches is always supported */
785                                         BITFIELD_BIT(MESA_PRIM_PATCHES);
786    st->active_states = _mesa_get_active_states(ctx);
787 
788    return st;
789 }
790 
791 void
st_set_background_context(struct gl_context * ctx,struct util_queue_monitoring * queue_info)792 st_set_background_context(struct gl_context *ctx,
793                           struct util_queue_monitoring *queue_info)
794 {
795    struct st_context *st = ctx->st;
796    struct pipe_frontend_screen *fscreen = st->frontend_screen;
797 
798    assert(fscreen->set_background_context);
799    fscreen->set_background_context(st, queue_info);
800 }
801 
802 static void
st_init_driver_functions(struct pipe_screen * screen,struct dd_function_table * functions,bool has_egl_image_validate)803 st_init_driver_functions(struct pipe_screen *screen,
804                          struct dd_function_table *functions,
805                          bool has_egl_image_validate)
806 {
807    st_init_draw_functions(screen, functions);
808 
809    functions->NewProgram = _mesa_new_program;
810    st_init_flush_functions(screen, functions);
811 
812    /* GL_ARB_get_program_binary */
813    functions->ShaderCacheSerializeDriverBlob =  st_serialise_nir_program;
814    functions->ProgramBinarySerializeDriverBlob =
815       st_serialise_nir_program_binary;
816    functions->ProgramBinaryDeserializeDriverBlob =
817       st_deserialise_nir_program;
818 }
819 
820 
821 struct st_context *
st_create_context(gl_api api,struct pipe_context * pipe,const struct gl_config * visual,struct st_context * share,const struct st_config_options * options,bool no_error,bool has_egl_image_validate)822 st_create_context(gl_api api, struct pipe_context *pipe,
823                   const struct gl_config *visual,
824                   struct st_context *share,
825                   const struct st_config_options *options,
826                   bool no_error, bool has_egl_image_validate)
827 {
828    struct gl_context *ctx;
829    struct gl_context *shareCtx = share ? share->ctx : NULL;
830    struct dd_function_table funcs;
831    struct st_context *st;
832 
833    memset(&funcs, 0, sizeof(funcs));
834    st_init_driver_functions(pipe->screen, &funcs, has_egl_image_validate);
835 
836    /* gl_context must be 16-byte aligned due to the alignment on GLmatrix. */
837    ctx = align_malloc(sizeof(struct gl_context), 16);
838    if (!ctx)
839       return NULL;
840    memset(ctx, 0, sizeof(*ctx));
841 
842    ctx->pipe = pipe;
843    ctx->screen = pipe->screen;
844 
845    if (!_mesa_initialize_context(ctx, api, no_error, visual, shareCtx, &funcs)) {
846       align_free(ctx);
847       return NULL;
848    }
849 
850    st_debug_init();
851 
852    if (pipe->screen->get_disk_shader_cache)
853       ctx->Cache = pipe->screen->get_disk_shader_cache(pipe->screen);
854 
855    /* XXX: need a capability bit in gallium to query if the pipe
856     * driver prefers DP4 or MUL/MAD for vertex transformation.
857     */
858    if (debug_get_option_mesa_mvp_dp4())
859       ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS = GL_TRUE;
860 
861    if (pipe->screen->get_param(pipe->screen, PIPE_CAP_INVALIDATE_BUFFER))
862       ctx->has_invalidate_buffer = true;
863 
864    if (pipe->screen->get_param(pipe->screen, PIPE_CAP_STRING_MARKER))
865       ctx->has_string_marker = true;
866 
867    st = st_create_context_priv(ctx, pipe, options);
868    if (!st) {
869       _mesa_free_context_data(ctx, true);
870       align_free(ctx);
871    }
872 
873    return st;
874 }
875 
876 
877 /**
878  * When we destroy a context, we must examine all texture objects to
879  * find/release any sampler views created by that context.
880  *
881  * This callback is called per-texture object.  It releases all the
882  * texture's sampler views which belong to the context.
883  */
884 static void
destroy_tex_sampler_cb(void * data,void * userData)885 destroy_tex_sampler_cb(void *data, void *userData)
886 {
887    struct gl_texture_object *texObj = (struct gl_texture_object *) data;
888    struct st_context *st = (struct st_context *) userData;
889 
890    st_texture_release_context_sampler_view(st, texObj);
891 }
892 
893 static void
destroy_framebuffer_attachment_sampler_cb(void * data,void * userData)894 destroy_framebuffer_attachment_sampler_cb(void *data, void *userData)
895 {
896    struct gl_framebuffer* glfb = (struct gl_framebuffer*) data;
897    struct st_context *st = (struct st_context *) userData;
898 
899     for (unsigned i = 0; i < BUFFER_COUNT; i++) {
900       struct gl_renderbuffer_attachment *att = &glfb->Attachment[i];
901       if (att->Texture) {
902         st_texture_release_context_sampler_view(st, att->Texture);
903       }
904    }
905 }
906 
907 void
st_destroy_context(struct st_context * st)908 st_destroy_context(struct st_context *st)
909 {
910    struct gl_context *ctx = st->ctx;
911    struct gl_framebuffer *stfb, *next;
912    struct gl_framebuffer *save_drawbuffer;
913    struct gl_framebuffer *save_readbuffer;
914 
915    /* Save the current context and draw/read buffers*/
916    GET_CURRENT_CONTEXT(save_ctx);
917    if (save_ctx) {
918       save_drawbuffer = save_ctx->WinSysDrawBuffer;
919       save_readbuffer = save_ctx->WinSysReadBuffer;
920    } else {
921       save_drawbuffer = save_readbuffer = NULL;
922    }
923 
924    /*
925     * We need to bind the context we're deleting so that
926     * _mesa_reference_texobj_() uses this context when deleting textures.
927     * Similarly for framebuffer objects, etc.
928     */
929    _mesa_make_current(ctx, NULL, NULL);
930 
931    /* This must be called first so that glthread has a chance to finish */
932    _mesa_glthread_destroy(ctx);
933 
934    _mesa_HashWalk(&ctx->Shared->TexObjects, destroy_tex_sampler_cb, st);
935 
936    /* For the fallback textures, free any sampler views belonging to this
937     * context.
938     */
939    for (unsigned i = 0; i < NUM_TEXTURE_TARGETS; i++) {
940       for (unsigned j = 0; j < ARRAY_SIZE(ctx->Shared->FallbackTex[0]); j++) {
941          struct gl_texture_object *stObj =
942             ctx->Shared->FallbackTex[i][j];
943          if (stObj) {
944             st_texture_release_context_sampler_view(st, stObj);
945          }
946       }
947    }
948 
949    st_release_program(st, &st->fp);
950    st_release_program(st, &st->gp);
951    st_release_program(st, &st->vp);
952    st_release_program(st, &st->tcp);
953    st_release_program(st, &st->tep);
954    st_release_program(st, &st->cp);
955 
956    if (st->hw_select_shaders) {
957       hash_table_foreach(st->hw_select_shaders, entry)
958          st->pipe->delete_gs_state(st->pipe, entry->data);
959       _mesa_hash_table_destroy(st->hw_select_shaders, NULL);
960    }
961 
962    /* release framebuffer in the winsys buffers list */
963    LIST_FOR_EACH_ENTRY_SAFE_REV(stfb, next, &st->winsys_buffers, head) {
964       _mesa_reference_framebuffer(&stfb, NULL);
965    }
966 
967    _mesa_HashWalk(&ctx->Shared->FrameBuffers, destroy_framebuffer_attachment_sampler_cb, st);
968 
969    pipe_sampler_view_reference(&st->pixel_xfer.pixelmap_sampler_view, NULL);
970    pipe_resource_reference(&st->pixel_xfer.pixelmap_texture, NULL);
971 
972    _vbo_DestroyContext(ctx);
973 
974    st_destroy_program_variants(st);
975 
976    /* Do not release debug_output yet because it might be in use by other threads.
977     * These threads will be terminated by _mesa_free_context_data and
978     * st_destroy_context_priv.
979     */
980    _mesa_free_context_data(ctx, false);
981 
982    st_context_free_zombie_objects(st);
983 
984    simple_mtx_destroy(&st->zombie_sampler_views.mutex);
985    simple_mtx_destroy(&st->zombie_shaders.mutex);
986 
987    /* This will free the st_context too, so 'st' must not be accessed
988     * afterwards. */
989    st_destroy_context_priv(st, true);
990    st = NULL;
991 
992    _mesa_destroy_debug_output(ctx);
993 
994    align_free(ctx);
995 
996    if (save_ctx == ctx) {
997       /* unbind the context we just deleted */
998       _mesa_make_current(NULL, NULL, NULL);
999    } else {
1000       /* Restore the current context and draw/read buffers (may be NULL) */
1001       _mesa_make_current(save_ctx, save_drawbuffer, save_readbuffer);
1002    }
1003 }
1004 
1005 const struct nir_shader_compiler_options *
st_get_nir_compiler_options(struct st_context * st,gl_shader_stage stage)1006 st_get_nir_compiler_options(struct st_context *st, gl_shader_stage stage)
1007 {
1008    return st->ctx->Const.ShaderCompilerOptions[stage].NirOptions;
1009 }
1010