1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker *
3*bbecb9d1SAndroid Build Coastguard Worker * Copyright (C) 2014 Red Hat Inc.
4*bbecb9d1SAndroid Build Coastguard Worker *
5*bbecb9d1SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker *
12*bbecb9d1SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker *
15*bbecb9d1SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker *
23*bbecb9d1SAndroid Build Coastguard Worker **************************************************************************/
24*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
25*bbecb9d1SAndroid Build Coastguard Worker #include "config.h"
26*bbecb9d1SAndroid Build Coastguard Worker #endif
27*bbecb9d1SAndroid Build Coastguard Worker
28*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
29*bbecb9d1SAndroid Build Coastguard Worker #include <stdatomic.h>
30*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
31*bbecb9d1SAndroid Build Coastguard Worker #include <errno.h>
32*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_shader_tokens.h"
33*bbecb9d1SAndroid Build Coastguard Worker
34*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_defines.h"
35*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_state.h"
36*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_inlines.h"
37*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_memory.h"
38*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_dual_blend.h"
39*bbecb9d1SAndroid Build Coastguard Worker
40*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_thread.h"
41*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_format.h"
42*bbecb9d1SAndroid Build Coastguard Worker #include "tgsi/tgsi_parse.h"
43*bbecb9d1SAndroid Build Coastguard Worker
44*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_object.h"
45*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_shader.h"
46*bbecb9d1SAndroid Build Coastguard Worker
47*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_renderer.h"
48*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_blitter.h"
49*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_debug.h"
50*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_winsys.h"
51*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_blitter.h"
52*bbecb9d1SAndroid Build Coastguard Worker
53*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_util.h"
54*bbecb9d1SAndroid Build Coastguard Worker
55*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_hw.h"
56*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_resource.h"
57*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer.h"
58*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer_hw.h"
59*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_protocol.h"
60*bbecb9d1SAndroid Build Coastguard Worker
61*bbecb9d1SAndroid Build Coastguard Worker #include "tgsi/tgsi_text.h"
62*bbecb9d1SAndroid Build Coastguard Worker
63*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_GLX_H
64*bbecb9d1SAndroid Build Coastguard Worker #include <epoxy/glx.h>
65*bbecb9d1SAndroid Build Coastguard Worker #endif
66*bbecb9d1SAndroid Build Coastguard Worker
67*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
68*bbecb9d1SAndroid Build Coastguard Worker #include <vrend_video.h>
69*bbecb9d1SAndroid Build Coastguard Worker #endif
70*bbecb9d1SAndroid Build Coastguard Worker
71*bbecb9d1SAndroid Build Coastguard Worker /*
72*bbecb9d1SAndroid Build Coastguard Worker * VIRGL_RENDERER_CAPSET_VIRGL has version 0 and 1, but they are both
73*bbecb9d1SAndroid Build Coastguard Worker * virgl_caps_v1 and are exactly the same.
74*bbecb9d1SAndroid Build Coastguard Worker *
75*bbecb9d1SAndroid Build Coastguard Worker * VIRGL_RENDERER_CAPSET_VIRGL2 has version 0, 1, and 2, but they are
76*bbecb9d1SAndroid Build Coastguard Worker * all virgl_caps_v2 and are exactly the same.
77*bbecb9d1SAndroid Build Coastguard Worker *
78*bbecb9d1SAndroid Build Coastguard Worker * Since virgl_caps_v2 is growable and no backward-incompatible change is
79*bbecb9d1SAndroid Build Coastguard Worker * expected, we don't bump up these versions anymore.
80*bbecb9d1SAndroid Build Coastguard Worker */
81*bbecb9d1SAndroid Build Coastguard Worker #define VREND_CAPSET_VIRGL_MAX_VERSION 1
82*bbecb9d1SAndroid Build Coastguard Worker #define VREND_CAPSET_VIRGL2_MAX_VERSION 2
83*bbecb9d1SAndroid Build Coastguard Worker
84*bbecb9d1SAndroid Build Coastguard Worker static const uint32_t fake_occlusion_query_samples_passed_default = 1024;
85*bbecb9d1SAndroid Build Coastguard Worker
86*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_if_cbs *vrend_clicbs;
87*bbecb9d1SAndroid Build Coastguard Worker
88*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence {
89*bbecb9d1SAndroid Build Coastguard Worker /* When the sync thread is waiting on the fence and the main thread
90*bbecb9d1SAndroid Build Coastguard Worker * destroys the context, ctx is set to NULL. Otherwise, ctx is always
91*bbecb9d1SAndroid Build Coastguard Worker * valid.
92*bbecb9d1SAndroid Build Coastguard Worker */
93*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *ctx;
94*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags;
95*bbecb9d1SAndroid Build Coastguard Worker uint64_t fence_id;
96*bbecb9d1SAndroid Build Coastguard Worker
97*bbecb9d1SAndroid Build Coastguard Worker union {
98*bbecb9d1SAndroid Build Coastguard Worker GLsync glsyncobj;
99*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
100*bbecb9d1SAndroid Build Coastguard Worker EGLSyncKHR eglsyncobj;
101*bbecb9d1SAndroid Build Coastguard Worker #endif
102*bbecb9d1SAndroid Build Coastguard Worker };
103*bbecb9d1SAndroid Build Coastguard Worker struct list_head fences;
104*bbecb9d1SAndroid Build Coastguard Worker };
105*bbecb9d1SAndroid Build Coastguard Worker
106*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query {
107*bbecb9d1SAndroid Build Coastguard Worker struct list_head waiting_queries;
108*bbecb9d1SAndroid Build Coastguard Worker
109*bbecb9d1SAndroid Build Coastguard Worker GLuint id;
110*bbecb9d1SAndroid Build Coastguard Worker GLuint type;
111*bbecb9d1SAndroid Build Coastguard Worker GLuint index;
112*bbecb9d1SAndroid Build Coastguard Worker GLuint gltype;
113*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *ctx;
114*bbecb9d1SAndroid Build Coastguard Worker int sub_ctx_id;
115*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
116*bbecb9d1SAndroid Build Coastguard Worker bool fake_samples_passed;
117*bbecb9d1SAndroid Build Coastguard Worker };
118*bbecb9d1SAndroid Build Coastguard Worker
119*bbecb9d1SAndroid Build Coastguard Worker struct global_error_state {
120*bbecb9d1SAndroid Build Coastguard Worker enum virgl_errors last_error;
121*bbecb9d1SAndroid Build Coastguard Worker };
122*bbecb9d1SAndroid Build Coastguard Worker
123*bbecb9d1SAndroid Build Coastguard Worker enum features_id
124*bbecb9d1SAndroid Build Coastguard Worker {
125*bbecb9d1SAndroid Build Coastguard Worker feat_arb_or_gles_ext_texture_buffer,
126*bbecb9d1SAndroid Build Coastguard Worker feat_arb_robustness,
127*bbecb9d1SAndroid Build Coastguard Worker feat_arb_buffer_storage,
128*bbecb9d1SAndroid Build Coastguard Worker feat_arrays_of_arrays,
129*bbecb9d1SAndroid Build Coastguard Worker feat_ati_meminfo,
130*bbecb9d1SAndroid Build Coastguard Worker feat_atomic_counters,
131*bbecb9d1SAndroid Build Coastguard Worker feat_base_instance,
132*bbecb9d1SAndroid Build Coastguard Worker feat_barrier,
133*bbecb9d1SAndroid Build Coastguard Worker feat_bind_vertex_buffers,
134*bbecb9d1SAndroid Build Coastguard Worker feat_bit_encoding,
135*bbecb9d1SAndroid Build Coastguard Worker feat_blend_equation_advanced,
136*bbecb9d1SAndroid Build Coastguard Worker feat_clear_texture,
137*bbecb9d1SAndroid Build Coastguard Worker feat_clip_control,
138*bbecb9d1SAndroid Build Coastguard Worker feat_compute_shader,
139*bbecb9d1SAndroid Build Coastguard Worker feat_copy_image,
140*bbecb9d1SAndroid Build Coastguard Worker feat_conditional_render_inverted,
141*bbecb9d1SAndroid Build Coastguard Worker feat_conservative_depth,
142*bbecb9d1SAndroid Build Coastguard Worker feat_cube_map_array,
143*bbecb9d1SAndroid Build Coastguard Worker feat_cull_distance,
144*bbecb9d1SAndroid Build Coastguard Worker feat_debug_cb,
145*bbecb9d1SAndroid Build Coastguard Worker feat_depth_clamp,
146*bbecb9d1SAndroid Build Coastguard Worker feat_draw_instance,
147*bbecb9d1SAndroid Build Coastguard Worker feat_dual_src_blend,
148*bbecb9d1SAndroid Build Coastguard Worker feat_egl_image,
149*bbecb9d1SAndroid Build Coastguard Worker feat_egl_image_storage,
150*bbecb9d1SAndroid Build Coastguard Worker feat_enhanced_layouts,
151*bbecb9d1SAndroid Build Coastguard Worker feat_fb_no_attach,
152*bbecb9d1SAndroid Build Coastguard Worker feat_framebuffer_fetch,
153*bbecb9d1SAndroid Build Coastguard Worker feat_framebuffer_fetch_non_coherent,
154*bbecb9d1SAndroid Build Coastguard Worker feat_geometry_shader,
155*bbecb9d1SAndroid Build Coastguard Worker feat_gl_conditional_render,
156*bbecb9d1SAndroid Build Coastguard Worker feat_gl_prim_restart,
157*bbecb9d1SAndroid Build Coastguard Worker feat_gles_khr_robustness,
158*bbecb9d1SAndroid Build Coastguard Worker feat_gles31_compatibility,
159*bbecb9d1SAndroid Build Coastguard Worker feat_gles31_vertex_attrib_binding,
160*bbecb9d1SAndroid Build Coastguard Worker feat_gpu_shader5,
161*bbecb9d1SAndroid Build Coastguard Worker feat_images,
162*bbecb9d1SAndroid Build Coastguard Worker feat_indep_blend,
163*bbecb9d1SAndroid Build Coastguard Worker feat_indep_blend_func,
164*bbecb9d1SAndroid Build Coastguard Worker feat_indirect_draw,
165*bbecb9d1SAndroid Build Coastguard Worker feat_indirect_params,
166*bbecb9d1SAndroid Build Coastguard Worker feat_khr_debug,
167*bbecb9d1SAndroid Build Coastguard Worker feat_memory_object,
168*bbecb9d1SAndroid Build Coastguard Worker feat_memory_object_fd,
169*bbecb9d1SAndroid Build Coastguard Worker feat_mesa_invert,
170*bbecb9d1SAndroid Build Coastguard Worker feat_ms_scaled_blit,
171*bbecb9d1SAndroid Build Coastguard Worker feat_multisample,
172*bbecb9d1SAndroid Build Coastguard Worker feat_multi_draw_indirect,
173*bbecb9d1SAndroid Build Coastguard Worker feat_nv_conditional_render,
174*bbecb9d1SAndroid Build Coastguard Worker feat_nv_prim_restart,
175*bbecb9d1SAndroid Build Coastguard Worker feat_shader_noperspective_interpolation,
176*bbecb9d1SAndroid Build Coastguard Worker feat_nvx_gpu_memory_info,
177*bbecb9d1SAndroid Build Coastguard Worker feat_polygon_offset_clamp,
178*bbecb9d1SAndroid Build Coastguard Worker feat_occlusion_query,
179*bbecb9d1SAndroid Build Coastguard Worker feat_occlusion_query_boolean,
180*bbecb9d1SAndroid Build Coastguard Worker feat_qbo,
181*bbecb9d1SAndroid Build Coastguard Worker feat_robust_buffer_access,
182*bbecb9d1SAndroid Build Coastguard Worker feat_sample_mask,
183*bbecb9d1SAndroid Build Coastguard Worker feat_sample_shading,
184*bbecb9d1SAndroid Build Coastguard Worker feat_samplers,
185*bbecb9d1SAndroid Build Coastguard Worker feat_sampler_border_colors,
186*bbecb9d1SAndroid Build Coastguard Worker feat_shader_clock,
187*bbecb9d1SAndroid Build Coastguard Worker feat_separate_shader_objects,
188*bbecb9d1SAndroid Build Coastguard Worker feat_ssbo,
189*bbecb9d1SAndroid Build Coastguard Worker feat_ssbo_barrier,
190*bbecb9d1SAndroid Build Coastguard Worker feat_srgb_write_control,
191*bbecb9d1SAndroid Build Coastguard Worker feat_stencil_texturing,
192*bbecb9d1SAndroid Build Coastguard Worker feat_storage_multisample,
193*bbecb9d1SAndroid Build Coastguard Worker feat_tessellation,
194*bbecb9d1SAndroid Build Coastguard Worker feat_texture_array,
195*bbecb9d1SAndroid Build Coastguard Worker feat_texture_barrier,
196*bbecb9d1SAndroid Build Coastguard Worker feat_texture_buffer_range,
197*bbecb9d1SAndroid Build Coastguard Worker feat_texture_gather,
198*bbecb9d1SAndroid Build Coastguard Worker feat_texture_multisample,
199*bbecb9d1SAndroid Build Coastguard Worker feat_texture_query_lod,
200*bbecb9d1SAndroid Build Coastguard Worker feat_texture_shadow_lod,
201*bbecb9d1SAndroid Build Coastguard Worker feat_texture_srgb_decode,
202*bbecb9d1SAndroid Build Coastguard Worker feat_texture_storage,
203*bbecb9d1SAndroid Build Coastguard Worker feat_texture_view,
204*bbecb9d1SAndroid Build Coastguard Worker feat_timer_query,
205*bbecb9d1SAndroid Build Coastguard Worker feat_transform_feedback,
206*bbecb9d1SAndroid Build Coastguard Worker feat_transform_feedback2,
207*bbecb9d1SAndroid Build Coastguard Worker feat_transform_feedback3,
208*bbecb9d1SAndroid Build Coastguard Worker feat_transform_feedback_overflow_query,
209*bbecb9d1SAndroid Build Coastguard Worker feat_txqs,
210*bbecb9d1SAndroid Build Coastguard Worker feat_ubo,
211*bbecb9d1SAndroid Build Coastguard Worker feat_viewport_array,
212*bbecb9d1SAndroid Build Coastguard Worker feat_implicit_msaa,
213*bbecb9d1SAndroid Build Coastguard Worker feat_anisotropic_filter,
214*bbecb9d1SAndroid Build Coastguard Worker feat_last,
215*bbecb9d1SAndroid Build Coastguard Worker };
216*bbecb9d1SAndroid Build Coastguard Worker
217*bbecb9d1SAndroid Build Coastguard Worker #define FEAT_MAX_EXTS 4
218*bbecb9d1SAndroid Build Coastguard Worker #define UNAVAIL INT_MAX
219*bbecb9d1SAndroid Build Coastguard Worker
220*bbecb9d1SAndroid Build Coastguard Worker #define FEAT(NAME, GLVER, GLESVER, ...) \
221*bbecb9d1SAndroid Build Coastguard Worker [feat_ ## NAME ] = {GLVER, GLESVER, { __VA_ARGS__ }, #NAME}
222*bbecb9d1SAndroid Build Coastguard Worker
223*bbecb9d1SAndroid Build Coastguard Worker static const struct {
224*bbecb9d1SAndroid Build Coastguard Worker int gl_ver;
225*bbecb9d1SAndroid Build Coastguard Worker int gles_ver;
226*bbecb9d1SAndroid Build Coastguard Worker const char *gl_ext[FEAT_MAX_EXTS];
227*bbecb9d1SAndroid Build Coastguard Worker const char *log_name;
228*bbecb9d1SAndroid Build Coastguard Worker } feature_list[] = {
229*bbecb9d1SAndroid Build Coastguard Worker FEAT(arb_or_gles_ext_texture_buffer, 31, UNAVAIL, "GL_ARB_texture_buffer_object", "GL_EXT_texture_buffer", NULL),
230*bbecb9d1SAndroid Build Coastguard Worker FEAT(arb_robustness, UNAVAIL, UNAVAIL, "GL_ARB_robustness" ),
231*bbecb9d1SAndroid Build Coastguard Worker FEAT(arb_buffer_storage, 44, UNAVAIL, "GL_ARB_buffer_storage", "GL_EXT_buffer_storage"),
232*bbecb9d1SAndroid Build Coastguard Worker FEAT(arrays_of_arrays, 43, 31, "GL_ARB_arrays_of_arrays"),
233*bbecb9d1SAndroid Build Coastguard Worker FEAT(ati_meminfo, UNAVAIL, UNAVAIL, "GL_ATI_meminfo" ),
234*bbecb9d1SAndroid Build Coastguard Worker FEAT(atomic_counters, 42, 31, "GL_ARB_shader_atomic_counters" ),
235*bbecb9d1SAndroid Build Coastguard Worker FEAT(base_instance, 42, UNAVAIL, "GL_ARB_base_instance", "GL_EXT_base_instance" ),
236*bbecb9d1SAndroid Build Coastguard Worker FEAT(barrier, 42, 31, "GL_ARB_shader_image_load_store"),
237*bbecb9d1SAndroid Build Coastguard Worker FEAT(bind_vertex_buffers, 44, UNAVAIL, NULL),
238*bbecb9d1SAndroid Build Coastguard Worker FEAT(bit_encoding, 33, UNAVAIL, "GL_ARB_shader_bit_encoding" ),
239*bbecb9d1SAndroid Build Coastguard Worker FEAT(blend_equation_advanced, UNAVAIL, 32, "GL_KHR_blend_equation_advanced" ),
240*bbecb9d1SAndroid Build Coastguard Worker FEAT(clear_texture, 44, UNAVAIL, "GL_ARB_clear_texture", "GL_EXT_clear_texture"),
241*bbecb9d1SAndroid Build Coastguard Worker FEAT(clip_control, 45, UNAVAIL, "GL_ARB_clip_control", "GL_EXT_clip_control"),
242*bbecb9d1SAndroid Build Coastguard Worker FEAT(compute_shader, 43, 31, "GL_ARB_compute_shader" ),
243*bbecb9d1SAndroid Build Coastguard Worker FEAT(copy_image, 43, 32, "GL_ARB_copy_image", "GL_EXT_copy_image", "GL_OES_copy_image" ),
244*bbecb9d1SAndroid Build Coastguard Worker FEAT(conditional_render_inverted, 45, UNAVAIL, "GL_ARB_conditional_render_inverted" ),
245*bbecb9d1SAndroid Build Coastguard Worker FEAT(conservative_depth, 42, UNAVAIL, "GL_ARB_conservative_depth", "GL_EXT_conservative_depth" ),
246*bbecb9d1SAndroid Build Coastguard Worker FEAT(cube_map_array, 40, 32, "GL_ARB_texture_cube_map_array", "GL_EXT_texture_cube_map_array", "GL_OES_texture_cube_map_array" ),
247*bbecb9d1SAndroid Build Coastguard Worker FEAT(cull_distance, 45, UNAVAIL, "GL_ARB_cull_distance", "GL_EXT_clip_cull_distance" ),
248*bbecb9d1SAndroid Build Coastguard Worker FEAT(debug_cb, UNAVAIL, UNAVAIL, NULL), /* special case */
249*bbecb9d1SAndroid Build Coastguard Worker FEAT(draw_instance, 31, 30, "GL_ARB_draw_instanced" ),
250*bbecb9d1SAndroid Build Coastguard Worker FEAT(dual_src_blend, 33, UNAVAIL, "GL_ARB_blend_func_extended", "GL_EXT_blend_func_extended" ),
251*bbecb9d1SAndroid Build Coastguard Worker FEAT(depth_clamp, 32, UNAVAIL, "GL_ARB_depth_clamp", "GL_EXT_depth_clamp", "GL_NV_depth_clamp"),
252*bbecb9d1SAndroid Build Coastguard Worker FEAT(enhanced_layouts, 44, UNAVAIL, "GL_ARB_enhanced_layouts"),
253*bbecb9d1SAndroid Build Coastguard Worker FEAT(egl_image, UNAVAIL, UNAVAIL, "GL_OES_EGL_image"),
254*bbecb9d1SAndroid Build Coastguard Worker FEAT(egl_image_storage, UNAVAIL, UNAVAIL, "GL_EXT_EGL_image_storage"),
255*bbecb9d1SAndroid Build Coastguard Worker FEAT(fb_no_attach, 43, 31, "GL_ARB_framebuffer_no_attachments" ),
256*bbecb9d1SAndroid Build Coastguard Worker FEAT(framebuffer_fetch, UNAVAIL, UNAVAIL, "GL_EXT_shader_framebuffer_fetch" ),
257*bbecb9d1SAndroid Build Coastguard Worker FEAT(framebuffer_fetch_non_coherent, UNAVAIL, UNAVAIL, "GL_EXT_shader_framebuffer_fetch_non_coherent" ),
258*bbecb9d1SAndroid Build Coastguard Worker FEAT(geometry_shader, 32, 32, "GL_EXT_geometry_shader", "GL_OES_geometry_shader"),
259*bbecb9d1SAndroid Build Coastguard Worker FEAT(gl_conditional_render, 30, UNAVAIL, NULL),
260*bbecb9d1SAndroid Build Coastguard Worker FEAT(gl_prim_restart, 31, 30, NULL),
261*bbecb9d1SAndroid Build Coastguard Worker FEAT(gles_khr_robustness, UNAVAIL, UNAVAIL, "GL_KHR_robustness" ),
262*bbecb9d1SAndroid Build Coastguard Worker FEAT(gles31_compatibility, 45, 31, "ARB_ES3_1_compatibility" ),
263*bbecb9d1SAndroid Build Coastguard Worker FEAT(gles31_vertex_attrib_binding, 43, 31, "GL_ARB_vertex_attrib_binding" ),
264*bbecb9d1SAndroid Build Coastguard Worker FEAT(gpu_shader5, 40, 32, "GL_ARB_gpu_shader5", "GL_EXT_gpu_shader5", "GL_OES_gpu_shader5" ),
265*bbecb9d1SAndroid Build Coastguard Worker FEAT(images, 42, 31, "GL_ARB_shader_image_load_store" ),
266*bbecb9d1SAndroid Build Coastguard Worker FEAT(indep_blend, 30, 32, "GL_EXT_draw_buffers2", "GL_OES_draw_buffers_indexed" ),
267*bbecb9d1SAndroid Build Coastguard Worker FEAT(indep_blend_func, 40, 32, "GL_ARB_draw_buffers_blend", "GL_OES_draw_buffers_indexed"),
268*bbecb9d1SAndroid Build Coastguard Worker FEAT(indirect_draw, 40, 31, "GL_ARB_draw_indirect" ),
269*bbecb9d1SAndroid Build Coastguard Worker FEAT(indirect_params, 46, UNAVAIL, "GL_ARB_indirect_parameters" ),
270*bbecb9d1SAndroid Build Coastguard Worker FEAT(khr_debug, 43, 32, "GL_KHR_debug" ),
271*bbecb9d1SAndroid Build Coastguard Worker FEAT(memory_object, UNAVAIL, UNAVAIL, "GL_EXT_memory_object"),
272*bbecb9d1SAndroid Build Coastguard Worker FEAT(memory_object_fd, UNAVAIL, UNAVAIL, "GL_EXT_memory_object_fd"),
273*bbecb9d1SAndroid Build Coastguard Worker FEAT(mesa_invert, UNAVAIL, UNAVAIL, "GL_MESA_pack_invert" ),
274*bbecb9d1SAndroid Build Coastguard Worker FEAT(ms_scaled_blit, UNAVAIL, UNAVAIL, "GL_EXT_framebuffer_multisample_blit_scaled" ),
275*bbecb9d1SAndroid Build Coastguard Worker FEAT(multisample, 32, 30, "GL_ARB_texture_multisample" ),
276*bbecb9d1SAndroid Build Coastguard Worker FEAT(multi_draw_indirect, 43, UNAVAIL, "GL_ARB_multi_draw_indirect", "GL_EXT_multi_draw_indirect" ),
277*bbecb9d1SAndroid Build Coastguard Worker FEAT(nv_conditional_render, UNAVAIL, UNAVAIL, "GL_NV_conditional_render" ),
278*bbecb9d1SAndroid Build Coastguard Worker FEAT(nv_prim_restart, UNAVAIL, UNAVAIL, "GL_NV_primitive_restart" ),
279*bbecb9d1SAndroid Build Coastguard Worker FEAT(shader_noperspective_interpolation, 31, UNAVAIL, "GL_NV_shader_noperspective_interpolation", "GL_EXT_gpu_shader4"),
280*bbecb9d1SAndroid Build Coastguard Worker FEAT(nvx_gpu_memory_info, UNAVAIL, UNAVAIL, "GL_NVX_gpu_memory_info" ),
281*bbecb9d1SAndroid Build Coastguard Worker FEAT(polygon_offset_clamp, 46, UNAVAIL, "GL_ARB_polygon_offset_clamp", "GL_EXT_polygon_offset_clamp"),
282*bbecb9d1SAndroid Build Coastguard Worker FEAT(occlusion_query, 15, UNAVAIL, "GL_ARB_occlusion_query"),
283*bbecb9d1SAndroid Build Coastguard Worker FEAT(occlusion_query_boolean, 33, 30, "GL_EXT_occlusion_query_boolean", "GL_ARB_occlusion_query2"),
284*bbecb9d1SAndroid Build Coastguard Worker FEAT(qbo, 44, UNAVAIL, "GL_ARB_query_buffer_object" ),
285*bbecb9d1SAndroid Build Coastguard Worker FEAT(robust_buffer_access, 43, UNAVAIL, "GL_ARB_robust_buffer_access_behavior", "GL_KHR_robust_buffer_access_behavior" ),
286*bbecb9d1SAndroid Build Coastguard Worker FEAT(sample_mask, 32, 31, "GL_ARB_texture_multisample" ),
287*bbecb9d1SAndroid Build Coastguard Worker FEAT(sample_shading, 40, 32, "GL_ARB_sample_shading", "GL_OES_sample_shading" ),
288*bbecb9d1SAndroid Build Coastguard Worker FEAT(samplers, 33, 30, "GL_ARB_sampler_objects" ),
289*bbecb9d1SAndroid Build Coastguard Worker FEAT(sampler_border_colors, 33, 32, "GL_ARB_sampler_objects", "GL_EXT_texture_border_clamp", "GL_OES_texture_border_clamp" ),
290*bbecb9d1SAndroid Build Coastguard Worker FEAT(separate_shader_objects, 41, 31, "GL_ARB_seperate_shader_objects"),
291*bbecb9d1SAndroid Build Coastguard Worker FEAT(shader_clock, UNAVAIL, UNAVAIL, "GL_ARB_shader_clock" ),
292*bbecb9d1SAndroid Build Coastguard Worker FEAT(ssbo, 43, 31, "GL_ARB_shader_storage_buffer_object" ),
293*bbecb9d1SAndroid Build Coastguard Worker FEAT(ssbo_barrier, 43, 31, "GL_ARB_shader_storage_buffer_object"),
294*bbecb9d1SAndroid Build Coastguard Worker FEAT(srgb_write_control, 30, UNAVAIL, "GL_EXT_sRGB_write_control"),
295*bbecb9d1SAndroid Build Coastguard Worker FEAT(stencil_texturing, 43, 31, "GL_ARB_stencil_texturing" ),
296*bbecb9d1SAndroid Build Coastguard Worker FEAT(storage_multisample, 43, 31, "GL_ARB_texture_storage_multisample" ),
297*bbecb9d1SAndroid Build Coastguard Worker FEAT(tessellation, 40, 32, "GL_ARB_tessellation_shader", "GL_OES_tessellation_shader", "GL_EXT_tessellation_shader" ),
298*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_array, 30, 30, "GL_EXT_texture_array" ),
299*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_barrier, 45, UNAVAIL, "GL_ARB_texture_barrier" ),
300*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_buffer_range, 43, 32, "GL_ARB_texture_buffer_range" ),
301*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_gather, 40, 31, "GL_ARB_texture_gather" ),
302*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_multisample, 32, 31, "GL_ARB_texture_multisample" ),
303*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_query_lod, 40, UNAVAIL, "GL_ARB_texture_query_lod", "GL_EXT_texture_query_lod"),
304*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_shadow_lod, UNAVAIL, UNAVAIL, "GL_EXT_texture_shadow_lod"),
305*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_srgb_decode, UNAVAIL, UNAVAIL, "GL_EXT_texture_sRGB_decode" ),
306*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_storage, 42, 30, "GL_ARB_texture_storage" ),
307*bbecb9d1SAndroid Build Coastguard Worker FEAT(texture_view, 43, UNAVAIL, "GL_ARB_texture_view", "GL_OES_texture_view", "GL_EXT_texture_view" ),
308*bbecb9d1SAndroid Build Coastguard Worker FEAT(timer_query, 33, UNAVAIL, "GL_ARB_timer_query", "GL_EXT_disjoint_timer_query"),
309*bbecb9d1SAndroid Build Coastguard Worker FEAT(transform_feedback, 30, 30, "GL_EXT_transform_feedback" ),
310*bbecb9d1SAndroid Build Coastguard Worker FEAT(transform_feedback2, 40, 30, "GL_ARB_transform_feedback2" ),
311*bbecb9d1SAndroid Build Coastguard Worker FEAT(transform_feedback3, 40, UNAVAIL, "GL_ARB_transform_feedback3" ),
312*bbecb9d1SAndroid Build Coastguard Worker FEAT(transform_feedback_overflow_query, 46, UNAVAIL, "GL_ARB_transform_feedback_overflow_query" ),
313*bbecb9d1SAndroid Build Coastguard Worker FEAT(txqs, 45, UNAVAIL, "GL_ARB_shader_texture_image_samples" ),
314*bbecb9d1SAndroid Build Coastguard Worker FEAT(ubo, 31, 30, "GL_ARB_uniform_buffer_object" ),
315*bbecb9d1SAndroid Build Coastguard Worker FEAT(viewport_array, 41, UNAVAIL, "GL_ARB_viewport_array", "GL_OES_viewport_array"),
316*bbecb9d1SAndroid Build Coastguard Worker FEAT(implicit_msaa, UNAVAIL, UNAVAIL, "GL_EXT_multisampled_render_to_texture"),
317*bbecb9d1SAndroid Build Coastguard Worker FEAT(anisotropic_filter, 46, UNAVAIL, "GL_EXT_texture_filter_anisotropic", "GL_ARB_texture_filter_anisotropic"),
318*bbecb9d1SAndroid Build Coastguard Worker };
319*bbecb9d1SAndroid Build Coastguard Worker
320*bbecb9d1SAndroid Build Coastguard Worker struct global_renderer_state {
321*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *ctx0;
322*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *current_ctx;
323*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *current_hw_ctx;
324*bbecb9d1SAndroid Build Coastguard Worker
325*bbecb9d1SAndroid Build Coastguard Worker struct list_head waiting_query_list;
326*bbecb9d1SAndroid Build Coastguard Worker struct list_head fence_list;
327*bbecb9d1SAndroid Build Coastguard Worker struct list_head fence_wait_list;
328*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *fence_waiting;
329*bbecb9d1SAndroid Build Coastguard Worker
330*bbecb9d1SAndroid Build Coastguard Worker int gl_major_ver;
331*bbecb9d1SAndroid Build Coastguard Worker int gl_minor_ver;
332*bbecb9d1SAndroid Build Coastguard Worker
333*bbecb9d1SAndroid Build Coastguard Worker mtx_t fence_mutex;
334*bbecb9d1SAndroid Build Coastguard Worker thrd_t sync_thread;
335*bbecb9d1SAndroid Build Coastguard Worker virgl_gl_context sync_context;
336*bbecb9d1SAndroid Build Coastguard Worker
337*bbecb9d1SAndroid Build Coastguard Worker cnd_t fence_cond;
338*bbecb9d1SAndroid Build Coastguard Worker
339*bbecb9d1SAndroid Build Coastguard Worker /* only used with async fence callback */
340*bbecb9d1SAndroid Build Coastguard Worker atomic_bool has_waiting_queries;
341*bbecb9d1SAndroid Build Coastguard Worker bool polling;
342*bbecb9d1SAndroid Build Coastguard Worker mtx_t poll_mutex;
343*bbecb9d1SAndroid Build Coastguard Worker cnd_t poll_cond;
344*bbecb9d1SAndroid Build Coastguard Worker
345*bbecb9d1SAndroid Build Coastguard Worker float tess_factors[6];
346*bbecb9d1SAndroid Build Coastguard Worker int eventfd;
347*bbecb9d1SAndroid Build Coastguard Worker
348*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_draw_buffers;
349*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_texture_buffer_size;
350*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_texture_2d_size;
351*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_texture_3d_size;
352*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_texture_cube_size;
353*bbecb9d1SAndroid Build Coastguard Worker uint32_t max_shader_patch_varyings;
354*bbecb9d1SAndroid Build Coastguard Worker
355*bbecb9d1SAndroid Build Coastguard Worker /* inferred GL caching type */
356*bbecb9d1SAndroid Build Coastguard Worker uint32_t inferred_gl_caching_type;
357*bbecb9d1SAndroid Build Coastguard Worker
358*bbecb9d1SAndroid Build Coastguard Worker uint64_t features[feat_last / 64 + 1];
359*bbecb9d1SAndroid Build Coastguard Worker
360*bbecb9d1SAndroid Build Coastguard Worker bool finishing : 1;
361*bbecb9d1SAndroid Build Coastguard Worker bool use_gles : 1;
362*bbecb9d1SAndroid Build Coastguard Worker bool use_core_profile : 1;
363*bbecb9d1SAndroid Build Coastguard Worker bool use_external_blob : 1;
364*bbecb9d1SAndroid Build Coastguard Worker bool use_integer : 1;
365*bbecb9d1SAndroid Build Coastguard Worker /* these appeared broken on at least one driver */
366*bbecb9d1SAndroid Build Coastguard Worker bool use_explicit_locations : 1;
367*bbecb9d1SAndroid Build Coastguard Worker /* threaded sync */
368*bbecb9d1SAndroid Build Coastguard Worker bool stop_sync_thread : 1;
369*bbecb9d1SAndroid Build Coastguard Worker /* async fence callback */
370*bbecb9d1SAndroid Build Coastguard Worker bool use_async_fence_cb : 1;
371*bbecb9d1SAndroid Build Coastguard Worker
372*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
373*bbecb9d1SAndroid Build Coastguard Worker bool use_egl_fence : 1;
374*bbecb9d1SAndroid Build Coastguard Worker #endif
375*bbecb9d1SAndroid Build Coastguard Worker };
376*bbecb9d1SAndroid Build Coastguard Worker
377*bbecb9d1SAndroid Build Coastguard Worker struct sysval_uniform_block {
378*bbecb9d1SAndroid Build Coastguard Worker GLfloat clipp[VIRGL_NUM_CLIP_PLANES][4];
379*bbecb9d1SAndroid Build Coastguard Worker GLuint stipple_pattern[VREND_POLYGON_STIPPLE_SIZE][4];
380*bbecb9d1SAndroid Build Coastguard Worker GLfloat winsys_adjust_y;
381*bbecb9d1SAndroid Build Coastguard Worker GLfloat alpha_ref_val;
382*bbecb9d1SAndroid Build Coastguard Worker GLfloat clip_plane_enabled;
383*bbecb9d1SAndroid Build Coastguard Worker };
384*bbecb9d1SAndroid Build Coastguard Worker
385*bbecb9d1SAndroid Build Coastguard Worker static struct global_renderer_state vrend_state;
386*bbecb9d1SAndroid Build Coastguard Worker
has_feature(enum features_id feature_id)387*bbecb9d1SAndroid Build Coastguard Worker static inline bool has_feature(enum features_id feature_id)
388*bbecb9d1SAndroid Build Coastguard Worker {
389*bbecb9d1SAndroid Build Coastguard Worker int slot = feature_id / 64;
390*bbecb9d1SAndroid Build Coastguard Worker uint64_t mask = 1ull << (feature_id & 63);
391*bbecb9d1SAndroid Build Coastguard Worker bool retval = vrend_state.features[slot] & mask ? true : false;
392*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_feature_use, NULL, "Try using feature %s:%d\n",
393*bbecb9d1SAndroid Build Coastguard Worker feature_list[feature_id].log_name,
394*bbecb9d1SAndroid Build Coastguard Worker retval);
395*bbecb9d1SAndroid Build Coastguard Worker return retval;
396*bbecb9d1SAndroid Build Coastguard Worker }
397*bbecb9d1SAndroid Build Coastguard Worker
398*bbecb9d1SAndroid Build Coastguard Worker
set_feature(enum features_id feature_id)399*bbecb9d1SAndroid Build Coastguard Worker static inline void set_feature(enum features_id feature_id)
400*bbecb9d1SAndroid Build Coastguard Worker {
401*bbecb9d1SAndroid Build Coastguard Worker int slot = feature_id / 64;
402*bbecb9d1SAndroid Build Coastguard Worker uint64_t mask = 1ull << (feature_id & 63);
403*bbecb9d1SAndroid Build Coastguard Worker vrend_state.features[slot] |= mask;
404*bbecb9d1SAndroid Build Coastguard Worker }
405*bbecb9d1SAndroid Build Coastguard Worker
clear_feature(enum features_id feature_id)406*bbecb9d1SAndroid Build Coastguard Worker static inline void clear_feature(enum features_id feature_id)
407*bbecb9d1SAndroid Build Coastguard Worker {
408*bbecb9d1SAndroid Build Coastguard Worker int slot = feature_id / 64;
409*bbecb9d1SAndroid Build Coastguard Worker uint64_t mask = 1ull << (feature_id & 63);
410*bbecb9d1SAndroid Build Coastguard Worker vrend_state.features[slot] &= ~mask;
411*bbecb9d1SAndroid Build Coastguard Worker }
412*bbecb9d1SAndroid Build Coastguard Worker
413*bbecb9d1SAndroid Build Coastguard Worker
414*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program {
415*bbecb9d1SAndroid Build Coastguard Worker struct list_head head;
416*bbecb9d1SAndroid Build Coastguard Worker struct list_head sl[PIPE_SHADER_TYPES];
417*bbecb9d1SAndroid Build Coastguard Worker bool is_pipeline;
418*bbecb9d1SAndroid Build Coastguard Worker union {
419*bbecb9d1SAndroid Build Coastguard Worker GLuint program;
420*bbecb9d1SAndroid Build Coastguard Worker GLuint pipeline;
421*bbecb9d1SAndroid Build Coastguard Worker } id;
422*bbecb9d1SAndroid Build Coastguard Worker
423*bbecb9d1SAndroid Build Coastguard Worker bool dual_src_linked;
424*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *ss[PIPE_SHADER_TYPES];
425*bbecb9d1SAndroid Build Coastguard Worker uint64_t vs_fs_key;
426*bbecb9d1SAndroid Build Coastguard Worker
427*bbecb9d1SAndroid Build Coastguard Worker uint32_t ubo_used_mask[PIPE_SHADER_TYPES];
428*bbecb9d1SAndroid Build Coastguard Worker uint32_t samplers_used_mask[PIPE_SHADER_TYPES];
429*bbecb9d1SAndroid Build Coastguard Worker
430*bbecb9d1SAndroid Build Coastguard Worker GLuint *shadow_samp_mask_locs[PIPE_SHADER_TYPES];
431*bbecb9d1SAndroid Build Coastguard Worker GLuint *shadow_samp_add_locs[PIPE_SHADER_TYPES];
432*bbecb9d1SAndroid Build Coastguard Worker
433*bbecb9d1SAndroid Build Coastguard Worker GLint const_location[PIPE_SHADER_TYPES];
434*bbecb9d1SAndroid Build Coastguard Worker
435*bbecb9d1SAndroid Build Coastguard Worker GLuint *attrib_locs;
436*bbecb9d1SAndroid Build Coastguard Worker uint32_t shadow_samp_mask[PIPE_SHADER_TYPES];
437*bbecb9d1SAndroid Build Coastguard Worker
438*bbecb9d1SAndroid Build Coastguard Worker GLuint separate_virgl_block_id[PIPE_SHADER_TYPES];
439*bbecb9d1SAndroid Build Coastguard Worker GLint virgl_block_bind;
440*bbecb9d1SAndroid Build Coastguard Worker uint32_t sysvalue_data_cookie;
441*bbecb9d1SAndroid Build Coastguard Worker GLint ubo_sysval_buffer_id;
442*bbecb9d1SAndroid Build Coastguard Worker
443*bbecb9d1SAndroid Build Coastguard Worker uint32_t images_used_mask[PIPE_SHADER_TYPES];
444*bbecb9d1SAndroid Build Coastguard Worker GLint *img_locs[PIPE_SHADER_TYPES];
445*bbecb9d1SAndroid Build Coastguard Worker
446*bbecb9d1SAndroid Build Coastguard Worker uint32_t ssbo_used_mask[PIPE_SHADER_TYPES];
447*bbecb9d1SAndroid Build Coastguard Worker
448*bbecb9d1SAndroid Build Coastguard Worker int32_t tex_levels_uniform_id[PIPE_SHADER_TYPES];
449*bbecb9d1SAndroid Build Coastguard Worker
450*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *ref_context;
451*bbecb9d1SAndroid Build Coastguard Worker
452*bbecb9d1SAndroid Build Coastguard Worker uint32_t gles_use_query_texturelevel_mask;
453*bbecb9d1SAndroid Build Coastguard Worker };
454*bbecb9d1SAndroid Build Coastguard Worker
455*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader {
456*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *next_variant;
457*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel;
458*bbecb9d1SAndroid Build Coastguard Worker
459*bbecb9d1SAndroid Build Coastguard Worker struct vrend_variable_shader_info var_sinfo;
460*bbecb9d1SAndroid Build Coastguard Worker
461*bbecb9d1SAndroid Build Coastguard Worker struct vrend_strarray glsl_strings;
462*bbecb9d1SAndroid Build Coastguard Worker GLuint id;
463*bbecb9d1SAndroid Build Coastguard Worker GLuint program_id; /* only used for separable shaders */
464*bbecb9d1SAndroid Build Coastguard Worker GLuint last_pipeline_id;
465*bbecb9d1SAndroid Build Coastguard Worker uint32_t uid;
466*bbecb9d1SAndroid Build Coastguard Worker bool is_compiled;
467*bbecb9d1SAndroid Build Coastguard Worker bool is_linked; /* only used for separable shaders */
468*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_key key;
469*bbecb9d1SAndroid Build Coastguard Worker struct list_head programs;
470*bbecb9d1SAndroid Build Coastguard Worker };
471*bbecb9d1SAndroid Build Coastguard Worker
472*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector {
473*bbecb9d1SAndroid Build Coastguard Worker struct pipe_reference reference;
474*bbecb9d1SAndroid Build Coastguard Worker
475*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type type;
476*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_info sinfo;
477*bbecb9d1SAndroid Build Coastguard Worker
478*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *current;
479*bbecb9d1SAndroid Build Coastguard Worker struct tgsi_token *tokens;
480*bbecb9d1SAndroid Build Coastguard Worker
481*bbecb9d1SAndroid Build Coastguard Worker uint32_t req_local_mem;
482*bbecb9d1SAndroid Build Coastguard Worker char *tmp_buf;
483*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_len;
484*bbecb9d1SAndroid Build Coastguard Worker uint32_t buf_offset;
485*bbecb9d1SAndroid Build Coastguard Worker };
486*bbecb9d1SAndroid Build Coastguard Worker
487*bbecb9d1SAndroid Build Coastguard Worker struct vrend_texture {
488*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource base;
489*bbecb9d1SAndroid Build Coastguard Worker struct pipe_sampler_state state;
490*bbecb9d1SAndroid Build Coastguard Worker GLint cur_swizzle[4];
491*bbecb9d1SAndroid Build Coastguard Worker GLuint cur_srgb_decode;
492*bbecb9d1SAndroid Build Coastguard Worker GLuint cur_base, cur_max;
493*bbecb9d1SAndroid Build Coastguard Worker };
494*bbecb9d1SAndroid Build Coastguard Worker
495*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface {
496*bbecb9d1SAndroid Build Coastguard Worker struct pipe_reference reference;
497*bbecb9d1SAndroid Build Coastguard Worker GLuint id;
498*bbecb9d1SAndroid Build Coastguard Worker GLuint res_handle;
499*bbecb9d1SAndroid Build Coastguard Worker GLuint format;
500*bbecb9d1SAndroid Build Coastguard Worker GLuint val0, val1;
501*bbecb9d1SAndroid Build Coastguard Worker GLuint nr_samples;
502*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *texture;
503*bbecb9d1SAndroid Build Coastguard Worker };
504*bbecb9d1SAndroid Build Coastguard Worker
505*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_state {
506*bbecb9d1SAndroid Build Coastguard Worker struct pipe_sampler_state base;
507*bbecb9d1SAndroid Build Coastguard Worker GLuint ids[2];
508*bbecb9d1SAndroid Build Coastguard Worker };
509*bbecb9d1SAndroid Build Coastguard Worker
510*bbecb9d1SAndroid Build Coastguard Worker struct vrend_so_target {
511*bbecb9d1SAndroid Build Coastguard Worker struct pipe_reference reference;
512*bbecb9d1SAndroid Build Coastguard Worker GLuint res_handle;
513*bbecb9d1SAndroid Build Coastguard Worker unsigned buffer_offset;
514*bbecb9d1SAndroid Build Coastguard Worker unsigned buffer_size;
515*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *buffer;
516*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx;
517*bbecb9d1SAndroid Build Coastguard Worker };
518*bbecb9d1SAndroid Build Coastguard Worker
519*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view {
520*bbecb9d1SAndroid Build Coastguard Worker struct pipe_reference reference;
521*bbecb9d1SAndroid Build Coastguard Worker GLuint id;
522*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats format;
523*bbecb9d1SAndroid Build Coastguard Worker GLenum target;
524*bbecb9d1SAndroid Build Coastguard Worker GLuint val0, val1;
525*bbecb9d1SAndroid Build Coastguard Worker GLint gl_swizzle[4];
526*bbecb9d1SAndroid Build Coastguard Worker GLuint srgb_decode;
527*bbecb9d1SAndroid Build Coastguard Worker GLuint levels;
528*bbecb9d1SAndroid Build Coastguard Worker bool emulated_rect;
529*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *texture;
530*bbecb9d1SAndroid Build Coastguard Worker };
531*bbecb9d1SAndroid Build Coastguard Worker
532*bbecb9d1SAndroid Build Coastguard Worker struct vrend_image_view {
533*bbecb9d1SAndroid Build Coastguard Worker GLuint id;
534*bbecb9d1SAndroid Build Coastguard Worker GLenum access;
535*bbecb9d1SAndroid Build Coastguard Worker GLenum format;
536*bbecb9d1SAndroid Build Coastguard Worker uint32_t vformat;
537*bbecb9d1SAndroid Build Coastguard Worker union {
538*bbecb9d1SAndroid Build Coastguard Worker struct {
539*bbecb9d1SAndroid Build Coastguard Worker unsigned first_layer:16; /**< first layer to use for array textures */
540*bbecb9d1SAndroid Build Coastguard Worker unsigned last_layer:16; /**< last layer to use for array textures */
541*bbecb9d1SAndroid Build Coastguard Worker unsigned level:8; /**< mipmap level to use */
542*bbecb9d1SAndroid Build Coastguard Worker } tex;
543*bbecb9d1SAndroid Build Coastguard Worker struct {
544*bbecb9d1SAndroid Build Coastguard Worker unsigned offset; /**< offset in bytes */
545*bbecb9d1SAndroid Build Coastguard Worker unsigned size; /**< size of the accessible sub-range in bytes */
546*bbecb9d1SAndroid Build Coastguard Worker } buf;
547*bbecb9d1SAndroid Build Coastguard Worker } u;
548*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *texture;
549*bbecb9d1SAndroid Build Coastguard Worker };
550*bbecb9d1SAndroid Build Coastguard Worker
551*bbecb9d1SAndroid Build Coastguard Worker struct vrend_ssbo {
552*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
553*bbecb9d1SAndroid Build Coastguard Worker unsigned buffer_size;
554*bbecb9d1SAndroid Build Coastguard Worker unsigned buffer_offset;
555*bbecb9d1SAndroid Build Coastguard Worker };
556*bbecb9d1SAndroid Build Coastguard Worker
557*bbecb9d1SAndroid Build Coastguard Worker struct vrend_abo {
558*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
559*bbecb9d1SAndroid Build Coastguard Worker unsigned buffer_size;
560*bbecb9d1SAndroid Build Coastguard Worker unsigned buffer_offset;
561*bbecb9d1SAndroid Build Coastguard Worker };
562*bbecb9d1SAndroid Build Coastguard Worker
563*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element {
564*bbecb9d1SAndroid Build Coastguard Worker struct pipe_vertex_element base;
565*bbecb9d1SAndroid Build Coastguard Worker GLenum type;
566*bbecb9d1SAndroid Build Coastguard Worker GLboolean norm;
567*bbecb9d1SAndroid Build Coastguard Worker GLuint nr_chan;
568*bbecb9d1SAndroid Build Coastguard Worker };
569*bbecb9d1SAndroid Build Coastguard Worker
570*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element_array {
571*bbecb9d1SAndroid Build Coastguard Worker unsigned count;
572*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element elements[PIPE_MAX_ATTRIBS];
573*bbecb9d1SAndroid Build Coastguard Worker GLuint id;
574*bbecb9d1SAndroid Build Coastguard Worker uint32_t signed_int_bitmask;
575*bbecb9d1SAndroid Build Coastguard Worker uint32_t unsigned_int_bitmask;
576*bbecb9d1SAndroid Build Coastguard Worker uint32_t zyxw_bitmask;
577*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *owning_sub;
578*bbecb9d1SAndroid Build Coastguard Worker };
579*bbecb9d1SAndroid Build Coastguard Worker
580*bbecb9d1SAndroid Build Coastguard Worker struct vrend_constants {
581*bbecb9d1SAndroid Build Coastguard Worker unsigned int *consts;
582*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_consts;
583*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_allocated_consts;
584*bbecb9d1SAndroid Build Coastguard Worker };
585*bbecb9d1SAndroid Build Coastguard Worker
586*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_view {
587*bbecb9d1SAndroid Build Coastguard Worker int num_views;
588*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
589*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_id[PIPE_MAX_SHADER_SAMPLER_VIEWS];
590*bbecb9d1SAndroid Build Coastguard Worker uint32_t old_ids[PIPE_MAX_SHADER_SAMPLER_VIEWS];
591*bbecb9d1SAndroid Build Coastguard Worker };
592*bbecb9d1SAndroid Build Coastguard Worker
593*bbecb9d1SAndroid Build Coastguard Worker struct vrend_viewport {
594*bbecb9d1SAndroid Build Coastguard Worker GLint cur_x, cur_y;
595*bbecb9d1SAndroid Build Coastguard Worker GLsizei width, height;
596*bbecb9d1SAndroid Build Coastguard Worker GLclampd near_val, far_val;
597*bbecb9d1SAndroid Build Coastguard Worker };
598*bbecb9d1SAndroid Build Coastguard Worker
599*bbecb9d1SAndroid Build Coastguard Worker /* create a streamout object to support pause/resume */
600*bbecb9d1SAndroid Build Coastguard Worker struct vrend_streamout_object {
601*bbecb9d1SAndroid Build Coastguard Worker GLuint id;
602*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_targets;
603*bbecb9d1SAndroid Build Coastguard Worker uint32_t handles[16];
604*bbecb9d1SAndroid Build Coastguard Worker struct list_head head;
605*bbecb9d1SAndroid Build Coastguard Worker int xfb_state;
606*bbecb9d1SAndroid Build Coastguard Worker struct vrend_so_target *so_targets[16];
607*bbecb9d1SAndroid Build Coastguard Worker };
608*bbecb9d1SAndroid Build Coastguard Worker
609*bbecb9d1SAndroid Build Coastguard Worker #define XFB_STATE_OFF 0
610*bbecb9d1SAndroid Build Coastguard Worker #define XFB_STATE_STARTED_NEED_BEGIN 1
611*bbecb9d1SAndroid Build Coastguard Worker #define XFB_STATE_STARTED 2
612*bbecb9d1SAndroid Build Coastguard Worker #define XFB_STATE_PAUSED 3
613*bbecb9d1SAndroid Build Coastguard Worker
614*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_buffer {
615*bbecb9d1SAndroid Build Coastguard Worker struct pipe_vertex_buffer base;
616*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_id;
617*bbecb9d1SAndroid Build Coastguard Worker };
618*bbecb9d1SAndroid Build Coastguard Worker
619*bbecb9d1SAndroid Build Coastguard Worker #define VREND_PROGRAM_NQUEUES (1 << 8)
620*bbecb9d1SAndroid Build Coastguard Worker #define VREND_PROGRAM_NQUEUE_MASK (VREND_PROGRAM_NQUEUES - 1)
621*bbecb9d1SAndroid Build Coastguard Worker
622*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context {
623*bbecb9d1SAndroid Build Coastguard Worker struct list_head head;
624*bbecb9d1SAndroid Build Coastguard Worker
625*bbecb9d1SAndroid Build Coastguard Worker virgl_gl_context gl_context;
626*bbecb9d1SAndroid Build Coastguard Worker
627*bbecb9d1SAndroid Build Coastguard Worker int sub_ctx_id;
628*bbecb9d1SAndroid Build Coastguard Worker
629*bbecb9d1SAndroid Build Coastguard Worker GLuint vaoid;
630*bbecb9d1SAndroid Build Coastguard Worker uint32_t enabled_attribs_bitmask;
631*bbecb9d1SAndroid Build Coastguard Worker
632*bbecb9d1SAndroid Build Coastguard Worker /* Using an array of lists only adds VREND_PROGRAM_NQUEUES - 1 list_head
633*bbecb9d1SAndroid Build Coastguard Worker * structures to the consumed memory, but looking up the program can
634*bbecb9d1SAndroid Build Coastguard Worker * be spead up by the factor VREND_PROGRAM_NQUEUES which makes this
635*bbecb9d1SAndroid Build Coastguard Worker * worthwile. */
636*bbecb9d1SAndroid Build Coastguard Worker struct list_head gl_programs[VREND_PROGRAM_NQUEUES];
637*bbecb9d1SAndroid Build Coastguard Worker struct list_head cs_programs;
638*bbecb9d1SAndroid Build Coastguard Worker struct util_hash_table *object_hash;
639*bbecb9d1SAndroid Build Coastguard Worker
640*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element_array *ve;
641*bbecb9d1SAndroid Build Coastguard Worker int num_vbos;
642*bbecb9d1SAndroid Build Coastguard Worker int old_num_vbos; /* for cleaning up */
643*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_buffer vbo[PIPE_MAX_ATTRIBS];
644*bbecb9d1SAndroid Build Coastguard Worker
645*bbecb9d1SAndroid Build Coastguard Worker struct pipe_index_buffer ib;
646*bbecb9d1SAndroid Build Coastguard Worker uint32_t index_buffer_res_id;
647*bbecb9d1SAndroid Build Coastguard Worker
648*bbecb9d1SAndroid Build Coastguard Worker bool vbo_dirty;
649*bbecb9d1SAndroid Build Coastguard Worker bool shader_dirty;
650*bbecb9d1SAndroid Build Coastguard Worker bool cs_shader_dirty;
651*bbecb9d1SAndroid Build Coastguard Worker bool stencil_state_dirty;
652*bbecb9d1SAndroid Build Coastguard Worker bool image_state_dirty;
653*bbecb9d1SAndroid Build Coastguard Worker bool blend_state_dirty;
654*bbecb9d1SAndroid Build Coastguard Worker
655*bbecb9d1SAndroid Build Coastguard Worker uint32_t long_shader_in_progress_handle[PIPE_SHADER_TYPES];
656*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *shaders[PIPE_SHADER_TYPES];
657*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *prog;
658*bbecb9d1SAndroid Build Coastguard Worker
659*bbecb9d1SAndroid Build Coastguard Worker GLuint prog_ids[PIPE_SHADER_TYPES];
660*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_view views[PIPE_SHADER_TYPES];
661*bbecb9d1SAndroid Build Coastguard Worker
662*bbecb9d1SAndroid Build Coastguard Worker struct vrend_constants consts[PIPE_SHADER_TYPES];
663*bbecb9d1SAndroid Build Coastguard Worker bool const_dirty[PIPE_SHADER_TYPES];
664*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_state *sampler_state[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
665*bbecb9d1SAndroid Build Coastguard Worker
666*bbecb9d1SAndroid Build Coastguard Worker struct pipe_constant_buffer cbs[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
667*bbecb9d1SAndroid Build Coastguard Worker uint32_t const_bufs_used_mask[PIPE_SHADER_TYPES];
668*bbecb9d1SAndroid Build Coastguard Worker uint32_t const_bufs_dirty[PIPE_SHADER_TYPES];
669*bbecb9d1SAndroid Build Coastguard Worker
670*bbecb9d1SAndroid Build Coastguard Worker int num_sampler_states[PIPE_SHADER_TYPES];
671*bbecb9d1SAndroid Build Coastguard Worker
672*bbecb9d1SAndroid Build Coastguard Worker uint32_t sampler_views_dirty[PIPE_SHADER_TYPES];
673*bbecb9d1SAndroid Build Coastguard Worker int32_t texture_levels[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
674*bbecb9d1SAndroid Build Coastguard Worker int32_t n_samplers[PIPE_SHADER_TYPES];
675*bbecb9d1SAndroid Build Coastguard Worker
676*bbecb9d1SAndroid Build Coastguard Worker uint32_t fb_id;
677*bbecb9d1SAndroid Build Coastguard Worker int nr_cbufs;
678*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *zsurf;
679*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf[PIPE_MAX_COLOR_BUFS];
680*bbecb9d1SAndroid Build Coastguard Worker
681*bbecb9d1SAndroid Build Coastguard Worker struct vrend_viewport vps[PIPE_MAX_VIEWPORTS];
682*bbecb9d1SAndroid Build Coastguard Worker /* viewport is negative */
683*bbecb9d1SAndroid Build Coastguard Worker uint32_t scissor_state_dirty;
684*bbecb9d1SAndroid Build Coastguard Worker uint32_t viewport_state_dirty;
685*bbecb9d1SAndroid Build Coastguard Worker uint32_t viewport_state_initialized;
686*bbecb9d1SAndroid Build Coastguard Worker
687*bbecb9d1SAndroid Build Coastguard Worker uint32_t fb_height;
688*bbecb9d1SAndroid Build Coastguard Worker
689*bbecb9d1SAndroid Build Coastguard Worker struct pipe_scissor_state ss[PIPE_MAX_VIEWPORTS];
690*bbecb9d1SAndroid Build Coastguard Worker
691*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_state blend_state;
692*bbecb9d1SAndroid Build Coastguard Worker struct pipe_depth_stencil_alpha_state dsa_state;
693*bbecb9d1SAndroid Build Coastguard Worker struct pipe_rasterizer_state rs_state;
694*bbecb9d1SAndroid Build Coastguard Worker
695*bbecb9d1SAndroid Build Coastguard Worker uint8_t stencil_refs[2];
696*bbecb9d1SAndroid Build Coastguard Worker bool viewport_is_negative;
697*bbecb9d1SAndroid Build Coastguard Worker /* this is set if the contents of the FBO look upside down when viewed
698*bbecb9d1SAndroid Build Coastguard Worker with 0,0 as the bottom corner */
699*bbecb9d1SAndroid Build Coastguard Worker bool fbo_origin_upper_left;
700*bbecb9d1SAndroid Build Coastguard Worker
701*bbecb9d1SAndroid Build Coastguard Worker GLuint blit_fb_ids[2];
702*bbecb9d1SAndroid Build Coastguard Worker
703*bbecb9d1SAndroid Build Coastguard Worker struct pipe_depth_stencil_alpha_state *dsa;
704*bbecb9d1SAndroid Build Coastguard Worker
705*bbecb9d1SAndroid Build Coastguard Worker struct pipe_clip_state ucp_state;
706*bbecb9d1SAndroid Build Coastguard Worker
707*bbecb9d1SAndroid Build Coastguard Worker bool depth_test_enabled;
708*bbecb9d1SAndroid Build Coastguard Worker bool alpha_test_enabled;
709*bbecb9d1SAndroid Build Coastguard Worker bool stencil_test_enabled;
710*bbecb9d1SAndroid Build Coastguard Worker bool framebuffer_srgb_enabled;
711*bbecb9d1SAndroid Build Coastguard Worker
712*bbecb9d1SAndroid Build Coastguard Worker int last_shader_idx;
713*bbecb9d1SAndroid Build Coastguard Worker
714*bbecb9d1SAndroid Build Coastguard Worker GLint draw_indirect_buffer;
715*bbecb9d1SAndroid Build Coastguard Worker
716*bbecb9d1SAndroid Build Coastguard Worker GLint draw_indirect_params_buffer;
717*bbecb9d1SAndroid Build Coastguard Worker
718*bbecb9d1SAndroid Build Coastguard Worker struct pipe_rasterizer_state hw_rs_state;
719*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_state hw_blend_state;
720*bbecb9d1SAndroid Build Coastguard Worker
721*bbecb9d1SAndroid Build Coastguard Worker struct list_head streamout_list;
722*bbecb9d1SAndroid Build Coastguard Worker struct vrend_streamout_object *current_so;
723*bbecb9d1SAndroid Build Coastguard Worker
724*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_color blend_color;
725*bbecb9d1SAndroid Build Coastguard Worker
726*bbecb9d1SAndroid Build Coastguard Worker uint32_t cond_render_q_id;
727*bbecb9d1SAndroid Build Coastguard Worker GLenum cond_render_gl_mode;
728*bbecb9d1SAndroid Build Coastguard Worker
729*bbecb9d1SAndroid Build Coastguard Worker struct vrend_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
730*bbecb9d1SAndroid Build Coastguard Worker uint32_t images_used_mask[PIPE_SHADER_TYPES];
731*bbecb9d1SAndroid Build Coastguard Worker
732*bbecb9d1SAndroid Build Coastguard Worker struct vrend_ssbo ssbo[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
733*bbecb9d1SAndroid Build Coastguard Worker uint32_t ssbo_used_mask[PIPE_SHADER_TYPES];
734*bbecb9d1SAndroid Build Coastguard Worker
735*bbecb9d1SAndroid Build Coastguard Worker struct vrend_abo abo[PIPE_MAX_HW_ATOMIC_BUFFERS];
736*bbecb9d1SAndroid Build Coastguard Worker uint32_t abo_used_mask;
737*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context_tweaks tweaks;
738*bbecb9d1SAndroid Build Coastguard Worker uint8_t swizzle_output_rgb_to_bgr;
739*bbecb9d1SAndroid Build Coastguard Worker uint8_t needs_manual_srgb_encode_bitmask;
740*bbecb9d1SAndroid Build Coastguard Worker int fake_occlusion_query_samples_passed_multiplier;
741*bbecb9d1SAndroid Build Coastguard Worker
742*bbecb9d1SAndroid Build Coastguard Worker int prim_mode;
743*bbecb9d1SAndroid Build Coastguard Worker bool drawing;
744*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *parent;
745*bbecb9d1SAndroid Build Coastguard Worker struct sysval_uniform_block sysvalue_data;
746*bbecb9d1SAndroid Build Coastguard Worker uint32_t sysvalue_data_cookie;
747*bbecb9d1SAndroid Build Coastguard Worker uint32_t current_program_id;
748*bbecb9d1SAndroid Build Coastguard Worker uint32_t current_pipeline_id;
749*bbecb9d1SAndroid Build Coastguard Worker };
750*bbecb9d1SAndroid Build Coastguard Worker
751*bbecb9d1SAndroid Build Coastguard Worker struct vrend_untyped_resource {
752*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *resource;
753*bbecb9d1SAndroid Build Coastguard Worker struct list_head head;
754*bbecb9d1SAndroid Build Coastguard Worker };
755*bbecb9d1SAndroid Build Coastguard Worker
756*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context {
757*bbecb9d1SAndroid Build Coastguard Worker char debug_name[64];
758*bbecb9d1SAndroid Build Coastguard Worker
759*bbecb9d1SAndroid Build Coastguard Worker struct list_head sub_ctxs;
760*bbecb9d1SAndroid Build Coastguard Worker struct list_head vrend_resources;
761*bbecb9d1SAndroid Build Coastguard Worker
762*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
763*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *video;
764*bbecb9d1SAndroid Build Coastguard Worker #endif
765*bbecb9d1SAndroid Build Coastguard Worker
766*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub;
767*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub0;
768*bbecb9d1SAndroid Build Coastguard Worker
769*bbecb9d1SAndroid Build Coastguard Worker int ctx_id;
770*bbecb9d1SAndroid Build Coastguard Worker /* has this ctx gotten an error? */
771*bbecb9d1SAndroid Build Coastguard Worker bool in_error;
772*bbecb9d1SAndroid Build Coastguard Worker bool ctx_switch_pending;
773*bbecb9d1SAndroid Build Coastguard Worker
774*bbecb9d1SAndroid Build Coastguard Worker enum virgl_ctx_errors last_error;
775*bbecb9d1SAndroid Build Coastguard Worker
776*bbecb9d1SAndroid Build Coastguard Worker /* resource bounds to this context */
777*bbecb9d1SAndroid Build Coastguard Worker struct util_hash_table *res_hash;
778*bbecb9d1SAndroid Build Coastguard Worker
779*bbecb9d1SAndroid Build Coastguard Worker /*
780*bbecb9d1SAndroid Build Coastguard Worker * vrend_context only works with typed virgl_resources. More specifically,
781*bbecb9d1SAndroid Build Coastguard Worker * it works with vrend_resources that are inherited from pipe_resources
782*bbecb9d1SAndroid Build Coastguard Worker * wrapped in virgl_resources.
783*bbecb9d1SAndroid Build Coastguard Worker *
784*bbecb9d1SAndroid Build Coastguard Worker * Normally, a vrend_resource is created first by
785*bbecb9d1SAndroid Build Coastguard Worker * vrend_renderer_resource_create. It is then wrapped in a virgl_resource
786*bbecb9d1SAndroid Build Coastguard Worker * by virgl_resource_create_from_pipe. Depending on whether it is a blob
787*bbecb9d1SAndroid Build Coastguard Worker * resource or not, the two functions can be called from different paths.
788*bbecb9d1SAndroid Build Coastguard Worker * But we always get both a virgl_resource and a vrend_resource as a
789*bbecb9d1SAndroid Build Coastguard Worker * result.
790*bbecb9d1SAndroid Build Coastguard Worker *
791*bbecb9d1SAndroid Build Coastguard Worker * It is however possible that we encounter untyped virgl_resources that
792*bbecb9d1SAndroid Build Coastguard Worker * have no pipe_resources. To work with untyped virgl_resources, we park
793*bbecb9d1SAndroid Build Coastguard Worker * them in untyped_resources first when they are attached. We move them
794*bbecb9d1SAndroid Build Coastguard Worker * into res_hash only after we get the type information and create the
795*bbecb9d1SAndroid Build Coastguard Worker * vrend_resources in vrend_decode_pipe_resource_set_type.
796*bbecb9d1SAndroid Build Coastguard Worker */
797*bbecb9d1SAndroid Build Coastguard Worker struct list_head untyped_resources;
798*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *untyped_resource_cache;
799*bbecb9d1SAndroid Build Coastguard Worker
800*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_cfg shader_cfg;
801*bbecb9d1SAndroid Build Coastguard Worker
802*bbecb9d1SAndroid Build Coastguard Worker unsigned debug_flags;
803*bbecb9d1SAndroid Build Coastguard Worker
804*bbecb9d1SAndroid Build Coastguard Worker vrend_context_fence_retire fence_retire;
805*bbecb9d1SAndroid Build Coastguard Worker void *fence_retire_data;
806*bbecb9d1SAndroid Build Coastguard Worker };
807*bbecb9d1SAndroid Build Coastguard Worker
808*bbecb9d1SAndroid Build Coastguard Worker static void vrend_pause_render_condition(struct vrend_context *ctx, bool pause);
809*bbecb9d1SAndroid Build Coastguard Worker static void vrend_update_viewport_state(struct vrend_sub_context *sub_ctx);
810*bbecb9d1SAndroid Build Coastguard Worker static void vrend_update_scissor_state(struct vrend_sub_context *sub_ctx);
811*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_query_object(void *obj_ptr);
812*bbecb9d1SAndroid Build Coastguard Worker static void vrend_finish_context_switch(struct vrend_context *ctx);
813*bbecb9d1SAndroid Build Coastguard Worker static void vrend_patch_blend_state(struct vrend_sub_context *sub_ctx);
814*bbecb9d1SAndroid Build Coastguard Worker static void vrend_update_frontface_state(struct vrend_sub_context *ctx);
815*bbecb9d1SAndroid Build Coastguard Worker static int vrender_get_glsl_version(void);
816*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_program(struct vrend_linked_shader_program *ent);
817*bbecb9d1SAndroid Build Coastguard Worker static void vrend_apply_sampler_state(struct vrend_sub_context *sub_ctx,
818*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res,
819*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type,
820*bbecb9d1SAndroid Build Coastguard Worker int id, int sampler_id,
821*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *tview);
822*bbecb9d1SAndroid Build Coastguard Worker static GLenum tgsitargettogltarget(const enum pipe_texture_target target, int nr_samples);
823*bbecb9d1SAndroid Build Coastguard Worker
824*bbecb9d1SAndroid Build Coastguard Worker void vrend_update_stencil_state(struct vrend_sub_context *sub_ctx);
825*bbecb9d1SAndroid Build Coastguard Worker
826*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX_EXTENDED];
827*bbecb9d1SAndroid Build Coastguard Worker
828*bbecb9d1SAndroid Build Coastguard Worker static uint32_t vrend_renderer_get_video_memory(void);
829*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_can_sample(enum virgl_formats format)830*bbecb9d1SAndroid Build Coastguard Worker static inline bool vrend_format_can_sample(enum virgl_formats format)
831*bbecb9d1SAndroid Build Coastguard Worker {
832*bbecb9d1SAndroid Build Coastguard Worker if (tex_conv_table[format].bindings & VIRGL_BIND_SAMPLER_VIEW)
833*bbecb9d1SAndroid Build Coastguard Worker return true;
834*bbecb9d1SAndroid Build Coastguard Worker
835*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
836*bbecb9d1SAndroid Build Coastguard Worker uint32_t gbm_format = 0;
837*bbecb9d1SAndroid Build Coastguard Worker if (virgl_gbm_convert_format(&format, &gbm_format))
838*bbecb9d1SAndroid Build Coastguard Worker return false;
839*bbecb9d1SAndroid Build Coastguard Worker
840*bbecb9d1SAndroid Build Coastguard Worker if (!gbm || !gbm->device || !gbm_format)
841*bbecb9d1SAndroid Build Coastguard Worker return false;
842*bbecb9d1SAndroid Build Coastguard Worker
843*bbecb9d1SAndroid Build Coastguard Worker uint32_t gbm_usage = GBM_BO_USE_TEXTURING;
844*bbecb9d1SAndroid Build Coastguard Worker return gbm_device_is_format_supported(gbm->device, gbm_format, gbm_usage);
845*bbecb9d1SAndroid Build Coastguard Worker #else
846*bbecb9d1SAndroid Build Coastguard Worker return false;
847*bbecb9d1SAndroid Build Coastguard Worker #endif
848*bbecb9d1SAndroid Build Coastguard Worker }
849*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_can_readback(enum virgl_formats format)850*bbecb9d1SAndroid Build Coastguard Worker static inline bool vrend_format_can_readback(enum virgl_formats format)
851*bbecb9d1SAndroid Build Coastguard Worker {
852*bbecb9d1SAndroid Build Coastguard Worker return tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_READBACK;
853*bbecb9d1SAndroid Build Coastguard Worker }
854*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_can_multisample(enum virgl_formats format)855*bbecb9d1SAndroid Build Coastguard Worker static inline bool vrend_format_can_multisample(enum virgl_formats format)
856*bbecb9d1SAndroid Build Coastguard Worker {
857*bbecb9d1SAndroid Build Coastguard Worker return tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_MULTISAMPLE;
858*bbecb9d1SAndroid Build Coastguard Worker }
859*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_can_render(enum virgl_formats format)860*bbecb9d1SAndroid Build Coastguard Worker static inline bool vrend_format_can_render(enum virgl_formats format)
861*bbecb9d1SAndroid Build Coastguard Worker {
862*bbecb9d1SAndroid Build Coastguard Worker return tex_conv_table[format].bindings & VIRGL_BIND_RENDER_TARGET;
863*bbecb9d1SAndroid Build Coastguard Worker }
864*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_is_ds(enum virgl_formats format)865*bbecb9d1SAndroid Build Coastguard Worker static inline bool vrend_format_is_ds(enum virgl_formats format)
866*bbecb9d1SAndroid Build Coastguard Worker {
867*bbecb9d1SAndroid Build Coastguard Worker return tex_conv_table[format].bindings & VIRGL_BIND_DEPTH_STENCIL;
868*bbecb9d1SAndroid Build Coastguard Worker }
869*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_can_scanout(enum virgl_formats format)870*bbecb9d1SAndroid Build Coastguard Worker static inline bool vrend_format_can_scanout(enum virgl_formats format)
871*bbecb9d1SAndroid Build Coastguard Worker {
872*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
873*bbecb9d1SAndroid Build Coastguard Worker uint32_t gbm_format = 0;
874*bbecb9d1SAndroid Build Coastguard Worker if (virgl_gbm_convert_format(&format, &gbm_format))
875*bbecb9d1SAndroid Build Coastguard Worker return false;
876*bbecb9d1SAndroid Build Coastguard Worker
877*bbecb9d1SAndroid Build Coastguard Worker if (!gbm || !gbm->device || !gbm_format)
878*bbecb9d1SAndroid Build Coastguard Worker return false;
879*bbecb9d1SAndroid Build Coastguard Worker
880*bbecb9d1SAndroid Build Coastguard Worker return gbm_device_is_format_supported(gbm->device, gbm_format, GBM_BO_USE_SCANOUT);
881*bbecb9d1SAndroid Build Coastguard Worker #else
882*bbecb9d1SAndroid Build Coastguard Worker (void)format;
883*bbecb9d1SAndroid Build Coastguard Worker return true;
884*bbecb9d1SAndroid Build Coastguard Worker #endif
885*bbecb9d1SAndroid Build Coastguard Worker }
886*bbecb9d1SAndroid Build Coastguard Worker
887*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
vrend_format_can_texture_view(enum virgl_formats format)888*bbecb9d1SAndroid Build Coastguard Worker static inline bool vrend_format_can_texture_view(enum virgl_formats format)
889*bbecb9d1SAndroid Build Coastguard Worker {
890*bbecb9d1SAndroid Build Coastguard Worker return has_feature(feat_texture_view) &&
891*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE;
892*bbecb9d1SAndroid Build Coastguard Worker }
893*bbecb9d1SAndroid Build Coastguard Worker #endif
894*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_context_tweaks(struct vrend_context * ctx)895*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context_tweaks *vrend_get_context_tweaks(struct vrend_context *ctx)
896*bbecb9d1SAndroid Build Coastguard Worker {
897*bbecb9d1SAndroid Build Coastguard Worker return &ctx->sub->tweaks;
898*bbecb9d1SAndroid Build Coastguard Worker }
899*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_is_emulated_alpha(enum virgl_formats format)900*bbecb9d1SAndroid Build Coastguard Worker bool vrend_format_is_emulated_alpha(enum virgl_formats format)
901*bbecb9d1SAndroid Build Coastguard Worker {
902*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles || !vrend_state.use_core_profile)
903*bbecb9d1SAndroid Build Coastguard Worker return false;
904*bbecb9d1SAndroid Build Coastguard Worker return (format == VIRGL_FORMAT_A8_UNORM ||
905*bbecb9d1SAndroid Build Coastguard Worker format == VIRGL_FORMAT_A16_UNORM);
906*bbecb9d1SAndroid Build Coastguard Worker }
907*bbecb9d1SAndroid Build Coastguard Worker
vrend_format_is_bgra(enum virgl_formats format)908*bbecb9d1SAndroid Build Coastguard Worker bool vrend_format_is_bgra(enum virgl_formats format) {
909*bbecb9d1SAndroid Build Coastguard Worker return (format == VIRGL_FORMAT_B8G8R8X8_UNORM ||
910*bbecb9d1SAndroid Build Coastguard Worker format == VIRGL_FORMAT_B8G8R8A8_UNORM ||
911*bbecb9d1SAndroid Build Coastguard Worker format == VIRGL_FORMAT_B8G8R8X8_SRGB ||
912*bbecb9d1SAndroid Build Coastguard Worker format == VIRGL_FORMAT_B8G8R8A8_SRGB);
913*bbecb9d1SAndroid Build Coastguard Worker }
914*bbecb9d1SAndroid Build Coastguard Worker
vrend_resource_has_24bpp_internal_format(const struct vrend_resource * res)915*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_resource_has_24bpp_internal_format(const struct vrend_resource *res)
916*bbecb9d1SAndroid Build Coastguard Worker {
917*bbecb9d1SAndroid Build Coastguard Worker /* Some shared resources imported to guest mesa as EGL images occupy 24bpp instead of more common 32bpp. */
918*bbecb9d1SAndroid Build Coastguard Worker return (has_bit(res->storage_bits, VREND_STORAGE_EGL_IMAGE) &&
919*bbecb9d1SAndroid Build Coastguard Worker (res->base.format == VIRGL_FORMAT_B8G8R8X8_UNORM ||
920*bbecb9d1SAndroid Build Coastguard Worker res->base.format == VIRGL_FORMAT_R8G8B8X8_UNORM));
921*bbecb9d1SAndroid Build Coastguard Worker }
922*bbecb9d1SAndroid Build Coastguard Worker
vrend_resource_supports_view(const struct vrend_resource * res,UNUSED enum virgl_formats view_format)923*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_resource_supports_view(const struct vrend_resource *res,
924*bbecb9d1SAndroid Build Coastguard Worker UNUSED enum virgl_formats view_format)
925*bbecb9d1SAndroid Build Coastguard Worker {
926*bbecb9d1SAndroid Build Coastguard Worker /* Texture views on eglimage-backed bgr* resources are not supported and
927*bbecb9d1SAndroid Build Coastguard Worker * lead to unexpected format interpretation since internally allocated
928*bbecb9d1SAndroid Build Coastguard Worker * bgr* resources use GL_RGBA8 internal format, while eglimage-backed
929*bbecb9d1SAndroid Build Coastguard Worker * resources use BGRA8, but GL lacks an equivalent internalformat enum.
930*bbecb9d1SAndroid Build Coastguard Worker *
931*bbecb9d1SAndroid Build Coastguard Worker * For views that don't require colorspace conversion, we can add swizzles
932*bbecb9d1SAndroid Build Coastguard Worker * instead. For views that do require colorspace conversion, manual srgb
933*bbecb9d1SAndroid Build Coastguard Worker * decode/encode is required. */
934*bbecb9d1SAndroid Build Coastguard Worker return !(vrend_format_is_bgra(res->base.format) &&
935*bbecb9d1SAndroid Build Coastguard Worker has_bit(res->storage_bits, VREND_STORAGE_EGL_IMAGE)) &&
936*bbecb9d1SAndroid Build Coastguard Worker !vrend_resource_has_24bpp_internal_format(res);
937*bbecb9d1SAndroid Build Coastguard Worker }
938*bbecb9d1SAndroid Build Coastguard Worker
939*bbecb9d1SAndroid Build Coastguard Worker static inline bool
vrend_resource_needs_redblue_swizzle(struct vrend_resource * res,enum virgl_formats view_format)940*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_needs_redblue_swizzle(struct vrend_resource *res,
941*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats view_format)
942*bbecb9d1SAndroid Build Coastguard Worker {
943*bbecb9d1SAndroid Build Coastguard Worker return !vrend_resource_supports_view(res, view_format) &&
944*bbecb9d1SAndroid Build Coastguard Worker vrend_format_is_bgra(res->base.format) ^ vrend_format_is_bgra(view_format);
945*bbecb9d1SAndroid Build Coastguard Worker }
946*bbecb9d1SAndroid Build Coastguard Worker
947*bbecb9d1SAndroid Build Coastguard Worker static inline bool
vrend_resource_needs_srgb_decode(struct vrend_resource * res,enum virgl_formats view_format)948*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_needs_srgb_decode(struct vrend_resource *res,
949*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats view_format)
950*bbecb9d1SAndroid Build Coastguard Worker {
951*bbecb9d1SAndroid Build Coastguard Worker return !vrend_resource_supports_view(res, view_format) &&
952*bbecb9d1SAndroid Build Coastguard Worker util_format_is_srgb(res->base.format) &&
953*bbecb9d1SAndroid Build Coastguard Worker !util_format_is_srgb(view_format);
954*bbecb9d1SAndroid Build Coastguard Worker }
955*bbecb9d1SAndroid Build Coastguard Worker
956*bbecb9d1SAndroid Build Coastguard Worker static inline bool
vrend_resource_needs_srgb_encode(struct vrend_resource * res,enum virgl_formats view_format)957*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_needs_srgb_encode(struct vrend_resource *res,
958*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats view_format)
959*bbecb9d1SAndroid Build Coastguard Worker {
960*bbecb9d1SAndroid Build Coastguard Worker return !vrend_resource_supports_view(res, view_format) &&
961*bbecb9d1SAndroid Build Coastguard Worker !util_format_is_srgb(res->base.format) &&
962*bbecb9d1SAndroid Build Coastguard Worker util_format_is_srgb(view_format);
963*bbecb9d1SAndroid Build Coastguard Worker }
964*bbecb9d1SAndroid Build Coastguard Worker
vrend_blit_needs_swizzle(enum virgl_formats src,enum virgl_formats dst)965*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_blit_needs_swizzle(enum virgl_formats src,
966*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats dst)
967*bbecb9d1SAndroid Build Coastguard Worker {
968*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < 4; ++i) {
969*bbecb9d1SAndroid Build Coastguard Worker if (tex_conv_table[src].swizzle[i] != tex_conv_table[dst].swizzle[i])
970*bbecb9d1SAndroid Build Coastguard Worker return true;
971*bbecb9d1SAndroid Build Coastguard Worker }
972*bbecb9d1SAndroid Build Coastguard Worker return false;
973*bbecb9d1SAndroid Build Coastguard Worker }
974*bbecb9d1SAndroid Build Coastguard Worker
pipe_shader_to_prefix(enum pipe_shader_type shader_type)975*bbecb9d1SAndroid Build Coastguard Worker static inline const char *pipe_shader_to_prefix(enum pipe_shader_type shader_type)
976*bbecb9d1SAndroid Build Coastguard Worker {
977*bbecb9d1SAndroid Build Coastguard Worker switch (shader_type) {
978*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_VERTEX: return "vs";
979*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_FRAGMENT: return "fs";
980*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_GEOMETRY: return "gs";
981*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_CTRL: return "tc";
982*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_EVAL: return "te";
983*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_COMPUTE: return "cs";
984*bbecb9d1SAndroid Build Coastguard Worker default:
985*bbecb9d1SAndroid Build Coastguard Worker return NULL;
986*bbecb9d1SAndroid Build Coastguard Worker };
987*bbecb9d1SAndroid Build Coastguard Worker }
988*bbecb9d1SAndroid Build Coastguard Worker
translate_blend_func_advanced(enum gl_advanced_blend_mode blend)989*bbecb9d1SAndroid Build Coastguard Worker static GLenum translate_blend_func_advanced(enum gl_advanced_blend_mode blend)
990*bbecb9d1SAndroid Build Coastguard Worker {
991*bbecb9d1SAndroid Build Coastguard Worker switch(blend){
992*bbecb9d1SAndroid Build Coastguard Worker case BLEND_MULTIPLY: return GL_MULTIPLY_KHR;
993*bbecb9d1SAndroid Build Coastguard Worker case BLEND_SCREEN: return GL_SCREEN_KHR;
994*bbecb9d1SAndroid Build Coastguard Worker case BLEND_OVERLAY: return GL_OVERLAY_KHR;
995*bbecb9d1SAndroid Build Coastguard Worker case BLEND_DARKEN: return GL_DARKEN_KHR;
996*bbecb9d1SAndroid Build Coastguard Worker case BLEND_LIGHTEN: return GL_LIGHTEN_KHR;
997*bbecb9d1SAndroid Build Coastguard Worker case BLEND_COLORDODGE: return GL_COLORDODGE_KHR;
998*bbecb9d1SAndroid Build Coastguard Worker case BLEND_COLORBURN: return GL_COLORBURN_KHR;
999*bbecb9d1SAndroid Build Coastguard Worker case BLEND_HARDLIGHT: return GL_HARDLIGHT_KHR;
1000*bbecb9d1SAndroid Build Coastguard Worker case BLEND_SOFTLIGHT: return GL_SOFTLIGHT_KHR;
1001*bbecb9d1SAndroid Build Coastguard Worker case BLEND_DIFFERENCE: return GL_DIFFERENCE_KHR;
1002*bbecb9d1SAndroid Build Coastguard Worker case BLEND_EXCLUSION: return GL_EXCLUSION_KHR;
1003*bbecb9d1SAndroid Build Coastguard Worker case BLEND_HSL_HUE: return GL_HSL_HUE_KHR;
1004*bbecb9d1SAndroid Build Coastguard Worker case BLEND_HSL_SATURATION: return GL_HSL_SATURATION_KHR;
1005*bbecb9d1SAndroid Build Coastguard Worker case BLEND_HSL_COLOR: return GL_HSL_COLOR_KHR;
1006*bbecb9d1SAndroid Build Coastguard Worker case BLEND_HSL_LUMINOSITY: return GL_HSL_LUMINOSITY_KHR;
1007*bbecb9d1SAndroid Build Coastguard Worker default:
1008*bbecb9d1SAndroid Build Coastguard Worker assert("invalid blend token()" == NULL);
1009*bbecb9d1SAndroid Build Coastguard Worker return 0;
1010*bbecb9d1SAndroid Build Coastguard Worker }
1011*bbecb9d1SAndroid Build Coastguard Worker }
1012*bbecb9d1SAndroid Build Coastguard Worker
1013*bbecb9d1SAndroid Build Coastguard Worker static const char *vrend_ctx_error_strings[] = {
1014*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_NONE] = "None",
1015*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_UNKNOWN] = "Unknown",
1016*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_SHADER] = "Illegal shader",
1017*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_HANDLE] = "Illegal handle",
1018*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_RESOURCE] = "Illegal resource",
1019*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_SURFACE] = "Illegal surface",
1020*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT] = "Illegal vertex format",
1021*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER] = "Illegal command buffer",
1022*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_GLES_HAVE_TES_BUT_MISS_TCS] = "On GLES context and shader program has tesselation evaluation shader but no tesselation control shader",
1023*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_GL_ANY_SAMPLES_PASSED] = "Query for ANY_SAMPLES_PASSED not supported",
1024*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_FORMAT] = "Illegal format ID",
1025*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_SAMPLER_VIEW_TARGET] = "Illegat target for sampler view",
1026*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS] = "IOV data size exceeds resource capacity",
1027*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_DUAL_SRC_BLEND]= "Dual source blend not supported",
1028*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_UNSUPPORTED_FUNCTION] = "Unsupported host function called",
1029*bbecb9d1SAndroid Build Coastguard Worker [VIRGL_ERROR_CTX_ILLEGAL_PROGRAM_PIPELINE] = "Illegal shader program pipeline",
1030*bbecb9d1SAndroid Build Coastguard Worker };
1031*bbecb9d1SAndroid Build Coastguard Worker
vrend_report_context_error_internal(const char * fname,struct vrend_context * ctx,enum virgl_ctx_errors error,uint32_t value)1032*bbecb9d1SAndroid Build Coastguard Worker void vrend_report_context_error_internal(const char *fname, struct vrend_context *ctx,
1033*bbecb9d1SAndroid Build Coastguard Worker enum virgl_ctx_errors error, uint32_t value)
1034*bbecb9d1SAndroid Build Coastguard Worker {
1035*bbecb9d1SAndroid Build Coastguard Worker ctx->in_error = true;
1036*bbecb9d1SAndroid Build Coastguard Worker ctx->last_error = error;
1037*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: context error reported %d \"%s\" %s %d\n", fname,
1038*bbecb9d1SAndroid Build Coastguard Worker ctx->ctx_id, ctx->debug_name, vrend_ctx_error_strings[error],
1039*bbecb9d1SAndroid Build Coastguard Worker value);
1040*bbecb9d1SAndroid Build Coastguard Worker }
1041*bbecb9d1SAndroid Build Coastguard Worker
1042*bbecb9d1SAndroid Build Coastguard Worker #define CORE_PROFILE_WARN_NONE 0
1043*bbecb9d1SAndroid Build Coastguard Worker #define CORE_PROFILE_WARN_STIPPLE 1
1044*bbecb9d1SAndroid Build Coastguard Worker #define CORE_PROFILE_WARN_POLYGON_MODE 2
1045*bbecb9d1SAndroid Build Coastguard Worker #define CORE_PROFILE_WARN_TWO_SIDE 3
1046*bbecb9d1SAndroid Build Coastguard Worker #define CORE_PROFILE_WARN_CLAMP 4
1047*bbecb9d1SAndroid Build Coastguard Worker #define CORE_PROFILE_WARN_SHADE_MODEL 5
1048*bbecb9d1SAndroid Build Coastguard Worker
1049*bbecb9d1SAndroid Build Coastguard Worker static const char *vrend_core_profile_warn_strings[] = {
1050*bbecb9d1SAndroid Build Coastguard Worker [CORE_PROFILE_WARN_NONE] = "None",
1051*bbecb9d1SAndroid Build Coastguard Worker [CORE_PROFILE_WARN_STIPPLE] = "Stipple",
1052*bbecb9d1SAndroid Build Coastguard Worker [CORE_PROFILE_WARN_POLYGON_MODE] = "Polygon Mode",
1053*bbecb9d1SAndroid Build Coastguard Worker [CORE_PROFILE_WARN_TWO_SIDE] = "Two Side",
1054*bbecb9d1SAndroid Build Coastguard Worker [CORE_PROFILE_WARN_CLAMP] = "Clamping",
1055*bbecb9d1SAndroid Build Coastguard Worker [CORE_PROFILE_WARN_SHADE_MODEL] = "Shade Model",
1056*bbecb9d1SAndroid Build Coastguard Worker };
1057*bbecb9d1SAndroid Build Coastguard Worker
__report_core_warn(const char * fname,struct vrend_context * ctx,enum virgl_ctx_errors error)1058*bbecb9d1SAndroid Build Coastguard Worker static void __report_core_warn(const char *fname, struct vrend_context *ctx,
1059*bbecb9d1SAndroid Build Coastguard Worker enum virgl_ctx_errors error)
1060*bbecb9d1SAndroid Build Coastguard Worker {
1061*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: core profile violation reported %d \"%s\" %s\n", fname,
1062*bbecb9d1SAndroid Build Coastguard Worker ctx->ctx_id, ctx->debug_name,
1063*bbecb9d1SAndroid Build Coastguard Worker vrend_core_profile_warn_strings[error]);
1064*bbecb9d1SAndroid Build Coastguard Worker }
1065*bbecb9d1SAndroid Build Coastguard Worker #define report_core_warn(ctx, error) __report_core_warn(__func__, ctx, error)
1066*bbecb9d1SAndroid Build Coastguard Worker
1067*bbecb9d1SAndroid Build Coastguard Worker
1068*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_NONE 0
1069*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_STIPPLE 1
1070*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_POLYGON_MODE 2
1071*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_DEPTH_RANGE 3
1072*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_POINT_SIZE 4
1073*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_SEAMLESS_CUBE_MAP 5
1074*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_LOD_BIAS 6
1075*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_OFFSET_LINE 8
1076*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_OFFSET_POINT 9
1077*bbecb9d1SAndroid Build Coastguard Worker //#define GLES_WARN_ free slot 10
1078*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_FLATSHADE_FIRST 11
1079*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_LINE_SMOOTH 12
1080*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_POLY_SMOOTH 13
1081*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_DEPTH_CLEAR 14
1082*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_LOGIC_OP 15
1083*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_TIMESTAMP 16
1084*bbecb9d1SAndroid Build Coastguard Worker #define GLES_WARN_IMPLICIT_MSAA_SURFACE 17
1085*bbecb9d1SAndroid Build Coastguard Worker
1086*bbecb9d1SAndroid Build Coastguard Worker ASSERTED
1087*bbecb9d1SAndroid Build Coastguard Worker static const char *vrend_gles_warn_strings[] = {
1088*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_NONE] = "None",
1089*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_STIPPLE] = "Stipple",
1090*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_POLYGON_MODE] = "Polygon Mode",
1091*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_DEPTH_RANGE] = "Depth Range",
1092*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_POINT_SIZE] = "Point Size",
1093*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_SEAMLESS_CUBE_MAP] = "Seamless Cube Map",
1094*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_LOD_BIAS] = "Lod Bias",
1095*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_OFFSET_LINE] = "Offset Line",
1096*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_OFFSET_POINT] = "Offset Point",
1097*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_FLATSHADE_FIRST] = "Flatshade First",
1098*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_LINE_SMOOTH] = "Line Smooth",
1099*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_POLY_SMOOTH] = "Poly Smooth",
1100*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_DEPTH_CLEAR] = "Depth Clear",
1101*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_LOGIC_OP] = "LogicOp",
1102*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_TIMESTAMP] = "GL_TIMESTAMP",
1103*bbecb9d1SAndroid Build Coastguard Worker [GLES_WARN_IMPLICIT_MSAA_SURFACE] = "Implicit MSAA Surface",
1104*bbecb9d1SAndroid Build Coastguard Worker };
1105*bbecb9d1SAndroid Build Coastguard Worker
__report_gles_warn(ASSERTED const char * fname,ASSERTED struct vrend_context * ctx,ASSERTED enum virgl_ctx_errors error)1106*bbecb9d1SAndroid Build Coastguard Worker static void __report_gles_warn(ASSERTED const char *fname,
1107*bbecb9d1SAndroid Build Coastguard Worker ASSERTED struct vrend_context *ctx,
1108*bbecb9d1SAndroid Build Coastguard Worker ASSERTED enum virgl_ctx_errors error)
1109*bbecb9d1SAndroid Build Coastguard Worker {
1110*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_gles, ctx, "%s: GLES violation - %s\n", fname, vrend_gles_warn_strings[error]);
1111*bbecb9d1SAndroid Build Coastguard Worker }
1112*bbecb9d1SAndroid Build Coastguard Worker #define report_gles_warn(ctx, error) __report_gles_warn(__func__, ctx, error)
1113*bbecb9d1SAndroid Build Coastguard Worker
__report_gles_missing_func(ASSERTED const char * fname,ASSERTED struct vrend_context * ctx,ASSERTED const char * missf)1114*bbecb9d1SAndroid Build Coastguard Worker static void __report_gles_missing_func(ASSERTED const char *fname,
1115*bbecb9d1SAndroid Build Coastguard Worker ASSERTED struct vrend_context *ctx,
1116*bbecb9d1SAndroid Build Coastguard Worker ASSERTED const char *missf)
1117*bbecb9d1SAndroid Build Coastguard Worker {
1118*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_gles, ctx, "%s: GLES function %s is missing\n", fname, missf);
1119*bbecb9d1SAndroid Build Coastguard Worker }
1120*bbecb9d1SAndroid Build Coastguard Worker
1121*bbecb9d1SAndroid Build Coastguard Worker #define report_gles_missing_func(ctx, missf) __report_gles_missing_func(__func__, ctx, missf)
1122*bbecb9d1SAndroid Build Coastguard Worker
init_features(int gl_ver,int gles_ver)1123*bbecb9d1SAndroid Build Coastguard Worker static void init_features(int gl_ver, int gles_ver)
1124*bbecb9d1SAndroid Build Coastguard Worker {
1125*bbecb9d1SAndroid Build Coastguard Worker for (enum features_id id = 0; id < feat_last; id++) {
1126*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver >= feature_list[id].gl_ver ||
1127*bbecb9d1SAndroid Build Coastguard Worker gles_ver >= feature_list[id].gles_ver) {
1128*bbecb9d1SAndroid Build Coastguard Worker set_feature(id);
1129*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_features, NULL, "Host feature %s provided by %s %3.1f\n",
1130*bbecb9d1SAndroid Build Coastguard Worker feature_list[id].log_name, (gl_ver > 0 ? "GL" : "GLES"),
1131*bbecb9d1SAndroid Build Coastguard Worker 0.1f * (gl_ver > 0 ? gl_ver : gles_ver));
1132*bbecb9d1SAndroid Build Coastguard Worker } else {
1133*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < FEAT_MAX_EXTS; i++) {
1134*bbecb9d1SAndroid Build Coastguard Worker if (!feature_list[id].gl_ext[i])
1135*bbecb9d1SAndroid Build Coastguard Worker break;
1136*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension(feature_list[id].gl_ext[i])) {
1137*bbecb9d1SAndroid Build Coastguard Worker set_feature(id);
1138*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_features, NULL,
1139*bbecb9d1SAndroid Build Coastguard Worker "Host feature %s provide by %s\n", feature_list[id].log_name,
1140*bbecb9d1SAndroid Build Coastguard Worker feature_list[id].gl_ext[i]);
1141*bbecb9d1SAndroid Build Coastguard Worker break;
1142*bbecb9d1SAndroid Build Coastguard Worker }
1143*bbecb9d1SAndroid Build Coastguard Worker }
1144*bbecb9d1SAndroid Build Coastguard Worker }
1145*bbecb9d1SAndroid Build Coastguard Worker }
1146*bbecb9d1SAndroid Build Coastguard Worker }
1147*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_surface(struct vrend_surface * surf)1148*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_surface(struct vrend_surface *surf)
1149*bbecb9d1SAndroid Build Coastguard Worker {
1150*bbecb9d1SAndroid Build Coastguard Worker if (surf->id != surf->texture->id)
1151*bbecb9d1SAndroid Build Coastguard Worker glDeleteTextures(1, &surf->id);
1152*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&surf->texture, NULL);
1153*bbecb9d1SAndroid Build Coastguard Worker free(surf);
1154*bbecb9d1SAndroid Build Coastguard Worker }
1155*bbecb9d1SAndroid Build Coastguard Worker
1156*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_surface_reference(struct vrend_surface ** ptr,struct vrend_surface * surf)1157*bbecb9d1SAndroid Build Coastguard Worker vrend_surface_reference(struct vrend_surface **ptr, struct vrend_surface *surf)
1158*bbecb9d1SAndroid Build Coastguard Worker {
1159*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *old_surf = *ptr;
1160*bbecb9d1SAndroid Build Coastguard Worker
1161*bbecb9d1SAndroid Build Coastguard Worker if (pipe_reference(&(*ptr)->reference, &surf->reference))
1162*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_surface(old_surf);
1163*bbecb9d1SAndroid Build Coastguard Worker *ptr = surf;
1164*bbecb9d1SAndroid Build Coastguard Worker }
1165*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_sampler_view(struct vrend_sampler_view * samp)1166*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_sampler_view(struct vrend_sampler_view *samp)
1167*bbecb9d1SAndroid Build Coastguard Worker {
1168*bbecb9d1SAndroid Build Coastguard Worker if (samp->texture->id != samp->id)
1169*bbecb9d1SAndroid Build Coastguard Worker glDeleteTextures(1, &samp->id);
1170*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&samp->texture, NULL);
1171*bbecb9d1SAndroid Build Coastguard Worker free(samp);
1172*bbecb9d1SAndroid Build Coastguard Worker }
1173*bbecb9d1SAndroid Build Coastguard Worker
1174*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_sampler_view_reference(struct vrend_sampler_view ** ptr,struct vrend_sampler_view * view)1175*bbecb9d1SAndroid Build Coastguard Worker vrend_sampler_view_reference(struct vrend_sampler_view **ptr, struct vrend_sampler_view *view)
1176*bbecb9d1SAndroid Build Coastguard Worker {
1177*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *old_view = *ptr;
1178*bbecb9d1SAndroid Build Coastguard Worker
1179*bbecb9d1SAndroid Build Coastguard Worker if (pipe_reference(&(*ptr)->reference, &view->reference))
1180*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_sampler_view(old_view);
1181*bbecb9d1SAndroid Build Coastguard Worker *ptr = view;
1182*bbecb9d1SAndroid Build Coastguard Worker }
1183*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_so_target(struct vrend_so_target * target)1184*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_so_target(struct vrend_so_target *target)
1185*bbecb9d1SAndroid Build Coastguard Worker {
1186*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&target->buffer, NULL);
1187*bbecb9d1SAndroid Build Coastguard Worker free(target);
1188*bbecb9d1SAndroid Build Coastguard Worker }
1189*bbecb9d1SAndroid Build Coastguard Worker
1190*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_so_target_reference(struct vrend_so_target ** ptr,struct vrend_so_target * target)1191*bbecb9d1SAndroid Build Coastguard Worker vrend_so_target_reference(struct vrend_so_target **ptr, struct vrend_so_target *target)
1192*bbecb9d1SAndroid Build Coastguard Worker {
1193*bbecb9d1SAndroid Build Coastguard Worker struct vrend_so_target *old_target = *ptr;
1194*bbecb9d1SAndroid Build Coastguard Worker
1195*bbecb9d1SAndroid Build Coastguard Worker if (pipe_reference(&(*ptr)->reference, &target->reference))
1196*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_so_target(old_target);
1197*bbecb9d1SAndroid Build Coastguard Worker *ptr = target;
1198*bbecb9d1SAndroid Build Coastguard Worker }
1199*bbecb9d1SAndroid Build Coastguard Worker
vrend_shader_dump(struct vrend_shader * shader)1200*bbecb9d1SAndroid Build Coastguard Worker static void vrend_shader_dump(struct vrend_shader *shader)
1201*bbecb9d1SAndroid Build Coastguard Worker {
1202*bbecb9d1SAndroid Build Coastguard Worker const char *prefix = pipe_shader_to_prefix(shader->sel->type);
1203*bbecb9d1SAndroid Build Coastguard Worker if (shader->sel->tmp_buf)
1204*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: %d TGSI:\n%s\n", prefix, shader->id, shader->sel->tmp_buf);
1205*bbecb9d1SAndroid Build Coastguard Worker
1206*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: %d GLSL:\n", prefix, shader->id);
1207*bbecb9d1SAndroid Build Coastguard Worker strarray_dump_with_line_numbers(&shader->glsl_strings);
1208*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("\n");
1209*bbecb9d1SAndroid Build Coastguard Worker }
1210*bbecb9d1SAndroid Build Coastguard Worker
vrend_shader_destroy(struct vrend_shader * shader)1211*bbecb9d1SAndroid Build Coastguard Worker static void vrend_shader_destroy(struct vrend_shader *shader)
1212*bbecb9d1SAndroid Build Coastguard Worker {
1213*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *ent, *tmp;
1214*bbecb9d1SAndroid Build Coastguard Worker
1215*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(ent, tmp, &shader->programs, sl[shader->sel->type]) {
1216*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_program(ent);
1217*bbecb9d1SAndroid Build Coastguard Worker }
1218*bbecb9d1SAndroid Build Coastguard Worker
1219*bbecb9d1SAndroid Build Coastguard Worker if (shader->sel->sinfo.separable_program)
1220*bbecb9d1SAndroid Build Coastguard Worker glDeleteProgram(shader->program_id);
1221*bbecb9d1SAndroid Build Coastguard Worker glDeleteShader(shader->id);
1222*bbecb9d1SAndroid Build Coastguard Worker strarray_free(&shader->glsl_strings, true);
1223*bbecb9d1SAndroid Build Coastguard Worker free(shader);
1224*bbecb9d1SAndroid Build Coastguard Worker }
1225*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_shader_selector(struct vrend_shader_selector * sel)1226*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_shader_selector(struct vrend_shader_selector *sel)
1227*bbecb9d1SAndroid Build Coastguard Worker {
1228*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *p = sel->current, *c;
1229*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
1230*bbecb9d1SAndroid Build Coastguard Worker while (p) {
1231*bbecb9d1SAndroid Build Coastguard Worker c = p->next_variant;
1232*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_destroy(p);
1233*bbecb9d1SAndroid Build Coastguard Worker p = c;
1234*bbecb9d1SAndroid Build Coastguard Worker }
1235*bbecb9d1SAndroid Build Coastguard Worker if (sel->sinfo.so_names)
1236*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < sel->sinfo.so_info.num_outputs; i++)
1237*bbecb9d1SAndroid Build Coastguard Worker free(sel->sinfo.so_names[i]);
1238*bbecb9d1SAndroid Build Coastguard Worker free(sel->tmp_buf);
1239*bbecb9d1SAndroid Build Coastguard Worker free(sel->sinfo.so_names);
1240*bbecb9d1SAndroid Build Coastguard Worker free(sel->sinfo.sampler_arrays);
1241*bbecb9d1SAndroid Build Coastguard Worker free(sel->sinfo.image_arrays);
1242*bbecb9d1SAndroid Build Coastguard Worker free(sel->tokens);
1243*bbecb9d1SAndroid Build Coastguard Worker free(sel);
1244*bbecb9d1SAndroid Build Coastguard Worker }
1245*bbecb9d1SAndroid Build Coastguard Worker
conv_shader_type(int type)1246*bbecb9d1SAndroid Build Coastguard Worker static inline int conv_shader_type(int type)
1247*bbecb9d1SAndroid Build Coastguard Worker {
1248*bbecb9d1SAndroid Build Coastguard Worker switch (type) {
1249*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_VERTEX: return GL_VERTEX_SHADER;
1250*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_FRAGMENT: return GL_FRAGMENT_SHADER;
1251*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_GEOMETRY: return GL_GEOMETRY_SHADER;
1252*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_CTRL: return GL_TESS_CONTROL_SHADER;
1253*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_EVAL: return GL_TESS_EVALUATION_SHADER;
1254*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_COMPUTE: return GL_COMPUTE_SHADER;
1255*bbecb9d1SAndroid Build Coastguard Worker default:
1256*bbecb9d1SAndroid Build Coastguard Worker return 0;
1257*bbecb9d1SAndroid Build Coastguard Worker };
1258*bbecb9d1SAndroid Build Coastguard Worker }
1259*bbecb9d1SAndroid Build Coastguard Worker
vrend_compile_shader(struct vrend_sub_context * sub_ctx,struct vrend_shader * shader)1260*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_compile_shader(struct vrend_sub_context *sub_ctx,
1261*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *shader)
1262*bbecb9d1SAndroid Build Coastguard Worker {
1263*bbecb9d1SAndroid Build Coastguard Worker GLint param;
1264*bbecb9d1SAndroid Build Coastguard Worker const char *shader_parts[SHADER_MAX_STRINGS];
1265*bbecb9d1SAndroid Build Coastguard Worker
1266*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < shader->glsl_strings.num_strings; i++)
1267*bbecb9d1SAndroid Build Coastguard Worker shader_parts[i] = shader->glsl_strings.strings[i].buf;
1268*bbecb9d1SAndroid Build Coastguard Worker
1269*bbecb9d1SAndroid Build Coastguard Worker shader->id = glCreateShader(conv_shader_type(shader->sel->type));
1270*bbecb9d1SAndroid Build Coastguard Worker glShaderSource(shader->id, shader->glsl_strings.num_strings, shader_parts, NULL);
1271*bbecb9d1SAndroid Build Coastguard Worker glCompileShader(shader->id);
1272*bbecb9d1SAndroid Build Coastguard Worker glGetShaderiv(shader->id, GL_COMPILE_STATUS, ¶m);
1273*bbecb9d1SAndroid Build Coastguard Worker if (param == GL_FALSE) {
1274*bbecb9d1SAndroid Build Coastguard Worker char infolog[65536];
1275*bbecb9d1SAndroid Build Coastguard Worker int len;
1276*bbecb9d1SAndroid Build Coastguard Worker glGetShaderInfoLog(shader->id, 65536, &len, infolog);
1277*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0);
1278*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("shader failed to compile\n%s\n", infolog);
1279*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(shader);
1280*bbecb9d1SAndroid Build Coastguard Worker return false;
1281*bbecb9d1SAndroid Build Coastguard Worker }
1282*bbecb9d1SAndroid Build Coastguard Worker
1283*bbecb9d1SAndroid Build Coastguard Worker if (shader->sel->sinfo.separable_program) {
1284*bbecb9d1SAndroid Build Coastguard Worker shader->program_id = glCreateProgram();
1285*bbecb9d1SAndroid Build Coastguard Worker shader->last_pipeline_id = 0xffffffff;
1286*bbecb9d1SAndroid Build Coastguard Worker glProgramParameteri(shader->program_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
1287*bbecb9d1SAndroid Build Coastguard Worker glAttachShader(shader->program_id, shader->id);
1288*bbecb9d1SAndroid Build Coastguard Worker }
1289*bbecb9d1SAndroid Build Coastguard Worker
1290*bbecb9d1SAndroid Build Coastguard Worker shader->is_compiled = true;
1291*bbecb9d1SAndroid Build Coastguard Worker return true;
1292*bbecb9d1SAndroid Build Coastguard Worker }
1293*bbecb9d1SAndroid Build Coastguard Worker
1294*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_shader_state_reference(struct vrend_shader_selector ** ptr,struct vrend_shader_selector * shader)1295*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(struct vrend_shader_selector **ptr, struct vrend_shader_selector *shader)
1296*bbecb9d1SAndroid Build Coastguard Worker {
1297*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *old_shader = *ptr;
1298*bbecb9d1SAndroid Build Coastguard Worker
1299*bbecb9d1SAndroid Build Coastguard Worker if (pipe_reference(&(*ptr)->reference, &shader->reference))
1300*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_shader_selector(old_shader);
1301*bbecb9d1SAndroid Build Coastguard Worker *ptr = shader;
1302*bbecb9d1SAndroid Build Coastguard Worker }
1303*bbecb9d1SAndroid Build Coastguard Worker
1304*bbecb9d1SAndroid Build Coastguard Worker void
vrend_insert_format(struct vrend_format_table * entry,uint32_t bindings,uint32_t flags)1305*bbecb9d1SAndroid Build Coastguard Worker vrend_insert_format(struct vrend_format_table *entry, uint32_t bindings, uint32_t flags)
1306*bbecb9d1SAndroid Build Coastguard Worker {
1307*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[entry->format] = *entry;
1308*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[entry->format].bindings = bindings;
1309*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[entry->format].flags = flags;
1310*bbecb9d1SAndroid Build Coastguard Worker }
1311*bbecb9d1SAndroid Build Coastguard Worker
1312*bbecb9d1SAndroid Build Coastguard Worker void
vrend_insert_format_swizzle(int override_format,struct vrend_format_table * entry,uint32_t bindings,uint8_t swizzle[4],uint32_t flags)1313*bbecb9d1SAndroid Build Coastguard Worker vrend_insert_format_swizzle(int override_format, struct vrend_format_table *entry,
1314*bbecb9d1SAndroid Build Coastguard Worker uint32_t bindings, uint8_t swizzle[4], uint32_t flags)
1315*bbecb9d1SAndroid Build Coastguard Worker {
1316*bbecb9d1SAndroid Build Coastguard Worker int i;
1317*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[override_format] = *entry;
1318*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[override_format].bindings = bindings;
1319*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[override_format].flags = flags | VIRGL_TEXTURE_NEED_SWIZZLE;
1320*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
1321*bbecb9d1SAndroid Build Coastguard Worker tex_conv_table[override_format].swizzle[i] = swizzle[i];
1322*bbecb9d1SAndroid Build Coastguard Worker }
1323*bbecb9d1SAndroid Build Coastguard Worker
1324*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_format_table *
vrend_get_format_table_entry(enum virgl_formats format)1325*bbecb9d1SAndroid Build Coastguard Worker vrend_get_format_table_entry(enum virgl_formats format)
1326*bbecb9d1SAndroid Build Coastguard Worker {
1327*bbecb9d1SAndroid Build Coastguard Worker return &tex_conv_table[format];
1328*bbecb9d1SAndroid Build Coastguard Worker }
1329*bbecb9d1SAndroid Build Coastguard Worker
vrend_is_timer_query(GLenum gltype)1330*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_is_timer_query(GLenum gltype)
1331*bbecb9d1SAndroid Build Coastguard Worker {
1332*bbecb9d1SAndroid Build Coastguard Worker return gltype == GL_TIMESTAMP ||
1333*bbecb9d1SAndroid Build Coastguard Worker gltype == GL_TIME_ELAPSED;
1334*bbecb9d1SAndroid Build Coastguard Worker }
1335*bbecb9d1SAndroid Build Coastguard Worker
use_program(struct vrend_sub_context * sub_ctx,uint32_t id)1336*bbecb9d1SAndroid Build Coastguard Worker static inline void use_program(struct vrend_sub_context *sub_ctx, uint32_t id)
1337*bbecb9d1SAndroid Build Coastguard Worker {
1338*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->current_program_id != id) {
1339*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->current_program_id = id;
1340*bbecb9d1SAndroid Build Coastguard Worker glUseProgram(id);
1341*bbecb9d1SAndroid Build Coastguard Worker }
1342*bbecb9d1SAndroid Build Coastguard Worker }
1343*bbecb9d1SAndroid Build Coastguard Worker
bind_pipeline(struct vrend_sub_context * sub_ctx,uint32_t id)1344*bbecb9d1SAndroid Build Coastguard Worker static inline void bind_pipeline(struct vrend_sub_context *sub_ctx, uint32_t id)
1345*bbecb9d1SAndroid Build Coastguard Worker {
1346*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->current_pipeline_id != id) {
1347*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->current_pipeline_id = id;
1348*bbecb9d1SAndroid Build Coastguard Worker glBindProgramPipeline(id);
1349*bbecb9d1SAndroid Build Coastguard Worker }
1350*bbecb9d1SAndroid Build Coastguard Worker }
1351*bbecb9d1SAndroid Build Coastguard Worker
vrend_use_program(struct vrend_sub_context * sub_ctx,struct vrend_linked_shader_program * program)1352*bbecb9d1SAndroid Build Coastguard Worker static void vrend_use_program(struct vrend_sub_context *sub_ctx,
1353*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *program)
1354*bbecb9d1SAndroid Build Coastguard Worker {
1355*bbecb9d1SAndroid Build Coastguard Worker GLuint id = !program ? 0 :
1356*bbecb9d1SAndroid Build Coastguard Worker program->is_pipeline ? program->id.pipeline :
1357*bbecb9d1SAndroid Build Coastguard Worker program->id.program;
1358*bbecb9d1SAndroid Build Coastguard Worker if (program && program->is_pipeline) {
1359*bbecb9d1SAndroid Build Coastguard Worker use_program(sub_ctx, 0);
1360*bbecb9d1SAndroid Build Coastguard Worker bind_pipeline(sub_ctx, id);
1361*bbecb9d1SAndroid Build Coastguard Worker } else {
1362*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_separate_shader_objects))
1363*bbecb9d1SAndroid Build Coastguard Worker bind_pipeline(sub_ctx, 0);
1364*bbecb9d1SAndroid Build Coastguard Worker use_program(sub_ctx, id);
1365*bbecb9d1SAndroid Build Coastguard Worker }
1366*bbecb9d1SAndroid Build Coastguard Worker }
1367*bbecb9d1SAndroid Build Coastguard Worker
vrend_depth_test_enable(struct vrend_context * ctx,bool depth_test_enable)1368*bbecb9d1SAndroid Build Coastguard Worker static void vrend_depth_test_enable(struct vrend_context *ctx, bool depth_test_enable)
1369*bbecb9d1SAndroid Build Coastguard Worker {
1370*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->depth_test_enabled != depth_test_enable) {
1371*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->depth_test_enabled = depth_test_enable;
1372*bbecb9d1SAndroid Build Coastguard Worker if (depth_test_enable)
1373*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_DEPTH_TEST);
1374*bbecb9d1SAndroid Build Coastguard Worker else
1375*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_DEPTH_TEST);
1376*bbecb9d1SAndroid Build Coastguard Worker }
1377*bbecb9d1SAndroid Build Coastguard Worker }
1378*bbecb9d1SAndroid Build Coastguard Worker
vrend_alpha_test_enable(struct vrend_context * ctx,bool alpha_test_enable)1379*bbecb9d1SAndroid Build Coastguard Worker static void vrend_alpha_test_enable(struct vrend_context *ctx, bool alpha_test_enable)
1380*bbecb9d1SAndroid Build Coastguard Worker {
1381*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile) {
1382*bbecb9d1SAndroid Build Coastguard Worker /* handled in shaders */
1383*bbecb9d1SAndroid Build Coastguard Worker return;
1384*bbecb9d1SAndroid Build Coastguard Worker }
1385*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->alpha_test_enabled != alpha_test_enable) {
1386*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->alpha_test_enabled = alpha_test_enable;
1387*bbecb9d1SAndroid Build Coastguard Worker if (alpha_test_enable)
1388*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_ALPHA_TEST);
1389*bbecb9d1SAndroid Build Coastguard Worker else
1390*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_ALPHA_TEST);
1391*bbecb9d1SAndroid Build Coastguard Worker }
1392*bbecb9d1SAndroid Build Coastguard Worker }
1393*bbecb9d1SAndroid Build Coastguard Worker
vrend_stencil_test_enable(struct vrend_sub_context * sub_ctx,bool stencil_test_enable)1394*bbecb9d1SAndroid Build Coastguard Worker static void vrend_stencil_test_enable(struct vrend_sub_context *sub_ctx, bool stencil_test_enable)
1395*bbecb9d1SAndroid Build Coastguard Worker {
1396*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->stencil_test_enabled != stencil_test_enable) {
1397*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->stencil_test_enabled = stencil_test_enable;
1398*bbecb9d1SAndroid Build Coastguard Worker if (stencil_test_enable)
1399*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_STENCIL_TEST);
1400*bbecb9d1SAndroid Build Coastguard Worker else
1401*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_STENCIL_TEST);
1402*bbecb9d1SAndroid Build Coastguard Worker }
1403*bbecb9d1SAndroid Build Coastguard Worker }
1404*bbecb9d1SAndroid Build Coastguard Worker
1405*bbecb9d1SAndroid Build Coastguard Worker ASSERTED
dump_stream_out(struct pipe_stream_output_info * so)1406*bbecb9d1SAndroid Build Coastguard Worker static void dump_stream_out(struct pipe_stream_output_info *so)
1407*bbecb9d1SAndroid Build Coastguard Worker {
1408*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
1409*bbecb9d1SAndroid Build Coastguard Worker if (!so)
1410*bbecb9d1SAndroid Build Coastguard Worker return;
1411*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("streamout: %d\n", so->num_outputs);
1412*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("strides: ");
1413*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
1414*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%d ", so->stride[i]);
1415*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("\n");
1416*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("outputs:\n");
1417*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < so->num_outputs; i++) {
1418*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("\t%d: reg: %d sc: %d, nc: %d ob: %d do: %d st: %d\n",
1419*bbecb9d1SAndroid Build Coastguard Worker i,
1420*bbecb9d1SAndroid Build Coastguard Worker so->output[i].register_index,
1421*bbecb9d1SAndroid Build Coastguard Worker so->output[i].start_component,
1422*bbecb9d1SAndroid Build Coastguard Worker so->output[i].num_components,
1423*bbecb9d1SAndroid Build Coastguard Worker so->output[i].output_buffer,
1424*bbecb9d1SAndroid Build Coastguard Worker so->output[i].dst_offset,
1425*bbecb9d1SAndroid Build Coastguard Worker so->output[i].stream);
1426*bbecb9d1SAndroid Build Coastguard Worker }
1427*bbecb9d1SAndroid Build Coastguard Worker }
1428*bbecb9d1SAndroid Build Coastguard Worker
get_skip_str(int * skip_val)1429*bbecb9d1SAndroid Build Coastguard Worker static char *get_skip_str(int *skip_val)
1430*bbecb9d1SAndroid Build Coastguard Worker {
1431*bbecb9d1SAndroid Build Coastguard Worker char *start_skip = NULL;
1432*bbecb9d1SAndroid Build Coastguard Worker if (*skip_val < 0) {
1433*bbecb9d1SAndroid Build Coastguard Worker *skip_val = 0;
1434*bbecb9d1SAndroid Build Coastguard Worker return NULL;
1435*bbecb9d1SAndroid Build Coastguard Worker }
1436*bbecb9d1SAndroid Build Coastguard Worker
1437*bbecb9d1SAndroid Build Coastguard Worker if (*skip_val == 1) {
1438*bbecb9d1SAndroid Build Coastguard Worker start_skip = strdup("gl_SkipComponents1");
1439*bbecb9d1SAndroid Build Coastguard Worker *skip_val -= 1;
1440*bbecb9d1SAndroid Build Coastguard Worker } else if (*skip_val == 2) {
1441*bbecb9d1SAndroid Build Coastguard Worker start_skip = strdup("gl_SkipComponents2");
1442*bbecb9d1SAndroid Build Coastguard Worker *skip_val -= 2;
1443*bbecb9d1SAndroid Build Coastguard Worker } else if (*skip_val == 3) {
1444*bbecb9d1SAndroid Build Coastguard Worker start_skip = strdup("gl_SkipComponents3");
1445*bbecb9d1SAndroid Build Coastguard Worker *skip_val -= 3;
1446*bbecb9d1SAndroid Build Coastguard Worker } else if (*skip_val >= 4) {
1447*bbecb9d1SAndroid Build Coastguard Worker start_skip = strdup("gl_SkipComponents4");
1448*bbecb9d1SAndroid Build Coastguard Worker *skip_val -= 4;
1449*bbecb9d1SAndroid Build Coastguard Worker }
1450*bbecb9d1SAndroid Build Coastguard Worker return start_skip;
1451*bbecb9d1SAndroid Build Coastguard Worker }
1452*bbecb9d1SAndroid Build Coastguard Worker
set_stream_out_varyings(ASSERTED struct vrend_sub_context * sub_ctx,int prog_id,struct vrend_shader_info * sinfo)1453*bbecb9d1SAndroid Build Coastguard Worker static void set_stream_out_varyings(ASSERTED struct vrend_sub_context *sub_ctx,
1454*bbecb9d1SAndroid Build Coastguard Worker int prog_id,
1455*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_info *sinfo)
1456*bbecb9d1SAndroid Build Coastguard Worker {
1457*bbecb9d1SAndroid Build Coastguard Worker struct pipe_stream_output_info *so = &sinfo->so_info;
1458*bbecb9d1SAndroid Build Coastguard Worker char *varyings[PIPE_MAX_SHADER_OUTPUTS*2];
1459*bbecb9d1SAndroid Build Coastguard Worker int j;
1460*bbecb9d1SAndroid Build Coastguard Worker uint i, n_outputs = 0;
1461*bbecb9d1SAndroid Build Coastguard Worker int last_buffer = 0;
1462*bbecb9d1SAndroid Build Coastguard Worker char *start_skip;
1463*bbecb9d1SAndroid Build Coastguard Worker int buf_offset = 0;
1464*bbecb9d1SAndroid Build Coastguard Worker int skip;
1465*bbecb9d1SAndroid Build Coastguard Worker if (!so->num_outputs)
1466*bbecb9d1SAndroid Build Coastguard Worker return;
1467*bbecb9d1SAndroid Build Coastguard Worker
1468*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG_EXT(dbg_shader_streamout, sub_ctx->parent, dump_stream_out(so));
1469*bbecb9d1SAndroid Build Coastguard Worker
1470*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < so->num_outputs; i++) {
1471*bbecb9d1SAndroid Build Coastguard Worker if (last_buffer != so->output[i].output_buffer) {
1472*bbecb9d1SAndroid Build Coastguard Worker
1473*bbecb9d1SAndroid Build Coastguard Worker skip = so->stride[last_buffer] - buf_offset;
1474*bbecb9d1SAndroid Build Coastguard Worker while (skip) {
1475*bbecb9d1SAndroid Build Coastguard Worker start_skip = get_skip_str(&skip);
1476*bbecb9d1SAndroid Build Coastguard Worker if (start_skip)
1477*bbecb9d1SAndroid Build Coastguard Worker varyings[n_outputs++] = start_skip;
1478*bbecb9d1SAndroid Build Coastguard Worker }
1479*bbecb9d1SAndroid Build Coastguard Worker for (j = last_buffer; j < so->output[i].output_buffer; j++)
1480*bbecb9d1SAndroid Build Coastguard Worker varyings[n_outputs++] = strdup("gl_NextBuffer");
1481*bbecb9d1SAndroid Build Coastguard Worker last_buffer = so->output[i].output_buffer;
1482*bbecb9d1SAndroid Build Coastguard Worker buf_offset = 0;
1483*bbecb9d1SAndroid Build Coastguard Worker }
1484*bbecb9d1SAndroid Build Coastguard Worker
1485*bbecb9d1SAndroid Build Coastguard Worker skip = so->output[i].dst_offset - buf_offset;
1486*bbecb9d1SAndroid Build Coastguard Worker while (skip) {
1487*bbecb9d1SAndroid Build Coastguard Worker start_skip = get_skip_str(&skip);
1488*bbecb9d1SAndroid Build Coastguard Worker if (start_skip)
1489*bbecb9d1SAndroid Build Coastguard Worker varyings[n_outputs++] = start_skip;
1490*bbecb9d1SAndroid Build Coastguard Worker }
1491*bbecb9d1SAndroid Build Coastguard Worker buf_offset = so->output[i].dst_offset;
1492*bbecb9d1SAndroid Build Coastguard Worker
1493*bbecb9d1SAndroid Build Coastguard Worker buf_offset += so->output[i].num_components;
1494*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->so_names[i])
1495*bbecb9d1SAndroid Build Coastguard Worker varyings[n_outputs++] = strdup(sinfo->so_names[i]);
1496*bbecb9d1SAndroid Build Coastguard Worker }
1497*bbecb9d1SAndroid Build Coastguard Worker
1498*bbecb9d1SAndroid Build Coastguard Worker skip = so->stride[last_buffer] - buf_offset;
1499*bbecb9d1SAndroid Build Coastguard Worker while (skip) {
1500*bbecb9d1SAndroid Build Coastguard Worker start_skip = get_skip_str(&skip);
1501*bbecb9d1SAndroid Build Coastguard Worker if (start_skip)
1502*bbecb9d1SAndroid Build Coastguard Worker varyings[n_outputs++] = start_skip;
1503*bbecb9d1SAndroid Build Coastguard Worker }
1504*bbecb9d1SAndroid Build Coastguard Worker
1505*bbecb9d1SAndroid Build Coastguard Worker glTransformFeedbackVaryings(prog_id, n_outputs,
1506*bbecb9d1SAndroid Build Coastguard Worker (const GLchar **)varyings, GL_INTERLEAVED_ATTRIBS_EXT);
1507*bbecb9d1SAndroid Build Coastguard Worker
1508*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < n_outputs; i++)
1509*bbecb9d1SAndroid Build Coastguard Worker if (varyings[i])
1510*bbecb9d1SAndroid Build Coastguard Worker free(varyings[i]);
1511*bbecb9d1SAndroid Build Coastguard Worker }
1512*bbecb9d1SAndroid Build Coastguard Worker
1513*bbecb9d1SAndroid Build Coastguard Worker static inline int
vrend_get_uniform_location(struct vrend_linked_shader_program * sprog,char * name,int shader_type)1514*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_location(struct vrend_linked_shader_program *sprog,
1515*bbecb9d1SAndroid Build Coastguard Worker char *name, int shader_type)
1516*bbecb9d1SAndroid Build Coastguard Worker {
1517*bbecb9d1SAndroid Build Coastguard Worker assert(!sprog->is_pipeline || sprog->ss[shader_type]->sel->sinfo.separable_program);
1518*bbecb9d1SAndroid Build Coastguard Worker
1519*bbecb9d1SAndroid Build Coastguard Worker GLint id = sprog->is_pipeline ?
1520*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[shader_type]->program_id :
1521*bbecb9d1SAndroid Build Coastguard Worker sprog->id.program;
1522*bbecb9d1SAndroid Build Coastguard Worker
1523*bbecb9d1SAndroid Build Coastguard Worker return glGetUniformLocation(id, name);
1524*bbecb9d1SAndroid Build Coastguard Worker }
1525*bbecb9d1SAndroid Build Coastguard Worker
1526*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_set_active_pipeline_stage(struct vrend_linked_shader_program * sprog,int shader_type)1527*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_pipeline_stage(struct vrend_linked_shader_program *sprog, int shader_type)
1528*bbecb9d1SAndroid Build Coastguard Worker {
1529*bbecb9d1SAndroid Build Coastguard Worker if (sprog->is_pipeline && sprog->ss[shader_type])
1530*bbecb9d1SAndroid Build Coastguard Worker glActiveShaderProgram(sprog->id.pipeline, sprog->ss[shader_type]->program_id);
1531*bbecb9d1SAndroid Build Coastguard Worker }
1532*bbecb9d1SAndroid Build Coastguard Worker
bind_sampler_locs(struct vrend_linked_shader_program * sprog,enum pipe_shader_type shader_type,int next_sampler_id)1533*bbecb9d1SAndroid Build Coastguard Worker static int bind_sampler_locs(struct vrend_linked_shader_program *sprog,
1534*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type shader_type, int next_sampler_id)
1535*bbecb9d1SAndroid Build Coastguard Worker {
1536*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_shader_info *sinfo = &sprog->ss[shader_type]->sel->sinfo;
1537*bbecb9d1SAndroid Build Coastguard Worker
1538*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->samplers_used_mask) {
1539*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask = sinfo->samplers_used_mask;
1540*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_mask[shader_type] = sinfo->shadow_samp_mask;
1541*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->shadow_samp_mask) {
1542*bbecb9d1SAndroid Build Coastguard Worker unsigned nsamp = util_bitcount(sinfo->samplers_used_mask);
1543*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_mask_locs[shader_type] = calloc(nsamp, sizeof(uint32_t));
1544*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_add_locs[shader_type] = calloc(nsamp, sizeof(uint32_t));
1545*bbecb9d1SAndroid Build Coastguard Worker } else {
1546*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_mask_locs[shader_type] = sprog->shadow_samp_add_locs[shader_type] = NULL;
1547*bbecb9d1SAndroid Build Coastguard Worker }
1548*bbecb9d1SAndroid Build Coastguard Worker const char *prefix = pipe_shader_to_prefix(shader_type);
1549*bbecb9d1SAndroid Build Coastguard Worker int sampler_index = 0;
1550*bbecb9d1SAndroid Build Coastguard Worker while(mask) {
1551*bbecb9d1SAndroid Build Coastguard Worker uint32_t i = u_bit_scan(&mask);
1552*bbecb9d1SAndroid Build Coastguard Worker char name[64];
1553*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->num_sampler_arrays) {
1554*bbecb9d1SAndroid Build Coastguard Worker int arr_idx = vrend_shader_lookup_sampler_array(sinfo, i);
1555*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%ssamp%d[%d]", prefix, arr_idx, i - arr_idx);
1556*bbecb9d1SAndroid Build Coastguard Worker } else
1557*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%ssamp%d", prefix, i);
1558*bbecb9d1SAndroid Build Coastguard Worker
1559*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_pipeline_stage(sprog, shader_type);
1560*bbecb9d1SAndroid Build Coastguard Worker glUniform1i(vrend_get_uniform_location(sprog, name, shader_type),
1561*bbecb9d1SAndroid Build Coastguard Worker next_sampler_id++);
1562*bbecb9d1SAndroid Build Coastguard Worker
1563*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->shadow_samp_mask & (1 << i)) {
1564*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%sshadmask%d", prefix, i);
1565*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_mask_locs[shader_type][sampler_index] =
1566*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_location(sprog, name, shader_type);
1567*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%sshadadd%d", prefix, i);
1568*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_add_locs[shader_type][sampler_index] =
1569*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_location(sprog, name, shader_type);
1570*bbecb9d1SAndroid Build Coastguard Worker }
1571*bbecb9d1SAndroid Build Coastguard Worker sampler_index++;
1572*bbecb9d1SAndroid Build Coastguard Worker }
1573*bbecb9d1SAndroid Build Coastguard Worker } else {
1574*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_mask_locs[shader_type] = NULL;
1575*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_add_locs[shader_type] = NULL;
1576*bbecb9d1SAndroid Build Coastguard Worker sprog->shadow_samp_mask[shader_type] = 0;
1577*bbecb9d1SAndroid Build Coastguard Worker }
1578*bbecb9d1SAndroid Build Coastguard Worker sprog->samplers_used_mask[shader_type] = sinfo->samplers_used_mask;
1579*bbecb9d1SAndroid Build Coastguard Worker
1580*bbecb9d1SAndroid Build Coastguard Worker return next_sampler_id;
1581*bbecb9d1SAndroid Build Coastguard Worker }
1582*bbecb9d1SAndroid Build Coastguard Worker
bind_const_locs(struct vrend_linked_shader_program * sprog,enum pipe_shader_type shader_type)1583*bbecb9d1SAndroid Build Coastguard Worker static void bind_const_locs(struct vrend_linked_shader_program *sprog,
1584*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type shader_type)
1585*bbecb9d1SAndroid Build Coastguard Worker {
1586*bbecb9d1SAndroid Build Coastguard Worker if (sprog->ss[shader_type]->sel->sinfo.num_consts) {
1587*bbecb9d1SAndroid Build Coastguard Worker char name[32];
1588*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%sconst0", pipe_shader_to_prefix(shader_type));
1589*bbecb9d1SAndroid Build Coastguard Worker sprog->const_location[shader_type] = vrend_get_uniform_location(sprog, name,
1590*bbecb9d1SAndroid Build Coastguard Worker shader_type);
1591*bbecb9d1SAndroid Build Coastguard Worker } else
1592*bbecb9d1SAndroid Build Coastguard Worker sprog->const_location[shader_type] = -1;
1593*bbecb9d1SAndroid Build Coastguard Worker }
1594*bbecb9d1SAndroid Build Coastguard Worker
1595*bbecb9d1SAndroid Build Coastguard Worker static inline GLuint
vrend_get_uniform_block_index(struct vrend_linked_shader_program * sprog,char * name,int shader_type)1596*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_block_index(struct vrend_linked_shader_program *sprog,
1597*bbecb9d1SAndroid Build Coastguard Worker char *name, int shader_type)
1598*bbecb9d1SAndroid Build Coastguard Worker {
1599*bbecb9d1SAndroid Build Coastguard Worker assert(!sprog->is_pipeline || sprog->ss[shader_type]->sel->sinfo.separable_program);
1600*bbecb9d1SAndroid Build Coastguard Worker
1601*bbecb9d1SAndroid Build Coastguard Worker GLuint id = sprog->is_pipeline ?
1602*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[shader_type]->program_id :
1603*bbecb9d1SAndroid Build Coastguard Worker sprog->id.program;
1604*bbecb9d1SAndroid Build Coastguard Worker
1605*bbecb9d1SAndroid Build Coastguard Worker return glGetUniformBlockIndex(id, name);
1606*bbecb9d1SAndroid Build Coastguard Worker }
1607*bbecb9d1SAndroid Build Coastguard Worker
1608*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_uniform_block_binding(struct vrend_linked_shader_program * sprog,int shader_type,int loc,int value)1609*bbecb9d1SAndroid Build Coastguard Worker vrend_uniform_block_binding(struct vrend_linked_shader_program *sprog,
1610*bbecb9d1SAndroid Build Coastguard Worker int shader_type, int loc, int value)
1611*bbecb9d1SAndroid Build Coastguard Worker {
1612*bbecb9d1SAndroid Build Coastguard Worker assert(!sprog->is_pipeline || sprog->ss[shader_type]->sel->sinfo.separable_program);
1613*bbecb9d1SAndroid Build Coastguard Worker
1614*bbecb9d1SAndroid Build Coastguard Worker GLint id = sprog->is_pipeline ?
1615*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[shader_type]->program_id :
1616*bbecb9d1SAndroid Build Coastguard Worker sprog->id.program;
1617*bbecb9d1SAndroid Build Coastguard Worker
1618*bbecb9d1SAndroid Build Coastguard Worker glUniformBlockBinding(id, loc, value);
1619*bbecb9d1SAndroid Build Coastguard Worker }
1620*bbecb9d1SAndroid Build Coastguard Worker
bind_ubo_locs(struct vrend_linked_shader_program * sprog,enum pipe_shader_type shader_type,int next_ubo_id)1621*bbecb9d1SAndroid Build Coastguard Worker static int bind_ubo_locs(struct vrend_linked_shader_program *sprog,
1622*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type shader_type, int next_ubo_id)
1623*bbecb9d1SAndroid Build Coastguard Worker {
1624*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_shader_info *sinfo = &sprog->ss[shader_type]->sel->sinfo;
1625*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->ubo_used_mask) {
1626*bbecb9d1SAndroid Build Coastguard Worker const char *prefix = pipe_shader_to_prefix(shader_type);
1627*bbecb9d1SAndroid Build Coastguard Worker
1628*bbecb9d1SAndroid Build Coastguard Worker unsigned mask = sinfo->ubo_used_mask;
1629*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
1630*bbecb9d1SAndroid Build Coastguard Worker uint32_t ubo_idx = u_bit_scan(&mask);
1631*bbecb9d1SAndroid Build Coastguard Worker char name[32];
1632*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->ubo_indirect)
1633*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%subo[%d]", prefix, ubo_idx - 1);
1634*bbecb9d1SAndroid Build Coastguard Worker else
1635*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%subo%d", prefix, ubo_idx);
1636*bbecb9d1SAndroid Build Coastguard Worker
1637*bbecb9d1SAndroid Build Coastguard Worker GLuint loc = vrend_get_uniform_block_index(sprog, name, shader_type);
1638*bbecb9d1SAndroid Build Coastguard Worker vrend_uniform_block_binding(sprog, shader_type, loc, next_ubo_id++);
1639*bbecb9d1SAndroid Build Coastguard Worker }
1640*bbecb9d1SAndroid Build Coastguard Worker }
1641*bbecb9d1SAndroid Build Coastguard Worker
1642*bbecb9d1SAndroid Build Coastguard Worker sprog->ubo_used_mask[shader_type] = sinfo->ubo_used_mask;
1643*bbecb9d1SAndroid Build Coastguard Worker
1644*bbecb9d1SAndroid Build Coastguard Worker return next_ubo_id;
1645*bbecb9d1SAndroid Build Coastguard Worker }
1646*bbecb9d1SAndroid Build Coastguard Worker
bind_virgl_block_loc(struct vrend_linked_shader_program * sprog,enum pipe_shader_type shader_type,int virgl_block_ubo_id)1647*bbecb9d1SAndroid Build Coastguard Worker static void bind_virgl_block_loc(struct vrend_linked_shader_program *sprog,
1648*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type shader_type,
1649*bbecb9d1SAndroid Build Coastguard Worker int virgl_block_ubo_id)
1650*bbecb9d1SAndroid Build Coastguard Worker {
1651*bbecb9d1SAndroid Build Coastguard Worker sprog->separate_virgl_block_id[shader_type] =
1652*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_block_index(sprog, "VirglBlock", shader_type);
1653*bbecb9d1SAndroid Build Coastguard Worker
1654*bbecb9d1SAndroid Build Coastguard Worker if (sprog->separate_virgl_block_id[shader_type] != GL_INVALID_INDEX) {
1655*bbecb9d1SAndroid Build Coastguard Worker bool created_virgl_block_buffer = false;
1656*bbecb9d1SAndroid Build Coastguard Worker
1657*bbecb9d1SAndroid Build Coastguard Worker if (sprog->virgl_block_bind == -1) {
1658*bbecb9d1SAndroid Build Coastguard Worker sprog->virgl_block_bind = virgl_block_ubo_id;
1659*bbecb9d1SAndroid Build Coastguard Worker if (sprog->ubo_sysval_buffer_id == -1) {
1660*bbecb9d1SAndroid Build Coastguard Worker glGenBuffers(1, (GLuint *) &sprog->ubo_sysval_buffer_id);
1661*bbecb9d1SAndroid Build Coastguard Worker created_virgl_block_buffer = true;
1662*bbecb9d1SAndroid Build Coastguard Worker }
1663*bbecb9d1SAndroid Build Coastguard Worker }
1664*bbecb9d1SAndroid Build Coastguard Worker
1665*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_pipeline_stage(sprog, shader_type);
1666*bbecb9d1SAndroid Build Coastguard Worker vrend_uniform_block_binding(sprog, shader_type,
1667*bbecb9d1SAndroid Build Coastguard Worker sprog->separate_virgl_block_id[shader_type],
1668*bbecb9d1SAndroid Build Coastguard Worker sprog->virgl_block_bind);
1669*bbecb9d1SAndroid Build Coastguard Worker
1670*bbecb9d1SAndroid Build Coastguard Worker GLint virgl_block_size;
1671*bbecb9d1SAndroid Build Coastguard Worker int prog_id = sprog->is_pipeline ? sprog->ss[shader_type]->program_id :
1672*bbecb9d1SAndroid Build Coastguard Worker sprog->id.program;
1673*bbecb9d1SAndroid Build Coastguard Worker glGetActiveUniformBlockiv(prog_id, sprog->separate_virgl_block_id[shader_type],
1674*bbecb9d1SAndroid Build Coastguard Worker GL_UNIFORM_BLOCK_DATA_SIZE, &virgl_block_size);
1675*bbecb9d1SAndroid Build Coastguard Worker assert((size_t) virgl_block_size >= sizeof(struct sysval_uniform_block));
1676*bbecb9d1SAndroid Build Coastguard Worker
1677*bbecb9d1SAndroid Build Coastguard Worker if (created_virgl_block_buffer) {
1678*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_UNIFORM_BUFFER, sprog->ubo_sysval_buffer_id);
1679*bbecb9d1SAndroid Build Coastguard Worker glBufferData(GL_UNIFORM_BUFFER, virgl_block_size, NULL, GL_DYNAMIC_DRAW);
1680*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_UNIFORM_BUFFER, 0);
1681*bbecb9d1SAndroid Build Coastguard Worker }
1682*bbecb9d1SAndroid Build Coastguard Worker }
1683*bbecb9d1SAndroid Build Coastguard Worker }
1684*bbecb9d1SAndroid Build Coastguard Worker
rebind_ubo_and_sampler_locs(struct vrend_linked_shader_program * sprog,enum pipe_shader_type last_shader)1685*bbecb9d1SAndroid Build Coastguard Worker static void rebind_ubo_and_sampler_locs(struct vrend_linked_shader_program *sprog,
1686*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type last_shader)
1687*bbecb9d1SAndroid Build Coastguard Worker {
1688*bbecb9d1SAndroid Build Coastguard Worker int next_sampler_id = 0;
1689*bbecb9d1SAndroid Build Coastguard Worker int next_ubo_id = 0;
1690*bbecb9d1SAndroid Build Coastguard Worker
1691*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type shader_type = PIPE_SHADER_VERTEX;
1692*bbecb9d1SAndroid Build Coastguard Worker shader_type <= last_shader;
1693*bbecb9d1SAndroid Build Coastguard Worker shader_type++) {
1694*bbecb9d1SAndroid Build Coastguard Worker if (!sprog->ss[shader_type])
1695*bbecb9d1SAndroid Build Coastguard Worker continue;
1696*bbecb9d1SAndroid Build Coastguard Worker
1697*bbecb9d1SAndroid Build Coastguard Worker next_sampler_id = bind_sampler_locs(sprog, shader_type, next_sampler_id);
1698*bbecb9d1SAndroid Build Coastguard Worker next_ubo_id = bind_ubo_locs(sprog, shader_type, next_ubo_id);
1699*bbecb9d1SAndroid Build Coastguard Worker
1700*bbecb9d1SAndroid Build Coastguard Worker if (sprog->is_pipeline)
1701*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[shader_type]->last_pipeline_id = sprog->id.pipeline;
1702*bbecb9d1SAndroid Build Coastguard Worker }
1703*bbecb9d1SAndroid Build Coastguard Worker
1704*bbecb9d1SAndroid Build Coastguard Worker /* Now `next_ubo_id` is the last ubo id, which is used for the VirglBlock. */
1705*bbecb9d1SAndroid Build Coastguard Worker sprog->virgl_block_bind = -1;
1706*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type shader_type = PIPE_SHADER_VERTEX;
1707*bbecb9d1SAndroid Build Coastguard Worker shader_type <= last_shader;
1708*bbecb9d1SAndroid Build Coastguard Worker shader_type++) {
1709*bbecb9d1SAndroid Build Coastguard Worker if (!sprog->ss[shader_type])
1710*bbecb9d1SAndroid Build Coastguard Worker continue;
1711*bbecb9d1SAndroid Build Coastguard Worker
1712*bbecb9d1SAndroid Build Coastguard Worker bind_virgl_block_loc(sprog, shader_type, next_ubo_id);
1713*bbecb9d1SAndroid Build Coastguard Worker }
1714*bbecb9d1SAndroid Build Coastguard Worker }
1715*bbecb9d1SAndroid Build Coastguard Worker
bind_ssbo_locs(struct vrend_linked_shader_program * sprog,enum pipe_shader_type shader_type)1716*bbecb9d1SAndroid Build Coastguard Worker static void bind_ssbo_locs(struct vrend_linked_shader_program *sprog,
1717*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type shader_type)
1718*bbecb9d1SAndroid Build Coastguard Worker {
1719*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_ssbo))
1720*bbecb9d1SAndroid Build Coastguard Worker return;
1721*bbecb9d1SAndroid Build Coastguard Worker sprog->ssbo_used_mask[shader_type] = sprog->ss[shader_type]->sel->sinfo.ssbo_used_mask;
1722*bbecb9d1SAndroid Build Coastguard Worker }
1723*bbecb9d1SAndroid Build Coastguard Worker
bind_image_locs(struct vrend_linked_shader_program * sprog,enum pipe_shader_type shader_type)1724*bbecb9d1SAndroid Build Coastguard Worker static void bind_image_locs(struct vrend_linked_shader_program *sprog,
1725*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type shader_type)
1726*bbecb9d1SAndroid Build Coastguard Worker {
1727*bbecb9d1SAndroid Build Coastguard Worker int i;
1728*bbecb9d1SAndroid Build Coastguard Worker char name[32];
1729*bbecb9d1SAndroid Build Coastguard Worker const char *prefix = pipe_shader_to_prefix(shader_type);
1730*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_shader_info *sinfo = &sprog->ss[shader_type]->sel->sinfo;
1731*bbecb9d1SAndroid Build Coastguard Worker
1732*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask = sinfo->images_used_mask;
1733*bbecb9d1SAndroid Build Coastguard Worker if (!mask && !sinfo->num_image_arrays)
1734*bbecb9d1SAndroid Build Coastguard Worker return;
1735*bbecb9d1SAndroid Build Coastguard Worker
1736*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_images))
1737*bbecb9d1SAndroid Build Coastguard Worker return;
1738*bbecb9d1SAndroid Build Coastguard Worker
1739*bbecb9d1SAndroid Build Coastguard Worker int nsamp = util_last_bit(mask);
1740*bbecb9d1SAndroid Build Coastguard Worker if (nsamp) {
1741*bbecb9d1SAndroid Build Coastguard Worker sprog->img_locs[shader_type] = calloc(nsamp, sizeof(GLint));
1742*bbecb9d1SAndroid Build Coastguard Worker if (!sprog->img_locs[shader_type])
1743*bbecb9d1SAndroid Build Coastguard Worker return;
1744*bbecb9d1SAndroid Build Coastguard Worker } else
1745*bbecb9d1SAndroid Build Coastguard Worker sprog->img_locs[shader_type] = NULL;
1746*bbecb9d1SAndroid Build Coastguard Worker
1747*bbecb9d1SAndroid Build Coastguard Worker if (sinfo->num_image_arrays) {
1748*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < sinfo->num_image_arrays; i++) {
1749*bbecb9d1SAndroid Build Coastguard Worker struct vrend_array *img_array = &sinfo->image_arrays[i];
1750*bbecb9d1SAndroid Build Coastguard Worker for (int j = 0; j < img_array->array_size; j++) {
1751*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%simg%d[%d]", prefix, img_array->first, j);
1752*bbecb9d1SAndroid Build Coastguard Worker sprog->img_locs[shader_type][img_array->first + j] =
1753*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_location(sprog, name, shader_type);
1754*bbecb9d1SAndroid Build Coastguard Worker if (sprog->img_locs[shader_type][img_array->first + j] == -1)
1755*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failed to get uniform loc for image %s\n", name);
1756*bbecb9d1SAndroid Build Coastguard Worker }
1757*bbecb9d1SAndroid Build Coastguard Worker }
1758*bbecb9d1SAndroid Build Coastguard Worker } else if (mask) {
1759*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < nsamp; i++) {
1760*bbecb9d1SAndroid Build Coastguard Worker if (mask & (1 << i)) {
1761*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "%simg%d", prefix, i);
1762*bbecb9d1SAndroid Build Coastguard Worker sprog->img_locs[shader_type][i] =
1763*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_location(sprog, name, shader_type);
1764*bbecb9d1SAndroid Build Coastguard Worker if (sprog->img_locs[shader_type][i] == -1)
1765*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failed to get uniform loc for image %s\n", name);
1766*bbecb9d1SAndroid Build Coastguard Worker } else {
1767*bbecb9d1SAndroid Build Coastguard Worker sprog->img_locs[shader_type][i] = -1;
1768*bbecb9d1SAndroid Build Coastguard Worker }
1769*bbecb9d1SAndroid Build Coastguard Worker }
1770*bbecb9d1SAndroid Build Coastguard Worker }
1771*bbecb9d1SAndroid Build Coastguard Worker sprog->images_used_mask[shader_type] = mask;
1772*bbecb9d1SAndroid Build Coastguard Worker }
1773*bbecb9d1SAndroid Build Coastguard Worker
vrend_link(GLuint id)1774*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_link(GLuint id)
1775*bbecb9d1SAndroid Build Coastguard Worker {
1776*bbecb9d1SAndroid Build Coastguard Worker GLint lret;
1777*bbecb9d1SAndroid Build Coastguard Worker glLinkProgram(id);
1778*bbecb9d1SAndroid Build Coastguard Worker glGetProgramiv(id, GL_LINK_STATUS, &lret);
1779*bbecb9d1SAndroid Build Coastguard Worker if (lret == GL_FALSE) {
1780*bbecb9d1SAndroid Build Coastguard Worker char infolog[65536];
1781*bbecb9d1SAndroid Build Coastguard Worker int len;
1782*bbecb9d1SAndroid Build Coastguard Worker glGetProgramInfoLog(id, 65536, &len, infolog);
1783*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Error linking program:\n%s\n", infolog);
1784*bbecb9d1SAndroid Build Coastguard Worker return false;
1785*bbecb9d1SAndroid Build Coastguard Worker }
1786*bbecb9d1SAndroid Build Coastguard Worker return true;
1787*bbecb9d1SAndroid Build Coastguard Worker }
1788*bbecb9d1SAndroid Build Coastguard Worker
vrend_link_separable_shader(struct vrend_sub_context * sub_ctx,struct vrend_shader * shader,int type)1789*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_link_separable_shader(struct vrend_sub_context *sub_ctx,
1790*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *shader, int type)
1791*bbecb9d1SAndroid Build Coastguard Worker {
1792*bbecb9d1SAndroid Build Coastguard Worker int i;
1793*bbecb9d1SAndroid Build Coastguard Worker char name[64];
1794*bbecb9d1SAndroid Build Coastguard Worker
1795*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_VERTEX || type == PIPE_SHADER_GEOMETRY ||
1796*bbecb9d1SAndroid Build Coastguard Worker type == PIPE_SHADER_TESS_EVAL)
1797*bbecb9d1SAndroid Build Coastguard Worker set_stream_out_varyings(sub_ctx, shader->program_id, &shader->sel->sinfo);
1798*bbecb9d1SAndroid Build Coastguard Worker
1799*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_FRAGMENT && shader->sel->sinfo.num_outputs > 1) {
1800*bbecb9d1SAndroid Build Coastguard Worker bool dual_src_linked = util_blend_state_is_dual(&sub_ctx->blend_state, 0);
1801*bbecb9d1SAndroid Build Coastguard Worker if (dual_src_linked) {
1802*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_dual_src_blend)) {
1803*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles) {
1804*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexed(shader->program_id, 0, 0, "fsout_c0");
1805*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexed(shader->program_id, 0, 1, "fsout_c1");
1806*bbecb9d1SAndroid Build Coastguard Worker } else {
1807*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexedEXT(shader->program_id, 0, 0, "fsout_c0");
1808*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexedEXT(shader->program_id, 0, 1, "fsout_c1");
1809*bbecb9d1SAndroid Build Coastguard Worker }
1810*bbecb9d1SAndroid Build Coastguard Worker } else {
1811*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_DUAL_SRC_BLEND, 0);
1812*bbecb9d1SAndroid Build Coastguard Worker }
1813*bbecb9d1SAndroid Build Coastguard Worker } else if (!vrend_state.use_gles && has_feature(feat_dual_src_blend)) {
1814*bbecb9d1SAndroid Build Coastguard Worker /* On GLES without dual source blending we emit the layout directly in the shader
1815*bbecb9d1SAndroid Build Coastguard Worker * so there is no need to define the binding here */
1816*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < shader->sel->sinfo.num_outputs; ++i) {
1817*bbecb9d1SAndroid Build Coastguard Worker if (shader->sel->sinfo.fs_output_layout[i] >= 0) {
1818*bbecb9d1SAndroid Build Coastguard Worker char buf[64];
1819*bbecb9d1SAndroid Build Coastguard Worker snprintf(buf, sizeof(buf), "fsout_c%d",
1820*bbecb9d1SAndroid Build Coastguard Worker shader->sel->sinfo.fs_output_layout[i]);
1821*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexed(shader->program_id,
1822*bbecb9d1SAndroid Build Coastguard Worker shader->sel->sinfo.fs_output_layout[i],
1823*bbecb9d1SAndroid Build Coastguard Worker 0, buf);
1824*bbecb9d1SAndroid Build Coastguard Worker }
1825*bbecb9d1SAndroid Build Coastguard Worker }
1826*bbecb9d1SAndroid Build Coastguard Worker }
1827*bbecb9d1SAndroid Build Coastguard Worker }
1828*bbecb9d1SAndroid Build Coastguard Worker
1829*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_VERTEX && has_feature(feat_gles31_vertex_attrib_binding)) {
1830*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask = shader->sel->sinfo.attrib_input_mask;
1831*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
1832*bbecb9d1SAndroid Build Coastguard Worker i = u_bit_scan(&mask);
1833*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "in_%d", i);
1834*bbecb9d1SAndroid Build Coastguard Worker glBindAttribLocation(shader->program_id, i, name);
1835*bbecb9d1SAndroid Build Coastguard Worker }
1836*bbecb9d1SAndroid Build Coastguard Worker }
1837*bbecb9d1SAndroid Build Coastguard Worker
1838*bbecb9d1SAndroid Build Coastguard Worker shader->is_linked = vrend_link(shader->program_id);
1839*bbecb9d1SAndroid Build Coastguard Worker
1840*bbecb9d1SAndroid Build Coastguard Worker if (!shader->is_linked) {
1841*bbecb9d1SAndroid Build Coastguard Worker /* dump shaders */
1842*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0);
1843*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(shader);
1844*bbecb9d1SAndroid Build Coastguard Worker }
1845*bbecb9d1SAndroid Build Coastguard Worker
1846*bbecb9d1SAndroid Build Coastguard Worker return shader->is_linked;
1847*bbecb9d1SAndroid Build Coastguard Worker }
1848*bbecb9d1SAndroid Build Coastguard Worker
add_cs_shader_program(struct vrend_context * ctx,struct vrend_shader * cs)1849*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_linked_shader_program *add_cs_shader_program(struct vrend_context *ctx,
1850*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *cs)
1851*bbecb9d1SAndroid Build Coastguard Worker {
1852*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *sprog = CALLOC_STRUCT(vrend_linked_shader_program);
1853*bbecb9d1SAndroid Build Coastguard Worker GLuint prog_id;
1854*bbecb9d1SAndroid Build Coastguard Worker prog_id = glCreateProgram();
1855*bbecb9d1SAndroid Build Coastguard Worker glAttachShader(prog_id, cs->id);
1856*bbecb9d1SAndroid Build Coastguard Worker
1857*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_link(prog_id)) {
1858*bbecb9d1SAndroid Build Coastguard Worker /* dump shaders */
1859*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0);
1860*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(cs);
1861*bbecb9d1SAndroid Build Coastguard Worker glDeleteProgram(prog_id);
1862*bbecb9d1SAndroid Build Coastguard Worker free(sprog);
1863*bbecb9d1SAndroid Build Coastguard Worker return NULL;
1864*bbecb9d1SAndroid Build Coastguard Worker }
1865*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[PIPE_SHADER_COMPUTE] = cs;
1866*bbecb9d1SAndroid Build Coastguard Worker
1867*bbecb9d1SAndroid Build Coastguard Worker list_add(&sprog->sl[PIPE_SHADER_COMPUTE], &cs->programs);
1868*bbecb9d1SAndroid Build Coastguard Worker sprog->id.program = prog_id;
1869*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&sprog->head, &ctx->sub->cs_programs);
1870*bbecb9d1SAndroid Build Coastguard Worker
1871*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(ctx->sub, sprog);
1872*bbecb9d1SAndroid Build Coastguard Worker
1873*bbecb9d1SAndroid Build Coastguard Worker bind_sampler_locs(sprog, PIPE_SHADER_COMPUTE, 0);
1874*bbecb9d1SAndroid Build Coastguard Worker bind_ubo_locs(sprog, PIPE_SHADER_COMPUTE, 0);
1875*bbecb9d1SAndroid Build Coastguard Worker bind_ssbo_locs(sprog, PIPE_SHADER_COMPUTE);
1876*bbecb9d1SAndroid Build Coastguard Worker bind_const_locs(sprog, PIPE_SHADER_COMPUTE);
1877*bbecb9d1SAndroid Build Coastguard Worker bind_image_locs(sprog, PIPE_SHADER_COMPUTE);
1878*bbecb9d1SAndroid Build Coastguard Worker return sprog;
1879*bbecb9d1SAndroid Build Coastguard Worker }
1880*bbecb9d1SAndroid Build Coastguard Worker
1881*bbecb9d1SAndroid Build Coastguard Worker static inline bool
vrend_link_stage(struct vrend_shader * stage)1882*bbecb9d1SAndroid Build Coastguard Worker vrend_link_stage(struct vrend_shader *stage) {
1883*bbecb9d1SAndroid Build Coastguard Worker if (!stage->is_linked)
1884*bbecb9d1SAndroid Build Coastguard Worker stage->is_linked = vrend_link(stage->program_id);
1885*bbecb9d1SAndroid Build Coastguard Worker return stage->is_linked;
1886*bbecb9d1SAndroid Build Coastguard Worker }
1887*bbecb9d1SAndroid Build Coastguard Worker
add_shader_program(struct vrend_sub_context * sub_ctx,struct vrend_shader * vs,struct vrend_shader * fs,struct vrend_shader * gs,struct vrend_shader * tcs,struct vrend_shader * tes,bool separable)1888*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_linked_shader_program *add_shader_program(struct vrend_sub_context *sub_ctx,
1889*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *vs,
1890*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *fs,
1891*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *gs,
1892*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *tcs,
1893*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *tes,
1894*bbecb9d1SAndroid Build Coastguard Worker bool separable)
1895*bbecb9d1SAndroid Build Coastguard Worker {
1896*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *sprog = CALLOC_STRUCT(vrend_linked_shader_program);
1897*bbecb9d1SAndroid Build Coastguard Worker char name[64];
1898*bbecb9d1SAndroid Build Coastguard Worker int i;
1899*bbecb9d1SAndroid Build Coastguard Worker GLuint prog_id = 0;
1900*bbecb9d1SAndroid Build Coastguard Worker GLuint pipeline_id = 0;
1901*bbecb9d1SAndroid Build Coastguard Worker GLuint vs_id, fs_id, gs_id, tes_id = 0;
1902*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type last_shader;
1903*bbecb9d1SAndroid Build Coastguard Worker if (!sprog)
1904*bbecb9d1SAndroid Build Coastguard Worker return NULL;
1905*bbecb9d1SAndroid Build Coastguard Worker
1906*bbecb9d1SAndroid Build Coastguard Worker if (separable) {
1907*bbecb9d1SAndroid Build Coastguard Worker glGenProgramPipelines(1, &pipeline_id);
1908*bbecb9d1SAndroid Build Coastguard Worker
1909*bbecb9d1SAndroid Build Coastguard Worker vs_id = vs->program_id;
1910*bbecb9d1SAndroid Build Coastguard Worker fs_id = fs->program_id;
1911*bbecb9d1SAndroid Build Coastguard Worker if (gs)
1912*bbecb9d1SAndroid Build Coastguard Worker gs_id = gs->program_id;
1913*bbecb9d1SAndroid Build Coastguard Worker if (tes)
1914*bbecb9d1SAndroid Build Coastguard Worker tes_id = tes->program_id;
1915*bbecb9d1SAndroid Build Coastguard Worker } else { /* inseparable programs */
1916*bbecb9d1SAndroid Build Coastguard Worker prog_id = glCreateProgram();
1917*bbecb9d1SAndroid Build Coastguard Worker glAttachShader(prog_id, vs->id);
1918*bbecb9d1SAndroid Build Coastguard Worker if (tcs && tcs->id > 0)
1919*bbecb9d1SAndroid Build Coastguard Worker glAttachShader(prog_id, tcs->id);
1920*bbecb9d1SAndroid Build Coastguard Worker if (tes && tes->id > 0)
1921*bbecb9d1SAndroid Build Coastguard Worker glAttachShader(prog_id, tes->id);
1922*bbecb9d1SAndroid Build Coastguard Worker if (gs && gs->id > 0)
1923*bbecb9d1SAndroid Build Coastguard Worker glAttachShader(prog_id, gs->id);
1924*bbecb9d1SAndroid Build Coastguard Worker glAttachShader(prog_id, fs->id);
1925*bbecb9d1SAndroid Build Coastguard Worker
1926*bbecb9d1SAndroid Build Coastguard Worker /* For the non-separable codepath (the usual path), all these shader stages are
1927*bbecb9d1SAndroid Build Coastguard Worker * contained inside a single program. */
1928*bbecb9d1SAndroid Build Coastguard Worker vs_id = prog_id;
1929*bbecb9d1SAndroid Build Coastguard Worker fs_id = prog_id;
1930*bbecb9d1SAndroid Build Coastguard Worker if (gs)
1931*bbecb9d1SAndroid Build Coastguard Worker gs_id = prog_id;
1932*bbecb9d1SAndroid Build Coastguard Worker if (tes)
1933*bbecb9d1SAndroid Build Coastguard Worker tes_id = prog_id;
1934*bbecb9d1SAndroid Build Coastguard Worker }
1935*bbecb9d1SAndroid Build Coastguard Worker
1936*bbecb9d1SAndroid Build Coastguard Worker if (gs) {
1937*bbecb9d1SAndroid Build Coastguard Worker set_stream_out_varyings(sub_ctx, gs_id, &gs->sel->sinfo);
1938*bbecb9d1SAndroid Build Coastguard Worker } else if (tes)
1939*bbecb9d1SAndroid Build Coastguard Worker set_stream_out_varyings(sub_ctx, tes_id, &tes->sel->sinfo);
1940*bbecb9d1SAndroid Build Coastguard Worker else
1941*bbecb9d1SAndroid Build Coastguard Worker set_stream_out_varyings(sub_ctx, vs_id, &vs->sel->sinfo);
1942*bbecb9d1SAndroid Build Coastguard Worker
1943*bbecb9d1SAndroid Build Coastguard Worker if (fs->sel->sinfo.num_outputs > 1) {
1944*bbecb9d1SAndroid Build Coastguard Worker sprog->dual_src_linked = util_blend_state_is_dual(&sub_ctx->blend_state, 0);
1945*bbecb9d1SAndroid Build Coastguard Worker if (sprog->dual_src_linked) {
1946*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_dual_src_blend)) {
1947*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles) {
1948*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexed(fs_id, 0, 0, "fsout_c0");
1949*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexed(fs_id, 0, 1, "fsout_c1");
1950*bbecb9d1SAndroid Build Coastguard Worker } else {
1951*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexedEXT(fs_id, 0, 0, "fsout_c0");
1952*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexedEXT(fs_id, 0, 1, "fsout_c1");
1953*bbecb9d1SAndroid Build Coastguard Worker }
1954*bbecb9d1SAndroid Build Coastguard Worker } else {
1955*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_DUAL_SRC_BLEND, 0);
1956*bbecb9d1SAndroid Build Coastguard Worker }
1957*bbecb9d1SAndroid Build Coastguard Worker } else if (!vrend_state.use_gles && has_feature(feat_dual_src_blend)) {
1958*bbecb9d1SAndroid Build Coastguard Worker /* On GLES without dual source blending we emit the layout directly in the shader
1959*bbecb9d1SAndroid Build Coastguard Worker * so there is no need to define the binding here */
1960*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < fs->sel->sinfo.num_outputs; ++i) {
1961*bbecb9d1SAndroid Build Coastguard Worker if (fs->sel->sinfo.fs_output_layout[i] >= 0) {
1962*bbecb9d1SAndroid Build Coastguard Worker char buf[64];
1963*bbecb9d1SAndroid Build Coastguard Worker snprintf(buf, sizeof(buf), "fsout_c%d", fs->sel->sinfo.fs_output_layout[i]);
1964*bbecb9d1SAndroid Build Coastguard Worker glBindFragDataLocationIndexed(fs_id, fs->sel->sinfo.fs_output_layout[i], 0, buf);
1965*bbecb9d1SAndroid Build Coastguard Worker }
1966*bbecb9d1SAndroid Build Coastguard Worker }
1967*bbecb9d1SAndroid Build Coastguard Worker }
1968*bbecb9d1SAndroid Build Coastguard Worker } else
1969*bbecb9d1SAndroid Build Coastguard Worker sprog->dual_src_linked = false;
1970*bbecb9d1SAndroid Build Coastguard Worker
1971*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gles31_vertex_attrib_binding)) {
1972*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask = vs->sel->sinfo.attrib_input_mask;
1973*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
1974*bbecb9d1SAndroid Build Coastguard Worker i = u_bit_scan(&mask);
1975*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "in_%d", i);
1976*bbecb9d1SAndroid Build Coastguard Worker glBindAttribLocation(vs_id, i, name);
1977*bbecb9d1SAndroid Build Coastguard Worker }
1978*bbecb9d1SAndroid Build Coastguard Worker }
1979*bbecb9d1SAndroid Build Coastguard Worker
1980*bbecb9d1SAndroid Build Coastguard Worker bool link_success;
1981*bbecb9d1SAndroid Build Coastguard Worker if (separable) { /* separable programs */
1982*bbecb9d1SAndroid Build Coastguard Worker link_success = vrend_link_stage(vs);
1983*bbecb9d1SAndroid Build Coastguard Worker link_success &= vrend_link_stage(fs);
1984*bbecb9d1SAndroid Build Coastguard Worker if (gs) link_success &= vrend_link_stage(gs);
1985*bbecb9d1SAndroid Build Coastguard Worker if (tcs) link_success &= vrend_link_stage(tcs);
1986*bbecb9d1SAndroid Build Coastguard Worker if (tes) link_success &= vrend_link_stage(tes);
1987*bbecb9d1SAndroid Build Coastguard Worker } else { /* non-separable programs */
1988*bbecb9d1SAndroid Build Coastguard Worker link_success = vrend_link(prog_id);
1989*bbecb9d1SAndroid Build Coastguard Worker }
1990*bbecb9d1SAndroid Build Coastguard Worker
1991*bbecb9d1SAndroid Build Coastguard Worker if (!link_success) {
1992*bbecb9d1SAndroid Build Coastguard Worker if (separable) {
1993*bbecb9d1SAndroid Build Coastguard Worker glDeleteProgramPipelines(1, &pipeline_id);
1994*bbecb9d1SAndroid Build Coastguard Worker } else {
1995*bbecb9d1SAndroid Build Coastguard Worker glDeleteProgram(prog_id);
1996*bbecb9d1SAndroid Build Coastguard Worker }
1997*bbecb9d1SAndroid Build Coastguard Worker
1998*bbecb9d1SAndroid Build Coastguard Worker free(sprog);
1999*bbecb9d1SAndroid Build Coastguard Worker
2000*bbecb9d1SAndroid Build Coastguard Worker /* dump shaders */
2001*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_SHADER, 0);
2002*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(vs);
2003*bbecb9d1SAndroid Build Coastguard Worker if (tcs)
2004*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(tcs);
2005*bbecb9d1SAndroid Build Coastguard Worker if (tes)
2006*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(tes);
2007*bbecb9d1SAndroid Build Coastguard Worker if (gs)
2008*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(gs);
2009*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_dump(fs);
2010*bbecb9d1SAndroid Build Coastguard Worker return NULL;
2011*bbecb9d1SAndroid Build Coastguard Worker }
2012*bbecb9d1SAndroid Build Coastguard Worker
2013*bbecb9d1SAndroid Build Coastguard Worker if (separable) {
2014*bbecb9d1SAndroid Build Coastguard Worker glUseProgramStages(pipeline_id, GL_VERTEX_SHADER_BIT, vs->program_id);
2015*bbecb9d1SAndroid Build Coastguard Worker if (tcs) glUseProgramStages(pipeline_id, GL_TESS_CONTROL_SHADER_BIT, tcs->program_id);
2016*bbecb9d1SAndroid Build Coastguard Worker if (tes) glUseProgramStages(pipeline_id, GL_TESS_EVALUATION_SHADER_BIT, tes->program_id);
2017*bbecb9d1SAndroid Build Coastguard Worker if (gs) glUseProgramStages(pipeline_id, GL_GEOMETRY_SHADER_BIT, gs->program_id);
2018*bbecb9d1SAndroid Build Coastguard Worker glUseProgramStages(pipeline_id, GL_FRAGMENT_SHADER_BIT, fs->program_id);
2019*bbecb9d1SAndroid Build Coastguard Worker
2020*bbecb9d1SAndroid Build Coastguard Worker glValidateProgramPipeline(pipeline_id);
2021*bbecb9d1SAndroid Build Coastguard Worker GLint validation_status;
2022*bbecb9d1SAndroid Build Coastguard Worker glGetProgramPipelineiv(pipeline_id, GL_VALIDATE_STATUS, &validation_status);
2023*bbecb9d1SAndroid Build Coastguard Worker if (!validation_status) {
2024*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_PROGRAM_PIPELINE, 0);
2025*bbecb9d1SAndroid Build Coastguard Worker }
2026*bbecb9d1SAndroid Build Coastguard Worker }
2027*bbecb9d1SAndroid Build Coastguard Worker
2028*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[PIPE_SHADER_VERTEX] = vs;
2029*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[PIPE_SHADER_FRAGMENT] = fs;
2030*bbecb9d1SAndroid Build Coastguard Worker sprog->vs_fs_key = (((uint64_t)fs->id) << 32) | (vs->id & ~VREND_PROGRAM_NQUEUE_MASK) |
2031*bbecb9d1SAndroid Build Coastguard Worker (sprog->dual_src_linked ? 1 : 0);
2032*bbecb9d1SAndroid Build Coastguard Worker
2033*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[PIPE_SHADER_GEOMETRY] = gs;
2034*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[PIPE_SHADER_TESS_CTRL] = tcs;
2035*bbecb9d1SAndroid Build Coastguard Worker sprog->ss[PIPE_SHADER_TESS_EVAL] = tes;
2036*bbecb9d1SAndroid Build Coastguard Worker
2037*bbecb9d1SAndroid Build Coastguard Worker list_add(&sprog->sl[PIPE_SHADER_VERTEX], &vs->programs);
2038*bbecb9d1SAndroid Build Coastguard Worker list_add(&sprog->sl[PIPE_SHADER_FRAGMENT], &fs->programs);
2039*bbecb9d1SAndroid Build Coastguard Worker if (gs)
2040*bbecb9d1SAndroid Build Coastguard Worker list_add(&sprog->sl[PIPE_SHADER_GEOMETRY], &gs->programs);
2041*bbecb9d1SAndroid Build Coastguard Worker if (tcs)
2042*bbecb9d1SAndroid Build Coastguard Worker list_add(&sprog->sl[PIPE_SHADER_TESS_CTRL], &tcs->programs);
2043*bbecb9d1SAndroid Build Coastguard Worker if (tes)
2044*bbecb9d1SAndroid Build Coastguard Worker list_add(&sprog->sl[PIPE_SHADER_TESS_EVAL], &tes->programs);
2045*bbecb9d1SAndroid Build Coastguard Worker
2046*bbecb9d1SAndroid Build Coastguard Worker last_shader = tes ? PIPE_SHADER_TESS_EVAL : (gs ? PIPE_SHADER_GEOMETRY : PIPE_SHADER_FRAGMENT);
2047*bbecb9d1SAndroid Build Coastguard Worker
2048*bbecb9d1SAndroid Build Coastguard Worker sprog->is_pipeline = separable;
2049*bbecb9d1SAndroid Build Coastguard Worker if (sprog->is_pipeline)
2050*bbecb9d1SAndroid Build Coastguard Worker sprog->id.pipeline = pipeline_id;
2051*bbecb9d1SAndroid Build Coastguard Worker else
2052*bbecb9d1SAndroid Build Coastguard Worker sprog->id.program = prog_id;
2053*bbecb9d1SAndroid Build Coastguard Worker
2054*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&sprog->head, &sub_ctx->gl_programs[vs->id & VREND_PROGRAM_NQUEUE_MASK]);
2055*bbecb9d1SAndroid Build Coastguard Worker
2056*bbecb9d1SAndroid Build Coastguard Worker sprog->virgl_block_bind = -1;
2057*bbecb9d1SAndroid Build Coastguard Worker sprog->ubo_sysval_buffer_id = -1;
2058*bbecb9d1SAndroid Build Coastguard Worker
2059*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(sub_ctx, sprog);
2060*bbecb9d1SAndroid Build Coastguard Worker
2061*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type shader_type = PIPE_SHADER_VERTEX;
2062*bbecb9d1SAndroid Build Coastguard Worker shader_type <= last_shader;
2063*bbecb9d1SAndroid Build Coastguard Worker shader_type++) {
2064*bbecb9d1SAndroid Build Coastguard Worker if (!sprog->ss[shader_type])
2065*bbecb9d1SAndroid Build Coastguard Worker continue;
2066*bbecb9d1SAndroid Build Coastguard Worker
2067*bbecb9d1SAndroid Build Coastguard Worker bind_const_locs(sprog, shader_type);
2068*bbecb9d1SAndroid Build Coastguard Worker bind_image_locs(sprog, shader_type);
2069*bbecb9d1SAndroid Build Coastguard Worker bind_ssbo_locs(sprog, shader_type);
2070*bbecb9d1SAndroid Build Coastguard Worker }
2071*bbecb9d1SAndroid Build Coastguard Worker rebind_ubo_and_sampler_locs(sprog, last_shader);
2072*bbecb9d1SAndroid Build Coastguard Worker
2073*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_gles31_vertex_attrib_binding)) {
2074*bbecb9d1SAndroid Build Coastguard Worker if (vs->sel->sinfo.num_inputs) {
2075*bbecb9d1SAndroid Build Coastguard Worker sprog->attrib_locs = calloc(vs->sel->sinfo.num_inputs, sizeof(uint32_t));
2076*bbecb9d1SAndroid Build Coastguard Worker if (sprog->attrib_locs) {
2077*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < vs->sel->sinfo.num_inputs; i++) {
2078*bbecb9d1SAndroid Build Coastguard Worker snprintf(name, 32, "in_%d", i);
2079*bbecb9d1SAndroid Build Coastguard Worker sprog->attrib_locs[i] = glGetAttribLocation(vs_id, name);
2080*bbecb9d1SAndroid Build Coastguard Worker }
2081*bbecb9d1SAndroid Build Coastguard Worker }
2082*bbecb9d1SAndroid Build Coastguard Worker } else
2083*bbecb9d1SAndroid Build Coastguard Worker sprog->attrib_locs = NULL;
2084*bbecb9d1SAndroid Build Coastguard Worker }
2085*bbecb9d1SAndroid Build Coastguard Worker
2086*bbecb9d1SAndroid Build Coastguard Worker return sprog;
2087*bbecb9d1SAndroid Build Coastguard Worker }
2088*bbecb9d1SAndroid Build Coastguard Worker
lookup_cs_shader_program(struct vrend_context * ctx,GLuint cs_id)2089*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_linked_shader_program *lookup_cs_shader_program(struct vrend_context *ctx,
2090*bbecb9d1SAndroid Build Coastguard Worker GLuint cs_id)
2091*bbecb9d1SAndroid Build Coastguard Worker {
2092*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *ent;
2093*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(ent, &ctx->sub->cs_programs, head) {
2094*bbecb9d1SAndroid Build Coastguard Worker if (ent->ss[PIPE_SHADER_COMPUTE]->id == cs_id) {
2095*bbecb9d1SAndroid Build Coastguard Worker list_del(&ent->head);
2096*bbecb9d1SAndroid Build Coastguard Worker list_add(&ent->head, &ctx->sub->cs_programs);
2097*bbecb9d1SAndroid Build Coastguard Worker return ent;
2098*bbecb9d1SAndroid Build Coastguard Worker }
2099*bbecb9d1SAndroid Build Coastguard Worker }
2100*bbecb9d1SAndroid Build Coastguard Worker return NULL;
2101*bbecb9d1SAndroid Build Coastguard Worker }
2102*bbecb9d1SAndroid Build Coastguard Worker
lookup_shader_program(struct vrend_sub_context * sub_ctx,GLuint vs_id,GLuint fs_id,GLuint gs_id,GLuint tcs_id,GLuint tes_id,bool dual_src)2103*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_linked_shader_program *lookup_shader_program(struct vrend_sub_context *sub_ctx,
2104*bbecb9d1SAndroid Build Coastguard Worker GLuint vs_id,
2105*bbecb9d1SAndroid Build Coastguard Worker GLuint fs_id,
2106*bbecb9d1SAndroid Build Coastguard Worker GLuint gs_id,
2107*bbecb9d1SAndroid Build Coastguard Worker GLuint tcs_id,
2108*bbecb9d1SAndroid Build Coastguard Worker GLuint tes_id,
2109*bbecb9d1SAndroid Build Coastguard Worker bool dual_src)
2110*bbecb9d1SAndroid Build Coastguard Worker {
2111*bbecb9d1SAndroid Build Coastguard Worker uint64_t vs_fs_key = (((uint64_t)fs_id) << 32) | (vs_id & ~VREND_PROGRAM_NQUEUE_MASK) |
2112*bbecb9d1SAndroid Build Coastguard Worker (dual_src ? 1 : 0);
2113*bbecb9d1SAndroid Build Coastguard Worker
2114*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *ent;
2115*bbecb9d1SAndroid Build Coastguard Worker
2116*bbecb9d1SAndroid Build Coastguard Worker struct list_head *programs = &sub_ctx->gl_programs[vs_id & VREND_PROGRAM_NQUEUE_MASK];
2117*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(ent, programs, head) {
2118*bbecb9d1SAndroid Build Coastguard Worker if (likely(ent->vs_fs_key != vs_fs_key))
2119*bbecb9d1SAndroid Build Coastguard Worker continue;
2120*bbecb9d1SAndroid Build Coastguard Worker if (ent->ss[PIPE_SHADER_GEOMETRY] &&
2121*bbecb9d1SAndroid Build Coastguard Worker ent->ss[PIPE_SHADER_GEOMETRY]->id != gs_id)
2122*bbecb9d1SAndroid Build Coastguard Worker continue;
2123*bbecb9d1SAndroid Build Coastguard Worker if (ent->ss[PIPE_SHADER_TESS_CTRL] &&
2124*bbecb9d1SAndroid Build Coastguard Worker ent->ss[PIPE_SHADER_TESS_CTRL]->id != tcs_id)
2125*bbecb9d1SAndroid Build Coastguard Worker continue;
2126*bbecb9d1SAndroid Build Coastguard Worker if (ent->ss[PIPE_SHADER_TESS_EVAL] &&
2127*bbecb9d1SAndroid Build Coastguard Worker ent->ss[PIPE_SHADER_TESS_EVAL]->id != tes_id)
2128*bbecb9d1SAndroid Build Coastguard Worker continue;
2129*bbecb9d1SAndroid Build Coastguard Worker /* put the entry in front */
2130*bbecb9d1SAndroid Build Coastguard Worker if (programs->next != &ent->head) {
2131*bbecb9d1SAndroid Build Coastguard Worker list_del(&ent->head);
2132*bbecb9d1SAndroid Build Coastguard Worker list_add(&ent->head, programs);
2133*bbecb9d1SAndroid Build Coastguard Worker }
2134*bbecb9d1SAndroid Build Coastguard Worker return ent;
2135*bbecb9d1SAndroid Build Coastguard Worker }
2136*bbecb9d1SAndroid Build Coastguard Worker
2137*bbecb9d1SAndroid Build Coastguard Worker return NULL;
2138*bbecb9d1SAndroid Build Coastguard Worker }
2139*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_program(struct vrend_linked_shader_program * ent)2140*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_program(struct vrend_linked_shader_program *ent)
2141*bbecb9d1SAndroid Build Coastguard Worker {
2142*bbecb9d1SAndroid Build Coastguard Worker int i;
2143*bbecb9d1SAndroid Build Coastguard Worker if (ent->ref_context && ent->ref_context->prog == ent)
2144*bbecb9d1SAndroid Build Coastguard Worker ent->ref_context->prog = NULL;
2145*bbecb9d1SAndroid Build Coastguard Worker
2146*bbecb9d1SAndroid Build Coastguard Worker if (ent->ubo_sysval_buffer_id != -1) {
2147*bbecb9d1SAndroid Build Coastguard Worker glDeleteBuffers(1, (GLuint *) &ent->ubo_sysval_buffer_id);
2148*bbecb9d1SAndroid Build Coastguard Worker }
2149*bbecb9d1SAndroid Build Coastguard Worker
2150*bbecb9d1SAndroid Build Coastguard Worker if (ent->is_pipeline)
2151*bbecb9d1SAndroid Build Coastguard Worker glDeleteProgramPipelines(1, &ent->id.pipeline);
2152*bbecb9d1SAndroid Build Coastguard Worker else
2153*bbecb9d1SAndroid Build Coastguard Worker glDeleteProgram(ent->id.program);
2154*bbecb9d1SAndroid Build Coastguard Worker
2155*bbecb9d1SAndroid Build Coastguard Worker list_del(&ent->head);
2156*bbecb9d1SAndroid Build Coastguard Worker
2157*bbecb9d1SAndroid Build Coastguard Worker for (i = PIPE_SHADER_VERTEX; i <= PIPE_SHADER_COMPUTE; i++) {
2158*bbecb9d1SAndroid Build Coastguard Worker if (ent->ss[i])
2159*bbecb9d1SAndroid Build Coastguard Worker list_del(&ent->sl[i]);
2160*bbecb9d1SAndroid Build Coastguard Worker free(ent->shadow_samp_mask_locs[i]);
2161*bbecb9d1SAndroid Build Coastguard Worker free(ent->shadow_samp_add_locs[i]);
2162*bbecb9d1SAndroid Build Coastguard Worker free(ent->img_locs[i]);
2163*bbecb9d1SAndroid Build Coastguard Worker }
2164*bbecb9d1SAndroid Build Coastguard Worker free(ent->attrib_locs);
2165*bbecb9d1SAndroid Build Coastguard Worker free(ent);
2166*bbecb9d1SAndroid Build Coastguard Worker }
2167*bbecb9d1SAndroid Build Coastguard Worker
vrend_free_programs(struct vrend_sub_context * sub)2168*bbecb9d1SAndroid Build Coastguard Worker static void vrend_free_programs(struct vrend_sub_context *sub)
2169*bbecb9d1SAndroid Build Coastguard Worker {
2170*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *ent, *tmp;
2171*bbecb9d1SAndroid Build Coastguard Worker
2172*bbecb9d1SAndroid Build Coastguard Worker if (!LIST_IS_EMPTY(&sub->cs_programs)) {
2173*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(ent, tmp, &sub->cs_programs, head)
2174*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_program(ent);
2175*bbecb9d1SAndroid Build Coastguard Worker }
2176*bbecb9d1SAndroid Build Coastguard Worker
2177*bbecb9d1SAndroid Build Coastguard Worker for (unsigned i = 0; i < VREND_PROGRAM_NQUEUES; ++i) {
2178*bbecb9d1SAndroid Build Coastguard Worker if (!LIST_IS_EMPTY(&sub->gl_programs[i])) {
2179*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(ent, tmp, &sub->gl_programs[i], head)
2180*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_program(ent);
2181*bbecb9d1SAndroid Build Coastguard Worker }
2182*bbecb9d1SAndroid Build Coastguard Worker }
2183*bbecb9d1SAndroid Build Coastguard Worker }
2184*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_streamout_object(struct vrend_streamout_object * obj)2185*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_streamout_object(struct vrend_streamout_object *obj)
2186*bbecb9d1SAndroid Build Coastguard Worker {
2187*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
2188*bbecb9d1SAndroid Build Coastguard Worker list_del(&obj->head);
2189*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < obj->num_targets; i++)
2190*bbecb9d1SAndroid Build Coastguard Worker vrend_so_target_reference(&obj->so_targets[i], NULL);
2191*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback2))
2192*bbecb9d1SAndroid Build Coastguard Worker glDeleteTransformFeedbacks(1, &obj->id);
2193*bbecb9d1SAndroid Build Coastguard Worker FREE(obj);
2194*bbecb9d1SAndroid Build Coastguard Worker }
2195*bbecb9d1SAndroid Build Coastguard Worker
vrend_sync_make_current(virgl_gl_context gl_cxt)2196*bbecb9d1SAndroid Build Coastguard Worker void vrend_sync_make_current(virgl_gl_context gl_cxt) {
2197*bbecb9d1SAndroid Build Coastguard Worker GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
2198*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(gl_cxt);
2199*bbecb9d1SAndroid Build Coastguard Worker glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
2200*bbecb9d1SAndroid Build Coastguard Worker glDeleteSync(sync);
2201*bbecb9d1SAndroid Build Coastguard Worker }
2202*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_surface(struct vrend_context * ctx,uint32_t handle,uint32_t res_handle,uint32_t format,uint32_t val0,uint32_t val1,uint32_t nr_samples)2203*bbecb9d1SAndroid Build Coastguard Worker int vrend_create_surface(struct vrend_context *ctx,
2204*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
2205*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle, uint32_t format,
2206*bbecb9d1SAndroid Build Coastguard Worker uint32_t val0, uint32_t val1,
2207*bbecb9d1SAndroid Build Coastguard Worker uint32_t nr_samples)
2208*bbecb9d1SAndroid Build Coastguard Worker {
2209*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf;
2210*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
2211*bbecb9d1SAndroid Build Coastguard Worker uint32_t ret_handle;
2212*bbecb9d1SAndroid Build Coastguard Worker
2213*bbecb9d1SAndroid Build Coastguard Worker if (format >= PIPE_FORMAT_COUNT) {
2214*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
2215*bbecb9d1SAndroid Build Coastguard Worker }
2216*bbecb9d1SAndroid Build Coastguard Worker
2217*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
2218*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
2219*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
2220*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
2221*bbecb9d1SAndroid Build Coastguard Worker }
2222*bbecb9d1SAndroid Build Coastguard Worker
2223*bbecb9d1SAndroid Build Coastguard Worker surf = CALLOC_STRUCT(vrend_surface);
2224*bbecb9d1SAndroid Build Coastguard Worker if (!surf)
2225*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
2226*bbecb9d1SAndroid Build Coastguard Worker
2227*bbecb9d1SAndroid Build Coastguard Worker surf->res_handle = res_handle;
2228*bbecb9d1SAndroid Build Coastguard Worker surf->format = format;
2229*bbecb9d1SAndroid Build Coastguard Worker
2230*bbecb9d1SAndroid Build Coastguard Worker surf->val0 = val0;
2231*bbecb9d1SAndroid Build Coastguard Worker surf->val1 = val1;
2232*bbecb9d1SAndroid Build Coastguard Worker surf->id = res->id;
2233*bbecb9d1SAndroid Build Coastguard Worker surf->nr_samples = nr_samples;
2234*bbecb9d1SAndroid Build Coastguard Worker
2235*bbecb9d1SAndroid Build Coastguard Worker if (!has_bit(res->storage_bits, VREND_STORAGE_GL_BUFFER) &&
2236*bbecb9d1SAndroid Build Coastguard Worker has_bit(res->storage_bits, VREND_STORAGE_GL_IMMUTABLE) &&
2237*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_texture_view)) {
2238*bbecb9d1SAndroid Build Coastguard Worker /* We don't need texture views for buffer objects.
2239*bbecb9d1SAndroid Build Coastguard Worker * Otherwise we only need a texture view if the
2240*bbecb9d1SAndroid Build Coastguard Worker * a) formats differ between the surface and base texture
2241*bbecb9d1SAndroid Build Coastguard Worker * b) we need to map a sub range > 1 layer to a surface,
2242*bbecb9d1SAndroid Build Coastguard Worker * GL can make a single layer fine without a view, and it
2243*bbecb9d1SAndroid Build Coastguard Worker * can map the whole texure fine. In those cases we don't
2244*bbecb9d1SAndroid Build Coastguard Worker * create a texture view.
2245*bbecb9d1SAndroid Build Coastguard Worker */
2246*bbecb9d1SAndroid Build Coastguard Worker int first_layer = surf->val1 & 0xffff;
2247*bbecb9d1SAndroid Build Coastguard Worker int last_layer = (surf->val1 >> 16) & 0xffff;
2248*bbecb9d1SAndroid Build Coastguard Worker
2249*bbecb9d1SAndroid Build Coastguard Worker bool needs_view = first_layer != last_layer &&
2250*bbecb9d1SAndroid Build Coastguard Worker (first_layer != 0 || (last_layer != (int)util_max_layer(&res->base, surf->val0)));
2251*bbecb9d1SAndroid Build Coastguard Worker if (!needs_view && surf->format != res->base.format)
2252*bbecb9d1SAndroid Build Coastguard Worker needs_view = true;
2253*bbecb9d1SAndroid Build Coastguard Worker
2254*bbecb9d1SAndroid Build Coastguard Worker if (needs_view && vrend_resource_supports_view(res, surf->format)) {
2255*bbecb9d1SAndroid Build Coastguard Worker GLenum target = res->target;
2256*bbecb9d1SAndroid Build Coastguard Worker GLenum internalformat = tex_conv_table[format].internalformat;
2257*bbecb9d1SAndroid Build Coastguard Worker
2258*bbecb9d1SAndroid Build Coastguard Worker if (target == GL_TEXTURE_CUBE_MAP && first_layer == last_layer) {
2259*bbecb9d1SAndroid Build Coastguard Worker first_layer = 0;
2260*bbecb9d1SAndroid Build Coastguard Worker last_layer = 5;
2261*bbecb9d1SAndroid Build Coastguard Worker }
2262*bbecb9d1SAndroid Build Coastguard Worker
2263*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_tex, ctx, "Create texture view from %s for %s\n",
2264*bbecb9d1SAndroid Build Coastguard Worker util_format_name(res->base.format),
2265*bbecb9d1SAndroid Build Coastguard Worker util_format_name(surf->format));
2266*bbecb9d1SAndroid Build Coastguard Worker
2267*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &surf->id);
2268*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
2269*bbecb9d1SAndroid Build Coastguard Worker if (target == GL_TEXTURE_1D)
2270*bbecb9d1SAndroid Build Coastguard Worker target = GL_TEXTURE_2D;
2271*bbecb9d1SAndroid Build Coastguard Worker else if (target == GL_TEXTURE_1D_ARRAY)
2272*bbecb9d1SAndroid Build Coastguard Worker target = GL_TEXTURE_2D_ARRAY;
2273*bbecb9d1SAndroid Build Coastguard Worker }
2274*bbecb9d1SAndroid Build Coastguard Worker
2275*bbecb9d1SAndroid Build Coastguard Worker if (target == GL_TEXTURE_RECTANGLE_NV &&
2276*bbecb9d1SAndroid Build Coastguard Worker !(tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TARGET_RECTANGLE)) {
2277*bbecb9d1SAndroid Build Coastguard Worker target = GL_TEXTURE_2D;
2278*bbecb9d1SAndroid Build Coastguard Worker }
2279*bbecb9d1SAndroid Build Coastguard Worker
2280*bbecb9d1SAndroid Build Coastguard Worker glTextureView(surf->id, target, res->id, internalformat,
2281*bbecb9d1SAndroid Build Coastguard Worker 0, res->base.last_level + 1,
2282*bbecb9d1SAndroid Build Coastguard Worker first_layer, last_layer - first_layer + 1);
2283*bbecb9d1SAndroid Build Coastguard Worker }
2284*bbecb9d1SAndroid Build Coastguard Worker }
2285*bbecb9d1SAndroid Build Coastguard Worker
2286*bbecb9d1SAndroid Build Coastguard Worker pipe_reference_init(&surf->reference, 1);
2287*bbecb9d1SAndroid Build Coastguard Worker
2288*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&surf->texture, res);
2289*bbecb9d1SAndroid Build Coastguard Worker
2290*bbecb9d1SAndroid Build Coastguard Worker ret_handle = vrend_renderer_object_insert(ctx, surf, handle, VIRGL_OBJECT_SURFACE);
2291*bbecb9d1SAndroid Build Coastguard Worker if (ret_handle == 0) {
2292*bbecb9d1SAndroid Build Coastguard Worker FREE(surf);
2293*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
2294*bbecb9d1SAndroid Build Coastguard Worker }
2295*bbecb9d1SAndroid Build Coastguard Worker return 0;
2296*bbecb9d1SAndroid Build Coastguard Worker }
2297*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_surface_object(void * obj_ptr)2298*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_surface_object(void *obj_ptr)
2299*bbecb9d1SAndroid Build Coastguard Worker {
2300*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surface = obj_ptr;
2301*bbecb9d1SAndroid Build Coastguard Worker
2302*bbecb9d1SAndroid Build Coastguard Worker vrend_surface_reference(&surface, NULL);
2303*bbecb9d1SAndroid Build Coastguard Worker }
2304*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_sampler_view_object(void * obj_ptr)2305*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_sampler_view_object(void *obj_ptr)
2306*bbecb9d1SAndroid Build Coastguard Worker {
2307*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *samp = obj_ptr;
2308*bbecb9d1SAndroid Build Coastguard Worker
2309*bbecb9d1SAndroid Build Coastguard Worker vrend_sampler_view_reference(&samp, NULL);
2310*bbecb9d1SAndroid Build Coastguard Worker }
2311*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_so_target_object(void * obj_ptr)2312*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_so_target_object(void *obj_ptr)
2313*bbecb9d1SAndroid Build Coastguard Worker {
2314*bbecb9d1SAndroid Build Coastguard Worker struct vrend_so_target *target = obj_ptr;
2315*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx = target->sub_ctx;
2316*bbecb9d1SAndroid Build Coastguard Worker struct vrend_streamout_object *obj, *tmp;
2317*bbecb9d1SAndroid Build Coastguard Worker bool found;
2318*bbecb9d1SAndroid Build Coastguard Worker unsigned i;
2319*bbecb9d1SAndroid Build Coastguard Worker
2320*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(obj, tmp, &sub_ctx->streamout_list, head) {
2321*bbecb9d1SAndroid Build Coastguard Worker found = false;
2322*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < obj->num_targets; i++) {
2323*bbecb9d1SAndroid Build Coastguard Worker if (obj->so_targets[i] == target) {
2324*bbecb9d1SAndroid Build Coastguard Worker found = true;
2325*bbecb9d1SAndroid Build Coastguard Worker break;
2326*bbecb9d1SAndroid Build Coastguard Worker }
2327*bbecb9d1SAndroid Build Coastguard Worker }
2328*bbecb9d1SAndroid Build Coastguard Worker if (found) {
2329*bbecb9d1SAndroid Build Coastguard Worker if (obj == sub_ctx->current_so)
2330*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->current_so = NULL;
2331*bbecb9d1SAndroid Build Coastguard Worker if (obj->xfb_state == XFB_STATE_PAUSED) {
2332*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback2))
2333*bbecb9d1SAndroid Build Coastguard Worker glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, obj->id);
2334*bbecb9d1SAndroid Build Coastguard Worker glEndTransformFeedback();
2335*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->current_so && has_feature(feat_transform_feedback2))
2336*bbecb9d1SAndroid Build Coastguard Worker glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, sub_ctx->current_so->id);
2337*bbecb9d1SAndroid Build Coastguard Worker }
2338*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_streamout_object(obj);
2339*bbecb9d1SAndroid Build Coastguard Worker }
2340*bbecb9d1SAndroid Build Coastguard Worker }
2341*bbecb9d1SAndroid Build Coastguard Worker
2342*bbecb9d1SAndroid Build Coastguard Worker vrend_so_target_reference(&target, NULL);
2343*bbecb9d1SAndroid Build Coastguard Worker }
2344*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_vertex_elements_object(void * obj_ptr)2345*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_vertex_elements_object(void *obj_ptr)
2346*bbecb9d1SAndroid Build Coastguard Worker {
2347*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element_array *v = obj_ptr;
2348*bbecb9d1SAndroid Build Coastguard Worker
2349*bbecb9d1SAndroid Build Coastguard Worker if (v == v->owning_sub->ve)
2350*bbecb9d1SAndroid Build Coastguard Worker v->owning_sub->ve = NULL;
2351*bbecb9d1SAndroid Build Coastguard Worker
2352*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gles31_vertex_attrib_binding)) {
2353*bbecb9d1SAndroid Build Coastguard Worker glDeleteVertexArrays(1, &v->id);
2354*bbecb9d1SAndroid Build Coastguard Worker }
2355*bbecb9d1SAndroid Build Coastguard Worker FREE(v);
2356*bbecb9d1SAndroid Build Coastguard Worker }
2357*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_sampler_state_object(void * obj_ptr)2358*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_sampler_state_object(void *obj_ptr)
2359*bbecb9d1SAndroid Build Coastguard Worker {
2360*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_state *state = obj_ptr;
2361*bbecb9d1SAndroid Build Coastguard Worker
2362*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_samplers))
2363*bbecb9d1SAndroid Build Coastguard Worker glDeleteSamplers(2, state->ids);
2364*bbecb9d1SAndroid Build Coastguard Worker FREE(state);
2365*bbecb9d1SAndroid Build Coastguard Worker }
2366*bbecb9d1SAndroid Build Coastguard Worker
convert_wrap(int wrap)2367*bbecb9d1SAndroid Build Coastguard Worker static GLuint convert_wrap(int wrap)
2368*bbecb9d1SAndroid Build Coastguard Worker {
2369*bbecb9d1SAndroid Build Coastguard Worker switch(wrap){
2370*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_REPEAT: return GL_REPEAT;
2371*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_CLAMP: if (vrend_state.use_core_profile == false) return GL_CLAMP; else return GL_CLAMP_TO_EDGE;
2372*bbecb9d1SAndroid Build Coastguard Worker
2373*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_CLAMP_TO_EDGE: return GL_CLAMP_TO_EDGE;
2374*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return GL_CLAMP_TO_BORDER;
2375*bbecb9d1SAndroid Build Coastguard Worker
2376*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_MIRROR_REPEAT: return GL_MIRRORED_REPEAT;
2377*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_MIRROR_CLAMP: return GL_MIRROR_CLAMP_EXT;
2378*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: return GL_MIRROR_CLAMP_TO_EDGE_EXT;
2379*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: return GL_MIRROR_CLAMP_TO_BORDER_EXT;
2380*bbecb9d1SAndroid Build Coastguard Worker default:
2381*bbecb9d1SAndroid Build Coastguard Worker assert(0);
2382*bbecb9d1SAndroid Build Coastguard Worker return -1;
2383*bbecb9d1SAndroid Build Coastguard Worker }
2384*bbecb9d1SAndroid Build Coastguard Worker }
2385*bbecb9d1SAndroid Build Coastguard Worker
convert_mag_filter(enum pipe_tex_filter filter)2386*bbecb9d1SAndroid Build Coastguard Worker static inline GLenum convert_mag_filter(enum pipe_tex_filter filter)
2387*bbecb9d1SAndroid Build Coastguard Worker {
2388*bbecb9d1SAndroid Build Coastguard Worker if (filter == PIPE_TEX_FILTER_NEAREST)
2389*bbecb9d1SAndroid Build Coastguard Worker return GL_NEAREST;
2390*bbecb9d1SAndroid Build Coastguard Worker return GL_LINEAR;
2391*bbecb9d1SAndroid Build Coastguard Worker }
2392*bbecb9d1SAndroid Build Coastguard Worker
convert_min_filter(enum pipe_tex_filter filter,enum pipe_tex_mipfilter mip_filter)2393*bbecb9d1SAndroid Build Coastguard Worker static inline GLenum convert_min_filter(enum pipe_tex_filter filter, enum pipe_tex_mipfilter mip_filter)
2394*bbecb9d1SAndroid Build Coastguard Worker {
2395*bbecb9d1SAndroid Build Coastguard Worker if (mip_filter == PIPE_TEX_MIPFILTER_NONE)
2396*bbecb9d1SAndroid Build Coastguard Worker return convert_mag_filter(filter);
2397*bbecb9d1SAndroid Build Coastguard Worker else if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
2398*bbecb9d1SAndroid Build Coastguard Worker if (filter == PIPE_TEX_FILTER_NEAREST)
2399*bbecb9d1SAndroid Build Coastguard Worker return GL_NEAREST_MIPMAP_LINEAR;
2400*bbecb9d1SAndroid Build Coastguard Worker else
2401*bbecb9d1SAndroid Build Coastguard Worker return GL_LINEAR_MIPMAP_LINEAR;
2402*bbecb9d1SAndroid Build Coastguard Worker } else if (mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
2403*bbecb9d1SAndroid Build Coastguard Worker if (filter == PIPE_TEX_FILTER_NEAREST)
2404*bbecb9d1SAndroid Build Coastguard Worker return GL_NEAREST_MIPMAP_NEAREST;
2405*bbecb9d1SAndroid Build Coastguard Worker else
2406*bbecb9d1SAndroid Build Coastguard Worker return GL_LINEAR_MIPMAP_NEAREST;
2407*bbecb9d1SAndroid Build Coastguard Worker }
2408*bbecb9d1SAndroid Build Coastguard Worker assert(0);
2409*bbecb9d1SAndroid Build Coastguard Worker return 0;
2410*bbecb9d1SAndroid Build Coastguard Worker }
2411*bbecb9d1SAndroid Build Coastguard Worker
apply_sampler_border_color(GLuint sampler,const GLuint colors[static4])2412*bbecb9d1SAndroid Build Coastguard Worker static void apply_sampler_border_color(GLuint sampler,
2413*bbecb9d1SAndroid Build Coastguard Worker const GLuint colors[static 4])
2414*bbecb9d1SAndroid Build Coastguard Worker {
2415*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_sampler_border_colors)) {
2416*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameterIuiv(sampler, GL_TEXTURE_BORDER_COLOR, colors);
2417*bbecb9d1SAndroid Build Coastguard Worker } else if (colors[0] || colors[1] || colors[2] || colors[3]) {
2418*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("sampler border color setting requested but not supported\n");
2419*bbecb9d1SAndroid Build Coastguard Worker }
2420*bbecb9d1SAndroid Build Coastguard Worker }
2421*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_sampler_state(struct vrend_context * ctx,uint32_t handle,struct pipe_sampler_state * templ)2422*bbecb9d1SAndroid Build Coastguard Worker int vrend_create_sampler_state(struct vrend_context *ctx,
2423*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
2424*bbecb9d1SAndroid Build Coastguard Worker struct pipe_sampler_state *templ)
2425*bbecb9d1SAndroid Build Coastguard Worker {
2426*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_state *state = CALLOC_STRUCT(vrend_sampler_state);
2427*bbecb9d1SAndroid Build Coastguard Worker int ret_handle;
2428*bbecb9d1SAndroid Build Coastguard Worker
2429*bbecb9d1SAndroid Build Coastguard Worker if (!state)
2430*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
2431*bbecb9d1SAndroid Build Coastguard Worker
2432*bbecb9d1SAndroid Build Coastguard Worker state->base = *templ;
2433*bbecb9d1SAndroid Build Coastguard Worker
2434*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_samplers)) {
2435*bbecb9d1SAndroid Build Coastguard Worker glGenSamplers(2, state->ids);
2436*bbecb9d1SAndroid Build Coastguard Worker
2437*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < 2; ++i) {
2438*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameteri(state->ids[i], GL_TEXTURE_WRAP_S, convert_wrap(templ->wrap_s));
2439*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameteri(state->ids[i], GL_TEXTURE_WRAP_T, convert_wrap(templ->wrap_t));
2440*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameteri(state->ids[i], GL_TEXTURE_WRAP_R, convert_wrap(templ->wrap_r));
2441*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameterf(state->ids[i], GL_TEXTURE_MIN_FILTER, convert_min_filter(templ->min_img_filter, templ->min_mip_filter));
2442*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameterf(state->ids[i], GL_TEXTURE_MAG_FILTER, convert_mag_filter(templ->mag_img_filter));
2443*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameterf(state->ids[i], GL_TEXTURE_MIN_LOD, templ->min_lod);
2444*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameterf(state->ids[i], GL_TEXTURE_MAX_LOD, templ->max_lod);
2445*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameteri(state->ids[i], GL_TEXTURE_COMPARE_MODE, templ->compare_mode ? GL_COMPARE_R_TO_TEXTURE : GL_NONE);
2446*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameteri(state->ids[i], GL_TEXTURE_COMPARE_FUNC, GL_NEVER + templ->compare_func);
2447*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
2448*bbecb9d1SAndroid Build Coastguard Worker if (templ->lod_bias)
2449*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_LOD_BIAS);
2450*bbecb9d1SAndroid Build Coastguard Worker } else
2451*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameterf(state->ids[i], GL_TEXTURE_LOD_BIAS, templ->lod_bias);
2452*bbecb9d1SAndroid Build Coastguard Worker
2453*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
2454*bbecb9d1SAndroid Build Coastguard Worker if (templ->seamless_cube_map != 0) {
2455*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_SEAMLESS_CUBE_MAP);
2456*bbecb9d1SAndroid Build Coastguard Worker }
2457*bbecb9d1SAndroid Build Coastguard Worker } else {
2458*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameteri(state->ids[i], GL_TEXTURE_CUBE_MAP_SEAMLESS, templ->seamless_cube_map);
2459*bbecb9d1SAndroid Build Coastguard Worker
2460*bbecb9d1SAndroid Build Coastguard Worker }
2461*bbecb9d1SAndroid Build Coastguard Worker
2462*bbecb9d1SAndroid Build Coastguard Worker apply_sampler_border_color(state->ids[i], templ->border_color.ui);
2463*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_srgb_decode))
2464*bbecb9d1SAndroid Build Coastguard Worker glSamplerParameteri(state->ids[i], GL_TEXTURE_SRGB_DECODE_EXT,
2465*bbecb9d1SAndroid Build Coastguard Worker i == 0 ? GL_SKIP_DECODE_EXT : GL_DECODE_EXT);
2466*bbecb9d1SAndroid Build Coastguard Worker }
2467*bbecb9d1SAndroid Build Coastguard Worker }
2468*bbecb9d1SAndroid Build Coastguard Worker ret_handle = vrend_renderer_object_insert(ctx, state, handle,
2469*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_SAMPLER_STATE);
2470*bbecb9d1SAndroid Build Coastguard Worker if (!ret_handle) {
2471*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_samplers))
2472*bbecb9d1SAndroid Build Coastguard Worker glDeleteSamplers(2, state->ids);
2473*bbecb9d1SAndroid Build Coastguard Worker FREE(state);
2474*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
2475*bbecb9d1SAndroid Build Coastguard Worker }
2476*bbecb9d1SAndroid Build Coastguard Worker return 0;
2477*bbecb9d1SAndroid Build Coastguard Worker }
2478*bbecb9d1SAndroid Build Coastguard Worker
to_gl_swizzle(enum pipe_swizzle swizzle)2479*bbecb9d1SAndroid Build Coastguard Worker static inline GLenum to_gl_swizzle(enum pipe_swizzle swizzle)
2480*bbecb9d1SAndroid Build Coastguard Worker {
2481*bbecb9d1SAndroid Build Coastguard Worker switch (swizzle) {
2482*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SWIZZLE_RED: return GL_RED;
2483*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SWIZZLE_GREEN: return GL_GREEN;
2484*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SWIZZLE_BLUE: return GL_BLUE;
2485*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SWIZZLE_ALPHA: return GL_ALPHA;
2486*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SWIZZLE_ZERO: return GL_ZERO;
2487*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SWIZZLE_ONE: return GL_ONE;
2488*bbecb9d1SAndroid Build Coastguard Worker default:
2489*bbecb9d1SAndroid Build Coastguard Worker assert(0);
2490*bbecb9d1SAndroid Build Coastguard Worker return 0;
2491*bbecb9d1SAndroid Build Coastguard Worker }
2492*bbecb9d1SAndroid Build Coastguard Worker }
2493*bbecb9d1SAndroid Build Coastguard Worker
to_pipe_swizzle(GLenum swizzle)2494*bbecb9d1SAndroid Build Coastguard Worker static inline enum pipe_swizzle to_pipe_swizzle(GLenum swizzle)
2495*bbecb9d1SAndroid Build Coastguard Worker {
2496*bbecb9d1SAndroid Build Coastguard Worker switch (swizzle) {
2497*bbecb9d1SAndroid Build Coastguard Worker case GL_RED: return PIPE_SWIZZLE_RED;
2498*bbecb9d1SAndroid Build Coastguard Worker case GL_GREEN: return PIPE_SWIZZLE_GREEN;
2499*bbecb9d1SAndroid Build Coastguard Worker case GL_BLUE: return PIPE_SWIZZLE_BLUE;
2500*bbecb9d1SAndroid Build Coastguard Worker case GL_ALPHA: return PIPE_SWIZZLE_ALPHA;
2501*bbecb9d1SAndroid Build Coastguard Worker case GL_ZERO: return PIPE_SWIZZLE_ZERO;
2502*bbecb9d1SAndroid Build Coastguard Worker case GL_ONE: return PIPE_SWIZZLE_ONE;
2503*bbecb9d1SAndroid Build Coastguard Worker default:
2504*bbecb9d1SAndroid Build Coastguard Worker assert(0);
2505*bbecb9d1SAndroid Build Coastguard Worker return 0;
2506*bbecb9d1SAndroid Build Coastguard Worker }
2507*bbecb9d1SAndroid Build Coastguard Worker }
2508*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_sampler_view(struct vrend_context * ctx,uint32_t handle,uint32_t res_handle,uint32_t format,uint32_t val0,uint32_t val1,uint32_t swizzle_packed)2509*bbecb9d1SAndroid Build Coastguard Worker int vrend_create_sampler_view(struct vrend_context *ctx,
2510*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
2511*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle, uint32_t format,
2512*bbecb9d1SAndroid Build Coastguard Worker uint32_t val0, uint32_t val1, uint32_t swizzle_packed)
2513*bbecb9d1SAndroid Build Coastguard Worker {
2514*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *view;
2515*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
2516*bbecb9d1SAndroid Build Coastguard Worker int ret_handle;
2517*bbecb9d1SAndroid Build Coastguard Worker uint8_t swizzle[4];
2518*bbecb9d1SAndroid Build Coastguard Worker
2519*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
2520*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
2521*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
2522*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
2523*bbecb9d1SAndroid Build Coastguard Worker }
2524*bbecb9d1SAndroid Build Coastguard Worker
2525*bbecb9d1SAndroid Build Coastguard Worker view = CALLOC_STRUCT(vrend_sampler_view);
2526*bbecb9d1SAndroid Build Coastguard Worker if (!view)
2527*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
2528*bbecb9d1SAndroid Build Coastguard Worker
2529*bbecb9d1SAndroid Build Coastguard Worker pipe_reference_init(&view->reference, 1);
2530*bbecb9d1SAndroid Build Coastguard Worker view->format = format & 0xffffff;
2531*bbecb9d1SAndroid Build Coastguard Worker
2532*bbecb9d1SAndroid Build Coastguard Worker if (!view->format || view->format >= VIRGL_FORMAT_MAX) {
2533*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_FORMAT, view->format);
2534*bbecb9d1SAndroid Build Coastguard Worker FREE(view);
2535*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
2536*bbecb9d1SAndroid Build Coastguard Worker }
2537*bbecb9d1SAndroid Build Coastguard Worker
2538*bbecb9d1SAndroid Build Coastguard Worker uint32_t pipe_target = (format >> 24) & 0xff;
2539*bbecb9d1SAndroid Build Coastguard Worker if (pipe_target >= PIPE_MAX_TEXTURE_TYPES) {
2540*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SAMPLER_VIEW_TARGET,
2541*bbecb9d1SAndroid Build Coastguard Worker view->format);
2542*bbecb9d1SAndroid Build Coastguard Worker FREE(view);
2543*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
2544*bbecb9d1SAndroid Build Coastguard Worker }
2545*bbecb9d1SAndroid Build Coastguard Worker
2546*bbecb9d1SAndroid Build Coastguard Worker view->target = tgsitargettogltarget(pipe_target, res->base.nr_samples);
2547*bbecb9d1SAndroid Build Coastguard Worker
2548*bbecb9d1SAndroid Build Coastguard Worker /* Work around TEXTURE_1D missing on GLES */
2549*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
2550*bbecb9d1SAndroid Build Coastguard Worker if (view->target == GL_TEXTURE_1D)
2551*bbecb9d1SAndroid Build Coastguard Worker view->target = GL_TEXTURE_2D;
2552*bbecb9d1SAndroid Build Coastguard Worker else if (view->target == GL_TEXTURE_1D_ARRAY)
2553*bbecb9d1SAndroid Build Coastguard Worker view->target = GL_TEXTURE_2D_ARRAY;
2554*bbecb9d1SAndroid Build Coastguard Worker }
2555*bbecb9d1SAndroid Build Coastguard Worker
2556*bbecb9d1SAndroid Build Coastguard Worker if (view->target == GL_TEXTURE_RECTANGLE_NV &&
2557*bbecb9d1SAndroid Build Coastguard Worker !(tex_conv_table[view->format].flags & VIRGL_TEXTURE_CAN_TARGET_RECTANGLE)) {
2558*bbecb9d1SAndroid Build Coastguard Worker view->emulated_rect = true;
2559*bbecb9d1SAndroid Build Coastguard Worker view->target = GL_TEXTURE_2D;
2560*bbecb9d1SAndroid Build Coastguard Worker }
2561*bbecb9d1SAndroid Build Coastguard Worker
2562*bbecb9d1SAndroid Build Coastguard Worker view->val0 = val0;
2563*bbecb9d1SAndroid Build Coastguard Worker view->val1 = val1;
2564*bbecb9d1SAndroid Build Coastguard Worker
2565*bbecb9d1SAndroid Build Coastguard Worker swizzle[0] = swizzle_packed & 0x7;
2566*bbecb9d1SAndroid Build Coastguard Worker swizzle[1] = (swizzle_packed >> 3) & 0x7;
2567*bbecb9d1SAndroid Build Coastguard Worker swizzle[2] = (swizzle_packed >> 6) & 0x7;
2568*bbecb9d1SAndroid Build Coastguard Worker swizzle[3] = (swizzle_packed >> 9) & 0x7;
2569*bbecb9d1SAndroid Build Coastguard Worker
2570*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&view->texture, res);
2571*bbecb9d1SAndroid Build Coastguard Worker
2572*bbecb9d1SAndroid Build Coastguard Worker view->id = view->texture->id;
2573*bbecb9d1SAndroid Build Coastguard Worker if (view->target == PIPE_BUFFER)
2574*bbecb9d1SAndroid Build Coastguard Worker view->target = view->texture->target;
2575*bbecb9d1SAndroid Build Coastguard Worker
2576*bbecb9d1SAndroid Build Coastguard Worker view->srgb_decode = GL_DECODE_EXT;
2577*bbecb9d1SAndroid Build Coastguard Worker if (view->format != view->texture->base.format) {
2578*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_srgb(view->texture->base.format) &&
2579*bbecb9d1SAndroid Build Coastguard Worker !util_format_is_srgb(view->format))
2580*bbecb9d1SAndroid Build Coastguard Worker view->srgb_decode = GL_SKIP_DECODE_EXT;
2581*bbecb9d1SAndroid Build Coastguard Worker }
2582*bbecb9d1SAndroid Build Coastguard Worker
2583*bbecb9d1SAndroid Build Coastguard Worker if (!(util_format_has_alpha(view->format) || util_format_is_depth_or_stencil(view->format))) {
2584*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[0] == PIPE_SWIZZLE_ALPHA)
2585*bbecb9d1SAndroid Build Coastguard Worker swizzle[0] = PIPE_SWIZZLE_ONE;
2586*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[1] == PIPE_SWIZZLE_ALPHA)
2587*bbecb9d1SAndroid Build Coastguard Worker swizzle[1] = PIPE_SWIZZLE_ONE;
2588*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[2] == PIPE_SWIZZLE_ALPHA)
2589*bbecb9d1SAndroid Build Coastguard Worker swizzle[2] = PIPE_SWIZZLE_ONE;
2590*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[3] == PIPE_SWIZZLE_ALPHA)
2591*bbecb9d1SAndroid Build Coastguard Worker swizzle[3] = PIPE_SWIZZLE_ONE;
2592*bbecb9d1SAndroid Build Coastguard Worker }
2593*bbecb9d1SAndroid Build Coastguard Worker
2594*bbecb9d1SAndroid Build Coastguard Worker if (tex_conv_table[view->format].flags & VIRGL_TEXTURE_NEED_SWIZZLE) {
2595*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[0] <= PIPE_SWIZZLE_ALPHA)
2596*bbecb9d1SAndroid Build Coastguard Worker swizzle[0] = tex_conv_table[view->format].swizzle[swizzle[0]];
2597*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[1] <= PIPE_SWIZZLE_ALPHA)
2598*bbecb9d1SAndroid Build Coastguard Worker swizzle[1] = tex_conv_table[view->format].swizzle[swizzle[1]];
2599*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[2] <= PIPE_SWIZZLE_ALPHA)
2600*bbecb9d1SAndroid Build Coastguard Worker swizzle[2] = tex_conv_table[view->format].swizzle[swizzle[2]];
2601*bbecb9d1SAndroid Build Coastguard Worker if (swizzle[3] <= PIPE_SWIZZLE_ALPHA)
2602*bbecb9d1SAndroid Build Coastguard Worker swizzle[3] = tex_conv_table[view->format].swizzle[swizzle[3]];
2603*bbecb9d1SAndroid Build Coastguard Worker }
2604*bbecb9d1SAndroid Build Coastguard Worker
2605*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_swizzle i = 0; i < 4; ++i)
2606*bbecb9d1SAndroid Build Coastguard Worker view->gl_swizzle[i] = to_gl_swizzle(swizzle[i]);
2607*bbecb9d1SAndroid Build Coastguard Worker
2608*bbecb9d1SAndroid Build Coastguard Worker if (!has_bit(view->texture->storage_bits, VREND_STORAGE_GL_BUFFER)) {
2609*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats format;
2610*bbecb9d1SAndroid Build Coastguard Worker bool needs_view = false;
2611*bbecb9d1SAndroid Build Coastguard Worker
2612*bbecb9d1SAndroid Build Coastguard Worker /*
2613*bbecb9d1SAndroid Build Coastguard Worker * Need to use a texture view if the gallium
2614*bbecb9d1SAndroid Build Coastguard Worker * view target is different than the underlying
2615*bbecb9d1SAndroid Build Coastguard Worker * texture target.
2616*bbecb9d1SAndroid Build Coastguard Worker */
2617*bbecb9d1SAndroid Build Coastguard Worker if (view->target != view->texture->target)
2618*bbecb9d1SAndroid Build Coastguard Worker needs_view = true;
2619*bbecb9d1SAndroid Build Coastguard Worker
2620*bbecb9d1SAndroid Build Coastguard Worker /*
2621*bbecb9d1SAndroid Build Coastguard Worker * If the formats are different and this isn't
2622*bbecb9d1SAndroid Build Coastguard Worker * a DS texture a view is required.
2623*bbecb9d1SAndroid Build Coastguard Worker * DS are special as they use different gallium
2624*bbecb9d1SAndroid Build Coastguard Worker * formats for DS views into a combined resource.
2625*bbecb9d1SAndroid Build Coastguard Worker * GL texture views can't be use for this, stencil
2626*bbecb9d1SAndroid Build Coastguard Worker * texturing is used instead. For DS formats
2627*bbecb9d1SAndroid Build Coastguard Worker * aways program the underlying DS format as a
2628*bbecb9d1SAndroid Build Coastguard Worker * view could be required for layers.
2629*bbecb9d1SAndroid Build Coastguard Worker */
2630*bbecb9d1SAndroid Build Coastguard Worker format = view->format;
2631*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_depth_or_stencil(view->texture->base.format))
2632*bbecb9d1SAndroid Build Coastguard Worker format = view->texture->base.format;
2633*bbecb9d1SAndroid Build Coastguard Worker else if (view->format != view->texture->base.format)
2634*bbecb9d1SAndroid Build Coastguard Worker needs_view = true;
2635*bbecb9d1SAndroid Build Coastguard Worker
2636*bbecb9d1SAndroid Build Coastguard Worker if (needs_view &&
2637*bbecb9d1SAndroid Build Coastguard Worker has_bit(view->texture->storage_bits, VREND_STORAGE_GL_IMMUTABLE) &&
2638*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_texture_view)) {
2639*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &view->id);
2640*bbecb9d1SAndroid Build Coastguard Worker GLenum internalformat = tex_conv_table[format].internalformat;
2641*bbecb9d1SAndroid Build Coastguard Worker unsigned base_layer = view->val0 & 0xffff;
2642*bbecb9d1SAndroid Build Coastguard Worker unsigned max_layer = (view->val0 >> 16) & 0xffff;
2643*bbecb9d1SAndroid Build Coastguard Worker int base_level = view->val1 & 0xff;
2644*bbecb9d1SAndroid Build Coastguard Worker int max_level = (view->val1 >> 8) & 0xff;
2645*bbecb9d1SAndroid Build Coastguard Worker view->levels = (max_level - base_level) + 1;
2646*bbecb9d1SAndroid Build Coastguard Worker
2647*bbecb9d1SAndroid Build Coastguard Worker /* texture views for eglimage-backed bgr* resources are usually not
2648*bbecb9d1SAndroid Build Coastguard Worker * supported since they cause unintended red/blue channel-swapping.
2649*bbecb9d1SAndroid Build Coastguard Worker * Since we have control over the swizzle parameters of the sampler, we
2650*bbecb9d1SAndroid Build Coastguard Worker * can just compensate in this case by swapping the red/blue channels
2651*bbecb9d1SAndroid Build Coastguard Worker * back, and still benefit from automatic srgb decoding.
2652*bbecb9d1SAndroid Build Coastguard Worker * If the red/blue swap is intended, we just let it happen and don't
2653*bbecb9d1SAndroid Build Coastguard Worker * need to explicit change to the sampler's swizzle parameters. */
2654*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_resource_supports_view(view->texture, view->format) &&
2655*bbecb9d1SAndroid Build Coastguard Worker vrend_format_is_bgra(view->format)) {
2656*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_tex, ctx, "texture view with red/blue swizzle created for EGL-backed texture sampler"
2657*bbecb9d1SAndroid Build Coastguard Worker " (format: %s; view: %s)\n",
2658*bbecb9d1SAndroid Build Coastguard Worker util_format_name(view->texture->base.format),
2659*bbecb9d1SAndroid Build Coastguard Worker util_format_name(view->format));
2660*bbecb9d1SAndroid Build Coastguard Worker GLint temp = view->gl_swizzle[0];
2661*bbecb9d1SAndroid Build Coastguard Worker view->gl_swizzle[0] = view->gl_swizzle[2];
2662*bbecb9d1SAndroid Build Coastguard Worker view->gl_swizzle[2] = temp;
2663*bbecb9d1SAndroid Build Coastguard Worker }
2664*bbecb9d1SAndroid Build Coastguard Worker
2665*bbecb9d1SAndroid Build Coastguard Worker glTextureView(view->id, view->target, view->texture->id, internalformat,
2666*bbecb9d1SAndroid Build Coastguard Worker base_level, view->levels,
2667*bbecb9d1SAndroid Build Coastguard Worker base_layer, max_layer - base_layer + 1);
2668*bbecb9d1SAndroid Build Coastguard Worker
2669*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(view->target, view->id);
2670*bbecb9d1SAndroid Build Coastguard Worker
2671*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_depth_or_stencil(view->format)) {
2672*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false) {
2673*bbecb9d1SAndroid Build Coastguard Worker /* setting depth texture mode is deprecated in core profile */
2674*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->target, GL_DEPTH_TEXTURE_MODE, GL_RED);
2675*bbecb9d1SAndroid Build Coastguard Worker }
2676*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_stencil_texturing)) {
2677*bbecb9d1SAndroid Build Coastguard Worker const struct util_format_description *desc = util_format_description(view->format);
2678*bbecb9d1SAndroid Build Coastguard Worker if (!util_format_has_depth(desc)) {
2679*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
2680*bbecb9d1SAndroid Build Coastguard Worker } else {
2681*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
2682*bbecb9d1SAndroid Build Coastguard Worker }
2683*bbecb9d1SAndroid Build Coastguard Worker }
2684*bbecb9d1SAndroid Build Coastguard Worker }
2685*bbecb9d1SAndroid Build Coastguard Worker
2686*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->target, GL_TEXTURE_BASE_LEVEL, base_level);
2687*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->target, GL_TEXTURE_MAX_LEVEL, max_level);
2688*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
2689*bbecb9d1SAndroid Build Coastguard Worker for (unsigned int i = 0; i < 4; ++i) {
2690*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->target, GL_TEXTURE_SWIZZLE_R + i, view->gl_swizzle[i]);
2691*bbecb9d1SAndroid Build Coastguard Worker }
2692*bbecb9d1SAndroid Build Coastguard Worker } else
2693*bbecb9d1SAndroid Build Coastguard Worker glTexParameteriv(view->target, GL_TEXTURE_SWIZZLE_RGBA, view->gl_swizzle);
2694*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_srgb(view->format) &&
2695*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_texture_srgb_decode)) {
2696*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->target, GL_TEXTURE_SRGB_DECODE_EXT,
2697*bbecb9d1SAndroid Build Coastguard Worker view->srgb_decode);
2698*bbecb9d1SAndroid Build Coastguard Worker }
2699*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(view->target, 0);
2700*bbecb9d1SAndroid Build Coastguard Worker } else if (needs_view && view->val0 < ARRAY_SIZE(res->aux_plane_egl_image) &&
2701*bbecb9d1SAndroid Build Coastguard Worker res->aux_plane_egl_image[view->val0]) {
2702*bbecb9d1SAndroid Build Coastguard Worker void *image = res->aux_plane_egl_image[view->val0];
2703*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &view->id);
2704*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(view->target, view->id);
2705*bbecb9d1SAndroid Build Coastguard Worker glEGLImageTargetTexture2DOES(view->target, (GLeglImageOES) image);
2706*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(view->target, 0);
2707*bbecb9d1SAndroid Build Coastguard Worker }
2708*bbecb9d1SAndroid Build Coastguard Worker }
2709*bbecb9d1SAndroid Build Coastguard Worker
2710*bbecb9d1SAndroid Build Coastguard Worker ret_handle = vrend_renderer_object_insert(ctx, view, handle, VIRGL_OBJECT_SAMPLER_VIEW);
2711*bbecb9d1SAndroid Build Coastguard Worker if (ret_handle == 0) {
2712*bbecb9d1SAndroid Build Coastguard Worker FREE(view);
2713*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
2714*bbecb9d1SAndroid Build Coastguard Worker }
2715*bbecb9d1SAndroid Build Coastguard Worker return 0;
2716*bbecb9d1SAndroid Build Coastguard Worker }
2717*bbecb9d1SAndroid Build Coastguard Worker
vrend_framebuffer_texture_2d(struct vrend_resource * res,GLenum target,GLenum attachment,GLenum textarget,uint32_t texture,int32_t level,uint32_t samples)2718*bbecb9d1SAndroid Build Coastguard Worker static void vrend_framebuffer_texture_2d(struct vrend_resource *res,
2719*bbecb9d1SAndroid Build Coastguard Worker GLenum target, GLenum attachment,
2720*bbecb9d1SAndroid Build Coastguard Worker GLenum textarget, uint32_t texture,
2721*bbecb9d1SAndroid Build Coastguard Worker int32_t level, uint32_t samples)
2722*bbecb9d1SAndroid Build Coastguard Worker {
2723*bbecb9d1SAndroid Build Coastguard Worker if (samples == 0) {
2724*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(target, attachment, textarget, texture, level);
2725*bbecb9d1SAndroid Build Coastguard Worker } else if (!has_feature(feat_implicit_msaa)) {
2726*bbecb9d1SAndroid Build Coastguard Worker /* fallback to non-msaa */
2727*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(vrend_state.current_ctx, GLES_WARN_IMPLICIT_MSAA_SURFACE);
2728*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(target, attachment, textarget, texture, level);
2729*bbecb9d1SAndroid Build Coastguard Worker } else if (attachment == GL_COLOR_ATTACHMENT0){
2730*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
2731*bbecb9d1SAndroid Build Coastguard Worker texture, level, samples);
2732*bbecb9d1SAndroid Build Coastguard Worker } else if (attachment == GL_STENCIL_ATTACHMENT || attachment == GL_DEPTH_ATTACHMENT) {
2733*bbecb9d1SAndroid Build Coastguard Worker GLenum internalformat =
2734*bbecb9d1SAndroid Build Coastguard Worker attachment == GL_STENCIL_ATTACHMENT ? GL_STENCIL_INDEX8 : GL_DEPTH_COMPONENT16;
2735*bbecb9d1SAndroid Build Coastguard Worker
2736*bbecb9d1SAndroid Build Coastguard Worker glGenRenderbuffers(1, &res->rbo_id);
2737*bbecb9d1SAndroid Build Coastguard Worker glBindRenderbuffer(GL_RENDERBUFFER, res->rbo_id);
2738*bbecb9d1SAndroid Build Coastguard Worker glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
2739*bbecb9d1SAndroid Build Coastguard Worker internalformat, res->base.width0,
2740*bbecb9d1SAndroid Build Coastguard Worker res->base.height0);
2741*bbecb9d1SAndroid Build Coastguard Worker glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment,
2742*bbecb9d1SAndroid Build Coastguard Worker GL_RENDERBUFFER, res->rbo_id);
2743*bbecb9d1SAndroid Build Coastguard Worker glBindRenderbuffer(GL_RENDERBUFFER, 0);
2744*bbecb9d1SAndroid Build Coastguard Worker } else {
2745*bbecb9d1SAndroid Build Coastguard Worker /* unsupported attachment for EXT_multisampled_render_to_texture, fallback to non-msaa */
2746*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(vrend_state.current_ctx, GLES_WARN_IMPLICIT_MSAA_SURFACE);
2747*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(target, attachment, textarget, texture, level);
2748*bbecb9d1SAndroid Build Coastguard Worker }
2749*bbecb9d1SAndroid Build Coastguard Worker }
2750*bbecb9d1SAndroid Build Coastguard Worker
2751*bbecb9d1SAndroid Build Coastguard Worker static
debug_texture(ASSERTED const char * f,const struct vrend_resource * gt)2752*bbecb9d1SAndroid Build Coastguard Worker void debug_texture(ASSERTED const char *f, const struct vrend_resource *gt)
2753*bbecb9d1SAndroid Build Coastguard Worker {
2754*bbecb9d1SAndroid Build Coastguard Worker ASSERTED const struct pipe_resource *pr = >->base;
2755*bbecb9d1SAndroid Build Coastguard Worker #define PRINT_TARGET(X) case X: vrend_printf( #X); break
2756*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG_EXT(dbg_tex, NULL,
2757*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: ", f);
2758*bbecb9d1SAndroid Build Coastguard Worker switch (tgsitargettogltarget(pr->target, pr->nr_samples)) {
2759*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_RECTANGLE_NV);
2760*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_1D);
2761*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_2D);
2762*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_3D);
2763*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_1D_ARRAY);
2764*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_2D_ARRAY);
2765*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_2D_MULTISAMPLE);
2766*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_CUBE_MAP);
2767*bbecb9d1SAndroid Build Coastguard Worker PRINT_TARGET(GL_TEXTURE_CUBE_MAP_ARRAY);
2768*bbecb9d1SAndroid Build Coastguard Worker default:
2769*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("UNKNOWN");
2770*bbecb9d1SAndroid Build Coastguard Worker }
2771*bbecb9d1SAndroid Build Coastguard Worker vrend_printf(" id:%d pipe_type:%d ms:%d format:%s size: %dx%dx%d mip:%d\n",
2772*bbecb9d1SAndroid Build Coastguard Worker gt->id, pr->target, pr->nr_samples, util_format_name(pr->format),
2773*bbecb9d1SAndroid Build Coastguard Worker pr->width0, pr->height0, pr->depth0, pr->last_level);
2774*bbecb9d1SAndroid Build Coastguard Worker );
2775*bbecb9d1SAndroid Build Coastguard Worker #undef PRINT_TARGET
2776*bbecb9d1SAndroid Build Coastguard Worker }
2777*bbecb9d1SAndroid Build Coastguard Worker
vrend_fb_bind_texture_id(struct vrend_resource * res,int id,int idx,uint32_t level,uint32_t layer,uint32_t samples)2778*bbecb9d1SAndroid Build Coastguard Worker void vrend_fb_bind_texture_id(struct vrend_resource *res,
2779*bbecb9d1SAndroid Build Coastguard Worker int id, int idx, uint32_t level,
2780*bbecb9d1SAndroid Build Coastguard Worker uint32_t layer, uint32_t samples)
2781*bbecb9d1SAndroid Build Coastguard Worker {
2782*bbecb9d1SAndroid Build Coastguard Worker const struct util_format_description *desc = util_format_description(res->base.format);
2783*bbecb9d1SAndroid Build Coastguard Worker GLenum attachment = GL_COLOR_ATTACHMENT0 + idx;
2784*bbecb9d1SAndroid Build Coastguard Worker
2785*bbecb9d1SAndroid Build Coastguard Worker debug_texture(__func__, res);
2786*bbecb9d1SAndroid Build Coastguard Worker
2787*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_is_ds(res->base.format)) {
2788*bbecb9d1SAndroid Build Coastguard Worker if (util_format_has_stencil(desc)) {
2789*bbecb9d1SAndroid Build Coastguard Worker if (util_format_has_depth(desc))
2790*bbecb9d1SAndroid Build Coastguard Worker attachment = GL_DEPTH_STENCIL_ATTACHMENT;
2791*bbecb9d1SAndroid Build Coastguard Worker else
2792*bbecb9d1SAndroid Build Coastguard Worker attachment = GL_STENCIL_ATTACHMENT;
2793*bbecb9d1SAndroid Build Coastguard Worker } else
2794*bbecb9d1SAndroid Build Coastguard Worker attachment = GL_DEPTH_ATTACHMENT;
2795*bbecb9d1SAndroid Build Coastguard Worker }
2796*bbecb9d1SAndroid Build Coastguard Worker
2797*bbecb9d1SAndroid Build Coastguard Worker switch (res->target) {
2798*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_1D_ARRAY:
2799*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
2800*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2801*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY:
2802*bbecb9d1SAndroid Build Coastguard Worker if (layer == 0xffffffff)
2803*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture(GL_FRAMEBUFFER, attachment,
2804*bbecb9d1SAndroid Build Coastguard Worker id, level);
2805*bbecb9d1SAndroid Build Coastguard Worker else
2806*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTextureLayer(GL_FRAMEBUFFER, attachment,
2807*bbecb9d1SAndroid Build Coastguard Worker id, level, layer);
2808*bbecb9d1SAndroid Build Coastguard Worker break;
2809*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
2810*bbecb9d1SAndroid Build Coastguard Worker if (layer == 0xffffffff)
2811*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture(GL_FRAMEBUFFER, attachment,
2812*bbecb9d1SAndroid Build Coastguard Worker id, level);
2813*bbecb9d1SAndroid Build Coastguard Worker else if (vrend_state.use_gles)
2814*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture3DOES(GL_FRAMEBUFFER, attachment,
2815*bbecb9d1SAndroid Build Coastguard Worker res->target, id, level, layer);
2816*bbecb9d1SAndroid Build Coastguard Worker else
2817*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture3D(GL_FRAMEBUFFER, attachment,
2818*bbecb9d1SAndroid Build Coastguard Worker res->target, id, level, layer);
2819*bbecb9d1SAndroid Build Coastguard Worker break;
2820*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
2821*bbecb9d1SAndroid Build Coastguard Worker if (layer == 0xffffffff)
2822*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture(GL_FRAMEBUFFER, attachment,
2823*bbecb9d1SAndroid Build Coastguard Worker id, level);
2824*bbecb9d1SAndroid Build Coastguard Worker else
2825*bbecb9d1SAndroid Build Coastguard Worker vrend_framebuffer_texture_2d(res, GL_FRAMEBUFFER, attachment,
2826*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer,
2827*bbecb9d1SAndroid Build Coastguard Worker id, level, samples);
2828*bbecb9d1SAndroid Build Coastguard Worker break;
2829*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_1D:
2830*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture1D(GL_FRAMEBUFFER, attachment,
2831*bbecb9d1SAndroid Build Coastguard Worker res->target, id, level);
2832*bbecb9d1SAndroid Build Coastguard Worker break;
2833*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
2834*bbecb9d1SAndroid Build Coastguard Worker default:
2835*bbecb9d1SAndroid Build Coastguard Worker vrend_framebuffer_texture_2d(res, GL_FRAMEBUFFER, attachment,
2836*bbecb9d1SAndroid Build Coastguard Worker res->target, id, level, samples);
2837*bbecb9d1SAndroid Build Coastguard Worker break;
2838*bbecb9d1SAndroid Build Coastguard Worker }
2839*bbecb9d1SAndroid Build Coastguard Worker
2840*bbecb9d1SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_ATTACHMENT) {
2841*bbecb9d1SAndroid Build Coastguard Worker switch (res->target) {
2842*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_1D:
2843*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture1D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
2844*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_1D, 0, 0);
2845*bbecb9d1SAndroid Build Coastguard Worker break;
2846*bbecb9d1SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
2847*bbecb9d1SAndroid Build Coastguard Worker default:
2848*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
2849*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
2850*bbecb9d1SAndroid Build Coastguard Worker break;
2851*bbecb9d1SAndroid Build Coastguard Worker }
2852*bbecb9d1SAndroid Build Coastguard Worker }
2853*bbecb9d1SAndroid Build Coastguard Worker }
2854*bbecb9d1SAndroid Build Coastguard Worker
vrend_fb_bind_texture(struct vrend_resource * res,int idx,uint32_t level,uint32_t layer)2855*bbecb9d1SAndroid Build Coastguard Worker void vrend_fb_bind_texture(struct vrend_resource *res,
2856*bbecb9d1SAndroid Build Coastguard Worker int idx,
2857*bbecb9d1SAndroid Build Coastguard Worker uint32_t level, uint32_t layer)
2858*bbecb9d1SAndroid Build Coastguard Worker {
2859*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture_id(res, res->id, idx, level, layer, 0);
2860*bbecb9d1SAndroid Build Coastguard Worker }
2861*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_set_zsurf_texture(struct vrend_context * ctx)2862*bbecb9d1SAndroid Build Coastguard Worker static void vrend_hw_set_zsurf_texture(struct vrend_context *ctx)
2863*bbecb9d1SAndroid Build Coastguard Worker {
2864*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf = ctx->sub->zsurf;
2865*bbecb9d1SAndroid Build Coastguard Worker
2866*bbecb9d1SAndroid Build Coastguard Worker if (!surf) {
2867*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2868*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
2869*bbecb9d1SAndroid Build Coastguard Worker } else {
2870*bbecb9d1SAndroid Build Coastguard Worker uint32_t first_layer = surf->val1 & 0xffff;
2871*bbecb9d1SAndroid Build Coastguard Worker uint32_t last_layer = (surf->val1 >> 16) & 0xffff;
2872*bbecb9d1SAndroid Build Coastguard Worker
2873*bbecb9d1SAndroid Build Coastguard Worker if (!surf->texture)
2874*bbecb9d1SAndroid Build Coastguard Worker return;
2875*bbecb9d1SAndroid Build Coastguard Worker
2876*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture_id(surf->texture, surf->id, 0, surf->val0,
2877*bbecb9d1SAndroid Build Coastguard Worker first_layer != last_layer ? 0xffffffff : first_layer,
2878*bbecb9d1SAndroid Build Coastguard Worker surf->nr_samples);
2879*bbecb9d1SAndroid Build Coastguard Worker }
2880*bbecb9d1SAndroid Build Coastguard Worker }
2881*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_set_color_surface(struct vrend_sub_context * sub_ctx,int index)2882*bbecb9d1SAndroid Build Coastguard Worker static void vrend_hw_set_color_surface(struct vrend_sub_context *sub_ctx, int index)
2883*bbecb9d1SAndroid Build Coastguard Worker {
2884*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf = sub_ctx->surf[index];
2885*bbecb9d1SAndroid Build Coastguard Worker
2886*bbecb9d1SAndroid Build Coastguard Worker if (!surf) {
2887*bbecb9d1SAndroid Build Coastguard Worker GLenum attachment = GL_COLOR_ATTACHMENT0 + index;
2888*bbecb9d1SAndroid Build Coastguard Worker
2889*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, attachment,
2890*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
2891*bbecb9d1SAndroid Build Coastguard Worker } else {
2892*bbecb9d1SAndroid Build Coastguard Worker uint32_t first_layer = sub_ctx->surf[index]->val1 & 0xffff;
2893*bbecb9d1SAndroid Build Coastguard Worker uint32_t last_layer = (sub_ctx->surf[index]->val1 >> 16) & 0xffff;
2894*bbecb9d1SAndroid Build Coastguard Worker
2895*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture_id(surf->texture, surf->id, index, surf->val0,
2896*bbecb9d1SAndroid Build Coastguard Worker first_layer != last_layer ? 0xffffffff : first_layer,
2897*bbecb9d1SAndroid Build Coastguard Worker surf->nr_samples);
2898*bbecb9d1SAndroid Build Coastguard Worker }
2899*bbecb9d1SAndroid Build Coastguard Worker }
2900*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_emit_framebuffer_state(struct vrend_sub_context * sub_ctx)2901*bbecb9d1SAndroid Build Coastguard Worker static void vrend_hw_emit_framebuffer_state(struct vrend_sub_context *sub_ctx)
2902*bbecb9d1SAndroid Build Coastguard Worker {
2903*bbecb9d1SAndroid Build Coastguard Worker static const GLenum buffers[8] = {
2904*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT0,
2905*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT1,
2906*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT2,
2907*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT3,
2908*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT4,
2909*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT5,
2910*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT6,
2911*bbecb9d1SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT7,
2912*bbecb9d1SAndroid Build Coastguard Worker };
2913*bbecb9d1SAndroid Build Coastguard Worker
2914*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->nr_cbufs == 0) {
2915*bbecb9d1SAndroid Build Coastguard Worker glReadBuffer(GL_NONE);
2916*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_srgb_write_control)) {
2917*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2918*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->framebuffer_srgb_enabled = false;
2919*bbecb9d1SAndroid Build Coastguard Worker }
2920*bbecb9d1SAndroid Build Coastguard Worker } else if (has_feature(feat_srgb_write_control)) {
2921*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf = NULL;
2922*bbecb9d1SAndroid Build Coastguard Worker bool use_srgb = false;
2923*bbecb9d1SAndroid Build Coastguard Worker int i;
2924*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < sub_ctx->nr_cbufs; i++) {
2925*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->surf[i]) {
2926*bbecb9d1SAndroid Build Coastguard Worker surf = sub_ctx->surf[i];
2927*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_srgb(surf->format)) {
2928*bbecb9d1SAndroid Build Coastguard Worker use_srgb = true;
2929*bbecb9d1SAndroid Build Coastguard Worker break;
2930*bbecb9d1SAndroid Build Coastguard Worker }
2931*bbecb9d1SAndroid Build Coastguard Worker }
2932*bbecb9d1SAndroid Build Coastguard Worker }
2933*bbecb9d1SAndroid Build Coastguard Worker if (use_srgb) {
2934*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_FRAMEBUFFER_SRGB_EXT);
2935*bbecb9d1SAndroid Build Coastguard Worker } else {
2936*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_FRAMEBUFFER_SRGB_EXT);
2937*bbecb9d1SAndroid Build Coastguard Worker }
2938*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->framebuffer_srgb_enabled = use_srgb;
2939*bbecb9d1SAndroid Build Coastguard Worker }
2940*bbecb9d1SAndroid Build Coastguard Worker
2941*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->swizzle_output_rgb_to_bgr = 0;
2942*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->needs_manual_srgb_encode_bitmask = 0;
2943*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < sub_ctx->nr_cbufs; i++) {
2944*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf = sub_ctx->surf[i];
2945*bbecb9d1SAndroid Build Coastguard Worker if (!surf)
2946*bbecb9d1SAndroid Build Coastguard Worker continue;
2947*bbecb9d1SAndroid Build Coastguard Worker
2948*bbecb9d1SAndroid Build Coastguard Worker /* glTextureView() is not applied to eglimage-backed surfaces, because it
2949*bbecb9d1SAndroid Build Coastguard Worker * causes unintended format interpretation errors. But a swizzle may still
2950*bbecb9d1SAndroid Build Coastguard Worker * be necessary, e.g. for rgb* views on bgr* resources. Ensure this
2951*bbecb9d1SAndroid Build Coastguard Worker * happens by adding a shader swizzle to the final write of such surfaces.
2952*bbecb9d1SAndroid Build Coastguard Worker */
2953*bbecb9d1SAndroid Build Coastguard Worker if (vrend_resource_needs_redblue_swizzle(surf->texture, surf->format))
2954*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->swizzle_output_rgb_to_bgr |= 1 << i;
2955*bbecb9d1SAndroid Build Coastguard Worker
2956*bbecb9d1SAndroid Build Coastguard Worker /* glTextureView() on eglimage-backed bgr* textures for is not supported.
2957*bbecb9d1SAndroid Build Coastguard Worker * To work around this for colorspace conversion, views are avoided
2958*bbecb9d1SAndroid Build Coastguard Worker * manual colorspace conversion is instead injected in the fragment
2959*bbecb9d1SAndroid Build Coastguard Worker * shader writing to such surfaces and during glClearColor(). */
2960*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_srgb(surf->format) &&
2961*bbecb9d1SAndroid Build Coastguard Worker !vrend_resource_supports_view(surf->texture, surf->format)) {
2962*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_tex, sub_ctx->parent,
2963*bbecb9d1SAndroid Build Coastguard Worker "manually converting linear->srgb for EGL-backed framebuffer color attachment 0x%x"
2964*bbecb9d1SAndroid Build Coastguard Worker " (surface format is %s; resource format is %s)\n",
2965*bbecb9d1SAndroid Build Coastguard Worker i, util_format_name(surf->format), util_format_name(surf->texture->base.format));
2966*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->needs_manual_srgb_encode_bitmask |= 1 << i;
2967*bbecb9d1SAndroid Build Coastguard Worker }
2968*bbecb9d1SAndroid Build Coastguard Worker }
2969*bbecb9d1SAndroid Build Coastguard Worker
2970*bbecb9d1SAndroid Build Coastguard Worker glDrawBuffers(sub_ctx->nr_cbufs, buffers);
2971*bbecb9d1SAndroid Build Coastguard Worker }
2972*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_framebuffer_state(struct vrend_context * ctx,uint32_t nr_cbufs,uint32_t surf_handle[PIPE_MAX_COLOR_BUFS],uint32_t zsurf_handle)2973*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_framebuffer_state(struct vrend_context *ctx,
2974*bbecb9d1SAndroid Build Coastguard Worker uint32_t nr_cbufs, uint32_t surf_handle[PIPE_MAX_COLOR_BUFS],
2975*bbecb9d1SAndroid Build Coastguard Worker uint32_t zsurf_handle)
2976*bbecb9d1SAndroid Build Coastguard Worker {
2977*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf, *zsurf;
2978*bbecb9d1SAndroid Build Coastguard Worker int i;
2979*bbecb9d1SAndroid Build Coastguard Worker int old_num;
2980*bbecb9d1SAndroid Build Coastguard Worker GLenum status;
2981*bbecb9d1SAndroid Build Coastguard Worker GLint new_height = -1;
2982*bbecb9d1SAndroid Build Coastguard Worker bool new_fbo_origin_upper_left = false;
2983*bbecb9d1SAndroid Build Coastguard Worker
2984*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx = ctx->sub;
2985*bbecb9d1SAndroid Build Coastguard Worker
2986*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, sub_ctx->fb_id);
2987*bbecb9d1SAndroid Build Coastguard Worker
2988*bbecb9d1SAndroid Build Coastguard Worker if (zsurf_handle) {
2989*bbecb9d1SAndroid Build Coastguard Worker zsurf = vrend_object_lookup(sub_ctx->object_hash, zsurf_handle, VIRGL_OBJECT_SURFACE);
2990*bbecb9d1SAndroid Build Coastguard Worker if (!zsurf) {
2991*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SURFACE, zsurf_handle);
2992*bbecb9d1SAndroid Build Coastguard Worker return;
2993*bbecb9d1SAndroid Build Coastguard Worker }
2994*bbecb9d1SAndroid Build Coastguard Worker } else
2995*bbecb9d1SAndroid Build Coastguard Worker zsurf = NULL;
2996*bbecb9d1SAndroid Build Coastguard Worker
2997*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->zsurf != zsurf) {
2998*bbecb9d1SAndroid Build Coastguard Worker vrend_surface_reference(&sub_ctx->zsurf, zsurf);
2999*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_set_zsurf_texture(ctx);
3000*bbecb9d1SAndroid Build Coastguard Worker }
3001*bbecb9d1SAndroid Build Coastguard Worker
3002*bbecb9d1SAndroid Build Coastguard Worker old_num = sub_ctx->nr_cbufs;
3003*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->nr_cbufs = nr_cbufs;
3004*bbecb9d1SAndroid Build Coastguard Worker
3005*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < (int)nr_cbufs; i++) {
3006*bbecb9d1SAndroid Build Coastguard Worker if (surf_handle[i] != 0) {
3007*bbecb9d1SAndroid Build Coastguard Worker surf = vrend_object_lookup(sub_ctx->object_hash, surf_handle[i], VIRGL_OBJECT_SURFACE);
3008*bbecb9d1SAndroid Build Coastguard Worker if (!surf) {
3009*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SURFACE, surf_handle[i]);
3010*bbecb9d1SAndroid Build Coastguard Worker return;
3011*bbecb9d1SAndroid Build Coastguard Worker }
3012*bbecb9d1SAndroid Build Coastguard Worker } else
3013*bbecb9d1SAndroid Build Coastguard Worker surf = NULL;
3014*bbecb9d1SAndroid Build Coastguard Worker
3015*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->surf[i] != surf) {
3016*bbecb9d1SAndroid Build Coastguard Worker vrend_surface_reference(&sub_ctx->surf[i], surf);
3017*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_set_color_surface(sub_ctx, i);
3018*bbecb9d1SAndroid Build Coastguard Worker }
3019*bbecb9d1SAndroid Build Coastguard Worker }
3020*bbecb9d1SAndroid Build Coastguard Worker
3021*bbecb9d1SAndroid Build Coastguard Worker if (old_num > sub_ctx->nr_cbufs) {
3022*bbecb9d1SAndroid Build Coastguard Worker for (i = sub_ctx->nr_cbufs; i < old_num; i++) {
3023*bbecb9d1SAndroid Build Coastguard Worker vrend_surface_reference(&sub_ctx->surf[i], NULL);
3024*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_set_color_surface(sub_ctx, i);
3025*bbecb9d1SAndroid Build Coastguard Worker }
3026*bbecb9d1SAndroid Build Coastguard Worker }
3027*bbecb9d1SAndroid Build Coastguard Worker
3028*bbecb9d1SAndroid Build Coastguard Worker /* find a buffer to set fb_height from */
3029*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->nr_cbufs == 0 && !sub_ctx->zsurf) {
3030*bbecb9d1SAndroid Build Coastguard Worker new_height = 0;
3031*bbecb9d1SAndroid Build Coastguard Worker new_fbo_origin_upper_left = false;
3032*bbecb9d1SAndroid Build Coastguard Worker } else if (sub_ctx->nr_cbufs == 0) {
3033*bbecb9d1SAndroid Build Coastguard Worker new_height = u_minify(sub_ctx->zsurf->texture->base.height0, sub_ctx->zsurf->val0);
3034*bbecb9d1SAndroid Build Coastguard Worker new_fbo_origin_upper_left = sub_ctx->zsurf->texture->y_0_top ? true : false;
3035*bbecb9d1SAndroid Build Coastguard Worker }
3036*bbecb9d1SAndroid Build Coastguard Worker else {
3037*bbecb9d1SAndroid Build Coastguard Worker surf = NULL;
3038*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < sub_ctx->nr_cbufs; i++) {
3039*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->surf[i]) {
3040*bbecb9d1SAndroid Build Coastguard Worker surf = sub_ctx->surf[i];
3041*bbecb9d1SAndroid Build Coastguard Worker break;
3042*bbecb9d1SAndroid Build Coastguard Worker }
3043*bbecb9d1SAndroid Build Coastguard Worker }
3044*bbecb9d1SAndroid Build Coastguard Worker if (surf == NULL) {
3045*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SURFACE, i);
3046*bbecb9d1SAndroid Build Coastguard Worker return;
3047*bbecb9d1SAndroid Build Coastguard Worker }
3048*bbecb9d1SAndroid Build Coastguard Worker new_height = u_minify(surf->texture->base.height0, surf->val0);
3049*bbecb9d1SAndroid Build Coastguard Worker new_fbo_origin_upper_left = surf->texture->y_0_top ? true : false;
3050*bbecb9d1SAndroid Build Coastguard Worker }
3051*bbecb9d1SAndroid Build Coastguard Worker
3052*bbecb9d1SAndroid Build Coastguard Worker if (new_height != -1) {
3053*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->fb_height != (uint32_t)new_height ||
3054*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->fbo_origin_upper_left != new_fbo_origin_upper_left) {
3055*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->fb_height = new_height;
3056*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->fbo_origin_upper_left = new_fbo_origin_upper_left;
3057*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->viewport_state_dirty = (1 << 0);
3058*bbecb9d1SAndroid Build Coastguard Worker }
3059*bbecb9d1SAndroid Build Coastguard Worker }
3060*bbecb9d1SAndroid Build Coastguard Worker
3061*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_emit_framebuffer_state(sub_ctx);
3062*bbecb9d1SAndroid Build Coastguard Worker
3063*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->nr_cbufs > 0 || sub_ctx->zsurf) {
3064*bbecb9d1SAndroid Build Coastguard Worker status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
3065*bbecb9d1SAndroid Build Coastguard Worker if (status != GL_FRAMEBUFFER_COMPLETE)
3066*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("failed to complete framebuffer 0x%x %s\n", status, ctx->debug_name);
3067*bbecb9d1SAndroid Build Coastguard Worker }
3068*bbecb9d1SAndroid Build Coastguard Worker
3069*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shader_dirty = true;
3070*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->blend_state_dirty = true;
3071*bbecb9d1SAndroid Build Coastguard Worker }
3072*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_framebuffer_state_no_attach(UNUSED struct vrend_context * ctx,uint32_t width,uint32_t height,uint32_t layers,uint32_t samples)3073*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_framebuffer_state_no_attach(UNUSED struct vrend_context *ctx,
3074*bbecb9d1SAndroid Build Coastguard Worker uint32_t width, uint32_t height,
3075*bbecb9d1SAndroid Build Coastguard Worker uint32_t layers, uint32_t samples)
3076*bbecb9d1SAndroid Build Coastguard Worker {
3077*bbecb9d1SAndroid Build Coastguard Worker int gl_ver = vrend_state.gl_major_ver * 10 + vrend_state.gl_minor_ver;
3078*bbecb9d1SAndroid Build Coastguard Worker
3079*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_fb_no_attach)) {
3080*bbecb9d1SAndroid Build Coastguard Worker glFramebufferParameteri(GL_FRAMEBUFFER,
3081*bbecb9d1SAndroid Build Coastguard Worker GL_FRAMEBUFFER_DEFAULT_WIDTH, width);
3082*bbecb9d1SAndroid Build Coastguard Worker glFramebufferParameteri(GL_FRAMEBUFFER,
3083*bbecb9d1SAndroid Build Coastguard Worker GL_FRAMEBUFFER_DEFAULT_HEIGHT, height);
3084*bbecb9d1SAndroid Build Coastguard Worker if (!(vrend_state.use_gles && gl_ver <= 31))
3085*bbecb9d1SAndroid Build Coastguard Worker glFramebufferParameteri(GL_FRAMEBUFFER,
3086*bbecb9d1SAndroid Build Coastguard Worker GL_FRAMEBUFFER_DEFAULT_LAYERS, layers);
3087*bbecb9d1SAndroid Build Coastguard Worker glFramebufferParameteri(GL_FRAMEBUFFER,
3088*bbecb9d1SAndroid Build Coastguard Worker GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples);
3089*bbecb9d1SAndroid Build Coastguard Worker }
3090*bbecb9d1SAndroid Build Coastguard Worker }
3091*bbecb9d1SAndroid Build Coastguard Worker
3092*bbecb9d1SAndroid Build Coastguard Worker /*
3093*bbecb9d1SAndroid Build Coastguard Worker * if the viewport Y scale factor is > 0 then we are rendering to
3094*bbecb9d1SAndroid Build Coastguard Worker * an FBO already so don't need to invert rendering?
3095*bbecb9d1SAndroid Build Coastguard Worker */
vrend_set_viewport_states(struct vrend_context * ctx,uint32_t start_slot,uint32_t num_viewports,const struct pipe_viewport_state * state)3096*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_viewport_states(struct vrend_context *ctx,
3097*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot,
3098*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_viewports,
3099*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_viewport_state *state)
3100*bbecb9d1SAndroid Build Coastguard Worker {
3101*bbecb9d1SAndroid Build Coastguard Worker /* convert back to glViewport */
3102*bbecb9d1SAndroid Build Coastguard Worker GLint x, y;
3103*bbecb9d1SAndroid Build Coastguard Worker GLsizei width, height;
3104*bbecb9d1SAndroid Build Coastguard Worker GLclampd near_val, far_val;
3105*bbecb9d1SAndroid Build Coastguard Worker bool viewport_is_negative = (state[0].scale[1] < 0) ? true : false;
3106*bbecb9d1SAndroid Build Coastguard Worker uint i, idx;
3107*bbecb9d1SAndroid Build Coastguard Worker
3108*bbecb9d1SAndroid Build Coastguard Worker if (num_viewports > PIPE_MAX_VIEWPORTS ||
3109*bbecb9d1SAndroid Build Coastguard Worker start_slot > (PIPE_MAX_VIEWPORTS - num_viewports)) {
3110*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, num_viewports);
3111*bbecb9d1SAndroid Build Coastguard Worker return;
3112*bbecb9d1SAndroid Build Coastguard Worker }
3113*bbecb9d1SAndroid Build Coastguard Worker
3114*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_viewports; i++) {
3115*bbecb9d1SAndroid Build Coastguard Worker GLfloat abs_s1 = fabsf(state[i].scale[1]);
3116*bbecb9d1SAndroid Build Coastguard Worker
3117*bbecb9d1SAndroid Build Coastguard Worker idx = start_slot + i;
3118*bbecb9d1SAndroid Build Coastguard Worker width = state[i].scale[0] * 2.0f;
3119*bbecb9d1SAndroid Build Coastguard Worker height = abs_s1 * 2.0f;
3120*bbecb9d1SAndroid Build Coastguard Worker x = state[i].translate[0] - state[i].scale[0];
3121*bbecb9d1SAndroid Build Coastguard Worker y = state[i].translate[1] - state[i].scale[1];
3122*bbecb9d1SAndroid Build Coastguard Worker
3123*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->sub->rs_state.clip_halfz) {
3124*bbecb9d1SAndroid Build Coastguard Worker near_val = state[i].translate[2] - state[i].scale[2];
3125*bbecb9d1SAndroid Build Coastguard Worker far_val = near_val + (state[i].scale[2] * 2.0);
3126*bbecb9d1SAndroid Build Coastguard Worker } else {
3127*bbecb9d1SAndroid Build Coastguard Worker near_val = state[i].translate[2];
3128*bbecb9d1SAndroid Build Coastguard Worker far_val = state[i].scale[2] + state[i].translate[2];
3129*bbecb9d1SAndroid Build Coastguard Worker }
3130*bbecb9d1SAndroid Build Coastguard Worker
3131*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->vps[idx].cur_x != x ||
3132*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].cur_y != y ||
3133*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].width != width ||
3134*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].height != height ||
3135*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].near_val != near_val ||
3136*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].far_val != far_val ||
3137*bbecb9d1SAndroid Build Coastguard Worker (!(ctx->sub->viewport_state_initialized &= (1 << idx)))) {
3138*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].cur_x = x;
3139*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].cur_y = y;
3140*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].width = width;
3141*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].height = height;
3142*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].near_val = near_val;
3143*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vps[idx].far_val = far_val;
3144*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->viewport_state_dirty |= (1 << idx);
3145*bbecb9d1SAndroid Build Coastguard Worker }
3146*bbecb9d1SAndroid Build Coastguard Worker
3147*bbecb9d1SAndroid Build Coastguard Worker if (idx == 0) {
3148*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->viewport_is_negative != viewport_is_negative) {
3149*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->viewport_is_negative = viewport_is_negative;
3150*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data.winsys_adjust_y =
3151*bbecb9d1SAndroid Build Coastguard Worker viewport_is_negative ? -1.f : 1.f;
3152*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data_cookie++;
3153*bbecb9d1SAndroid Build Coastguard Worker }
3154*bbecb9d1SAndroid Build Coastguard Worker }
3155*bbecb9d1SAndroid Build Coastguard Worker }
3156*bbecb9d1SAndroid Build Coastguard Worker }
3157*bbecb9d1SAndroid Build Coastguard Worker
3158*bbecb9d1SAndroid Build Coastguard Worker #define UPDATE_INT_SIGN_MASK(fmt, i, signed_mask, unsigned_mask) \
3159*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_integer && \
3160*bbecb9d1SAndroid Build Coastguard Worker util_format_is_pure_integer(fmt)) { \
3161*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_pure_uint(fmt)) \
3162*bbecb9d1SAndroid Build Coastguard Worker unsigned_mask |= (1 << i); \
3163*bbecb9d1SAndroid Build Coastguard Worker else \
3164*bbecb9d1SAndroid Build Coastguard Worker signed_mask |= (1 << i); \
3165*bbecb9d1SAndroid Build Coastguard Worker }
3166*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_vertex_elements_state(struct vrend_context * ctx,uint32_t handle,unsigned num_elements,const struct pipe_vertex_element * elements)3167*bbecb9d1SAndroid Build Coastguard Worker int vrend_create_vertex_elements_state(struct vrend_context *ctx,
3168*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
3169*bbecb9d1SAndroid Build Coastguard Worker unsigned num_elements,
3170*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_vertex_element *elements)
3171*bbecb9d1SAndroid Build Coastguard Worker {
3172*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element_array *v;
3173*bbecb9d1SAndroid Build Coastguard Worker const struct util_format_description *desc;
3174*bbecb9d1SAndroid Build Coastguard Worker GLenum type;
3175*bbecb9d1SAndroid Build Coastguard Worker uint i;
3176*bbecb9d1SAndroid Build Coastguard Worker uint32_t ret_handle;
3177*bbecb9d1SAndroid Build Coastguard Worker
3178*bbecb9d1SAndroid Build Coastguard Worker if (num_elements > PIPE_MAX_ATTRIBS)
3179*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
3180*bbecb9d1SAndroid Build Coastguard Worker
3181*bbecb9d1SAndroid Build Coastguard Worker v = CALLOC_STRUCT(vrend_vertex_element_array);
3182*bbecb9d1SAndroid Build Coastguard Worker if (!v)
3183*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
3184*bbecb9d1SAndroid Build Coastguard Worker
3185*bbecb9d1SAndroid Build Coastguard Worker v->count = num_elements;
3186*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_elements; i++) {
3187*bbecb9d1SAndroid Build Coastguard Worker memcpy(&v->elements[i].base, &elements[i], sizeof(struct pipe_vertex_element));
3188*bbecb9d1SAndroid Build Coastguard Worker
3189*bbecb9d1SAndroid Build Coastguard Worker desc = util_format_description(elements[i].src_format);
3190*bbecb9d1SAndroid Build Coastguard Worker if (!desc) {
3191*bbecb9d1SAndroid Build Coastguard Worker FREE(v);
3192*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
3193*bbecb9d1SAndroid Build Coastguard Worker }
3194*bbecb9d1SAndroid Build Coastguard Worker
3195*bbecb9d1SAndroid Build Coastguard Worker type = GL_FALSE;
3196*bbecb9d1SAndroid Build Coastguard Worker switch (desc->channel[0].type) {
3197*bbecb9d1SAndroid Build Coastguard Worker case UTIL_FORMAT_TYPE_FLOAT:
3198*bbecb9d1SAndroid Build Coastguard Worker switch (desc->channel[0].size) {
3199*bbecb9d1SAndroid Build Coastguard Worker case 16: type = GL_HALF_FLOAT; break;
3200*bbecb9d1SAndroid Build Coastguard Worker case 32: type = GL_FLOAT; break;
3201*bbecb9d1SAndroid Build Coastguard Worker case 64: type = GL_DOUBLE; break;
3202*bbecb9d1SAndroid Build Coastguard Worker }
3203*bbecb9d1SAndroid Build Coastguard Worker break;
3204*bbecb9d1SAndroid Build Coastguard Worker case UTIL_FORMAT_TYPE_UNSIGNED:
3205*bbecb9d1SAndroid Build Coastguard Worker switch (desc->channel[0].size) {
3206*bbecb9d1SAndroid Build Coastguard Worker case 8: type = GL_UNSIGNED_BYTE; break;
3207*bbecb9d1SAndroid Build Coastguard Worker case 16: type = GL_UNSIGNED_SHORT; break;
3208*bbecb9d1SAndroid Build Coastguard Worker case 32: type = GL_UNSIGNED_INT; break;
3209*bbecb9d1SAndroid Build Coastguard Worker }
3210*bbecb9d1SAndroid Build Coastguard Worker break;
3211*bbecb9d1SAndroid Build Coastguard Worker case UTIL_FORMAT_TYPE_SIGNED:
3212*bbecb9d1SAndroid Build Coastguard Worker switch (desc->channel[0].size) {
3213*bbecb9d1SAndroid Build Coastguard Worker case 8: type = GL_BYTE; break;
3214*bbecb9d1SAndroid Build Coastguard Worker case 16: type = GL_SHORT; break;
3215*bbecb9d1SAndroid Build Coastguard Worker case 32: type = GL_INT; break;
3216*bbecb9d1SAndroid Build Coastguard Worker }
3217*bbecb9d1SAndroid Build Coastguard Worker break;
3218*bbecb9d1SAndroid Build Coastguard Worker }
3219*bbecb9d1SAndroid Build Coastguard Worker if (type == GL_FALSE) {
3220*bbecb9d1SAndroid Build Coastguard Worker switch (elements[i].src_format) {
3221*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FORMAT_R10G10B10A2_SSCALED:
3222*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FORMAT_R10G10B10A2_SNORM:
3223*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FORMAT_B10G10R10A2_SNORM:
3224*bbecb9d1SAndroid Build Coastguard Worker type = GL_INT_2_10_10_10_REV;
3225*bbecb9d1SAndroid Build Coastguard Worker break;
3226*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FORMAT_R10G10B10A2_USCALED:
3227*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FORMAT_R10G10B10A2_UNORM:
3228*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FORMAT_B10G10R10A2_UNORM:
3229*bbecb9d1SAndroid Build Coastguard Worker type = GL_UNSIGNED_INT_2_10_10_10_REV;
3230*bbecb9d1SAndroid Build Coastguard Worker break;
3231*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FORMAT_R11G11B10_FLOAT:
3232*bbecb9d1SAndroid Build Coastguard Worker type = GL_UNSIGNED_INT_10F_11F_11F_REV;
3233*bbecb9d1SAndroid Build Coastguard Worker break;
3234*bbecb9d1SAndroid Build Coastguard Worker default:
3235*bbecb9d1SAndroid Build Coastguard Worker ;
3236*bbecb9d1SAndroid Build Coastguard Worker }
3237*bbecb9d1SAndroid Build Coastguard Worker }
3238*bbecb9d1SAndroid Build Coastguard Worker
3239*bbecb9d1SAndroid Build Coastguard Worker if (type == GL_FALSE) {
3240*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT, elements[i].src_format);
3241*bbecb9d1SAndroid Build Coastguard Worker FREE(v);
3242*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
3243*bbecb9d1SAndroid Build Coastguard Worker }
3244*bbecb9d1SAndroid Build Coastguard Worker
3245*bbecb9d1SAndroid Build Coastguard Worker v->elements[i].type = type;
3246*bbecb9d1SAndroid Build Coastguard Worker if (desc->channel[0].normalized)
3247*bbecb9d1SAndroid Build Coastguard Worker v->elements[i].norm = GL_TRUE;
3248*bbecb9d1SAndroid Build Coastguard Worker if (elements[i].src_format == PIPE_FORMAT_R11G11B10_FLOAT)
3249*bbecb9d1SAndroid Build Coastguard Worker v->elements[i].nr_chan = 3;
3250*bbecb9d1SAndroid Build Coastguard Worker else
3251*bbecb9d1SAndroid Build Coastguard Worker v->elements[i].nr_chan = desc->nr_channels;
3252*bbecb9d1SAndroid Build Coastguard Worker
3253*bbecb9d1SAndroid Build Coastguard Worker if (desc->nr_channels == 4 && desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_Z)
3254*bbecb9d1SAndroid Build Coastguard Worker v->zyxw_bitmask |= 1 << i;
3255*bbecb9d1SAndroid Build Coastguard Worker }
3256*bbecb9d1SAndroid Build Coastguard Worker
3257*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gles31_vertex_attrib_binding)) {
3258*bbecb9d1SAndroid Build Coastguard Worker glGenVertexArrays(1, &v->id);
3259*bbecb9d1SAndroid Build Coastguard Worker glBindVertexArray(v->id);
3260*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_elements; i++) {
3261*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element *ve = &v->elements[i];
3262*bbecb9d1SAndroid Build Coastguard Worker GLint size = !vrend_state.use_gles && (v->zyxw_bitmask & (1 << i)) ? GL_BGRA : ve->nr_chan;
3263*bbecb9d1SAndroid Build Coastguard Worker
3264*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_pure_integer(ve->base.src_format)) {
3265*bbecb9d1SAndroid Build Coastguard Worker UPDATE_INT_SIGN_MASK(ve->base.src_format, i,
3266*bbecb9d1SAndroid Build Coastguard Worker v->signed_int_bitmask,
3267*bbecb9d1SAndroid Build Coastguard Worker v->unsigned_int_bitmask);
3268*bbecb9d1SAndroid Build Coastguard Worker glVertexAttribIFormat(i, size, ve->type, ve->base.src_offset);
3269*bbecb9d1SAndroid Build Coastguard Worker }
3270*bbecb9d1SAndroid Build Coastguard Worker else
3271*bbecb9d1SAndroid Build Coastguard Worker glVertexAttribFormat(i, size, ve->type, ve->norm, ve->base.src_offset);
3272*bbecb9d1SAndroid Build Coastguard Worker glVertexAttribBinding(i, ve->base.vertex_buffer_index);
3273*bbecb9d1SAndroid Build Coastguard Worker glVertexBindingDivisor(i, ve->base.instance_divisor);
3274*bbecb9d1SAndroid Build Coastguard Worker glEnableVertexAttribArray(i);
3275*bbecb9d1SAndroid Build Coastguard Worker }
3276*bbecb9d1SAndroid Build Coastguard Worker }
3277*bbecb9d1SAndroid Build Coastguard Worker ret_handle = vrend_renderer_object_insert(ctx, v, handle,
3278*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_VERTEX_ELEMENTS);
3279*bbecb9d1SAndroid Build Coastguard Worker if (!ret_handle) {
3280*bbecb9d1SAndroid Build Coastguard Worker FREE(v);
3281*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
3282*bbecb9d1SAndroid Build Coastguard Worker }
3283*bbecb9d1SAndroid Build Coastguard Worker v->owning_sub = ctx->sub;
3284*bbecb9d1SAndroid Build Coastguard Worker return 0;
3285*bbecb9d1SAndroid Build Coastguard Worker }
3286*bbecb9d1SAndroid Build Coastguard Worker
vrend_bind_vertex_elements_state(struct vrend_context * ctx,uint32_t handle)3287*bbecb9d1SAndroid Build Coastguard Worker void vrend_bind_vertex_elements_state(struct vrend_context *ctx,
3288*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
3289*bbecb9d1SAndroid Build Coastguard Worker {
3290*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element_array *v;
3291*bbecb9d1SAndroid Build Coastguard Worker
3292*bbecb9d1SAndroid Build Coastguard Worker if (!handle) {
3293*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ve = NULL;
3294*bbecb9d1SAndroid Build Coastguard Worker return;
3295*bbecb9d1SAndroid Build Coastguard Worker }
3296*bbecb9d1SAndroid Build Coastguard Worker v = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_VERTEX_ELEMENTS);
3297*bbecb9d1SAndroid Build Coastguard Worker if (!v) {
3298*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handle);
3299*bbecb9d1SAndroid Build Coastguard Worker return;
3300*bbecb9d1SAndroid Build Coastguard Worker }
3301*bbecb9d1SAndroid Build Coastguard Worker
3302*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->ve != v)
3303*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vbo_dirty = true;
3304*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ve = v;
3305*bbecb9d1SAndroid Build Coastguard Worker }
3306*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_constants(struct vrend_context * ctx,uint32_t shader,uint32_t num_constant,const float * data)3307*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_constants(struct vrend_context *ctx,
3308*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader,
3309*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_constant,
3310*bbecb9d1SAndroid Build Coastguard Worker const float *data)
3311*bbecb9d1SAndroid Build Coastguard Worker {
3312*bbecb9d1SAndroid Build Coastguard Worker struct vrend_constants *consts;
3313*bbecb9d1SAndroid Build Coastguard Worker
3314*bbecb9d1SAndroid Build Coastguard Worker consts = &ctx->sub->consts[shader];
3315*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->const_dirty[shader] = true;
3316*bbecb9d1SAndroid Build Coastguard Worker
3317*bbecb9d1SAndroid Build Coastguard Worker /* avoid reallocations by only growing the buffer */
3318*bbecb9d1SAndroid Build Coastguard Worker if (consts->num_allocated_consts < num_constant) {
3319*bbecb9d1SAndroid Build Coastguard Worker free(consts->consts);
3320*bbecb9d1SAndroid Build Coastguard Worker consts->consts = malloc(num_constant * sizeof(float));
3321*bbecb9d1SAndroid Build Coastguard Worker if (!consts->consts)
3322*bbecb9d1SAndroid Build Coastguard Worker return;
3323*bbecb9d1SAndroid Build Coastguard Worker consts->num_allocated_consts = num_constant;
3324*bbecb9d1SAndroid Build Coastguard Worker }
3325*bbecb9d1SAndroid Build Coastguard Worker
3326*bbecb9d1SAndroid Build Coastguard Worker memcpy(consts->consts, data, num_constant * sizeof(unsigned int));
3327*bbecb9d1SAndroid Build Coastguard Worker consts->num_consts = num_constant;
3328*bbecb9d1SAndroid Build Coastguard Worker }
3329*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_uniform_buffer(struct vrend_context * ctx,uint32_t shader,uint32_t index,uint32_t offset,uint32_t length,uint32_t res_handle)3330*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_uniform_buffer(struct vrend_context *ctx,
3331*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader,
3332*bbecb9d1SAndroid Build Coastguard Worker uint32_t index,
3333*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset,
3334*bbecb9d1SAndroid Build Coastguard Worker uint32_t length,
3335*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle)
3336*bbecb9d1SAndroid Build Coastguard Worker {
3337*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
3338*bbecb9d1SAndroid Build Coastguard Worker
3339*bbecb9d1SAndroid Build Coastguard Worker struct pipe_constant_buffer *cbs = &ctx->sub->cbs[shader][index];
3340*bbecb9d1SAndroid Build Coastguard Worker const uint32_t mask = 1u << index;
3341*bbecb9d1SAndroid Build Coastguard Worker
3342*bbecb9d1SAndroid Build Coastguard Worker if (res_handle) {
3343*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
3344*bbecb9d1SAndroid Build Coastguard Worker
3345*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
3346*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
3347*bbecb9d1SAndroid Build Coastguard Worker return;
3348*bbecb9d1SAndroid Build Coastguard Worker }
3349*bbecb9d1SAndroid Build Coastguard Worker cbs->buffer = (struct pipe_resource *)res;
3350*bbecb9d1SAndroid Build Coastguard Worker cbs->buffer_offset = offset;
3351*bbecb9d1SAndroid Build Coastguard Worker cbs->buffer_size = length;
3352*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->const_bufs_used_mask[shader] |= mask;
3353*bbecb9d1SAndroid Build Coastguard Worker } else {
3354*bbecb9d1SAndroid Build Coastguard Worker cbs->buffer = NULL;
3355*bbecb9d1SAndroid Build Coastguard Worker cbs->buffer_offset = 0;
3356*bbecb9d1SAndroid Build Coastguard Worker cbs->buffer_size = 0;
3357*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->const_bufs_used_mask[shader] &= ~mask;
3358*bbecb9d1SAndroid Build Coastguard Worker }
3359*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->const_bufs_dirty[shader] |= mask;
3360*bbecb9d1SAndroid Build Coastguard Worker }
3361*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_index_buffer(struct vrend_context * ctx,uint32_t res_handle,uint32_t index_size,uint32_t offset)3362*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_index_buffer(struct vrend_context *ctx,
3363*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle,
3364*bbecb9d1SAndroid Build Coastguard Worker uint32_t index_size,
3365*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset)
3366*bbecb9d1SAndroid Build Coastguard Worker {
3367*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
3368*bbecb9d1SAndroid Build Coastguard Worker
3369*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ib.index_size = index_size;
3370*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ib.offset = offset;
3371*bbecb9d1SAndroid Build Coastguard Worker if (res_handle) {
3372*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->index_buffer_res_id != res_handle) {
3373*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
3374*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
3375*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference((struct vrend_resource **)&ctx->sub->ib.buffer, NULL);
3376*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->index_buffer_res_id = 0;
3377*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
3378*bbecb9d1SAndroid Build Coastguard Worker return;
3379*bbecb9d1SAndroid Build Coastguard Worker }
3380*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference((struct vrend_resource **)&ctx->sub->ib.buffer, res);
3381*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->index_buffer_res_id = res_handle;
3382*bbecb9d1SAndroid Build Coastguard Worker }
3383*bbecb9d1SAndroid Build Coastguard Worker } else {
3384*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference((struct vrend_resource **)&ctx->sub->ib.buffer, NULL);
3385*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->index_buffer_res_id = 0;
3386*bbecb9d1SAndroid Build Coastguard Worker }
3387*bbecb9d1SAndroid Build Coastguard Worker }
3388*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_single_vbo(struct vrend_context * ctx,uint32_t index,uint32_t stride,uint32_t buffer_offset,uint32_t res_handle)3389*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_single_vbo(struct vrend_context *ctx,
3390*bbecb9d1SAndroid Build Coastguard Worker uint32_t index,
3391*bbecb9d1SAndroid Build Coastguard Worker uint32_t stride,
3392*bbecb9d1SAndroid Build Coastguard Worker uint32_t buffer_offset,
3393*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle)
3394*bbecb9d1SAndroid Build Coastguard Worker {
3395*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
3396*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_buffer *vbo = &ctx->sub->vbo[index];
3397*bbecb9d1SAndroid Build Coastguard Worker
3398*bbecb9d1SAndroid Build Coastguard Worker if (vbo->base.stride != stride ||
3399*bbecb9d1SAndroid Build Coastguard Worker vbo->base.buffer_offset != buffer_offset ||
3400*bbecb9d1SAndroid Build Coastguard Worker vbo->res_id != res_handle)
3401*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vbo_dirty = true;
3402*bbecb9d1SAndroid Build Coastguard Worker
3403*bbecb9d1SAndroid Build Coastguard Worker vbo->base.stride = stride;
3404*bbecb9d1SAndroid Build Coastguard Worker vbo->base.buffer_offset = buffer_offset;
3405*bbecb9d1SAndroid Build Coastguard Worker
3406*bbecb9d1SAndroid Build Coastguard Worker if (res_handle == 0) {
3407*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference((struct vrend_resource **)&vbo->base.buffer, NULL);
3408*bbecb9d1SAndroid Build Coastguard Worker vbo->res_id = 0;
3409*bbecb9d1SAndroid Build Coastguard Worker } else if (vbo->res_id != res_handle) {
3410*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
3411*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
3412*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
3413*bbecb9d1SAndroid Build Coastguard Worker vbo->res_id = 0;
3414*bbecb9d1SAndroid Build Coastguard Worker return;
3415*bbecb9d1SAndroid Build Coastguard Worker }
3416*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference((struct vrend_resource **)&vbo->base.buffer, res);
3417*bbecb9d1SAndroid Build Coastguard Worker vbo->res_id = res_handle;
3418*bbecb9d1SAndroid Build Coastguard Worker }
3419*bbecb9d1SAndroid Build Coastguard Worker }
3420*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_num_vbo_sub(struct vrend_sub_context * sub,int num_vbo)3421*bbecb9d1SAndroid Build Coastguard Worker static void vrend_set_num_vbo_sub(struct vrend_sub_context *sub,
3422*bbecb9d1SAndroid Build Coastguard Worker int num_vbo)
3423*bbecb9d1SAndroid Build Coastguard Worker {
3424*bbecb9d1SAndroid Build Coastguard Worker int old_num = sub->num_vbos;
3425*bbecb9d1SAndroid Build Coastguard Worker int i;
3426*bbecb9d1SAndroid Build Coastguard Worker
3427*bbecb9d1SAndroid Build Coastguard Worker sub->num_vbos = num_vbo;
3428*bbecb9d1SAndroid Build Coastguard Worker sub->old_num_vbos = old_num;
3429*bbecb9d1SAndroid Build Coastguard Worker
3430*bbecb9d1SAndroid Build Coastguard Worker if (old_num != num_vbo)
3431*bbecb9d1SAndroid Build Coastguard Worker sub->vbo_dirty = true;
3432*bbecb9d1SAndroid Build Coastguard Worker
3433*bbecb9d1SAndroid Build Coastguard Worker for (i = num_vbo; i < old_num; i++) {
3434*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference((struct vrend_resource **)&sub->vbo[i].base.buffer, NULL);
3435*bbecb9d1SAndroid Build Coastguard Worker sub->vbo[i].res_id = 0;
3436*bbecb9d1SAndroid Build Coastguard Worker }
3437*bbecb9d1SAndroid Build Coastguard Worker
3438*bbecb9d1SAndroid Build Coastguard Worker }
3439*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_num_vbo(struct vrend_context * ctx,int num_vbo)3440*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_num_vbo(struct vrend_context *ctx,
3441*bbecb9d1SAndroid Build Coastguard Worker int num_vbo)
3442*bbecb9d1SAndroid Build Coastguard Worker {
3443*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_vbo_sub(ctx->sub, num_vbo);
3444*bbecb9d1SAndroid Build Coastguard Worker }
3445*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_arb_format(enum virgl_formats format)3446*bbecb9d1SAndroid Build Coastguard Worker static GLenum vrend_get_arb_format(enum virgl_formats format)
3447*bbecb9d1SAndroid Build Coastguard Worker {
3448*bbecb9d1SAndroid Build Coastguard Worker switch (format) {
3449*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A8_UNORM: return GL_R8;
3450*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A8_SINT: return GL_R8I;
3451*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A8_UINT: return GL_R8UI;
3452*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8_UNORM: return GL_R8;
3453*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8_SINT: return GL_R8I;
3454*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8_UINT: return GL_R8UI;
3455*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_UNORM: return GL_R16F;
3456*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_SINT: return GL_R16I;
3457*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_UINT: return GL_R16UI;
3458*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_FLOAT: return GL_R16F;
3459*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32_SINT: return GL_R32F;
3460*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32_UINT: return GL_R32I;
3461*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32_FLOAT: return GL_R32UI;
3462*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8A8_UNORM: return GL_RG8;
3463*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8A8_SINT: return GL_RG8I;
3464*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8A8_UINT: return GL_RG8UI;
3465*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_UNORM: return GL_RG16;
3466*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_SINT: return GL_RG16I;
3467*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_UINT: return GL_RG16UI;
3468*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_FLOAT: return GL_RG16F;
3469*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32A32_FLOAT: return GL_RG32F;
3470*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32A32_SINT: return GL_RG32I;
3471*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32A32_UINT: return GL_RG32UI;
3472*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I8_UNORM: return GL_R8;
3473*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I8_SINT: return GL_R8I;
3474*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I8_UINT: return GL_R8UI;
3475*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_UNORM: return GL_R16;
3476*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_SINT: return GL_R16I;
3477*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_UINT: return GL_R16UI;
3478*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_FLOAT: return GL_R16F;
3479*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I32_FLOAT: return GL_R32F;
3480*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I32_SINT: return GL_R32I;
3481*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I32_UINT: return GL_R32UI;
3482*bbecb9d1SAndroid Build Coastguard Worker default:
3483*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Texture format %s unsupported for texture buffers\n", util_format_name(format));
3484*bbecb9d1SAndroid Build Coastguard Worker return GL_R8;
3485*bbecb9d1SAndroid Build Coastguard Worker }
3486*bbecb9d1SAndroid Build Coastguard Worker }
3487*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_single_sampler_view(struct vrend_context * ctx,uint32_t shader_type,uint32_t index,uint32_t handle)3488*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_single_sampler_view(struct vrend_context *ctx,
3489*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type,
3490*bbecb9d1SAndroid Build Coastguard Worker uint32_t index,
3491*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
3492*bbecb9d1SAndroid Build Coastguard Worker {
3493*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *view = NULL;
3494*bbecb9d1SAndroid Build Coastguard Worker struct vrend_texture *tex;
3495*bbecb9d1SAndroid Build Coastguard Worker
3496*bbecb9d1SAndroid Build Coastguard Worker if (handle) {
3497*bbecb9d1SAndroid Build Coastguard Worker view = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_SAMPLER_VIEW);
3498*bbecb9d1SAndroid Build Coastguard Worker if (!view) {
3499*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->views[shader_type].views[index] = NULL;
3500*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handle);
3501*bbecb9d1SAndroid Build Coastguard Worker return;
3502*bbecb9d1SAndroid Build Coastguard Worker }
3503*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->views[shader_type].views[index] == view) {
3504*bbecb9d1SAndroid Build Coastguard Worker return;
3505*bbecb9d1SAndroid Build Coastguard Worker }
3506*bbecb9d1SAndroid Build Coastguard Worker /* we should have a reference to this texture taken at create time */
3507*bbecb9d1SAndroid Build Coastguard Worker tex = (struct vrend_texture *)view->texture;
3508*bbecb9d1SAndroid Build Coastguard Worker if (!tex) {
3509*bbecb9d1SAndroid Build Coastguard Worker return;
3510*bbecb9d1SAndroid Build Coastguard Worker }
3511*bbecb9d1SAndroid Build Coastguard Worker
3512*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sampler_views_dirty[shader_type] |= 1u << index;
3513*bbecb9d1SAndroid Build Coastguard Worker
3514*bbecb9d1SAndroid Build Coastguard Worker if (!has_bit(view->texture->storage_bits, VREND_STORAGE_GL_BUFFER)) {
3515*bbecb9d1SAndroid Build Coastguard Worker if (view->texture->id == view->id) {
3516*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(view->target, view->id);
3517*bbecb9d1SAndroid Build Coastguard Worker
3518*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_depth_or_stencil(view->format)) {
3519*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false) {
3520*bbecb9d1SAndroid Build Coastguard Worker /* setting depth texture mode is deprecated in core profile */
3521*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->texture->target, GL_DEPTH_TEXTURE_MODE, GL_RED);
3522*bbecb9d1SAndroid Build Coastguard Worker }
3523*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_stencil_texturing)) {
3524*bbecb9d1SAndroid Build Coastguard Worker const struct util_format_description *desc = util_format_description(view->format);
3525*bbecb9d1SAndroid Build Coastguard Worker if (!util_format_has_depth(desc)) {
3526*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->texture->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
3527*bbecb9d1SAndroid Build Coastguard Worker } else {
3528*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->texture->target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
3529*bbecb9d1SAndroid Build Coastguard Worker }
3530*bbecb9d1SAndroid Build Coastguard Worker }
3531*bbecb9d1SAndroid Build Coastguard Worker }
3532*bbecb9d1SAndroid Build Coastguard Worker
3533*bbecb9d1SAndroid Build Coastguard Worker GLuint base_level = view->val1 & 0xff;
3534*bbecb9d1SAndroid Build Coastguard Worker GLuint max_level = (view->val1 >> 8) & 0xff;
3535*bbecb9d1SAndroid Build Coastguard Worker view->levels = max_level - base_level + 1;
3536*bbecb9d1SAndroid Build Coastguard Worker
3537*bbecb9d1SAndroid Build Coastguard Worker if (tex->cur_base != base_level) {
3538*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->texture->target, GL_TEXTURE_BASE_LEVEL, base_level);
3539*bbecb9d1SAndroid Build Coastguard Worker tex->cur_base = base_level;
3540*bbecb9d1SAndroid Build Coastguard Worker }
3541*bbecb9d1SAndroid Build Coastguard Worker if (tex->cur_max != max_level) {
3542*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->texture->target, GL_TEXTURE_MAX_LEVEL, max_level);
3543*bbecb9d1SAndroid Build Coastguard Worker tex->cur_max = max_level;
3544*bbecb9d1SAndroid Build Coastguard Worker }
3545*bbecb9d1SAndroid Build Coastguard Worker if (memcmp(tex->cur_swizzle, view->gl_swizzle, 4 * sizeof(GLint))) {
3546*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
3547*bbecb9d1SAndroid Build Coastguard Worker for (unsigned int i = 0; i < 4; ++i) {
3548*bbecb9d1SAndroid Build Coastguard Worker if (tex->cur_swizzle[i] != view->gl_swizzle[i]) {
3549*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->texture->target, GL_TEXTURE_SWIZZLE_R + i, view->gl_swizzle[i]);
3550*bbecb9d1SAndroid Build Coastguard Worker }
3551*bbecb9d1SAndroid Build Coastguard Worker }
3552*bbecb9d1SAndroid Build Coastguard Worker } else
3553*bbecb9d1SAndroid Build Coastguard Worker glTexParameteriv(view->texture->target, GL_TEXTURE_SWIZZLE_RGBA, view->gl_swizzle);
3554*bbecb9d1SAndroid Build Coastguard Worker memcpy(tex->cur_swizzle, view->gl_swizzle, 4 * sizeof(GLint));
3555*bbecb9d1SAndroid Build Coastguard Worker }
3556*bbecb9d1SAndroid Build Coastguard Worker
3557*bbecb9d1SAndroid Build Coastguard Worker if (tex->cur_srgb_decode != view->srgb_decode && util_format_is_srgb(tex->base.base.format)) {
3558*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_samplers))
3559*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sampler_views_dirty[shader_type] |= (1u << index);
3560*bbecb9d1SAndroid Build Coastguard Worker else if (has_feature(feat_texture_srgb_decode)) {
3561*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(view->texture->target, GL_TEXTURE_SRGB_DECODE_EXT,
3562*bbecb9d1SAndroid Build Coastguard Worker view->srgb_decode);
3563*bbecb9d1SAndroid Build Coastguard Worker tex->cur_srgb_decode = view->srgb_decode;
3564*bbecb9d1SAndroid Build Coastguard Worker }
3565*bbecb9d1SAndroid Build Coastguard Worker }
3566*bbecb9d1SAndroid Build Coastguard Worker }
3567*bbecb9d1SAndroid Build Coastguard Worker } else {
3568*bbecb9d1SAndroid Build Coastguard Worker GLenum internalformat;
3569*bbecb9d1SAndroid Build Coastguard Worker
3570*bbecb9d1SAndroid Build Coastguard Worker if (!view->texture->tbo_tex_id)
3571*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &view->texture->tbo_tex_id);
3572*bbecb9d1SAndroid Build Coastguard Worker
3573*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_BUFFER, view->texture->tbo_tex_id);
3574*bbecb9d1SAndroid Build Coastguard Worker internalformat = tex_conv_table[view->format].internalformat;
3575*bbecb9d1SAndroid Build Coastguard Worker
3576*bbecb9d1SAndroid Build Coastguard Worker if (internalformat == GL_NONE ||
3577*bbecb9d1SAndroid Build Coastguard Worker (vrend_state.use_gles && internalformat == GL_ALPHA8)) {
3578*bbecb9d1SAndroid Build Coastguard Worker internalformat = vrend_get_arb_format(view->format);
3579*bbecb9d1SAndroid Build Coastguard Worker }
3580*bbecb9d1SAndroid Build Coastguard Worker
3581*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_buffer_range)) {
3582*bbecb9d1SAndroid Build Coastguard Worker unsigned offset = view->val0;
3583*bbecb9d1SAndroid Build Coastguard Worker unsigned size = view->val1 - view->val0 + 1;
3584*bbecb9d1SAndroid Build Coastguard Worker int blsize = util_format_get_blocksize(view->format);
3585*bbecb9d1SAndroid Build Coastguard Worker
3586*bbecb9d1SAndroid Build Coastguard Worker if (offset + size > vrend_state.max_texture_buffer_size)
3587*bbecb9d1SAndroid Build Coastguard Worker size = vrend_state.max_texture_buffer_size - offset;
3588*bbecb9d1SAndroid Build Coastguard Worker offset *= blsize;
3589*bbecb9d1SAndroid Build Coastguard Worker size *= blsize;
3590*bbecb9d1SAndroid Build Coastguard Worker glTexBufferRange(GL_TEXTURE_BUFFER, internalformat, view->texture->id, offset, size);
3591*bbecb9d1SAndroid Build Coastguard Worker } else
3592*bbecb9d1SAndroid Build Coastguard Worker glTexBuffer(GL_TEXTURE_BUFFER, internalformat, view->texture->id);
3593*bbecb9d1SAndroid Build Coastguard Worker }
3594*bbecb9d1SAndroid Build Coastguard Worker }
3595*bbecb9d1SAndroid Build Coastguard Worker
3596*bbecb9d1SAndroid Build Coastguard Worker vrend_sampler_view_reference(&ctx->sub->views[shader_type].views[index], view);
3597*bbecb9d1SAndroid Build Coastguard Worker }
3598*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_num_sampler_views(struct vrend_context * ctx,uint32_t shader_type,uint32_t start_slot,uint32_t num_sampler_views)3599*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_num_sampler_views(struct vrend_context *ctx,
3600*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type,
3601*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot,
3602*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_sampler_views)
3603*bbecb9d1SAndroid Build Coastguard Worker {
3604*bbecb9d1SAndroid Build Coastguard Worker int last_slot = start_slot + num_sampler_views;
3605*bbecb9d1SAndroid Build Coastguard Worker int i;
3606*bbecb9d1SAndroid Build Coastguard Worker
3607*bbecb9d1SAndroid Build Coastguard Worker for (i = last_slot; i < ctx->sub->views[shader_type].num_views; i++)
3608*bbecb9d1SAndroid Build Coastguard Worker vrend_sampler_view_reference(&ctx->sub->views[shader_type].views[i], NULL);
3609*bbecb9d1SAndroid Build Coastguard Worker
3610*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->views[shader_type].num_views = last_slot;
3611*bbecb9d1SAndroid Build Coastguard Worker }
3612*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_single_image_view(struct vrend_context * ctx,uint32_t shader_type,uint32_t index,uint32_t format,uint32_t access,uint32_t layer_offset,uint32_t level_size,uint32_t handle)3613*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_single_image_view(struct vrend_context *ctx,
3614*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type,
3615*bbecb9d1SAndroid Build Coastguard Worker uint32_t index,
3616*bbecb9d1SAndroid Build Coastguard Worker uint32_t format, uint32_t access,
3617*bbecb9d1SAndroid Build Coastguard Worker uint32_t layer_offset, uint32_t level_size,
3618*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
3619*bbecb9d1SAndroid Build Coastguard Worker {
3620*bbecb9d1SAndroid Build Coastguard Worker struct vrend_image_view *iview = &ctx->sub->image_views[shader_type][index];
3621*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
3622*bbecb9d1SAndroid Build Coastguard Worker
3623*bbecb9d1SAndroid Build Coastguard Worker if (handle) {
3624*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_images))
3625*bbecb9d1SAndroid Build Coastguard Worker return;
3626*bbecb9d1SAndroid Build Coastguard Worker
3627*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, handle);
3628*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
3629*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, handle);
3630*bbecb9d1SAndroid Build Coastguard Worker return;
3631*bbecb9d1SAndroid Build Coastguard Worker }
3632*bbecb9d1SAndroid Build Coastguard Worker iview->texture = res;
3633*bbecb9d1SAndroid Build Coastguard Worker iview->vformat = format;
3634*bbecb9d1SAndroid Build Coastguard Worker iview->format = tex_conv_table[format].internalformat;
3635*bbecb9d1SAndroid Build Coastguard Worker iview->access = access;
3636*bbecb9d1SAndroid Build Coastguard Worker iview->u.buf.offset = layer_offset;
3637*bbecb9d1SAndroid Build Coastguard Worker iview->u.buf.size = level_size;
3638*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->images_used_mask[shader_type] |= (1u << index);
3639*bbecb9d1SAndroid Build Coastguard Worker } else {
3640*bbecb9d1SAndroid Build Coastguard Worker iview->texture = NULL;
3641*bbecb9d1SAndroid Build Coastguard Worker iview->format = 0;
3642*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->images_used_mask[shader_type] &= ~(1u << index);
3643*bbecb9d1SAndroid Build Coastguard Worker }
3644*bbecb9d1SAndroid Build Coastguard Worker }
3645*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_single_ssbo(struct vrend_context * ctx,uint32_t shader_type,uint32_t index,uint32_t offset,uint32_t length,uint32_t handle)3646*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_single_ssbo(struct vrend_context *ctx,
3647*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type,
3648*bbecb9d1SAndroid Build Coastguard Worker uint32_t index,
3649*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset, uint32_t length,
3650*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
3651*bbecb9d1SAndroid Build Coastguard Worker {
3652*bbecb9d1SAndroid Build Coastguard Worker struct vrend_ssbo *ssbo = &ctx->sub->ssbo[shader_type][index];
3653*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
3654*bbecb9d1SAndroid Build Coastguard Worker
3655*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_ssbo))
3656*bbecb9d1SAndroid Build Coastguard Worker return;
3657*bbecb9d1SAndroid Build Coastguard Worker
3658*bbecb9d1SAndroid Build Coastguard Worker if (handle) {
3659*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, handle);
3660*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
3661*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, handle);
3662*bbecb9d1SAndroid Build Coastguard Worker return;
3663*bbecb9d1SAndroid Build Coastguard Worker }
3664*bbecb9d1SAndroid Build Coastguard Worker ssbo->res = res;
3665*bbecb9d1SAndroid Build Coastguard Worker ssbo->buffer_offset = offset;
3666*bbecb9d1SAndroid Build Coastguard Worker ssbo->buffer_size = length;
3667*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ssbo_used_mask[shader_type] |= (1u << index);
3668*bbecb9d1SAndroid Build Coastguard Worker } else {
3669*bbecb9d1SAndroid Build Coastguard Worker ssbo->res = 0;
3670*bbecb9d1SAndroid Build Coastguard Worker ssbo->buffer_offset = 0;
3671*bbecb9d1SAndroid Build Coastguard Worker ssbo->buffer_size = 0;
3672*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ssbo_used_mask[shader_type] &= ~(1u << index);
3673*bbecb9d1SAndroid Build Coastguard Worker }
3674*bbecb9d1SAndroid Build Coastguard Worker }
3675*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_single_abo(struct vrend_context * ctx,uint32_t index,uint32_t offset,uint32_t length,uint32_t handle)3676*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_single_abo(struct vrend_context *ctx,
3677*bbecb9d1SAndroid Build Coastguard Worker uint32_t index,
3678*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset, uint32_t length,
3679*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
3680*bbecb9d1SAndroid Build Coastguard Worker {
3681*bbecb9d1SAndroid Build Coastguard Worker struct vrend_abo *abo = &ctx->sub->abo[index];
3682*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
3683*bbecb9d1SAndroid Build Coastguard Worker
3684*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_atomic_counters))
3685*bbecb9d1SAndroid Build Coastguard Worker return;
3686*bbecb9d1SAndroid Build Coastguard Worker
3687*bbecb9d1SAndroid Build Coastguard Worker if (handle) {
3688*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, handle);
3689*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
3690*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, handle);
3691*bbecb9d1SAndroid Build Coastguard Worker return;
3692*bbecb9d1SAndroid Build Coastguard Worker }
3693*bbecb9d1SAndroid Build Coastguard Worker abo->res = res;
3694*bbecb9d1SAndroid Build Coastguard Worker abo->buffer_offset = offset;
3695*bbecb9d1SAndroid Build Coastguard Worker abo->buffer_size = length;
3696*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->abo_used_mask |= (1u << index);
3697*bbecb9d1SAndroid Build Coastguard Worker } else {
3698*bbecb9d1SAndroid Build Coastguard Worker abo->res = 0;
3699*bbecb9d1SAndroid Build Coastguard Worker abo->buffer_offset = 0;
3700*bbecb9d1SAndroid Build Coastguard Worker abo->buffer_size = 0;
3701*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->abo_used_mask &= ~(1u << index);
3702*bbecb9d1SAndroid Build Coastguard Worker }
3703*bbecb9d1SAndroid Build Coastguard Worker }
3704*bbecb9d1SAndroid Build Coastguard Worker
vrend_memory_barrier(UNUSED struct vrend_context * ctx,unsigned flags)3705*bbecb9d1SAndroid Build Coastguard Worker void vrend_memory_barrier(UNUSED struct vrend_context *ctx,
3706*bbecb9d1SAndroid Build Coastguard Worker unsigned flags)
3707*bbecb9d1SAndroid Build Coastguard Worker {
3708*bbecb9d1SAndroid Build Coastguard Worker GLbitfield gl_barrier = 0;
3709*bbecb9d1SAndroid Build Coastguard Worker
3710*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_barrier))
3711*bbecb9d1SAndroid Build Coastguard Worker return;
3712*bbecb9d1SAndroid Build Coastguard Worker
3713*bbecb9d1SAndroid Build Coastguard Worker if ((flags & PIPE_BARRIER_ALL) == PIPE_BARRIER_ALL)
3714*bbecb9d1SAndroid Build Coastguard Worker gl_barrier = GL_ALL_BARRIER_BITS;
3715*bbecb9d1SAndroid Build Coastguard Worker else {
3716*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_VERTEX_BUFFER)
3717*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
3718*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_INDEX_BUFFER)
3719*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_ELEMENT_ARRAY_BARRIER_BIT;
3720*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_CONSTANT_BUFFER)
3721*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_UNIFORM_BARRIER_BIT;
3722*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_TEXTURE)
3723*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_TEXTURE_FETCH_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT;
3724*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_IMAGE)
3725*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
3726*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_INDIRECT_BUFFER)
3727*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_COMMAND_BARRIER_BIT;
3728*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_MAPPED_BUFFER)
3729*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT;
3730*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_FRAMEBUFFER)
3731*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_FRAMEBUFFER_BARRIER_BIT;
3732*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_STREAMOUT_BUFFER)
3733*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT;
3734*bbecb9d1SAndroid Build Coastguard Worker if (flags & PIPE_BARRIER_SHADER_BUFFER) {
3735*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_ATOMIC_COUNTER_BARRIER_BIT;
3736*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_ssbo_barrier))
3737*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_SHADER_STORAGE_BARRIER_BIT;
3738*bbecb9d1SAndroid Build Coastguard Worker }
3739*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_qbo) && (flags & PIPE_BARRIER_QUERY_BUFFER))
3740*bbecb9d1SAndroid Build Coastguard Worker gl_barrier |= GL_QUERY_BUFFER_BARRIER_BIT;
3741*bbecb9d1SAndroid Build Coastguard Worker }
3742*bbecb9d1SAndroid Build Coastguard Worker glMemoryBarrier(gl_barrier);
3743*bbecb9d1SAndroid Build Coastguard Worker }
3744*bbecb9d1SAndroid Build Coastguard Worker
vrend_texture_barrier(UNUSED struct vrend_context * ctx,unsigned flags)3745*bbecb9d1SAndroid Build Coastguard Worker void vrend_texture_barrier(UNUSED struct vrend_context *ctx,
3746*bbecb9d1SAndroid Build Coastguard Worker unsigned flags)
3747*bbecb9d1SAndroid Build Coastguard Worker {
3748*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_barrier) && (flags & PIPE_TEXTURE_BARRIER_SAMPLER))
3749*bbecb9d1SAndroid Build Coastguard Worker glTextureBarrier();
3750*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_blend_equation_advanced) && (flags & PIPE_TEXTURE_BARRIER_FRAMEBUFFER))
3751*bbecb9d1SAndroid Build Coastguard Worker glBlendBarrierKHR();
3752*bbecb9d1SAndroid Build Coastguard Worker }
3753*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_shader_object(void * obj_ptr)3754*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_shader_object(void *obj_ptr)
3755*bbecb9d1SAndroid Build Coastguard Worker {
3756*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *state = obj_ptr;
3757*bbecb9d1SAndroid Build Coastguard Worker
3758*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&state, NULL);
3759*bbecb9d1SAndroid Build Coastguard Worker }
3760*bbecb9d1SAndroid Build Coastguard Worker
can_emulate_logicop(enum pipe_logicop op)3761*bbecb9d1SAndroid Build Coastguard Worker static inline bool can_emulate_logicop(enum pipe_logicop op)
3762*bbecb9d1SAndroid Build Coastguard Worker {
3763*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_framebuffer_fetch_non_coherent) ||
3764*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_framebuffer_fetch))
3765*bbecb9d1SAndroid Build Coastguard Worker return true;
3766*bbecb9d1SAndroid Build Coastguard Worker
3767*bbecb9d1SAndroid Build Coastguard Worker /* These ops don't need to read back from the framebuffer */
3768*bbecb9d1SAndroid Build Coastguard Worker switch (op) {
3769*bbecb9d1SAndroid Build Coastguard Worker case PIPE_LOGICOP_CLEAR:
3770*bbecb9d1SAndroid Build Coastguard Worker case PIPE_LOGICOP_COPY:
3771*bbecb9d1SAndroid Build Coastguard Worker case PIPE_LOGICOP_SET:
3772*bbecb9d1SAndroid Build Coastguard Worker case PIPE_LOGICOP_COPY_INVERTED:
3773*bbecb9d1SAndroid Build Coastguard Worker return true;
3774*bbecb9d1SAndroid Build Coastguard Worker default:
3775*bbecb9d1SAndroid Build Coastguard Worker return false;
3776*bbecb9d1SAndroid Build Coastguard Worker }
3777*bbecb9d1SAndroid Build Coastguard Worker }
3778*bbecb9d1SAndroid Build Coastguard Worker
vrend_sync_shader_io(struct vrend_sub_context * sub_ctx,struct vrend_shader_selector * sel,struct vrend_shader_key * key)3779*bbecb9d1SAndroid Build Coastguard Worker static inline void vrend_sync_shader_io(struct vrend_sub_context *sub_ctx,
3780*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel,
3781*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_key *key)
3782*bbecb9d1SAndroid Build Coastguard Worker {
3783*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type type = sel->type;
3784*bbecb9d1SAndroid Build Coastguard Worker
3785*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type prev_type =
3786*bbecb9d1SAndroid Build Coastguard Worker (type != PIPE_SHADER_VERTEX) ? PIPE_SHADER_VERTEX : PIPE_SHADER_INVALID;
3787*bbecb9d1SAndroid Build Coastguard Worker
3788*bbecb9d1SAndroid Build Coastguard Worker /* Gallium sends and binds the shaders in the reverse order, so if an
3789*bbecb9d1SAndroid Build Coastguard Worker * old shader is still bound we should ignore the "previous" (as in
3790*bbecb9d1SAndroid Build Coastguard Worker * execution order) shader when the key is evaluated, unless the currently
3791*bbecb9d1SAndroid Build Coastguard Worker * bound shader selector is actually refers to the current shader. */
3792*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->shaders[type] == sel) {
3793*bbecb9d1SAndroid Build Coastguard Worker switch (type) {
3794*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_GEOMETRY:
3795*bbecb9d1SAndroid Build Coastguard Worker if (key->tcs_present || key->tes_present)
3796*bbecb9d1SAndroid Build Coastguard Worker prev_type = PIPE_SHADER_TESS_EVAL;
3797*bbecb9d1SAndroid Build Coastguard Worker break;
3798*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_FRAGMENT:
3799*bbecb9d1SAndroid Build Coastguard Worker if (key->gs_present)
3800*bbecb9d1SAndroid Build Coastguard Worker prev_type = PIPE_SHADER_GEOMETRY;
3801*bbecb9d1SAndroid Build Coastguard Worker else if (key->tcs_present || key->tes_present)
3802*bbecb9d1SAndroid Build Coastguard Worker prev_type = PIPE_SHADER_TESS_EVAL;
3803*bbecb9d1SAndroid Build Coastguard Worker break;
3804*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_EVAL:
3805*bbecb9d1SAndroid Build Coastguard Worker if (key->tcs_present)
3806*bbecb9d1SAndroid Build Coastguard Worker prev_type = PIPE_SHADER_TESS_CTRL;
3807*bbecb9d1SAndroid Build Coastguard Worker break;
3808*bbecb9d1SAndroid Build Coastguard Worker default:
3809*bbecb9d1SAndroid Build Coastguard Worker break;
3810*bbecb9d1SAndroid Build Coastguard Worker }
3811*bbecb9d1SAndroid Build Coastguard Worker }
3812*bbecb9d1SAndroid Build Coastguard Worker
3813*bbecb9d1SAndroid Build Coastguard Worker
3814*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *prev = prev_type != PIPE_SHADER_INVALID ? sub_ctx->shaders[prev_type] : NULL;
3815*bbecb9d1SAndroid Build Coastguard Worker
3816*bbecb9d1SAndroid Build Coastguard Worker if (prev) {
3817*bbecb9d1SAndroid Build Coastguard Worker if (!prev->sinfo.separable_program || !sel->sinfo.separable_program) {
3818*bbecb9d1SAndroid Build Coastguard Worker key->require_input_arrays = prev->sinfo.has_output_arrays;
3819*bbecb9d1SAndroid Build Coastguard Worker key->in_generic_expected_mask = prev->sinfo.out_generic_emitted_mask;
3820*bbecb9d1SAndroid Build Coastguard Worker key->in_texcoord_expected_mask = prev->sinfo.out_texcoord_emitted_mask;
3821*bbecb9d1SAndroid Build Coastguard Worker key->in_patch_expected_mask = prev->sinfo.out_patch_emitted_mask;
3822*bbecb9d1SAndroid Build Coastguard Worker key->in_arrays = prev->sinfo.output_arrays;
3823*bbecb9d1SAndroid Build Coastguard Worker
3824*bbecb9d1SAndroid Build Coastguard Worker memcpy(key->force_invariant_inputs, prev->sinfo.invariant_outputs, 4 * sizeof(uint32_t));
3825*bbecb9d1SAndroid Build Coastguard Worker }
3826*bbecb9d1SAndroid Build Coastguard Worker
3827*bbecb9d1SAndroid Build Coastguard Worker key->num_in_clip = sub_ctx->shaders[prev_type]->current->var_sinfo.num_out_clip;
3828*bbecb9d1SAndroid Build Coastguard Worker key->num_in_cull = sub_ctx->shaders[prev_type]->current->var_sinfo.num_out_cull;
3829*bbecb9d1SAndroid Build Coastguard Worker
3830*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && type == PIPE_SHADER_FRAGMENT)
3831*bbecb9d1SAndroid Build Coastguard Worker key->fs.available_color_in_bits = sub_ctx->shaders[prev_type]->current->var_sinfo.legacy_color_bits;
3832*bbecb9d1SAndroid Build Coastguard Worker }
3833*bbecb9d1SAndroid Build Coastguard Worker
3834*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type next_type = PIPE_SHADER_INVALID;
3835*bbecb9d1SAndroid Build Coastguard Worker
3836*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_FRAGMENT) {
3837*bbecb9d1SAndroid Build Coastguard Worker key->fs.lower_left_origin = !sub_ctx->fbo_origin_upper_left;
3838*bbecb9d1SAndroid Build Coastguard Worker key->fs.swizzle_output_rgb_to_bgr = sub_ctx->swizzle_output_rgb_to_bgr;
3839*bbecb9d1SAndroid Build Coastguard Worker key->fs.needs_manual_srgb_encode_bitmask = sub_ctx->needs_manual_srgb_encode_bitmask;
3840*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && can_emulate_logicop(sub_ctx->blend_state.logicop_func)) {
3841*bbecb9d1SAndroid Build Coastguard Worker key->fs.logicop_enabled = sub_ctx->blend_state.logicop_enable;
3842*bbecb9d1SAndroid Build Coastguard Worker key->fs.logicop_func = sub_ctx->blend_state.logicop_func;
3843*bbecb9d1SAndroid Build Coastguard Worker }
3844*bbecb9d1SAndroid Build Coastguard Worker int fs_prim_mode = sub_ctx->prim_mode; // inherit draw-call's mode
3845*bbecb9d1SAndroid Build Coastguard Worker
3846*bbecb9d1SAndroid Build Coastguard Worker // Only use coord_replace if frag shader receives GL_POINTS
3847*bbecb9d1SAndroid Build Coastguard Worker if (prev) {
3848*bbecb9d1SAndroid Build Coastguard Worker switch (prev->type) {
3849*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_EVAL:
3850*bbecb9d1SAndroid Build Coastguard Worker if (prev->sinfo.tes_point_mode)
3851*bbecb9d1SAndroid Build Coastguard Worker fs_prim_mode = PIPE_PRIM_POINTS;
3852*bbecb9d1SAndroid Build Coastguard Worker break;
3853*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_GEOMETRY:
3854*bbecb9d1SAndroid Build Coastguard Worker fs_prim_mode = prev->sinfo.gs_out_prim;
3855*bbecb9d1SAndroid Build Coastguard Worker break;
3856*bbecb9d1SAndroid Build Coastguard Worker default:
3857*bbecb9d1SAndroid Build Coastguard Worker break;
3858*bbecb9d1SAndroid Build Coastguard Worker }
3859*bbecb9d1SAndroid Build Coastguard Worker }
3860*bbecb9d1SAndroid Build Coastguard Worker
3861*bbecb9d1SAndroid Build Coastguard Worker key->fs.prim_is_points = (fs_prim_mode == PIPE_PRIM_POINTS);
3862*bbecb9d1SAndroid Build Coastguard Worker key->fs.coord_replace = sub_ctx->rs_state.point_quad_rasterization
3863*bbecb9d1SAndroid Build Coastguard Worker && key->fs.prim_is_points
3864*bbecb9d1SAndroid Build Coastguard Worker ? sub_ctx->rs_state.sprite_coord_enable
3865*bbecb9d1SAndroid Build Coastguard Worker : 0x0;
3866*bbecb9d1SAndroid Build Coastguard Worker
3867*bbecb9d1SAndroid Build Coastguard Worker } else {
3868*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->shaders[PIPE_SHADER_FRAGMENT])
3869*bbecb9d1SAndroid Build Coastguard Worker next_type = PIPE_SHADER_FRAGMENT;
3870*bbecb9d1SAndroid Build Coastguard Worker }
3871*bbecb9d1SAndroid Build Coastguard Worker
3872*bbecb9d1SAndroid Build Coastguard Worker switch (type) {
3873*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_VERTEX:
3874*bbecb9d1SAndroid Build Coastguard Worker if (key->tcs_present)
3875*bbecb9d1SAndroid Build Coastguard Worker next_type = PIPE_SHADER_TESS_CTRL;
3876*bbecb9d1SAndroid Build Coastguard Worker else if (key->gs_present)
3877*bbecb9d1SAndroid Build Coastguard Worker next_type = PIPE_SHADER_GEOMETRY;
3878*bbecb9d1SAndroid Build Coastguard Worker else if (key->tes_present) {
3879*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles)
3880*bbecb9d1SAndroid Build Coastguard Worker next_type = PIPE_SHADER_TESS_EVAL;
3881*bbecb9d1SAndroid Build Coastguard Worker else
3882*bbecb9d1SAndroid Build Coastguard Worker next_type = PIPE_SHADER_TESS_CTRL;
3883*bbecb9d1SAndroid Build Coastguard Worker }
3884*bbecb9d1SAndroid Build Coastguard Worker break;
3885*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_CTRL:
3886*bbecb9d1SAndroid Build Coastguard Worker next_type = PIPE_SHADER_TESS_EVAL;
3887*bbecb9d1SAndroid Build Coastguard Worker break;
3888*bbecb9d1SAndroid Build Coastguard Worker case PIPE_SHADER_TESS_EVAL:
3889*bbecb9d1SAndroid Build Coastguard Worker if (key->gs_present)
3890*bbecb9d1SAndroid Build Coastguard Worker next_type = PIPE_SHADER_GEOMETRY;
3891*bbecb9d1SAndroid Build Coastguard Worker default:
3892*bbecb9d1SAndroid Build Coastguard Worker break;
3893*bbecb9d1SAndroid Build Coastguard Worker }
3894*bbecb9d1SAndroid Build Coastguard Worker
3895*bbecb9d1SAndroid Build Coastguard Worker if (next_type != PIPE_SHADER_INVALID && sub_ctx->shaders[next_type]) {
3896*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->shaders[next_type]->sinfo.separable_program ||
3897*bbecb9d1SAndroid Build Coastguard Worker !sel->sinfo.separable_program) {
3898*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *next = sub_ctx->shaders[next_type];
3899*bbecb9d1SAndroid Build Coastguard Worker
3900*bbecb9d1SAndroid Build Coastguard Worker key->use_pervertex_in = next->sinfo.use_pervertex_in;
3901*bbecb9d1SAndroid Build Coastguard Worker key->require_output_arrays = next->sinfo.has_input_arrays;
3902*bbecb9d1SAndroid Build Coastguard Worker key->out_generic_expected_mask = next->sinfo.in_generic_emitted_mask;
3903*bbecb9d1SAndroid Build Coastguard Worker key->out_texcoord_expected_mask = next->sinfo.in_texcoord_emitted_mask;
3904*bbecb9d1SAndroid Build Coastguard Worker
3905*bbecb9d1SAndroid Build Coastguard Worker /* FS gets the clip/cull info in the key from this shader, so
3906*bbecb9d1SAndroid Build Coastguard Worker * we can avoid re-translating this shader by not updating the
3907*bbecb9d1SAndroid Build Coastguard Worker * info in the key */
3908*bbecb9d1SAndroid Build Coastguard Worker if (next_type != PIPE_SHADER_FRAGMENT) {
3909*bbecb9d1SAndroid Build Coastguard Worker key->num_out_clip = sub_ctx->shaders[next_type]->current->var_sinfo.num_in_clip;
3910*bbecb9d1SAndroid Build Coastguard Worker key->num_out_cull = sub_ctx->shaders[next_type]->current->var_sinfo.num_in_cull;
3911*bbecb9d1SAndroid Build Coastguard Worker }
3912*bbecb9d1SAndroid Build Coastguard Worker
3913*bbecb9d1SAndroid Build Coastguard Worker if (next_type == PIPE_SHADER_FRAGMENT) {
3914*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *fs =
3915*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[PIPE_SHADER_FRAGMENT]->current;
3916*bbecb9d1SAndroid Build Coastguard Worker key->fs_info = fs->var_sinfo.fs_info;
3917*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_VERTEX && sub_ctx->shaders[type]) {
3918*bbecb9d1SAndroid Build Coastguard Worker uint32_t fog_input = sub_ctx->shaders[next_type]->sinfo.fog_input_mask;
3919*bbecb9d1SAndroid Build Coastguard Worker uint32_t fog_output = sub_ctx->shaders[type]->sinfo.fog_output_mask;
3920*bbecb9d1SAndroid Build Coastguard Worker
3921*bbecb9d1SAndroid Build Coastguard Worker // We only want to issue the fixup for inputs not fed by
3922*bbecb9d1SAndroid Build Coastguard Worker // the outputs of the previous stage
3923*bbecb9d1SAndroid Build Coastguard Worker key->vs.fog_fixup_mask = (fog_input ^ fog_output) & fog_input;
3924*bbecb9d1SAndroid Build Coastguard Worker }
3925*bbecb9d1SAndroid Build Coastguard Worker }
3926*bbecb9d1SAndroid Build Coastguard Worker }
3927*bbecb9d1SAndroid Build Coastguard Worker }
3928*bbecb9d1SAndroid Build Coastguard Worker }
3929*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_swizzle(struct vrend_sampler_view * view,GLint swizzle[4])3930*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_get_swizzle(struct vrend_sampler_view *view,
3931*bbecb9d1SAndroid Build Coastguard Worker GLint swizzle[4])
3932*bbecb9d1SAndroid Build Coastguard Worker {
3933*bbecb9d1SAndroid Build Coastguard Worker static const GLint OOOR[] = {GL_ZERO, GL_ZERO, GL_ZERO, GL_RED};
3934*bbecb9d1SAndroid Build Coastguard Worker static const GLint RRR1[] = {GL_RED, GL_RED, GL_RED, GL_ONE};
3935*bbecb9d1SAndroid Build Coastguard Worker static const GLint RRRG[] = {GL_RED, GL_RED, GL_RED, GL_GREEN};
3936*bbecb9d1SAndroid Build Coastguard Worker static const GLint RRRR[] = {GL_RED, GL_RED, GL_RED, GL_RED};
3937*bbecb9d1SAndroid Build Coastguard Worker
3938*bbecb9d1SAndroid Build Coastguard Worker switch (view->format) {
3939*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A8_UNORM:
3940*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A8_SINT:
3941*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A8_UINT:
3942*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A16_UNORM:
3943*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A16_SINT:
3944*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A16_UINT:
3945*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A16_FLOAT:
3946*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A32_SINT:
3947*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A32_UINT:
3948*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_A32_FLOAT:
3949*bbecb9d1SAndroid Build Coastguard Worker memcpy(swizzle, OOOR, 4 * sizeof(GLuint));
3950*bbecb9d1SAndroid Build Coastguard Worker return true;
3951*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8_UNORM:
3952*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8_SINT:
3953*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8_UINT:
3954*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_UNORM:
3955*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_SINT:
3956*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_UINT:
3957*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16_FLOAT:
3958*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32_SINT:
3959*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32_UINT:
3960*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32_FLOAT:
3961*bbecb9d1SAndroid Build Coastguard Worker memcpy(swizzle, RRR1, 4 * sizeof(GLuint));
3962*bbecb9d1SAndroid Build Coastguard Worker return true;
3963*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8A8_UNORM:
3964*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8A8_SINT:
3965*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L8A8_UINT:
3966*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_UNORM:
3967*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_SINT:
3968*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_UINT:
3969*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L16A16_FLOAT:
3970*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32A32_FLOAT:
3971*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32A32_SINT:
3972*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_L32A32_UINT:
3973*bbecb9d1SAndroid Build Coastguard Worker memcpy(swizzle, RRRG, 4 * sizeof(GLuint));
3974*bbecb9d1SAndroid Build Coastguard Worker return true;
3975*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I8_UNORM:
3976*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I8_SINT:
3977*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I8_UINT:
3978*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_UNORM:
3979*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_SINT:
3980*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_UINT:
3981*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I16_FLOAT:
3982*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I32_FLOAT:
3983*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I32_SINT:
3984*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_FORMAT_I32_UINT:
3985*bbecb9d1SAndroid Build Coastguard Worker memcpy(swizzle, RRRR, 4 * sizeof(GLuint));
3986*bbecb9d1SAndroid Build Coastguard Worker return true;
3987*bbecb9d1SAndroid Build Coastguard Worker default:
3988*bbecb9d1SAndroid Build Coastguard Worker if (tex_conv_table[view->format].flags & VIRGL_TEXTURE_NEED_SWIZZLE) {
3989*bbecb9d1SAndroid Build Coastguard Worker swizzle[0] = tex_conv_table[view->format].swizzle[0];
3990*bbecb9d1SAndroid Build Coastguard Worker swizzle[1] = tex_conv_table[view->format].swizzle[1];
3991*bbecb9d1SAndroid Build Coastguard Worker swizzle[2] = tex_conv_table[view->format].swizzle[2];
3992*bbecb9d1SAndroid Build Coastguard Worker swizzle[3] = tex_conv_table[view->format].swizzle[3];
3993*bbecb9d1SAndroid Build Coastguard Worker return true;
3994*bbecb9d1SAndroid Build Coastguard Worker } else {
3995*bbecb9d1SAndroid Build Coastguard Worker return false;
3996*bbecb9d1SAndroid Build Coastguard Worker }
3997*bbecb9d1SAndroid Build Coastguard Worker }
3998*bbecb9d1SAndroid Build Coastguard Worker }
3999*bbecb9d1SAndroid Build Coastguard Worker
4000*bbecb9d1SAndroid Build Coastguard Worker
vrend_fill_shader_key(struct vrend_sub_context * sub_ctx,struct vrend_shader_selector * sel,struct vrend_shader_key * key)4001*bbecb9d1SAndroid Build Coastguard Worker static inline void vrend_fill_shader_key(struct vrend_sub_context *sub_ctx,
4002*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel,
4003*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_key *key)
4004*bbecb9d1SAndroid Build Coastguard Worker {
4005*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type type = sel->type;
4006*bbecb9d1SAndroid Build Coastguard Worker
4007*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile) {
4008*bbecb9d1SAndroid Build Coastguard Worker int i;
4009*bbecb9d1SAndroid Build Coastguard Worker bool add_alpha_test = true;
4010*bbecb9d1SAndroid Build Coastguard Worker
4011*bbecb9d1SAndroid Build Coastguard Worker /* Only use integer info when drawing to avoid stale info.
4012*bbecb9d1SAndroid Build Coastguard Worker * Since we can get here from link_shaders before actually drawing anything,
4013*bbecb9d1SAndroid Build Coastguard Worker * we may have no vertex element array */
4014*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_integer && sub_ctx->drawing && sub_ctx->ve &&
4015*bbecb9d1SAndroid Build Coastguard Worker type == PIPE_SHADER_VERTEX) {
4016*bbecb9d1SAndroid Build Coastguard Worker key->vs.attrib_signed_int_bitmask = sub_ctx->ve->signed_int_bitmask;
4017*bbecb9d1SAndroid Build Coastguard Worker key->vs.attrib_unsigned_int_bitmask = sub_ctx->ve->unsigned_int_bitmask;
4018*bbecb9d1SAndroid Build Coastguard Worker }
4019*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_FRAGMENT) {
4020*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < sub_ctx->nr_cbufs; i++) {
4021*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->surf[i])
4022*bbecb9d1SAndroid Build Coastguard Worker continue;
4023*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_is_emulated_alpha(sub_ctx->surf[i]->format))
4024*bbecb9d1SAndroid Build Coastguard Worker key->fs.cbufs_are_a8_bitmask |= (1 << i);
4025*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_pure_integer(sub_ctx->surf[i]->format)) {
4026*bbecb9d1SAndroid Build Coastguard Worker add_alpha_test = false;
4027*bbecb9d1SAndroid Build Coastguard Worker UPDATE_INT_SIGN_MASK(sub_ctx->surf[i]->format, i,
4028*bbecb9d1SAndroid Build Coastguard Worker key->fs.cbufs_signed_int_bitmask,
4029*bbecb9d1SAndroid Build Coastguard Worker key->fs.cbufs_unsigned_int_bitmask);
4030*bbecb9d1SAndroid Build Coastguard Worker }
4031*bbecb9d1SAndroid Build Coastguard Worker /* Currently we only use this information if logicop_enable is set */
4032*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->blend_state.logicop_enable) {
4033*bbecb9d1SAndroid Build Coastguard Worker key->fs.surface_component_bits[i] = util_format_get_component_bits(sub_ctx->surf[i]->format, UTIL_FORMAT_COLORSPACE_RGB, 0);
4034*bbecb9d1SAndroid Build Coastguard Worker }
4035*bbecb9d1SAndroid Build Coastguard Worker }
4036*bbecb9d1SAndroid Build Coastguard Worker if (add_alpha_test) {
4037*bbecb9d1SAndroid Build Coastguard Worker key->add_alpha_test = sub_ctx->dsa_state.alpha.enabled;
4038*bbecb9d1SAndroid Build Coastguard Worker key->alpha_test = sub_ctx->dsa_state.alpha.func;
4039*bbecb9d1SAndroid Build Coastguard Worker }
4040*bbecb9d1SAndroid Build Coastguard Worker }
4041*bbecb9d1SAndroid Build Coastguard Worker
4042*bbecb9d1SAndroid Build Coastguard Worker key->pstipple_enabled = sub_ctx->rs_state.poly_stipple_enable;
4043*bbecb9d1SAndroid Build Coastguard Worker key->color_two_side = sub_ctx->rs_state.light_twoside;
4044*bbecb9d1SAndroid Build Coastguard Worker
4045*bbecb9d1SAndroid Build Coastguard Worker key->flatshade = sub_ctx->rs_state.flatshade ? true : false;
4046*bbecb9d1SAndroid Build Coastguard Worker }
4047*bbecb9d1SAndroid Build Coastguard Worker
4048*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && sub_ctx->ve && type == PIPE_SHADER_VERTEX) {
4049*bbecb9d1SAndroid Build Coastguard Worker key->vs.attrib_zyxw_bitmask = sub_ctx->ve->zyxw_bitmask;
4050*bbecb9d1SAndroid Build Coastguard Worker }
4051*bbecb9d1SAndroid Build Coastguard Worker
4052*bbecb9d1SAndroid Build Coastguard Worker key->gs_present = !!sub_ctx->shaders[PIPE_SHADER_GEOMETRY] || type == PIPE_SHADER_GEOMETRY;
4053*bbecb9d1SAndroid Build Coastguard Worker key->tcs_present = !!sub_ctx->shaders[PIPE_SHADER_TESS_CTRL] || type == PIPE_SHADER_TESS_CTRL;
4054*bbecb9d1SAndroid Build Coastguard Worker key->tes_present = !!sub_ctx->shaders[PIPE_SHADER_TESS_EVAL] || type == PIPE_SHADER_TESS_EVAL;
4055*bbecb9d1SAndroid Build Coastguard Worker
4056*bbecb9d1SAndroid Build Coastguard Worker if (type != PIPE_SHADER_COMPUTE)
4057*bbecb9d1SAndroid Build Coastguard Worker vrend_sync_shader_io(sub_ctx, sel, key);
4058*bbecb9d1SAndroid Build Coastguard Worker
4059*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_GEOMETRY)
4060*bbecb9d1SAndroid Build Coastguard Worker key->gs.emit_clip_distance = sub_ctx->rs_state.clip_plane_enable != 0;
4061*bbecb9d1SAndroid Build Coastguard Worker
4062*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < sub_ctx->views[type].num_views; i++) {
4063*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *view = sub_ctx->views[type].views[i];
4064*bbecb9d1SAndroid Build Coastguard Worker if (!view)
4065*bbecb9d1SAndroid Build Coastguard Worker continue;
4066*bbecb9d1SAndroid Build Coastguard Worker
4067*bbecb9d1SAndroid Build Coastguard Worker if (view->emulated_rect) {
4068*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_sampler_views_mask_set(key->sampler_views_emulated_rect_mask, i);
4069*bbecb9d1SAndroid Build Coastguard Worker }
4070*bbecb9d1SAndroid Build Coastguard Worker
4071*bbecb9d1SAndroid Build Coastguard Worker if (view->texture->target == GL_TEXTURE_BUFFER) {
4072*bbecb9d1SAndroid Build Coastguard Worker GLint swizzle[4];
4073*bbecb9d1SAndroid Build Coastguard Worker if (vrend_get_swizzle(view, swizzle)) {
4074*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_sampler_views_mask_set(key->sampler_views_lower_swizzle_mask, i);
4075*bbecb9d1SAndroid Build Coastguard Worker key->tex_swizzle[i] = to_pipe_swizzle(swizzle[0]) |
4076*bbecb9d1SAndroid Build Coastguard Worker to_pipe_swizzle(swizzle[1]) << 3 |
4077*bbecb9d1SAndroid Build Coastguard Worker to_pipe_swizzle(swizzle[2]) << 6 |
4078*bbecb9d1SAndroid Build Coastguard Worker to_pipe_swizzle(swizzle[3]) << 9;
4079*bbecb9d1SAndroid Build Coastguard Worker }
4080*bbecb9d1SAndroid Build Coastguard Worker }
4081*bbecb9d1SAndroid Build Coastguard Worker }
4082*bbecb9d1SAndroid Build Coastguard Worker }
4083*bbecb9d1SAndroid Build Coastguard Worker
vrend_shader_create(struct vrend_context * ctx,struct vrend_shader * shader,struct vrend_shader_key * key)4084*bbecb9d1SAndroid Build Coastguard Worker static int vrend_shader_create(struct vrend_context *ctx,
4085*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *shader,
4086*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_key *key)
4087*bbecb9d1SAndroid Build Coastguard Worker {
4088*bbecb9d1SAndroid Build Coastguard Worker static uint32_t uid;
4089*bbecb9d1SAndroid Build Coastguard Worker
4090*bbecb9d1SAndroid Build Coastguard Worker shader->uid = ++uid;
4091*bbecb9d1SAndroid Build Coastguard Worker
4092*bbecb9d1SAndroid Build Coastguard Worker if (shader->sel->tokens) {
4093*bbecb9d1SAndroid Build Coastguard Worker
4094*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_shader_tgsi, ctx, "shader\n%s\n", shader->sel->tmp_buf);
4095*bbecb9d1SAndroid Build Coastguard Worker
4096*bbecb9d1SAndroid Build Coastguard Worker bool ret = vrend_convert_shader(ctx, &ctx->shader_cfg, shader->sel->tokens,
4097*bbecb9d1SAndroid Build Coastguard Worker shader->sel->req_local_mem, key, &shader->sel->sinfo,
4098*bbecb9d1SAndroid Build Coastguard Worker &shader->var_sinfo, &shader->glsl_strings);
4099*bbecb9d1SAndroid Build Coastguard Worker if (!ret) {
4100*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, shader->sel->type);
4101*bbecb9d1SAndroid Build Coastguard Worker return -1;
4102*bbecb9d1SAndroid Build Coastguard Worker }
4103*bbecb9d1SAndroid Build Coastguard Worker } else if (!ctx->shader_cfg.use_gles && shader->sel->type != PIPE_SHADER_TESS_CTRL) {
4104*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_SHADER, shader->sel->type);
4105*bbecb9d1SAndroid Build Coastguard Worker return -1;
4106*bbecb9d1SAndroid Build Coastguard Worker }
4107*bbecb9d1SAndroid Build Coastguard Worker
4108*bbecb9d1SAndroid Build Coastguard Worker shader->key = *key;
4109*bbecb9d1SAndroid Build Coastguard Worker return 0;
4110*bbecb9d1SAndroid Build Coastguard Worker }
4111*bbecb9d1SAndroid Build Coastguard Worker
vrend_shader_select(struct vrend_sub_context * sub_ctx,struct vrend_shader_selector * sel,bool * dirty)4112*bbecb9d1SAndroid Build Coastguard Worker static int vrend_shader_select(struct vrend_sub_context *sub_ctx,
4113*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel,
4114*bbecb9d1SAndroid Build Coastguard Worker bool *dirty)
4115*bbecb9d1SAndroid Build Coastguard Worker {
4116*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_key key;
4117*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *shader = NULL;
4118*bbecb9d1SAndroid Build Coastguard Worker int r;
4119*bbecb9d1SAndroid Build Coastguard Worker
4120*bbecb9d1SAndroid Build Coastguard Worker memset(&key, 0, sizeof(key));
4121*bbecb9d1SAndroid Build Coastguard Worker vrend_fill_shader_key(sub_ctx, sel, &key);
4122*bbecb9d1SAndroid Build Coastguard Worker
4123*bbecb9d1SAndroid Build Coastguard Worker if (sel->current) {
4124*bbecb9d1SAndroid Build Coastguard Worker if (!memcmp(&sel->current->key, &key, sizeof(key)))
4125*bbecb9d1SAndroid Build Coastguard Worker return 0;
4126*bbecb9d1SAndroid Build Coastguard Worker
4127*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *p = sel->current;
4128*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *c = p->next_variant;
4129*bbecb9d1SAndroid Build Coastguard Worker
4130*bbecb9d1SAndroid Build Coastguard Worker while (c && memcmp(&c->key, &key, sizeof(key)) != 0) {
4131*bbecb9d1SAndroid Build Coastguard Worker p = c;
4132*bbecb9d1SAndroid Build Coastguard Worker c = c->next_variant;
4133*bbecb9d1SAndroid Build Coastguard Worker }
4134*bbecb9d1SAndroid Build Coastguard Worker if (c) {
4135*bbecb9d1SAndroid Build Coastguard Worker p->next_variant = c->next_variant;
4136*bbecb9d1SAndroid Build Coastguard Worker shader = c;
4137*bbecb9d1SAndroid Build Coastguard Worker }
4138*bbecb9d1SAndroid Build Coastguard Worker }
4139*bbecb9d1SAndroid Build Coastguard Worker
4140*bbecb9d1SAndroid Build Coastguard Worker if (!shader) {
4141*bbecb9d1SAndroid Build Coastguard Worker shader = CALLOC_STRUCT(vrend_shader);
4142*bbecb9d1SAndroid Build Coastguard Worker shader->sel = sel;
4143*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&shader->programs);
4144*bbecb9d1SAndroid Build Coastguard Worker strarray_alloc(&shader->glsl_strings, SHADER_MAX_STRINGS);
4145*bbecb9d1SAndroid Build Coastguard Worker
4146*bbecb9d1SAndroid Build Coastguard Worker r = vrend_shader_create(sub_ctx->parent, shader, &key);
4147*bbecb9d1SAndroid Build Coastguard Worker if (r) {
4148*bbecb9d1SAndroid Build Coastguard Worker sel->current = NULL;
4149*bbecb9d1SAndroid Build Coastguard Worker strarray_free(&shader->glsl_strings, true);
4150*bbecb9d1SAndroid Build Coastguard Worker FREE(shader);
4151*bbecb9d1SAndroid Build Coastguard Worker return r;
4152*bbecb9d1SAndroid Build Coastguard Worker }
4153*bbecb9d1SAndroid Build Coastguard Worker }
4154*bbecb9d1SAndroid Build Coastguard Worker if (dirty)
4155*bbecb9d1SAndroid Build Coastguard Worker *dirty = true;
4156*bbecb9d1SAndroid Build Coastguard Worker
4157*bbecb9d1SAndroid Build Coastguard Worker shader->next_variant = sel->current;
4158*bbecb9d1SAndroid Build Coastguard Worker sel->current = shader;
4159*bbecb9d1SAndroid Build Coastguard Worker return 0;
4160*bbecb9d1SAndroid Build Coastguard Worker }
4161*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_shader_state(const struct pipe_stream_output_info * so_info,uint32_t req_local_mem,enum pipe_shader_type pipe_shader_type)4162*bbecb9d1SAndroid Build Coastguard Worker static void *vrend_create_shader_state(const struct pipe_stream_output_info *so_info,
4163*bbecb9d1SAndroid Build Coastguard Worker uint32_t req_local_mem,
4164*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type pipe_shader_type)
4165*bbecb9d1SAndroid Build Coastguard Worker {
4166*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel = CALLOC_STRUCT(vrend_shader_selector);
4167*bbecb9d1SAndroid Build Coastguard Worker
4168*bbecb9d1SAndroid Build Coastguard Worker if (!sel)
4169*bbecb9d1SAndroid Build Coastguard Worker return NULL;
4170*bbecb9d1SAndroid Build Coastguard Worker
4171*bbecb9d1SAndroid Build Coastguard Worker sel->req_local_mem = req_local_mem;
4172*bbecb9d1SAndroid Build Coastguard Worker sel->type = pipe_shader_type;
4173*bbecb9d1SAndroid Build Coastguard Worker sel->sinfo.so_info = *so_info;
4174*bbecb9d1SAndroid Build Coastguard Worker pipe_reference_init(&sel->reference, 1);
4175*bbecb9d1SAndroid Build Coastguard Worker
4176*bbecb9d1SAndroid Build Coastguard Worker return sel;
4177*bbecb9d1SAndroid Build Coastguard Worker }
4178*bbecb9d1SAndroid Build Coastguard Worker
vrend_finish_shader(struct vrend_context * ctx,struct vrend_shader_selector * sel,const struct tgsi_token * tokens)4179*bbecb9d1SAndroid Build Coastguard Worker static int vrend_finish_shader(struct vrend_context *ctx,
4180*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel,
4181*bbecb9d1SAndroid Build Coastguard Worker const struct tgsi_token *tokens)
4182*bbecb9d1SAndroid Build Coastguard Worker {
4183*bbecb9d1SAndroid Build Coastguard Worker sel->tokens = tgsi_dup_tokens(tokens);
4184*bbecb9d1SAndroid Build Coastguard Worker
4185*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->shader_cfg.use_gles && sel->type != PIPE_SHADER_COMPUTE)
4186*bbecb9d1SAndroid Build Coastguard Worker sel->sinfo.separable_program =
4187*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_query_separable_program(sel->tokens, &ctx->shader_cfg);
4188*bbecb9d1SAndroid Build Coastguard Worker
4189*bbecb9d1SAndroid Build Coastguard Worker return vrend_shader_select(ctx->sub, sel, NULL) ? EINVAL : 0;
4190*bbecb9d1SAndroid Build Coastguard Worker }
4191*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_shader(struct vrend_context * ctx,uint32_t handle,const struct pipe_stream_output_info * so_info,uint32_t req_local_mem,const char * shd_text,uint32_t offlen,uint32_t num_tokens,enum pipe_shader_type type,uint32_t pkt_length)4192*bbecb9d1SAndroid Build Coastguard Worker int vrend_create_shader(struct vrend_context *ctx,
4193*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
4194*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_stream_output_info *so_info,
4195*bbecb9d1SAndroid Build Coastguard Worker uint32_t req_local_mem,
4196*bbecb9d1SAndroid Build Coastguard Worker const char *shd_text, uint32_t offlen, uint32_t num_tokens,
4197*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type type, uint32_t pkt_length)
4198*bbecb9d1SAndroid Build Coastguard Worker {
4199*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel = NULL;
4200*bbecb9d1SAndroid Build Coastguard Worker int ret_handle;
4201*bbecb9d1SAndroid Build Coastguard Worker bool finished = false;
4202*bbecb9d1SAndroid Build Coastguard Worker int ret;
4203*bbecb9d1SAndroid Build Coastguard Worker
4204*bbecb9d1SAndroid Build Coastguard Worker if (type > PIPE_SHADER_COMPUTE)
4205*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4206*bbecb9d1SAndroid Build Coastguard Worker
4207*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_GEOMETRY &&
4208*bbecb9d1SAndroid Build Coastguard Worker !has_feature(feat_geometry_shader))
4209*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4210*bbecb9d1SAndroid Build Coastguard Worker
4211*bbecb9d1SAndroid Build Coastguard Worker if ((type == PIPE_SHADER_TESS_CTRL ||
4212*bbecb9d1SAndroid Build Coastguard Worker type == PIPE_SHADER_TESS_EVAL) &&
4213*bbecb9d1SAndroid Build Coastguard Worker !has_feature(feat_tessellation))
4214*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4215*bbecb9d1SAndroid Build Coastguard Worker
4216*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_COMPUTE &&
4217*bbecb9d1SAndroid Build Coastguard Worker !has_feature(feat_compute_shader))
4218*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4219*bbecb9d1SAndroid Build Coastguard Worker
4220*bbecb9d1SAndroid Build Coastguard Worker /* offlen & VIRGL_OBJ_SHADER_OFFSET_CONT declares whether we have a new shader or
4221*bbecb9d1SAndroid Build Coastguard Worker * a shader continuation
4222*bbecb9d1SAndroid Build Coastguard Worker *
4223*bbecb9d1SAndroid Build Coastguard Worker * offlen & ~VIRGL_OBJ_SHADER_OFFSET_CONT
4224*bbecb9d1SAndroid Build Coastguard Worker * is the total shader length for a new shader (new_shader == true)
4225*bbecb9d1SAndroid Build Coastguard Worker * the continuation offset for a shader continuation (new_shader == false) */
4226*bbecb9d1SAndroid Build Coastguard Worker bool new_shader = !(offlen & VIRGL_OBJ_SHADER_OFFSET_CONT);
4227*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx = ctx->sub;
4228*bbecb9d1SAndroid Build Coastguard Worker
4229*bbecb9d1SAndroid Build Coastguard Worker /* if we have an in progress one - don't allow a new shader
4230*bbecb9d1SAndroid Build Coastguard Worker of that type or a different handle. */
4231*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->long_shader_in_progress_handle[type]) {
4232*bbecb9d1SAndroid Build Coastguard Worker if (new_shader == true)
4233*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4234*bbecb9d1SAndroid Build Coastguard Worker if (handle != sub_ctx->long_shader_in_progress_handle[type])
4235*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4236*bbecb9d1SAndroid Build Coastguard Worker }
4237*bbecb9d1SAndroid Build Coastguard Worker
4238*bbecb9d1SAndroid Build Coastguard Worker const uint32_t pkt_length_bytes = pkt_length * 4;
4239*bbecb9d1SAndroid Build Coastguard Worker
4240*bbecb9d1SAndroid Build Coastguard Worker if (new_shader) {
4241*bbecb9d1SAndroid Build Coastguard Worker const uint32_t expected_token_count = (offlen + 3) / 4; /* round up count */
4242*bbecb9d1SAndroid Build Coastguard Worker if (expected_token_count < pkt_length)
4243*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4244*bbecb9d1SAndroid Build Coastguard Worker
4245*bbecb9d1SAndroid Build Coastguard Worker sel = vrend_create_shader_state(so_info, req_local_mem, type);
4246*bbecb9d1SAndroid Build Coastguard Worker if (sel == NULL)
4247*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
4248*bbecb9d1SAndroid Build Coastguard Worker
4249*bbecb9d1SAndroid Build Coastguard Worker sel->buf_len = expected_token_count * 4;
4250*bbecb9d1SAndroid Build Coastguard Worker sel->tmp_buf = malloc(sel->buf_len);
4251*bbecb9d1SAndroid Build Coastguard Worker if (!sel->tmp_buf) {
4252*bbecb9d1SAndroid Build Coastguard Worker ret = ENOMEM;
4253*bbecb9d1SAndroid Build Coastguard Worker goto error;
4254*bbecb9d1SAndroid Build Coastguard Worker }
4255*bbecb9d1SAndroid Build Coastguard Worker
4256*bbecb9d1SAndroid Build Coastguard Worker memcpy(sel->tmp_buf, shd_text, pkt_length_bytes);
4257*bbecb9d1SAndroid Build Coastguard Worker if (expected_token_count > pkt_length) {
4258*bbecb9d1SAndroid Build Coastguard Worker sel->buf_offset = pkt_length_bytes;
4259*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->long_shader_in_progress_handle[type] = handle;
4260*bbecb9d1SAndroid Build Coastguard Worker } else
4261*bbecb9d1SAndroid Build Coastguard Worker finished = true;
4262*bbecb9d1SAndroid Build Coastguard Worker } else {
4263*bbecb9d1SAndroid Build Coastguard Worker sel = vrend_object_lookup(sub_ctx->object_hash, handle, VIRGL_OBJECT_SHADER);
4264*bbecb9d1SAndroid Build Coastguard Worker if (!sel) {
4265*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "got continuation without original shader %d\n", handle);
4266*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
4267*bbecb9d1SAndroid Build Coastguard Worker goto error;
4268*bbecb9d1SAndroid Build Coastguard Worker }
4269*bbecb9d1SAndroid Build Coastguard Worker
4270*bbecb9d1SAndroid Build Coastguard Worker offlen &= ~VIRGL_OBJ_SHADER_OFFSET_CONT;
4271*bbecb9d1SAndroid Build Coastguard Worker if (offlen != sel->buf_offset) {
4272*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "Got mismatched shader continuation %d vs %d\n",
4273*bbecb9d1SAndroid Build Coastguard Worker offlen, sel->buf_offset);
4274*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
4275*bbecb9d1SAndroid Build Coastguard Worker goto error;
4276*bbecb9d1SAndroid Build Coastguard Worker }
4277*bbecb9d1SAndroid Build Coastguard Worker
4278*bbecb9d1SAndroid Build Coastguard Worker /*make sure no overflow */
4279*bbecb9d1SAndroid Build Coastguard Worker if (pkt_length_bytes < pkt_length ||
4280*bbecb9d1SAndroid Build Coastguard Worker pkt_length_bytes + sel->buf_offset < pkt_length_bytes ||
4281*bbecb9d1SAndroid Build Coastguard Worker pkt_length_bytes + sel->buf_offset < sel->buf_offset) {
4282*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
4283*bbecb9d1SAndroid Build Coastguard Worker goto error;
4284*bbecb9d1SAndroid Build Coastguard Worker }
4285*bbecb9d1SAndroid Build Coastguard Worker
4286*bbecb9d1SAndroid Build Coastguard Worker if ((pkt_length_bytes + sel->buf_offset) > sel->buf_len) {
4287*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Got too large shader continuation %d vs %d\n",
4288*bbecb9d1SAndroid Build Coastguard Worker pkt_length_bytes + sel->buf_offset, sel->buf_len);
4289*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
4290*bbecb9d1SAndroid Build Coastguard Worker goto error;
4291*bbecb9d1SAndroid Build Coastguard Worker }
4292*bbecb9d1SAndroid Build Coastguard Worker
4293*bbecb9d1SAndroid Build Coastguard Worker memcpy(sel->tmp_buf + sel->buf_offset, shd_text, pkt_length_bytes);
4294*bbecb9d1SAndroid Build Coastguard Worker
4295*bbecb9d1SAndroid Build Coastguard Worker sel->buf_offset += pkt_length_bytes;
4296*bbecb9d1SAndroid Build Coastguard Worker if (sel->buf_offset >= sel->buf_len) {
4297*bbecb9d1SAndroid Build Coastguard Worker finished = true;
4298*bbecb9d1SAndroid Build Coastguard Worker shd_text = sel->tmp_buf;
4299*bbecb9d1SAndroid Build Coastguard Worker }
4300*bbecb9d1SAndroid Build Coastguard Worker }
4301*bbecb9d1SAndroid Build Coastguard Worker
4302*bbecb9d1SAndroid Build Coastguard Worker if (finished) {
4303*bbecb9d1SAndroid Build Coastguard Worker struct tgsi_token *tokens;
4304*bbecb9d1SAndroid Build Coastguard Worker
4305*bbecb9d1SAndroid Build Coastguard Worker /* check for null termination */
4306*bbecb9d1SAndroid Build Coastguard Worker uint32_t last_chunk_offset = sel->buf_offset ? sel->buf_offset : pkt_length_bytes;
4307*bbecb9d1SAndroid Build Coastguard Worker if (last_chunk_offset < 4 || !memchr(shd_text + last_chunk_offset - 4, '\0', 4)) {
4308*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
4309*bbecb9d1SAndroid Build Coastguard Worker goto error;
4310*bbecb9d1SAndroid Build Coastguard Worker }
4311*bbecb9d1SAndroid Build Coastguard Worker
4312*bbecb9d1SAndroid Build Coastguard Worker tokens = calloc(num_tokens + 10, sizeof(struct tgsi_token));
4313*bbecb9d1SAndroid Build Coastguard Worker if (!tokens) {
4314*bbecb9d1SAndroid Build Coastguard Worker ret = ENOMEM;
4315*bbecb9d1SAndroid Build Coastguard Worker goto error;
4316*bbecb9d1SAndroid Build Coastguard Worker }
4317*bbecb9d1SAndroid Build Coastguard Worker
4318*bbecb9d1SAndroid Build Coastguard Worker if (!tgsi_text_translate((const char *)shd_text, tokens, num_tokens + 10)) {
4319*bbecb9d1SAndroid Build Coastguard Worker free(tokens);
4320*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
4321*bbecb9d1SAndroid Build Coastguard Worker goto error;
4322*bbecb9d1SAndroid Build Coastguard Worker }
4323*bbecb9d1SAndroid Build Coastguard Worker
4324*bbecb9d1SAndroid Build Coastguard Worker if (vrend_finish_shader(ctx, sel, tokens)) {
4325*bbecb9d1SAndroid Build Coastguard Worker free(tokens);
4326*bbecb9d1SAndroid Build Coastguard Worker ret = EINVAL;
4327*bbecb9d1SAndroid Build Coastguard Worker goto error;
4328*bbecb9d1SAndroid Build Coastguard Worker } else if (!VREND_DEBUG_ENABLED) {
4329*bbecb9d1SAndroid Build Coastguard Worker free(sel->tmp_buf);
4330*bbecb9d1SAndroid Build Coastguard Worker sel->tmp_buf = NULL;
4331*bbecb9d1SAndroid Build Coastguard Worker }
4332*bbecb9d1SAndroid Build Coastguard Worker free(tokens);
4333*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->long_shader_in_progress_handle[type] = 0;
4334*bbecb9d1SAndroid Build Coastguard Worker }
4335*bbecb9d1SAndroid Build Coastguard Worker
4336*bbecb9d1SAndroid Build Coastguard Worker if (new_shader) {
4337*bbecb9d1SAndroid Build Coastguard Worker ret_handle = vrend_renderer_object_insert(ctx, sel, handle, VIRGL_OBJECT_SHADER);
4338*bbecb9d1SAndroid Build Coastguard Worker if (ret_handle == 0) {
4339*bbecb9d1SAndroid Build Coastguard Worker ret = ENOMEM;
4340*bbecb9d1SAndroid Build Coastguard Worker goto error;
4341*bbecb9d1SAndroid Build Coastguard Worker }
4342*bbecb9d1SAndroid Build Coastguard Worker }
4343*bbecb9d1SAndroid Build Coastguard Worker
4344*bbecb9d1SAndroid Build Coastguard Worker return 0;
4345*bbecb9d1SAndroid Build Coastguard Worker
4346*bbecb9d1SAndroid Build Coastguard Worker error:
4347*bbecb9d1SAndroid Build Coastguard Worker if (new_shader)
4348*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_shader_selector(sel);
4349*bbecb9d1SAndroid Build Coastguard Worker else
4350*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_object_destroy(ctx, handle);
4351*bbecb9d1SAndroid Build Coastguard Worker
4352*bbecb9d1SAndroid Build Coastguard Worker return ret;
4353*bbecb9d1SAndroid Build Coastguard Worker }
4354*bbecb9d1SAndroid Build Coastguard Worker
vrend_bind_shader(struct vrend_context * ctx,uint32_t handle,enum pipe_shader_type type)4355*bbecb9d1SAndroid Build Coastguard Worker void vrend_bind_shader(struct vrend_context *ctx,
4356*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle, enum pipe_shader_type type)
4357*bbecb9d1SAndroid Build Coastguard Worker {
4358*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel;
4359*bbecb9d1SAndroid Build Coastguard Worker
4360*bbecb9d1SAndroid Build Coastguard Worker if (type > PIPE_SHADER_COMPUTE)
4361*bbecb9d1SAndroid Build Coastguard Worker return;
4362*bbecb9d1SAndroid Build Coastguard Worker
4363*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx = ctx->sub;
4364*bbecb9d1SAndroid Build Coastguard Worker
4365*bbecb9d1SAndroid Build Coastguard Worker if (handle == 0) {
4366*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_COMPUTE)
4367*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->cs_shader_dirty = true;
4368*bbecb9d1SAndroid Build Coastguard Worker else
4369*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shader_dirty = true;
4370*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub_ctx->shaders[type], NULL);
4371*bbecb9d1SAndroid Build Coastguard Worker return;
4372*bbecb9d1SAndroid Build Coastguard Worker }
4373*bbecb9d1SAndroid Build Coastguard Worker
4374*bbecb9d1SAndroid Build Coastguard Worker sel = vrend_object_lookup(sub_ctx->object_hash, handle, VIRGL_OBJECT_SHADER);
4375*bbecb9d1SAndroid Build Coastguard Worker if (!sel)
4376*bbecb9d1SAndroid Build Coastguard Worker return;
4377*bbecb9d1SAndroid Build Coastguard Worker
4378*bbecb9d1SAndroid Build Coastguard Worker if (sel->type != type)
4379*bbecb9d1SAndroid Build Coastguard Worker return;
4380*bbecb9d1SAndroid Build Coastguard Worker
4381*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->shaders[sel->type] != sel) {
4382*bbecb9d1SAndroid Build Coastguard Worker if (type == PIPE_SHADER_COMPUTE)
4383*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->cs_shader_dirty = true;
4384*bbecb9d1SAndroid Build Coastguard Worker else
4385*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shader_dirty = true;
4386*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[sel->type] = 0;
4387*bbecb9d1SAndroid Build Coastguard Worker }
4388*bbecb9d1SAndroid Build Coastguard Worker
4389*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub_ctx->shaders[sel->type], sel);
4390*bbecb9d1SAndroid Build Coastguard Worker }
4391*bbecb9d1SAndroid Build Coastguard Worker
4392*bbecb9d1SAndroid Build Coastguard Worker static float
vrend_color_encode_as_srgb(float color)4393*bbecb9d1SAndroid Build Coastguard Worker vrend_color_encode_as_srgb(float color) {
4394*bbecb9d1SAndroid Build Coastguard Worker return color <= 0.0031308f
4395*bbecb9d1SAndroid Build Coastguard Worker ? 12.92f * color
4396*bbecb9d1SAndroid Build Coastguard Worker : 1.055f * powf(color, (1.f / 2.4f)) - 0.055f;
4397*bbecb9d1SAndroid Build Coastguard Worker }
4398*bbecb9d1SAndroid Build Coastguard Worker
vrend_clear(struct vrend_context * ctx,unsigned buffers,const union pipe_color_union * color,double depth,unsigned stencil)4399*bbecb9d1SAndroid Build Coastguard Worker void vrend_clear(struct vrend_context *ctx,
4400*bbecb9d1SAndroid Build Coastguard Worker unsigned buffers,
4401*bbecb9d1SAndroid Build Coastguard Worker const union pipe_color_union *color,
4402*bbecb9d1SAndroid Build Coastguard Worker double depth, unsigned stencil)
4403*bbecb9d1SAndroid Build Coastguard Worker {
4404*bbecb9d1SAndroid Build Coastguard Worker GLbitfield bits = 0;
4405*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx = ctx->sub;
4406*bbecb9d1SAndroid Build Coastguard Worker
4407*bbecb9d1SAndroid Build Coastguard Worker if (ctx->in_error)
4408*bbecb9d1SAndroid Build Coastguard Worker return;
4409*bbecb9d1SAndroid Build Coastguard Worker
4410*bbecb9d1SAndroid Build Coastguard Worker if (ctx->ctx_switch_pending)
4411*bbecb9d1SAndroid Build Coastguard Worker vrend_finish_context_switch(ctx);
4412*bbecb9d1SAndroid Build Coastguard Worker
4413*bbecb9d1SAndroid Build Coastguard Worker vrend_update_frontface_state(sub_ctx);
4414*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->stencil_state_dirty)
4415*bbecb9d1SAndroid Build Coastguard Worker vrend_update_stencil_state(sub_ctx);
4416*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->scissor_state_dirty)
4417*bbecb9d1SAndroid Build Coastguard Worker vrend_update_scissor_state(sub_ctx);
4418*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->viewport_state_dirty)
4419*bbecb9d1SAndroid Build Coastguard Worker vrend_update_viewport_state(sub_ctx);
4420*bbecb9d1SAndroid Build Coastguard Worker
4421*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(ctx->sub, NULL);
4422*bbecb9d1SAndroid Build Coastguard Worker
4423*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SCISSOR_TEST);
4424*bbecb9d1SAndroid Build Coastguard Worker
4425*bbecb9d1SAndroid Build Coastguard Worker float colorf[4];
4426*bbecb9d1SAndroid Build Coastguard Worker memcpy(colorf, color->f, sizeof(colorf));
4427*bbecb9d1SAndroid Build Coastguard Worker
4428*bbecb9d1SAndroid Build Coastguard Worker {
4429*bbecb9d1SAndroid Build Coastguard Worker struct vrend_surface *surf = sub_ctx->surf[0];
4430*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->nr_cbufs && surf &&
4431*bbecb9d1SAndroid Build Coastguard Worker util_format_is_srgb(surf->format) &&
4432*bbecb9d1SAndroid Build Coastguard Worker !vrend_resource_supports_view(surf->texture, surf->format)) {
4433*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_tex, ctx,
4434*bbecb9d1SAndroid Build Coastguard Worker "manually converting glClearColor from linear->srgb colorspace for EGL-backed framebuffer color attachment"
4435*bbecb9d1SAndroid Build Coastguard Worker " (surface format is %s; resource format is %s)\n",
4436*bbecb9d1SAndroid Build Coastguard Worker util_format_name(surf->format),
4437*bbecb9d1SAndroid Build Coastguard Worker util_format_name(surf->texture->base.format));
4438*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i) // i < 3: don't convert alpha channel
4439*bbecb9d1SAndroid Build Coastguard Worker colorf[i] = vrend_color_encode_as_srgb(colorf[i]);
4440*bbecb9d1SAndroid Build Coastguard Worker }
4441*bbecb9d1SAndroid Build Coastguard Worker }
4442*bbecb9d1SAndroid Build Coastguard Worker
4443*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_COLOR) {
4444*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->nr_cbufs && sub_ctx->surf[0] && vrend_format_is_emulated_alpha(sub_ctx->surf[0]->format)) {
4445*bbecb9d1SAndroid Build Coastguard Worker glClearColor(colorf[3], 0.0, 0.0, 0.0);
4446*bbecb9d1SAndroid Build Coastguard Worker } else if (sub_ctx->nr_cbufs && sub_ctx->surf[0] &&
4447*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_needs_redblue_swizzle(sub_ctx->surf[0]->texture, sub_ctx->surf[0]->format)) {
4448*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_bgra, ctx, "swizzling glClearColor() since rendering surface is an externally-stored BGR* resource\n");
4449*bbecb9d1SAndroid Build Coastguard Worker glClearColor(colorf[2], colorf[1], colorf[0], colorf[3]);
4450*bbecb9d1SAndroid Build Coastguard Worker } else {
4451*bbecb9d1SAndroid Build Coastguard Worker glClearColor(colorf[0], colorf[1], colorf[2], colorf[3]);
4452*bbecb9d1SAndroid Build Coastguard Worker }
4453*bbecb9d1SAndroid Build Coastguard Worker
4454*bbecb9d1SAndroid Build Coastguard Worker /* This function implements Gallium's full clear callback (st->pipe->clear) on the host. This
4455*bbecb9d1SAndroid Build Coastguard Worker callback requires no color component be masked. We must unmask all components before
4456*bbecb9d1SAndroid Build Coastguard Worker calling glClear* and restore the previous colormask afterwards, as Gallium expects. */
4457*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->hw_blend_state.independent_blend_enable &&
4458*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_indep_blend)) {
4459*bbecb9d1SAndroid Build Coastguard Worker int i;
4460*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
4461*bbecb9d1SAndroid Build Coastguard Worker glColorMaskIndexedEXT(i, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
4462*bbecb9d1SAndroid Build Coastguard Worker } else
4463*bbecb9d1SAndroid Build Coastguard Worker glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
4464*bbecb9d1SAndroid Build Coastguard Worker }
4465*bbecb9d1SAndroid Build Coastguard Worker
4466*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_DEPTH) {
4467*bbecb9d1SAndroid Build Coastguard Worker /* gallium clears don't respect depth mask */
4468*bbecb9d1SAndroid Build Coastguard Worker glDepthMask(GL_TRUE);
4469*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
4470*bbecb9d1SAndroid Build Coastguard Worker if (0.0f < depth && depth > 1.0f) {
4471*bbecb9d1SAndroid Build Coastguard Worker // Only warn, it is clamped by the function.
4472*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_DEPTH_CLEAR);
4473*bbecb9d1SAndroid Build Coastguard Worker }
4474*bbecb9d1SAndroid Build Coastguard Worker glClearDepthf(depth);
4475*bbecb9d1SAndroid Build Coastguard Worker } else {
4476*bbecb9d1SAndroid Build Coastguard Worker glClearDepth(depth);
4477*bbecb9d1SAndroid Build Coastguard Worker }
4478*bbecb9d1SAndroid Build Coastguard Worker }
4479*bbecb9d1SAndroid Build Coastguard Worker
4480*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_STENCIL) {
4481*bbecb9d1SAndroid Build Coastguard Worker glStencilMask(~0u);
4482*bbecb9d1SAndroid Build Coastguard Worker glClearStencil(stencil);
4483*bbecb9d1SAndroid Build Coastguard Worker }
4484*bbecb9d1SAndroid Build Coastguard Worker
4485*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->hw_rs_state.rasterizer_discard)
4486*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_RASTERIZER_DISCARD);
4487*bbecb9d1SAndroid Build Coastguard Worker
4488*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_COLOR) {
4489*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask = 0;
4490*bbecb9d1SAndroid Build Coastguard Worker int i;
4491*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < sub_ctx->nr_cbufs; i++) {
4492*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->surf[i])
4493*bbecb9d1SAndroid Build Coastguard Worker mask |= (1 << i);
4494*bbecb9d1SAndroid Build Coastguard Worker }
4495*bbecb9d1SAndroid Build Coastguard Worker if (mask != (buffers >> 2)) {
4496*bbecb9d1SAndroid Build Coastguard Worker mask = buffers >> 2;
4497*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
4498*bbecb9d1SAndroid Build Coastguard Worker i = u_bit_scan(&mask);
4499*bbecb9d1SAndroid Build Coastguard Worker if (i < PIPE_MAX_COLOR_BUFS && sub_ctx->surf[i] && util_format_is_pure_uint(sub_ctx->surf[i] && sub_ctx->surf[i]->format))
4500*bbecb9d1SAndroid Build Coastguard Worker glClearBufferuiv(GL_COLOR,
4501*bbecb9d1SAndroid Build Coastguard Worker i, (GLuint *)colorf);
4502*bbecb9d1SAndroid Build Coastguard Worker else if (i < PIPE_MAX_COLOR_BUFS && sub_ctx->surf[i] && util_format_is_pure_sint(sub_ctx->surf[i] && sub_ctx->surf[i]->format))
4503*bbecb9d1SAndroid Build Coastguard Worker glClearBufferiv(GL_COLOR,
4504*bbecb9d1SAndroid Build Coastguard Worker i, (GLint *)colorf);
4505*bbecb9d1SAndroid Build Coastguard Worker else
4506*bbecb9d1SAndroid Build Coastguard Worker glClearBufferfv(GL_COLOR,
4507*bbecb9d1SAndroid Build Coastguard Worker i, (GLfloat *)colorf);
4508*bbecb9d1SAndroid Build Coastguard Worker }
4509*bbecb9d1SAndroid Build Coastguard Worker }
4510*bbecb9d1SAndroid Build Coastguard Worker else
4511*bbecb9d1SAndroid Build Coastguard Worker bits |= GL_COLOR_BUFFER_BIT;
4512*bbecb9d1SAndroid Build Coastguard Worker }
4513*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_DEPTH)
4514*bbecb9d1SAndroid Build Coastguard Worker bits |= GL_DEPTH_BUFFER_BIT;
4515*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_STENCIL)
4516*bbecb9d1SAndroid Build Coastguard Worker bits |= GL_STENCIL_BUFFER_BIT;
4517*bbecb9d1SAndroid Build Coastguard Worker
4518*bbecb9d1SAndroid Build Coastguard Worker if (bits)
4519*bbecb9d1SAndroid Build Coastguard Worker glClear(bits);
4520*bbecb9d1SAndroid Build Coastguard Worker
4521*bbecb9d1SAndroid Build Coastguard Worker /* Is it really necessary to restore the old states? The only reason we
4522*bbecb9d1SAndroid Build Coastguard Worker * get here is because the guest cleared all those states but gallium
4523*bbecb9d1SAndroid Build Coastguard Worker * didn't forward them before calling the clear command
4524*bbecb9d1SAndroid Build Coastguard Worker */
4525*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->hw_rs_state.rasterizer_discard)
4526*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_RASTERIZER_DISCARD);
4527*bbecb9d1SAndroid Build Coastguard Worker
4528*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_DEPTH) {
4529*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->dsa_state.depth.writemask)
4530*bbecb9d1SAndroid Build Coastguard Worker glDepthMask(GL_FALSE);
4531*bbecb9d1SAndroid Build Coastguard Worker }
4532*bbecb9d1SAndroid Build Coastguard Worker
4533*bbecb9d1SAndroid Build Coastguard Worker /* Restore previous stencil buffer write masks for both front and back faces */
4534*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_STENCIL) {
4535*bbecb9d1SAndroid Build Coastguard Worker glStencilMaskSeparate(GL_FRONT, sub_ctx->dsa_state.stencil[0].writemask);
4536*bbecb9d1SAndroid Build Coastguard Worker glStencilMaskSeparate(GL_BACK, sub_ctx->dsa_state.stencil[1].writemask);
4537*bbecb9d1SAndroid Build Coastguard Worker }
4538*bbecb9d1SAndroid Build Coastguard Worker
4539*bbecb9d1SAndroid Build Coastguard Worker /* Restore previous colormask */
4540*bbecb9d1SAndroid Build Coastguard Worker if (buffers & PIPE_CLEAR_COLOR) {
4541*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->hw_blend_state.independent_blend_enable &&
4542*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_indep_blend)) {
4543*bbecb9d1SAndroid Build Coastguard Worker int i;
4544*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
4545*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_state *blend = &sub_ctx->hw_blend_state;
4546*bbecb9d1SAndroid Build Coastguard Worker glColorMaskIndexedEXT(i, blend->rt[i].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
4547*bbecb9d1SAndroid Build Coastguard Worker blend->rt[i].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
4548*bbecb9d1SAndroid Build Coastguard Worker blend->rt[i].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
4549*bbecb9d1SAndroid Build Coastguard Worker blend->rt[i].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
4550*bbecb9d1SAndroid Build Coastguard Worker }
4551*bbecb9d1SAndroid Build Coastguard Worker } else {
4552*bbecb9d1SAndroid Build Coastguard Worker glColorMask(sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
4553*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
4554*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
4555*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->hw_blend_state.rt[0].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
4556*bbecb9d1SAndroid Build Coastguard Worker }
4557*bbecb9d1SAndroid Build Coastguard Worker }
4558*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->hw_rs_state.scissor)
4559*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SCISSOR_TEST);
4560*bbecb9d1SAndroid Build Coastguard Worker else
4561*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SCISSOR_TEST);
4562*bbecb9d1SAndroid Build Coastguard Worker }
4563*bbecb9d1SAndroid Build Coastguard Worker
vrend_clear_texture(struct vrend_context * ctx,uint32_t handle,uint32_t level,const struct pipe_box * box,const void * data)4564*bbecb9d1SAndroid Build Coastguard Worker int vrend_clear_texture(struct vrend_context* ctx,
4565*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle, uint32_t level,
4566*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_box *box,
4567*bbecb9d1SAndroid Build Coastguard Worker const void * data)
4568*bbecb9d1SAndroid Build Coastguard Worker {
4569*bbecb9d1SAndroid Build Coastguard Worker GLenum format, type;
4570*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
4571*bbecb9d1SAndroid Build Coastguard Worker
4572*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, handle);
4573*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
4574*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, handle);
4575*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
4576*bbecb9d1SAndroid Build Coastguard Worker }
4577*bbecb9d1SAndroid Build Coastguard Worker
4578*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats fmt = res->base.format;
4579*bbecb9d1SAndroid Build Coastguard Worker format = tex_conv_table[fmt].glformat;
4580*bbecb9d1SAndroid Build Coastguard Worker type = tex_conv_table[fmt].gltype;
4581*bbecb9d1SAndroid Build Coastguard Worker
4582*bbecb9d1SAndroid Build Coastguard Worker /* 32-bit BGRA resources are always reordered to RGBA ordering before
4583*bbecb9d1SAndroid Build Coastguard Worker * submission to the host driver. Reorder red/blue color bytes in
4584*bbecb9d1SAndroid Build Coastguard Worker * the clear color to match. */
4585*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && vrend_format_is_bgra(fmt)) {
4586*bbecb9d1SAndroid Build Coastguard Worker assert(util_format_get_blocksizebits(fmt) >= 24);
4587*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_bgra, ctx, "swizzling clear_texture color for bgra texture\n");
4588*bbecb9d1SAndroid Build Coastguard Worker uint8_t temp = ((uint8_t*)data)[0];
4589*bbecb9d1SAndroid Build Coastguard Worker ((uint8_t*)data)[0] = ((uint8_t*)data)[2];
4590*bbecb9d1SAndroid Build Coastguard Worker ((uint8_t*)data)[2] = temp;
4591*bbecb9d1SAndroid Build Coastguard Worker }
4592*bbecb9d1SAndroid Build Coastguard Worker
4593*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
4594*bbecb9d1SAndroid Build Coastguard Worker glClearTexSubImageEXT(res->id, level,
4595*bbecb9d1SAndroid Build Coastguard Worker box->x, box->y, box->z,
4596*bbecb9d1SAndroid Build Coastguard Worker box->width, box->height, box->depth,
4597*bbecb9d1SAndroid Build Coastguard Worker format, type, data);
4598*bbecb9d1SAndroid Build Coastguard Worker } else {
4599*bbecb9d1SAndroid Build Coastguard Worker glClearTexSubImage(res->id, level,
4600*bbecb9d1SAndroid Build Coastguard Worker box->x, box->y, box->z,
4601*bbecb9d1SAndroid Build Coastguard Worker box->width, box->height, box->depth,
4602*bbecb9d1SAndroid Build Coastguard Worker format, type, data);
4603*bbecb9d1SAndroid Build Coastguard Worker }
4604*bbecb9d1SAndroid Build Coastguard Worker return 0;
4605*bbecb9d1SAndroid Build Coastguard Worker }
4606*bbecb9d1SAndroid Build Coastguard Worker
vrend_update_scissor_state(struct vrend_sub_context * sub_ctx)4607*bbecb9d1SAndroid Build Coastguard Worker static void vrend_update_scissor_state(struct vrend_sub_context *sub_ctx)
4608*bbecb9d1SAndroid Build Coastguard Worker {
4609*bbecb9d1SAndroid Build Coastguard Worker struct pipe_scissor_state *ss;
4610*bbecb9d1SAndroid Build Coastguard Worker GLint y;
4611*bbecb9d1SAndroid Build Coastguard Worker GLuint idx;
4612*bbecb9d1SAndroid Build Coastguard Worker unsigned mask = sub_ctx->scissor_state_dirty;
4613*bbecb9d1SAndroid Build Coastguard Worker
4614*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
4615*bbecb9d1SAndroid Build Coastguard Worker idx = u_bit_scan(&mask);
4616*bbecb9d1SAndroid Build Coastguard Worker if (idx >= PIPE_MAX_VIEWPORTS) {
4617*bbecb9d1SAndroid Build Coastguard Worker vrend_report_buffer_error(sub_ctx->parent, 0);
4618*bbecb9d1SAndroid Build Coastguard Worker break;
4619*bbecb9d1SAndroid Build Coastguard Worker }
4620*bbecb9d1SAndroid Build Coastguard Worker ss = &sub_ctx->ss[idx];
4621*bbecb9d1SAndroid Build Coastguard Worker y = ss->miny;
4622*bbecb9d1SAndroid Build Coastguard Worker
4623*bbecb9d1SAndroid Build Coastguard Worker if (idx > 0 && has_feature(feat_viewport_array))
4624*bbecb9d1SAndroid Build Coastguard Worker glScissorIndexed(idx, ss->minx, y, ss->maxx - ss->minx, ss->maxy - ss->miny);
4625*bbecb9d1SAndroid Build Coastguard Worker else
4626*bbecb9d1SAndroid Build Coastguard Worker glScissor(ss->minx, y, ss->maxx - ss->minx, ss->maxy - ss->miny);
4627*bbecb9d1SAndroid Build Coastguard Worker }
4628*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->scissor_state_dirty = 0;
4629*bbecb9d1SAndroid Build Coastguard Worker }
4630*bbecb9d1SAndroid Build Coastguard Worker
vrend_update_viewport_state(struct vrend_sub_context * sub_ctx)4631*bbecb9d1SAndroid Build Coastguard Worker static void vrend_update_viewport_state(struct vrend_sub_context *sub_ctx)
4632*bbecb9d1SAndroid Build Coastguard Worker {
4633*bbecb9d1SAndroid Build Coastguard Worker GLint cy;
4634*bbecb9d1SAndroid Build Coastguard Worker unsigned mask = sub_ctx->viewport_state_dirty;
4635*bbecb9d1SAndroid Build Coastguard Worker int idx;
4636*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
4637*bbecb9d1SAndroid Build Coastguard Worker idx = u_bit_scan(&mask);
4638*bbecb9d1SAndroid Build Coastguard Worker
4639*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->viewport_is_negative)
4640*bbecb9d1SAndroid Build Coastguard Worker cy = sub_ctx->vps[idx].cur_y - sub_ctx->vps[idx].height;
4641*bbecb9d1SAndroid Build Coastguard Worker else
4642*bbecb9d1SAndroid Build Coastguard Worker cy = sub_ctx->vps[idx].cur_y;
4643*bbecb9d1SAndroid Build Coastguard Worker if (idx > 0 && has_feature(feat_viewport_array))
4644*bbecb9d1SAndroid Build Coastguard Worker glViewportIndexedf(idx, sub_ctx->vps[idx].cur_x, cy, sub_ctx->vps[idx].width, sub_ctx->vps[idx].height);
4645*bbecb9d1SAndroid Build Coastguard Worker else
4646*bbecb9d1SAndroid Build Coastguard Worker glViewport(sub_ctx->vps[idx].cur_x, cy, sub_ctx->vps[idx].width, sub_ctx->vps[idx].height);
4647*bbecb9d1SAndroid Build Coastguard Worker
4648*bbecb9d1SAndroid Build Coastguard Worker if (idx && has_feature(feat_viewport_array))
4649*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
4650*bbecb9d1SAndroid Build Coastguard Worker glDepthRangeIndexedfOES(idx, sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val);
4651*bbecb9d1SAndroid Build Coastguard Worker } else
4652*bbecb9d1SAndroid Build Coastguard Worker glDepthRangeIndexed(idx, sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val);
4653*bbecb9d1SAndroid Build Coastguard Worker else
4654*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles)
4655*bbecb9d1SAndroid Build Coastguard Worker glDepthRangefOES(sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val);
4656*bbecb9d1SAndroid Build Coastguard Worker else
4657*bbecb9d1SAndroid Build Coastguard Worker glDepthRange(sub_ctx->vps[idx].near_val, sub_ctx->vps[idx].far_val);
4658*bbecb9d1SAndroid Build Coastguard Worker }
4659*bbecb9d1SAndroid Build Coastguard Worker
4660*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->viewport_state_dirty = 0;
4661*bbecb9d1SAndroid Build Coastguard Worker }
4662*bbecb9d1SAndroid Build Coastguard Worker
get_gs_xfb_mode(GLenum mode)4663*bbecb9d1SAndroid Build Coastguard Worker static GLenum get_gs_xfb_mode(GLenum mode)
4664*bbecb9d1SAndroid Build Coastguard Worker {
4665*bbecb9d1SAndroid Build Coastguard Worker switch (mode) {
4666*bbecb9d1SAndroid Build Coastguard Worker case GL_POINTS:
4667*bbecb9d1SAndroid Build Coastguard Worker return GL_POINTS;
4668*bbecb9d1SAndroid Build Coastguard Worker case GL_LINE_STRIP:
4669*bbecb9d1SAndroid Build Coastguard Worker return GL_LINES;
4670*bbecb9d1SAndroid Build Coastguard Worker case GL_TRIANGLE_STRIP:
4671*bbecb9d1SAndroid Build Coastguard Worker return GL_TRIANGLES;
4672*bbecb9d1SAndroid Build Coastguard Worker default:
4673*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "illegal gs transform feedback mode %d\n", mode);
4674*bbecb9d1SAndroid Build Coastguard Worker return GL_POINTS;
4675*bbecb9d1SAndroid Build Coastguard Worker }
4676*bbecb9d1SAndroid Build Coastguard Worker }
4677*bbecb9d1SAndroid Build Coastguard Worker
get_tess_xfb_mode(int mode,bool is_point_mode)4678*bbecb9d1SAndroid Build Coastguard Worker static GLenum get_tess_xfb_mode(int mode, bool is_point_mode)
4679*bbecb9d1SAndroid Build Coastguard Worker {
4680*bbecb9d1SAndroid Build Coastguard Worker if (is_point_mode)
4681*bbecb9d1SAndroid Build Coastguard Worker return GL_POINTS;
4682*bbecb9d1SAndroid Build Coastguard Worker switch (mode) {
4683*bbecb9d1SAndroid Build Coastguard Worker case GL_QUADS:
4684*bbecb9d1SAndroid Build Coastguard Worker case GL_TRIANGLES:
4685*bbecb9d1SAndroid Build Coastguard Worker return GL_TRIANGLES;
4686*bbecb9d1SAndroid Build Coastguard Worker case GL_LINES:
4687*bbecb9d1SAndroid Build Coastguard Worker return GL_LINES;
4688*bbecb9d1SAndroid Build Coastguard Worker default:
4689*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "illegal gs transform feedback mode %d\n", mode);
4690*bbecb9d1SAndroid Build Coastguard Worker return GL_POINTS;
4691*bbecb9d1SAndroid Build Coastguard Worker }
4692*bbecb9d1SAndroid Build Coastguard Worker }
4693*bbecb9d1SAndroid Build Coastguard Worker
get_xfb_mode(GLenum mode)4694*bbecb9d1SAndroid Build Coastguard Worker static GLenum get_xfb_mode(GLenum mode)
4695*bbecb9d1SAndroid Build Coastguard Worker {
4696*bbecb9d1SAndroid Build Coastguard Worker switch (mode) {
4697*bbecb9d1SAndroid Build Coastguard Worker case GL_POINTS:
4698*bbecb9d1SAndroid Build Coastguard Worker return GL_POINTS;
4699*bbecb9d1SAndroid Build Coastguard Worker case GL_TRIANGLES:
4700*bbecb9d1SAndroid Build Coastguard Worker case GL_TRIANGLE_STRIP:
4701*bbecb9d1SAndroid Build Coastguard Worker case GL_TRIANGLE_FAN:
4702*bbecb9d1SAndroid Build Coastguard Worker case GL_QUADS:
4703*bbecb9d1SAndroid Build Coastguard Worker case GL_QUAD_STRIP:
4704*bbecb9d1SAndroid Build Coastguard Worker case GL_POLYGON:
4705*bbecb9d1SAndroid Build Coastguard Worker return GL_TRIANGLES;
4706*bbecb9d1SAndroid Build Coastguard Worker case GL_LINES:
4707*bbecb9d1SAndroid Build Coastguard Worker case GL_LINE_LOOP:
4708*bbecb9d1SAndroid Build Coastguard Worker case GL_LINE_STRIP:
4709*bbecb9d1SAndroid Build Coastguard Worker return GL_LINES;
4710*bbecb9d1SAndroid Build Coastguard Worker default:
4711*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failed to translate TFB %d\n", mode);
4712*bbecb9d1SAndroid Build Coastguard Worker return GL_POINTS;
4713*bbecb9d1SAndroid Build Coastguard Worker }
4714*bbecb9d1SAndroid Build Coastguard Worker }
4715*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_vertex_legacy(struct vrend_context * ctx,struct vrend_vertex_element_array * va)4716*bbecb9d1SAndroid Build Coastguard Worker static void vrend_draw_bind_vertex_legacy(struct vrend_context *ctx,
4717*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element_array *va)
4718*bbecb9d1SAndroid Build Coastguard Worker {
4719*bbecb9d1SAndroid Build Coastguard Worker uint32_t enable_bitmask;
4720*bbecb9d1SAndroid Build Coastguard Worker uint32_t disable_bitmask;
4721*bbecb9d1SAndroid Build Coastguard Worker int i;
4722*bbecb9d1SAndroid Build Coastguard Worker
4723*bbecb9d1SAndroid Build Coastguard Worker enable_bitmask = 0;
4724*bbecb9d1SAndroid Build Coastguard Worker disable_bitmask = ~((1ull << va->count) - 1);
4725*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < (int)va->count; i++) {
4726*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element *ve = &va->elements[i];
4727*bbecb9d1SAndroid Build Coastguard Worker int vbo_index = ve->base.vertex_buffer_index;
4728*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
4729*bbecb9d1SAndroid Build Coastguard Worker GLint loc;
4730*bbecb9d1SAndroid Build Coastguard Worker
4731*bbecb9d1SAndroid Build Coastguard Worker if (i >= ctx->sub->prog->ss[PIPE_SHADER_VERTEX]->sel->sinfo.num_inputs) {
4732*bbecb9d1SAndroid Build Coastguard Worker /* XYZZY: debug this? */
4733*bbecb9d1SAndroid Build Coastguard Worker break;
4734*bbecb9d1SAndroid Build Coastguard Worker }
4735*bbecb9d1SAndroid Build Coastguard Worker res = (struct vrend_resource *)ctx->sub->vbo[vbo_index].base.buffer;
4736*bbecb9d1SAndroid Build Coastguard Worker
4737*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
4738*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("cannot find vbo buf %d %d %d\n", i, va->count, ctx->sub->prog->ss[PIPE_SHADER_VERTEX]->sel->sinfo.num_inputs);
4739*bbecb9d1SAndroid Build Coastguard Worker continue;
4740*bbecb9d1SAndroid Build Coastguard Worker }
4741*bbecb9d1SAndroid Build Coastguard Worker
4742*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_explicit_locations || has_feature(feat_gles31_vertex_attrib_binding)) {
4743*bbecb9d1SAndroid Build Coastguard Worker loc = i;
4744*bbecb9d1SAndroid Build Coastguard Worker } else {
4745*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->prog->attrib_locs) {
4746*bbecb9d1SAndroid Build Coastguard Worker loc = ctx->sub->prog->attrib_locs[i];
4747*bbecb9d1SAndroid Build Coastguard Worker } else loc = -1;
4748*bbecb9d1SAndroid Build Coastguard Worker
4749*bbecb9d1SAndroid Build Coastguard Worker if (loc == -1) {
4750*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: cannot find loc %d %d %d\n", ctx->debug_name, i, va->count, ctx->sub->prog->ss[PIPE_SHADER_VERTEX]->sel->sinfo.num_inputs);
4751*bbecb9d1SAndroid Build Coastguard Worker if (i == 0) {
4752*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: shader probably didn't compile - skipping rendering\n", ctx->debug_name);
4753*bbecb9d1SAndroid Build Coastguard Worker return;
4754*bbecb9d1SAndroid Build Coastguard Worker }
4755*bbecb9d1SAndroid Build Coastguard Worker continue;
4756*bbecb9d1SAndroid Build Coastguard Worker }
4757*bbecb9d1SAndroid Build Coastguard Worker }
4758*bbecb9d1SAndroid Build Coastguard Worker
4759*bbecb9d1SAndroid Build Coastguard Worker if (ve->type == GL_FALSE) {
4760*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("failed to translate vertex type - skipping render\n");
4761*bbecb9d1SAndroid Build Coastguard Worker return;
4762*bbecb9d1SAndroid Build Coastguard Worker }
4763*bbecb9d1SAndroid Build Coastguard Worker
4764*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_ARRAY_BUFFER, res->id);
4765*bbecb9d1SAndroid Build Coastguard Worker
4766*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_buffer *vbo = &ctx->sub->vbo[vbo_index];
4767*bbecb9d1SAndroid Build Coastguard Worker
4768*bbecb9d1SAndroid Build Coastguard Worker if (vbo->base.stride == 0) {
4769*bbecb9d1SAndroid Build Coastguard Worker void *data;
4770*bbecb9d1SAndroid Build Coastguard Worker /* for 0 stride we are kinda screwed */
4771*bbecb9d1SAndroid Build Coastguard Worker data = glMapBufferRange(GL_ARRAY_BUFFER, vbo->base.buffer_offset, ve->nr_chan * sizeof(GLfloat), GL_MAP_READ_BIT);
4772*bbecb9d1SAndroid Build Coastguard Worker
4773*bbecb9d1SAndroid Build Coastguard Worker switch (ve->nr_chan) {
4774*bbecb9d1SAndroid Build Coastguard Worker case 1:
4775*bbecb9d1SAndroid Build Coastguard Worker glVertexAttrib1fv(loc, data);
4776*bbecb9d1SAndroid Build Coastguard Worker break;
4777*bbecb9d1SAndroid Build Coastguard Worker case 2:
4778*bbecb9d1SAndroid Build Coastguard Worker glVertexAttrib2fv(loc, data);
4779*bbecb9d1SAndroid Build Coastguard Worker break;
4780*bbecb9d1SAndroid Build Coastguard Worker case 3:
4781*bbecb9d1SAndroid Build Coastguard Worker glVertexAttrib3fv(loc, data);
4782*bbecb9d1SAndroid Build Coastguard Worker break;
4783*bbecb9d1SAndroid Build Coastguard Worker case 4:
4784*bbecb9d1SAndroid Build Coastguard Worker glVertexAttrib4fv(loc, data);
4785*bbecb9d1SAndroid Build Coastguard Worker break;
4786*bbecb9d1SAndroid Build Coastguard Worker }
4787*bbecb9d1SAndroid Build Coastguard Worker glUnmapBuffer(GL_ARRAY_BUFFER);
4788*bbecb9d1SAndroid Build Coastguard Worker disable_bitmask |= (1 << loc);
4789*bbecb9d1SAndroid Build Coastguard Worker } else {
4790*bbecb9d1SAndroid Build Coastguard Worker GLint size = !vrend_state.use_gles && (va->zyxw_bitmask & (1 << i)) ? GL_BGRA : ve->nr_chan;
4791*bbecb9d1SAndroid Build Coastguard Worker
4792*bbecb9d1SAndroid Build Coastguard Worker enable_bitmask |= (1 << loc);
4793*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_pure_integer(ve->base.src_format)) {
4794*bbecb9d1SAndroid Build Coastguard Worker glVertexAttribIPointer(loc, size, ve->type, vbo->base.stride, (void *)(uintptr_t)(ve->base.src_offset + vbo->base.buffer_offset));
4795*bbecb9d1SAndroid Build Coastguard Worker } else {
4796*bbecb9d1SAndroid Build Coastguard Worker glVertexAttribPointer(loc, size, ve->type, ve->norm, vbo->base.stride, (void *)(uintptr_t)(ve->base.src_offset + vbo->base.buffer_offset));
4797*bbecb9d1SAndroid Build Coastguard Worker }
4798*bbecb9d1SAndroid Build Coastguard Worker glVertexAttribDivisorARB(loc, ve->base.instance_divisor);
4799*bbecb9d1SAndroid Build Coastguard Worker }
4800*bbecb9d1SAndroid Build Coastguard Worker }
4801*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->enabled_attribs_bitmask != enable_bitmask) {
4802*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask = ctx->sub->enabled_attribs_bitmask & disable_bitmask;
4803*bbecb9d1SAndroid Build Coastguard Worker
4804*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
4805*bbecb9d1SAndroid Build Coastguard Worker i = u_bit_scan(&mask);
4806*bbecb9d1SAndroid Build Coastguard Worker glDisableVertexAttribArray(i);
4807*bbecb9d1SAndroid Build Coastguard Worker }
4808*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->enabled_attribs_bitmask &= ~disable_bitmask;
4809*bbecb9d1SAndroid Build Coastguard Worker
4810*bbecb9d1SAndroid Build Coastguard Worker mask = ctx->sub->enabled_attribs_bitmask ^ enable_bitmask;
4811*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
4812*bbecb9d1SAndroid Build Coastguard Worker i = u_bit_scan(&mask);
4813*bbecb9d1SAndroid Build Coastguard Worker glEnableVertexAttribArray(i);
4814*bbecb9d1SAndroid Build Coastguard Worker }
4815*bbecb9d1SAndroid Build Coastguard Worker
4816*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->enabled_attribs_bitmask = enable_bitmask;
4817*bbecb9d1SAndroid Build Coastguard Worker }
4818*bbecb9d1SAndroid Build Coastguard Worker }
4819*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_vertex_binding(struct vrend_context * ctx,struct vrend_vertex_element_array * va)4820*bbecb9d1SAndroid Build Coastguard Worker static void vrend_draw_bind_vertex_binding(struct vrend_context *ctx,
4821*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_element_array *va)
4822*bbecb9d1SAndroid Build Coastguard Worker {
4823*bbecb9d1SAndroid Build Coastguard Worker int i;
4824*bbecb9d1SAndroid Build Coastguard Worker
4825*bbecb9d1SAndroid Build Coastguard Worker glBindVertexArray(va->id);
4826*bbecb9d1SAndroid Build Coastguard Worker
4827*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->vbo_dirty) {
4828*bbecb9d1SAndroid Build Coastguard Worker struct vrend_vertex_buffer *vbo = &ctx->sub->vbo[0];
4829*bbecb9d1SAndroid Build Coastguard Worker
4830*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_bind_vertex_buffers)) {
4831*bbecb9d1SAndroid Build Coastguard Worker GLsizei count = MAX2(ctx->sub->num_vbos, ctx->sub->old_num_vbos);
4832*bbecb9d1SAndroid Build Coastguard Worker
4833*bbecb9d1SAndroid Build Coastguard Worker GLuint buffers[PIPE_MAX_ATTRIBS];
4834*bbecb9d1SAndroid Build Coastguard Worker GLintptr offsets[PIPE_MAX_ATTRIBS];
4835*bbecb9d1SAndroid Build Coastguard Worker GLsizei strides[PIPE_MAX_ATTRIBS];
4836*bbecb9d1SAndroid Build Coastguard Worker
4837*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < ctx->sub->num_vbos; i++) {
4838*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)vbo[i].base.buffer;
4839*bbecb9d1SAndroid Build Coastguard Worker if (res) {
4840*bbecb9d1SAndroid Build Coastguard Worker buffers[i] = res->id;
4841*bbecb9d1SAndroid Build Coastguard Worker offsets[i] = vbo[i].base.buffer_offset;
4842*bbecb9d1SAndroid Build Coastguard Worker strides[i] = vbo[i].base.stride;
4843*bbecb9d1SAndroid Build Coastguard Worker } else {
4844*bbecb9d1SAndroid Build Coastguard Worker buffers[i] = 0;
4845*bbecb9d1SAndroid Build Coastguard Worker offsets[i] = 0;
4846*bbecb9d1SAndroid Build Coastguard Worker strides[i] = 0;
4847*bbecb9d1SAndroid Build Coastguard Worker }
4848*bbecb9d1SAndroid Build Coastguard Worker }
4849*bbecb9d1SAndroid Build Coastguard Worker
4850*bbecb9d1SAndroid Build Coastguard Worker for (i = ctx->sub->num_vbos; i < ctx->sub->old_num_vbos; i++) {
4851*bbecb9d1SAndroid Build Coastguard Worker buffers[i] = 0;
4852*bbecb9d1SAndroid Build Coastguard Worker offsets[i] = 0;
4853*bbecb9d1SAndroid Build Coastguard Worker strides[i] = 0;
4854*bbecb9d1SAndroid Build Coastguard Worker }
4855*bbecb9d1SAndroid Build Coastguard Worker
4856*bbecb9d1SAndroid Build Coastguard Worker glBindVertexBuffers(0, count, buffers, offsets, strides);
4857*bbecb9d1SAndroid Build Coastguard Worker } else {
4858*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < ctx->sub->num_vbos; i++) {
4859*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)vbo[i].base.buffer;
4860*bbecb9d1SAndroid Build Coastguard Worker if (res)
4861*bbecb9d1SAndroid Build Coastguard Worker glBindVertexBuffer(i, res->id, vbo[i].base.buffer_offset, vbo[i].base.stride);
4862*bbecb9d1SAndroid Build Coastguard Worker else
4863*bbecb9d1SAndroid Build Coastguard Worker glBindVertexBuffer(i, 0, 0, 0);
4864*bbecb9d1SAndroid Build Coastguard Worker }
4865*bbecb9d1SAndroid Build Coastguard Worker for (i = ctx->sub->num_vbos; i < ctx->sub->old_num_vbos; i++)
4866*bbecb9d1SAndroid Build Coastguard Worker glBindVertexBuffer(i, 0, 0, 0);
4867*bbecb9d1SAndroid Build Coastguard Worker }
4868*bbecb9d1SAndroid Build Coastguard Worker
4869*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->vbo_dirty = false;
4870*bbecb9d1SAndroid Build Coastguard Worker }
4871*bbecb9d1SAndroid Build Coastguard Worker }
4872*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_samplers_shader(struct vrend_sub_context * sub_ctx,int shader_type,int next_sampler_id)4873*bbecb9d1SAndroid Build Coastguard Worker static int vrend_draw_bind_samplers_shader(struct vrend_sub_context *sub_ctx,
4874*bbecb9d1SAndroid Build Coastguard Worker int shader_type,
4875*bbecb9d1SAndroid Build Coastguard Worker int next_sampler_id)
4876*bbecb9d1SAndroid Build Coastguard Worker {
4877*bbecb9d1SAndroid Build Coastguard Worker int sampler_index = 0;
4878*bbecb9d1SAndroid Build Coastguard Worker int n_samplers = 0;
4879*bbecb9d1SAndroid Build Coastguard Worker uint32_t dirty = sub_ctx->sampler_views_dirty[shader_type];
4880*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask = sub_ctx->prog->samplers_used_mask[shader_type];
4881*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_view *sviews = &sub_ctx->views[shader_type];
4882*bbecb9d1SAndroid Build Coastguard Worker
4883*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
4884*bbecb9d1SAndroid Build Coastguard Worker int i = u_bit_scan(&mask);
4885*bbecb9d1SAndroid Build Coastguard Worker
4886*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *tview = sviews->views[i];
4887*bbecb9d1SAndroid Build Coastguard Worker if ((dirty & (1 << i)) && tview) {
4888*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prog->shadow_samp_mask[shader_type] & (1 << i)) {
4889*bbecb9d1SAndroid Build Coastguard Worker struct vrend_texture *tex = (struct vrend_texture *)tview->texture;
4890*bbecb9d1SAndroid Build Coastguard Worker
4891*bbecb9d1SAndroid Build Coastguard Worker /* The modes LUMINANCE, INTENSITY, and ALPHA only apply when a depth texture
4892*bbecb9d1SAndroid Build Coastguard Worker * is used by a sampler that returns an RGBA value, i.e. by sampler*D, if
4893*bbecb9d1SAndroid Build Coastguard Worker * the texture is queries by using sampler*Shadow then these swizzles must
4894*bbecb9d1SAndroid Build Coastguard Worker * not be applied, therefore, reset the swizzled to the default */
4895*bbecb9d1SAndroid Build Coastguard Worker static const GLint swizzle[] = {GL_RED,GL_GREEN,GL_BLUE,GL_ALPHA};
4896*bbecb9d1SAndroid Build Coastguard Worker if (memcmp(tex->cur_swizzle, swizzle, 4 * sizeof(GLint))) {
4897*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
4898*bbecb9d1SAndroid Build Coastguard Worker for (unsigned int i = 0; i < 4; ++i) {
4899*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(tview->texture->target, GL_TEXTURE_SWIZZLE_R + i, swizzle[i]);
4900*bbecb9d1SAndroid Build Coastguard Worker }
4901*bbecb9d1SAndroid Build Coastguard Worker } else {
4902*bbecb9d1SAndroid Build Coastguard Worker glTexParameteriv(tview->texture->target, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
4903*bbecb9d1SAndroid Build Coastguard Worker }
4904*bbecb9d1SAndroid Build Coastguard Worker memcpy(tex->cur_swizzle, swizzle, 4 * sizeof(GLint));
4905*bbecb9d1SAndroid Build Coastguard Worker }
4906*bbecb9d1SAndroid Build Coastguard Worker
4907*bbecb9d1SAndroid Build Coastguard Worker glUniform4f(sub_ctx->prog->shadow_samp_mask_locs[shader_type][sampler_index],
4908*bbecb9d1SAndroid Build Coastguard Worker (tview->gl_swizzle[0] == GL_ZERO || tview->gl_swizzle[0] == GL_ONE) ? 0.0 : 1.0,
4909*bbecb9d1SAndroid Build Coastguard Worker (tview->gl_swizzle[1] == GL_ZERO || tview->gl_swizzle[1] == GL_ONE) ? 0.0 : 1.0,
4910*bbecb9d1SAndroid Build Coastguard Worker (tview->gl_swizzle[2] == GL_ZERO || tview->gl_swizzle[2] == GL_ONE) ? 0.0 : 1.0,
4911*bbecb9d1SAndroid Build Coastguard Worker (tview->gl_swizzle[3] == GL_ZERO || tview->gl_swizzle[3] == GL_ONE) ? 0.0 : 1.0);
4912*bbecb9d1SAndroid Build Coastguard Worker glUniform4f(sub_ctx->prog->shadow_samp_add_locs[shader_type][sampler_index],
4913*bbecb9d1SAndroid Build Coastguard Worker tview->gl_swizzle[0] == GL_ONE ? 1.0 : 0.0,
4914*bbecb9d1SAndroid Build Coastguard Worker tview->gl_swizzle[1] == GL_ONE ? 1.0 : 0.0,
4915*bbecb9d1SAndroid Build Coastguard Worker tview->gl_swizzle[2] == GL_ONE ? 1.0 : 0.0,
4916*bbecb9d1SAndroid Build Coastguard Worker tview->gl_swizzle[3] == GL_ONE ? 1.0 : 0.0);
4917*bbecb9d1SAndroid Build Coastguard Worker }
4918*bbecb9d1SAndroid Build Coastguard Worker
4919*bbecb9d1SAndroid Build Coastguard Worker if (tview->texture) {
4920*bbecb9d1SAndroid Build Coastguard Worker GLuint id = tview->id;
4921*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *texture = tview->texture;
4922*bbecb9d1SAndroid Build Coastguard Worker GLenum target = tview->target;
4923*bbecb9d1SAndroid Build Coastguard Worker
4924*bbecb9d1SAndroid Build Coastguard Worker debug_texture(__func__, tview->texture);
4925*bbecb9d1SAndroid Build Coastguard Worker
4926*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(tview->texture->storage_bits, VREND_STORAGE_GL_BUFFER)) {
4927*bbecb9d1SAndroid Build Coastguard Worker id = texture->tbo_tex_id;
4928*bbecb9d1SAndroid Build Coastguard Worker target = GL_TEXTURE_BUFFER;
4929*bbecb9d1SAndroid Build Coastguard Worker }
4930*bbecb9d1SAndroid Build Coastguard Worker
4931*bbecb9d1SAndroid Build Coastguard Worker glActiveTexture(GL_TEXTURE0 + next_sampler_id);
4932*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(target, id);
4933*bbecb9d1SAndroid Build Coastguard Worker
4934*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
4935*bbecb9d1SAndroid Build Coastguard Worker const unsigned levels = tview->levels ? tview->levels : tview->texture->base.last_level + 1u;
4936*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->texture_levels[shader_type][n_samplers++] = levels;
4937*bbecb9d1SAndroid Build Coastguard Worker }
4938*bbecb9d1SAndroid Build Coastguard Worker
4939*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->views[shader_type].old_ids[i] != id ||
4940*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->sampler_views_dirty[shader_type] & (1 << i)) {
4941*bbecb9d1SAndroid Build Coastguard Worker vrend_apply_sampler_state(sub_ctx, texture, shader_type, i,
4942*bbecb9d1SAndroid Build Coastguard Worker next_sampler_id, tview);
4943*bbecb9d1SAndroid Build Coastguard Worker sviews->old_ids[i] = id;
4944*bbecb9d1SAndroid Build Coastguard Worker }
4945*bbecb9d1SAndroid Build Coastguard Worker dirty &= ~(1 << i);
4946*bbecb9d1SAndroid Build Coastguard Worker }
4947*bbecb9d1SAndroid Build Coastguard Worker }
4948*bbecb9d1SAndroid Build Coastguard Worker sampler_index++;
4949*bbecb9d1SAndroid Build Coastguard Worker next_sampler_id++;
4950*bbecb9d1SAndroid Build Coastguard Worker }
4951*bbecb9d1SAndroid Build Coastguard Worker
4952*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->n_samplers[shader_type] = n_samplers;
4953*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->sampler_views_dirty[shader_type] = dirty;
4954*bbecb9d1SAndroid Build Coastguard Worker
4955*bbecb9d1SAndroid Build Coastguard Worker return next_sampler_id;
4956*bbecb9d1SAndroid Build Coastguard Worker }
4957*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_ubo_shader(struct vrend_sub_context * sub_ctx,int shader_type,int next_ubo_id)4958*bbecb9d1SAndroid Build Coastguard Worker static int vrend_draw_bind_ubo_shader(struct vrend_sub_context *sub_ctx,
4959*bbecb9d1SAndroid Build Coastguard Worker int shader_type, int next_ubo_id)
4960*bbecb9d1SAndroid Build Coastguard Worker {
4961*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask, dirty, update;
4962*bbecb9d1SAndroid Build Coastguard Worker struct pipe_constant_buffer *cb;
4963*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
4964*bbecb9d1SAndroid Build Coastguard Worker
4965*bbecb9d1SAndroid Build Coastguard Worker mask = sub_ctx->prog->ubo_used_mask[shader_type];
4966*bbecb9d1SAndroid Build Coastguard Worker dirty = sub_ctx->const_bufs_dirty[shader_type];
4967*bbecb9d1SAndroid Build Coastguard Worker update = dirty & sub_ctx->const_bufs_used_mask[shader_type];
4968*bbecb9d1SAndroid Build Coastguard Worker
4969*bbecb9d1SAndroid Build Coastguard Worker if (!update)
4970*bbecb9d1SAndroid Build Coastguard Worker return next_ubo_id + util_bitcount(mask);
4971*bbecb9d1SAndroid Build Coastguard Worker
4972*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
4973*bbecb9d1SAndroid Build Coastguard Worker /* The const_bufs_used_mask stores the gallium uniform buffer indices */
4974*bbecb9d1SAndroid Build Coastguard Worker int i = u_bit_scan(&mask);
4975*bbecb9d1SAndroid Build Coastguard Worker
4976*bbecb9d1SAndroid Build Coastguard Worker if (update & (1 << i)) {
4977*bbecb9d1SAndroid Build Coastguard Worker /* The cbs array is indexed using the gallium uniform buffer index */
4978*bbecb9d1SAndroid Build Coastguard Worker cb = &sub_ctx->cbs[shader_type][i];
4979*bbecb9d1SAndroid Build Coastguard Worker res = (struct vrend_resource *)cb->buffer;
4980*bbecb9d1SAndroid Build Coastguard Worker
4981*bbecb9d1SAndroid Build Coastguard Worker glBindBufferRange(GL_UNIFORM_BUFFER, next_ubo_id, res->id,
4982*bbecb9d1SAndroid Build Coastguard Worker cb->buffer_offset, cb->buffer_size);
4983*bbecb9d1SAndroid Build Coastguard Worker dirty &= ~(1 << i);
4984*bbecb9d1SAndroid Build Coastguard Worker }
4985*bbecb9d1SAndroid Build Coastguard Worker next_ubo_id++;
4986*bbecb9d1SAndroid Build Coastguard Worker }
4987*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->const_bufs_dirty[shader_type] = dirty;
4988*bbecb9d1SAndroid Build Coastguard Worker
4989*bbecb9d1SAndroid Build Coastguard Worker return next_ubo_id;
4990*bbecb9d1SAndroid Build Coastguard Worker }
4991*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_const_shader(struct vrend_sub_context * sub_ctx,int shader_type,bool new_program)4992*bbecb9d1SAndroid Build Coastguard Worker static void vrend_draw_bind_const_shader(struct vrend_sub_context *sub_ctx,
4993*bbecb9d1SAndroid Build Coastguard Worker int shader_type, bool new_program)
4994*bbecb9d1SAndroid Build Coastguard Worker {
4995*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->consts[shader_type].consts &&
4996*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[shader_type] &&
4997*bbecb9d1SAndroid Build Coastguard Worker (sub_ctx->prog->const_location[shader_type] != -1) &&
4998*bbecb9d1SAndroid Build Coastguard Worker (sub_ctx->const_dirty[shader_type] || new_program)) {
4999*bbecb9d1SAndroid Build Coastguard Worker glUniform4uiv(sub_ctx->prog->const_location[shader_type],
5000*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[shader_type]->sinfo.num_consts,
5001*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->consts[shader_type].consts);
5002*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->const_dirty[shader_type] = false;
5003*bbecb9d1SAndroid Build Coastguard Worker }
5004*bbecb9d1SAndroid Build Coastguard Worker }
5005*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_ssbo_shader(struct vrend_sub_context * sub_ctx,int shader_type)5006*bbecb9d1SAndroid Build Coastguard Worker static void vrend_draw_bind_ssbo_shader(struct vrend_sub_context *sub_ctx,
5007*bbecb9d1SAndroid Build Coastguard Worker int shader_type)
5008*bbecb9d1SAndroid Build Coastguard Worker {
5009*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask;
5010*bbecb9d1SAndroid Build Coastguard Worker struct vrend_ssbo *ssbo;
5011*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
5012*bbecb9d1SAndroid Build Coastguard Worker int i;
5013*bbecb9d1SAndroid Build Coastguard Worker
5014*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_ssbo))
5015*bbecb9d1SAndroid Build Coastguard Worker return;
5016*bbecb9d1SAndroid Build Coastguard Worker
5017*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->prog->ssbo_used_mask[shader_type])
5018*bbecb9d1SAndroid Build Coastguard Worker return;
5019*bbecb9d1SAndroid Build Coastguard Worker
5020*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->ssbo_used_mask[shader_type])
5021*bbecb9d1SAndroid Build Coastguard Worker return;
5022*bbecb9d1SAndroid Build Coastguard Worker
5023*bbecb9d1SAndroid Build Coastguard Worker mask = sub_ctx->ssbo_used_mask[shader_type];
5024*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
5025*bbecb9d1SAndroid Build Coastguard Worker i = u_bit_scan(&mask);
5026*bbecb9d1SAndroid Build Coastguard Worker
5027*bbecb9d1SAndroid Build Coastguard Worker ssbo = &sub_ctx->ssbo[shader_type][i];
5028*bbecb9d1SAndroid Build Coastguard Worker res = (struct vrend_resource *)ssbo->res;
5029*bbecb9d1SAndroid Build Coastguard Worker glBindBufferRange(GL_SHADER_STORAGE_BUFFER, i, res->id,
5030*bbecb9d1SAndroid Build Coastguard Worker ssbo->buffer_offset, ssbo->buffer_size);
5031*bbecb9d1SAndroid Build Coastguard Worker }
5032*bbecb9d1SAndroid Build Coastguard Worker }
5033*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_abo_shader(struct vrend_sub_context * sub_ctx)5034*bbecb9d1SAndroid Build Coastguard Worker static void vrend_draw_bind_abo_shader(struct vrend_sub_context *sub_ctx)
5035*bbecb9d1SAndroid Build Coastguard Worker {
5036*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask;
5037*bbecb9d1SAndroid Build Coastguard Worker struct vrend_abo *abo;
5038*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
5039*bbecb9d1SAndroid Build Coastguard Worker int i;
5040*bbecb9d1SAndroid Build Coastguard Worker
5041*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_atomic_counters))
5042*bbecb9d1SAndroid Build Coastguard Worker return;
5043*bbecb9d1SAndroid Build Coastguard Worker
5044*bbecb9d1SAndroid Build Coastguard Worker mask = sub_ctx->abo_used_mask;
5045*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
5046*bbecb9d1SAndroid Build Coastguard Worker i = u_bit_scan(&mask);
5047*bbecb9d1SAndroid Build Coastguard Worker
5048*bbecb9d1SAndroid Build Coastguard Worker abo = &sub_ctx->abo[i];
5049*bbecb9d1SAndroid Build Coastguard Worker res = (struct vrend_resource *)abo->res;
5050*bbecb9d1SAndroid Build Coastguard Worker glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, i, res->id,
5051*bbecb9d1SAndroid Build Coastguard Worker abo->buffer_offset, abo->buffer_size);
5052*bbecb9d1SAndroid Build Coastguard Worker }
5053*bbecb9d1SAndroid Build Coastguard Worker }
5054*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_images_shader(struct vrend_sub_context * sub_ctx,int shader_type)5055*bbecb9d1SAndroid Build Coastguard Worker static void vrend_draw_bind_images_shader(struct vrend_sub_context *sub_ctx, int shader_type)
5056*bbecb9d1SAndroid Build Coastguard Worker {
5057*bbecb9d1SAndroid Build Coastguard Worker GLenum access;
5058*bbecb9d1SAndroid Build Coastguard Worker GLboolean layered;
5059*bbecb9d1SAndroid Build Coastguard Worker struct vrend_image_view *iview;
5060*bbecb9d1SAndroid Build Coastguard Worker uint32_t mask, tex_id, level, first_layer;
5061*bbecb9d1SAndroid Build Coastguard Worker
5062*bbecb9d1SAndroid Build Coastguard Worker
5063*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->images_used_mask[shader_type])
5064*bbecb9d1SAndroid Build Coastguard Worker return;
5065*bbecb9d1SAndroid Build Coastguard Worker
5066*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->prog->img_locs[shader_type])
5067*bbecb9d1SAndroid Build Coastguard Worker return;
5068*bbecb9d1SAndroid Build Coastguard Worker
5069*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_images))
5070*bbecb9d1SAndroid Build Coastguard Worker return;
5071*bbecb9d1SAndroid Build Coastguard Worker
5072*bbecb9d1SAndroid Build Coastguard Worker mask = sub_ctx->images_used_mask[shader_type];
5073*bbecb9d1SAndroid Build Coastguard Worker while (mask) {
5074*bbecb9d1SAndroid Build Coastguard Worker unsigned i = u_bit_scan(&mask);
5075*bbecb9d1SAndroid Build Coastguard Worker
5076*bbecb9d1SAndroid Build Coastguard Worker if (!(sub_ctx->prog->images_used_mask[shader_type] & (1 << i)))
5077*bbecb9d1SAndroid Build Coastguard Worker continue;
5078*bbecb9d1SAndroid Build Coastguard Worker iview = &sub_ctx->image_views[shader_type][i];
5079*bbecb9d1SAndroid Build Coastguard Worker tex_id = iview->texture->id;
5080*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(iview->texture->storage_bits, VREND_STORAGE_GL_BUFFER)) {
5081*bbecb9d1SAndroid Build Coastguard Worker if (!iview->texture->tbo_tex_id)
5082*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &iview->texture->tbo_tex_id);
5083*bbecb9d1SAndroid Build Coastguard Worker
5084*bbecb9d1SAndroid Build Coastguard Worker /* glTexBuffer doesn't accept GL_RGBA8_SNORM, find an appropriate replacement. */
5085*bbecb9d1SAndroid Build Coastguard Worker uint32_t format = (iview->format == GL_RGBA8_SNORM) ? GL_RGBA8UI : iview->format;
5086*bbecb9d1SAndroid Build Coastguard Worker
5087*bbecb9d1SAndroid Build Coastguard Worker if (format == GL_NONE ||
5088*bbecb9d1SAndroid Build Coastguard Worker (vrend_state.use_gles && format == GL_ALPHA8)) {
5089*bbecb9d1SAndroid Build Coastguard Worker format = vrend_get_arb_format(iview->vformat);
5090*bbecb9d1SAndroid Build Coastguard Worker }
5091*bbecb9d1SAndroid Build Coastguard Worker
5092*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(GL_TEXTURE_BUFFER, iview->texture->id);
5093*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_BUFFER, iview->texture->tbo_tex_id);
5094*bbecb9d1SAndroid Build Coastguard Worker
5095*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_or_gles_ext_texture_buffer)) {
5096*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_buffer_range)) {
5097*bbecb9d1SAndroid Build Coastguard Worker /* Offset and size are given in byte, but the max_texture_buffer_size
5098*bbecb9d1SAndroid Build Coastguard Worker * is given as texels, so we have to take the blocksize into account.
5099*bbecb9d1SAndroid Build Coastguard Worker * To avoid an unsigned int overflow, we divide by blocksize,
5100*bbecb9d1SAndroid Build Coastguard Worker */
5101*bbecb9d1SAndroid Build Coastguard Worker int blsize = util_format_get_blocksize(iview->vformat);
5102*bbecb9d1SAndroid Build Coastguard Worker unsigned offset = iview->u.buf.offset / blsize;
5103*bbecb9d1SAndroid Build Coastguard Worker unsigned size = iview->u.buf.size / blsize;
5104*bbecb9d1SAndroid Build Coastguard Worker if (offset + size > vrend_state.max_texture_buffer_size)
5105*bbecb9d1SAndroid Build Coastguard Worker size = vrend_state.max_texture_buffer_size - offset;
5106*bbecb9d1SAndroid Build Coastguard Worker glTexBufferRange(GL_TEXTURE_BUFFER, format, iview->texture->id, iview->u.buf.offset,
5107*bbecb9d1SAndroid Build Coastguard Worker size * blsize);
5108*bbecb9d1SAndroid Build Coastguard Worker } else {
5109*bbecb9d1SAndroid Build Coastguard Worker glTexBuffer(GL_TEXTURE_BUFFER, format, iview->texture->id);
5110*bbecb9d1SAndroid Build Coastguard Worker }
5111*bbecb9d1SAndroid Build Coastguard Worker }
5112*bbecb9d1SAndroid Build Coastguard Worker
5113*bbecb9d1SAndroid Build Coastguard Worker tex_id = iview->texture->tbo_tex_id;
5114*bbecb9d1SAndroid Build Coastguard Worker level = first_layer = 0;
5115*bbecb9d1SAndroid Build Coastguard Worker layered = GL_TRUE;
5116*bbecb9d1SAndroid Build Coastguard Worker } else {
5117*bbecb9d1SAndroid Build Coastguard Worker level = iview->u.tex.level;
5118*bbecb9d1SAndroid Build Coastguard Worker first_layer = iview->u.tex.first_layer;
5119*bbecb9d1SAndroid Build Coastguard Worker layered = !((iview->texture->base.array_size > 1 ||
5120*bbecb9d1SAndroid Build Coastguard Worker iview->texture->base.depth0 > 1) && (iview->u.tex.first_layer == iview->u.tex.last_layer));
5121*bbecb9d1SAndroid Build Coastguard Worker }
5122*bbecb9d1SAndroid Build Coastguard Worker
5123*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles)
5124*bbecb9d1SAndroid Build Coastguard Worker glUniform1i(sub_ctx->prog->img_locs[shader_type][i], i);
5125*bbecb9d1SAndroid Build Coastguard Worker
5126*bbecb9d1SAndroid Build Coastguard Worker switch (iview->access) {
5127*bbecb9d1SAndroid Build Coastguard Worker case PIPE_IMAGE_ACCESS_READ:
5128*bbecb9d1SAndroid Build Coastguard Worker access = GL_READ_ONLY;
5129*bbecb9d1SAndroid Build Coastguard Worker break;
5130*bbecb9d1SAndroid Build Coastguard Worker case PIPE_IMAGE_ACCESS_WRITE:
5131*bbecb9d1SAndroid Build Coastguard Worker access = GL_WRITE_ONLY;
5132*bbecb9d1SAndroid Build Coastguard Worker break;
5133*bbecb9d1SAndroid Build Coastguard Worker case PIPE_IMAGE_ACCESS_READ_WRITE:
5134*bbecb9d1SAndroid Build Coastguard Worker access = GL_READ_WRITE;
5135*bbecb9d1SAndroid Build Coastguard Worker break;
5136*bbecb9d1SAndroid Build Coastguard Worker default:
5137*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "Invalid access specified\n");
5138*bbecb9d1SAndroid Build Coastguard Worker return;
5139*bbecb9d1SAndroid Build Coastguard Worker }
5140*bbecb9d1SAndroid Build Coastguard Worker
5141*bbecb9d1SAndroid Build Coastguard Worker glBindImageTexture(i, tex_id, level, layered, first_layer, access, iview->format);
5142*bbecb9d1SAndroid Build Coastguard Worker }
5143*bbecb9d1SAndroid Build Coastguard Worker }
5144*bbecb9d1SAndroid Build Coastguard Worker
5145*bbecb9d1SAndroid Build Coastguard Worker static void
vrend_fill_sysval_uniform_block(struct vrend_sub_context * sub_ctx)5146*bbecb9d1SAndroid Build Coastguard Worker vrend_fill_sysval_uniform_block (struct vrend_sub_context *sub_ctx)
5147*bbecb9d1SAndroid Build Coastguard Worker {
5148*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prog->virgl_block_bind == -1)
5149*bbecb9d1SAndroid Build Coastguard Worker return;
5150*bbecb9d1SAndroid Build Coastguard Worker
5151*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->sysvalue_data_cookie != sub_ctx->prog->sysvalue_data_cookie) {
5152*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_UNIFORM_BUFFER, sub_ctx->prog->ubo_sysval_buffer_id);
5153*bbecb9d1SAndroid Build Coastguard Worker glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(struct sysval_uniform_block),
5154*bbecb9d1SAndroid Build Coastguard Worker &sub_ctx->sysvalue_data);
5155*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_UNIFORM_BUFFER, 0);
5156*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog->sysvalue_data_cookie = sub_ctx->sysvalue_data_cookie;
5157*bbecb9d1SAndroid Build Coastguard Worker }
5158*bbecb9d1SAndroid Build Coastguard Worker }
5159*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_bind_objects(struct vrend_sub_context * sub_ctx,bool new_program)5160*bbecb9d1SAndroid Build Coastguard Worker static void vrend_draw_bind_objects(struct vrend_sub_context *sub_ctx, bool new_program)
5161*bbecb9d1SAndroid Build Coastguard Worker {
5162*bbecb9d1SAndroid Build Coastguard Worker int next_ubo_id = 0, next_sampler_id = 0;
5163*bbecb9d1SAndroid Build Coastguard Worker for (int shader_type = PIPE_SHADER_VERTEX; shader_type <= sub_ctx->last_shader_idx; shader_type++) {
5164*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_pipeline_stage(sub_ctx->prog, shader_type);
5165*bbecb9d1SAndroid Build Coastguard Worker
5166*bbecb9d1SAndroid Build Coastguard Worker next_ubo_id = vrend_draw_bind_ubo_shader(sub_ctx, shader_type, next_ubo_id);
5167*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_const_shader(sub_ctx, shader_type, new_program);
5168*bbecb9d1SAndroid Build Coastguard Worker next_sampler_id = vrend_draw_bind_samplers_shader(sub_ctx, shader_type, next_sampler_id);
5169*bbecb9d1SAndroid Build Coastguard Worker
5170*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_images_shader(sub_ctx, shader_type);
5171*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_ssbo_shader(sub_ctx, shader_type);
5172*bbecb9d1SAndroid Build Coastguard Worker
5173*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
5174*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prog->tex_levels_uniform_id[shader_type] != -1) {
5175*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_pipeline_stage(sub_ctx->prog, shader_type);
5176*bbecb9d1SAndroid Build Coastguard Worker glUniform1iv(sub_ctx->prog->tex_levels_uniform_id[shader_type],
5177*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->n_samplers[shader_type],
5178*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->texture_levels[shader_type]);
5179*bbecb9d1SAndroid Build Coastguard Worker }
5180*bbecb9d1SAndroid Build Coastguard Worker }
5181*bbecb9d1SAndroid Build Coastguard Worker }
5182*bbecb9d1SAndroid Build Coastguard Worker
5183*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prog->virgl_block_bind != -1)
5184*bbecb9d1SAndroid Build Coastguard Worker glBindBufferRange(GL_UNIFORM_BUFFER, sub_ctx->prog->virgl_block_bind,
5185*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog->ubo_sysval_buffer_id,
5186*bbecb9d1SAndroid Build Coastguard Worker 0, sizeof(struct sysval_uniform_block));
5187*bbecb9d1SAndroid Build Coastguard Worker
5188*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_abo_shader(sub_ctx);
5189*bbecb9d1SAndroid Build Coastguard Worker
5190*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_pipeline_stage(sub_ctx->prog, PIPE_SHADER_FRAGMENT);
5191*bbecb9d1SAndroid Build Coastguard Worker }
5192*bbecb9d1SAndroid Build Coastguard Worker
5193*bbecb9d1SAndroid Build Coastguard Worker static
vrend_inject_tcs(struct vrend_sub_context * sub_ctx,int vertices_per_patch)5194*bbecb9d1SAndroid Build Coastguard Worker void vrend_inject_tcs(struct vrend_sub_context *sub_ctx, int vertices_per_patch)
5195*bbecb9d1SAndroid Build Coastguard Worker {
5196*bbecb9d1SAndroid Build Coastguard Worker struct pipe_stream_output_info so_info;
5197*bbecb9d1SAndroid Build Coastguard Worker
5198*bbecb9d1SAndroid Build Coastguard Worker memset(&so_info, 0, sizeof(so_info));
5199*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel = vrend_create_shader_state(&so_info,
5200*bbecb9d1SAndroid Build Coastguard Worker false, PIPE_SHADER_TESS_CTRL);
5201*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *shader;
5202*bbecb9d1SAndroid Build Coastguard Worker shader = CALLOC_STRUCT(vrend_shader);
5203*bbecb9d1SAndroid Build Coastguard Worker vrend_fill_shader_key(sub_ctx, sel, &shader->key);
5204*bbecb9d1SAndroid Build Coastguard Worker
5205*bbecb9d1SAndroid Build Coastguard Worker shader->sel = sel;
5206*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&shader->programs);
5207*bbecb9d1SAndroid Build Coastguard Worker strarray_alloc(&shader->glsl_strings, SHADER_MAX_STRINGS);
5208*bbecb9d1SAndroid Build Coastguard Worker
5209*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_shader_create_passthrough_tcs(sub_ctx->parent, &sub_ctx->parent->shader_cfg,
5210*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[PIPE_SHADER_VERTEX]->tokens,
5211*bbecb9d1SAndroid Build Coastguard Worker &shader->key, vrend_state.tess_factors, &sel->sinfo,
5212*bbecb9d1SAndroid Build Coastguard Worker &shader->glsl_strings, vertices_per_patch)) {
5213*bbecb9d1SAndroid Build Coastguard Worker strarray_free(&shader->glsl_strings, true);
5214*bbecb9d1SAndroid Build Coastguard Worker FREE(shader);
5215*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(sub_ctx->parent, VIRGL_ERROR_CTX_ILLEGAL_SHADER, sel->type);
5216*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_shader_selector(sel);
5217*bbecb9d1SAndroid Build Coastguard Worker return;
5218*bbecb9d1SAndroid Build Coastguard Worker }
5219*bbecb9d1SAndroid Build Coastguard Worker // Need to add inject the selected shader to the shader selector and then the code below
5220*bbecb9d1SAndroid Build Coastguard Worker // can continue
5221*bbecb9d1SAndroid Build Coastguard Worker sel->tokens = NULL;
5222*bbecb9d1SAndroid Build Coastguard Worker sel->current = shader;
5223*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[PIPE_SHADER_TESS_CTRL] = sel;
5224*bbecb9d1SAndroid Build Coastguard Worker
5225*bbecb9d1SAndroid Build Coastguard Worker vrend_compile_shader(sub_ctx, shader);
5226*bbecb9d1SAndroid Build Coastguard Worker }
5227*bbecb9d1SAndroid Build Coastguard Worker
5228*bbecb9d1SAndroid Build Coastguard Worker
5229*bbecb9d1SAndroid Build Coastguard Worker static bool
vrend_select_program(struct vrend_sub_context * sub_ctx,ubyte vertices_per_patch)5230*bbecb9d1SAndroid Build Coastguard Worker vrend_select_program(struct vrend_sub_context *sub_ctx, ubyte vertices_per_patch)
5231*bbecb9d1SAndroid Build Coastguard Worker {
5232*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *prog;
5233*bbecb9d1SAndroid Build Coastguard Worker bool fs_dirty, vs_dirty, gs_dirty, tcs_dirty, tes_dirty;
5234*bbecb9d1SAndroid Build Coastguard Worker bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, 0);
5235*bbecb9d1SAndroid Build Coastguard Worker bool new_program = false;
5236*bbecb9d1SAndroid Build Coastguard Worker
5237*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector **shaders = sub_ctx->shaders;
5238*bbecb9d1SAndroid Build Coastguard Worker
5239*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shader_dirty = false;
5240*bbecb9d1SAndroid Build Coastguard Worker
5241*bbecb9d1SAndroid Build Coastguard Worker if (!shaders[PIPE_SHADER_VERTEX] || !shaders[PIPE_SHADER_FRAGMENT]) {
5242*bbecb9d1SAndroid Build Coastguard Worker return false;
5243*bbecb9d1SAndroid Build Coastguard Worker }
5244*bbecb9d1SAndroid Build Coastguard Worker
5245*bbecb9d1SAndroid Build Coastguard Worker // For some GPU, we'd like to use integer variable in generated GLSL if
5246*bbecb9d1SAndroid Build Coastguard Worker // the input buffers are integer formats. But we actually don't know the
5247*bbecb9d1SAndroid Build Coastguard Worker // buffer formats when the shader is created, we only know it here.
5248*bbecb9d1SAndroid Build Coastguard Worker // Set it to true so the underlying code knows to use the buffer formats
5249*bbecb9d1SAndroid Build Coastguard Worker // now.
5250*bbecb9d1SAndroid Build Coastguard Worker
5251*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->drawing = true;
5252*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_VERTEX], &vs_dirty);
5253*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->drawing = false;
5254*bbecb9d1SAndroid Build Coastguard Worker
5255*bbecb9d1SAndroid Build Coastguard Worker if (shaders[PIPE_SHADER_TESS_CTRL] && shaders[PIPE_SHADER_TESS_CTRL]->tokens)
5256*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_TESS_CTRL], &tcs_dirty);
5257*bbecb9d1SAndroid Build Coastguard Worker else if (vrend_state.use_gles && shaders[PIPE_SHADER_TESS_EVAL]) {
5258*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_shader, sub_ctx->parent, "Need to inject a TCS\n");
5259*bbecb9d1SAndroid Build Coastguard Worker vrend_inject_tcs(sub_ctx, vertices_per_patch);
5260*bbecb9d1SAndroid Build Coastguard Worker
5261*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_VERTEX], &vs_dirty);
5262*bbecb9d1SAndroid Build Coastguard Worker }
5263*bbecb9d1SAndroid Build Coastguard Worker
5264*bbecb9d1SAndroid Build Coastguard Worker if (shaders[PIPE_SHADER_TESS_EVAL])
5265*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_TESS_EVAL], &tes_dirty);
5266*bbecb9d1SAndroid Build Coastguard Worker if (shaders[PIPE_SHADER_GEOMETRY])
5267*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_GEOMETRY], &gs_dirty);
5268*bbecb9d1SAndroid Build Coastguard Worker
5269*bbecb9d1SAndroid Build Coastguard Worker if (vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_FRAGMENT], &fs_dirty))
5270*bbecb9d1SAndroid Build Coastguard Worker goto fail;
5271*bbecb9d1SAndroid Build Coastguard Worker
5272*bbecb9d1SAndroid Build Coastguard Worker // NOTE: run shader selection again as a workaround to #180 - "duplicated shader compilation"
5273*bbecb9d1SAndroid Build Coastguard Worker if (shaders[PIPE_SHADER_GEOMETRY])
5274*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_GEOMETRY], &gs_dirty);
5275*bbecb9d1SAndroid Build Coastguard Worker if (shaders[PIPE_SHADER_TESS_EVAL])
5276*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_TESS_EVAL], &tes_dirty);
5277*bbecb9d1SAndroid Build Coastguard Worker if (shaders[PIPE_SHADER_TESS_CTRL] && shaders[PIPE_SHADER_TESS_CTRL]->tokens)
5278*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_TESS_CTRL], &tcs_dirty);
5279*bbecb9d1SAndroid Build Coastguard Worker else if (vrend_state.use_gles && shaders[PIPE_SHADER_TESS_EVAL]) {
5280*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_shader, sub_ctx->parent, "Need to inject a TCS\n");
5281*bbecb9d1SAndroid Build Coastguard Worker vrend_inject_tcs(sub_ctx, vertices_per_patch);
5282*bbecb9d1SAndroid Build Coastguard Worker }
5283*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->drawing = true;
5284*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, shaders[PIPE_SHADER_VERTEX], &vs_dirty);
5285*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->drawing = false;
5286*bbecb9d1SAndroid Build Coastguard Worker
5287*bbecb9d1SAndroid Build Coastguard Worker uint8_t gles_emulate_query_texture_levels_mask = 0;
5288*bbecb9d1SAndroid Build Coastguard Worker
5289*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type i = 0; i < PIPE_SHADER_TYPES; i++) {
5290*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *sel = shaders[i];
5291*bbecb9d1SAndroid Build Coastguard Worker if (!sel)
5292*bbecb9d1SAndroid Build Coastguard Worker continue;
5293*bbecb9d1SAndroid Build Coastguard Worker
5294*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *shader = sel->current;
5295*bbecb9d1SAndroid Build Coastguard Worker if (shader && !shader->is_compiled) {
5296*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_compile_shader(sub_ctx, shader))
5297*bbecb9d1SAndroid Build Coastguard Worker return false;
5298*bbecb9d1SAndroid Build Coastguard Worker }
5299*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && sel->sinfo.gles_use_tex_query_level)
5300*bbecb9d1SAndroid Build Coastguard Worker gles_emulate_query_texture_levels_mask |= 1 << i;
5301*bbecb9d1SAndroid Build Coastguard Worker }
5302*bbecb9d1SAndroid Build Coastguard Worker
5303*bbecb9d1SAndroid Build Coastguard Worker if (!shaders[PIPE_SHADER_VERTEX]->current ||
5304*bbecb9d1SAndroid Build Coastguard Worker !shaders[PIPE_SHADER_FRAGMENT]->current ||
5305*bbecb9d1SAndroid Build Coastguard Worker (shaders[PIPE_SHADER_GEOMETRY] && !shaders[PIPE_SHADER_GEOMETRY]->current) ||
5306*bbecb9d1SAndroid Build Coastguard Worker (shaders[PIPE_SHADER_TESS_CTRL] && !shaders[PIPE_SHADER_TESS_CTRL]->current) ||
5307*bbecb9d1SAndroid Build Coastguard Worker (shaders[PIPE_SHADER_TESS_EVAL] && !shaders[PIPE_SHADER_TESS_EVAL]->current))
5308*bbecb9d1SAndroid Build Coastguard Worker goto fail;
5309*bbecb9d1SAndroid Build Coastguard Worker
5310*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *vs = shaders[PIPE_SHADER_VERTEX]->current;
5311*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *fs = shaders[PIPE_SHADER_FRAGMENT]->current;
5312*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *gs = shaders[PIPE_SHADER_GEOMETRY] ? shaders[PIPE_SHADER_GEOMETRY]->current : NULL;
5313*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *tcs = shaders[PIPE_SHADER_TESS_CTRL] ? shaders[PIPE_SHADER_TESS_CTRL]->current : NULL;
5314*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader *tes = shaders[PIPE_SHADER_TESS_EVAL] ? shaders[PIPE_SHADER_TESS_EVAL]->current : NULL;
5315*bbecb9d1SAndroid Build Coastguard Worker
5316*bbecb9d1SAndroid Build Coastguard Worker GLuint vs_id = vs->id;
5317*bbecb9d1SAndroid Build Coastguard Worker GLuint fs_id = fs->id;
5318*bbecb9d1SAndroid Build Coastguard Worker GLuint gs_id = !gs ? 0 : gs->id;
5319*bbecb9d1SAndroid Build Coastguard Worker GLuint tcs_id = !tcs ? 0 : tcs->id;
5320*bbecb9d1SAndroid Build Coastguard Worker GLuint tes_id = !tes ? 0 : tes->id;
5321*bbecb9d1SAndroid Build Coastguard Worker
5322*bbecb9d1SAndroid Build Coastguard Worker if (shaders[PIPE_SHADER_FRAGMENT]->current->sel->sinfo.num_outputs <= 1)
5323*bbecb9d1SAndroid Build Coastguard Worker dual_src = false;
5324*bbecb9d1SAndroid Build Coastguard Worker
5325*bbecb9d1SAndroid Build Coastguard Worker bool same_prog = sub_ctx->prog &&
5326*bbecb9d1SAndroid Build Coastguard Worker vs_id == sub_ctx->prog_ids[PIPE_SHADER_VERTEX] &&
5327*bbecb9d1SAndroid Build Coastguard Worker fs_id == sub_ctx->prog_ids[PIPE_SHADER_FRAGMENT] &&
5328*bbecb9d1SAndroid Build Coastguard Worker gs_id == sub_ctx->prog_ids[PIPE_SHADER_GEOMETRY] &&
5329*bbecb9d1SAndroid Build Coastguard Worker tcs_id == sub_ctx->prog_ids[PIPE_SHADER_TESS_CTRL] &&
5330*bbecb9d1SAndroid Build Coastguard Worker tes_id == sub_ctx->prog_ids[PIPE_SHADER_TESS_EVAL] &&
5331*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog->dual_src_linked == dual_src;
5332*bbecb9d1SAndroid Build Coastguard Worker
5333*bbecb9d1SAndroid Build Coastguard Worker bool separable = vs->sel->sinfo.separable_program &&
5334*bbecb9d1SAndroid Build Coastguard Worker fs->sel->sinfo.separable_program &&
5335*bbecb9d1SAndroid Build Coastguard Worker (!gs || gs->sel->sinfo.separable_program) &&
5336*bbecb9d1SAndroid Build Coastguard Worker (!tcs || tcs->sel->sinfo.separable_program) &&
5337*bbecb9d1SAndroid Build Coastguard Worker (!tes || tes->sel->sinfo.separable_program);
5338*bbecb9d1SAndroid Build Coastguard Worker
5339*bbecb9d1SAndroid Build Coastguard Worker if (!same_prog) {
5340*bbecb9d1SAndroid Build Coastguard Worker prog = lookup_shader_program(sub_ctx, vs_id, fs_id, gs_id, tcs_id, tes_id, dual_src);
5341*bbecb9d1SAndroid Build Coastguard Worker if (!prog) {
5342*bbecb9d1SAndroid Build Coastguard Worker prog = add_shader_program(sub_ctx,
5343*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[PIPE_SHADER_VERTEX]->current,
5344*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[PIPE_SHADER_FRAGMENT]->current,
5345*bbecb9d1SAndroid Build Coastguard Worker gs_id ? sub_ctx->shaders[PIPE_SHADER_GEOMETRY]->current : NULL,
5346*bbecb9d1SAndroid Build Coastguard Worker tcs_id ? sub_ctx->shaders[PIPE_SHADER_TESS_CTRL]->current : NULL,
5347*bbecb9d1SAndroid Build Coastguard Worker tes_id ? sub_ctx->shaders[PIPE_SHADER_TESS_EVAL]->current : NULL,
5348*bbecb9d1SAndroid Build Coastguard Worker separable);
5349*bbecb9d1SAndroid Build Coastguard Worker if (!prog)
5350*bbecb9d1SAndroid Build Coastguard Worker return false;
5351*bbecb9d1SAndroid Build Coastguard Worker prog->gles_use_query_texturelevel_mask = gles_emulate_query_texture_levels_mask;
5352*bbecb9d1SAndroid Build Coastguard Worker } else if (separable) {
5353*bbecb9d1SAndroid Build Coastguard Worker /* UBO block bindings are reset to zero if the programs are
5354*bbecb9d1SAndroid Build Coastguard Worker * re-linked. With separable shaders, the program can be relinked
5355*bbecb9d1SAndroid Build Coastguard Worker * because it's shared across multiple pipelines and some things like
5356*bbecb9d1SAndroid Build Coastguard Worker * transform feedback require relinking, so we have to make sure the
5357*bbecb9d1SAndroid Build Coastguard Worker * blocks are bound. */
5358*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type last_shader = tes_id ? PIPE_SHADER_TESS_EVAL :
5359*bbecb9d1SAndroid Build Coastguard Worker (gs_id ? PIPE_SHADER_GEOMETRY :
5360*bbecb9d1SAndroid Build Coastguard Worker PIPE_SHADER_FRAGMENT);
5361*bbecb9d1SAndroid Build Coastguard Worker bool need_rebind = false;
5362*bbecb9d1SAndroid Build Coastguard Worker
5363*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type shader_type = PIPE_SHADER_VERTEX;
5364*bbecb9d1SAndroid Build Coastguard Worker shader_type <= last_shader && !need_rebind;
5365*bbecb9d1SAndroid Build Coastguard Worker shader_type++) {
5366*bbecb9d1SAndroid Build Coastguard Worker if (!prog->ss[shader_type])
5367*bbecb9d1SAndroid Build Coastguard Worker continue;
5368*bbecb9d1SAndroid Build Coastguard Worker need_rebind |= prog->ss[shader_type]->last_pipeline_id != prog->id.pipeline;
5369*bbecb9d1SAndroid Build Coastguard Worker }
5370*bbecb9d1SAndroid Build Coastguard Worker
5371*bbecb9d1SAndroid Build Coastguard Worker if (need_rebind) {
5372*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(sub_ctx, prog);
5373*bbecb9d1SAndroid Build Coastguard Worker rebind_ubo_and_sampler_locs(prog, last_shader);
5374*bbecb9d1SAndroid Build Coastguard Worker }
5375*bbecb9d1SAndroid Build Coastguard Worker }
5376*bbecb9d1SAndroid Build Coastguard Worker
5377*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->last_shader_idx = sub_ctx->shaders[PIPE_SHADER_TESS_EVAL] ? PIPE_SHADER_TESS_EVAL : (sub_ctx->shaders[PIPE_SHADER_GEOMETRY] ? PIPE_SHADER_GEOMETRY : PIPE_SHADER_FRAGMENT);
5378*bbecb9d1SAndroid Build Coastguard Worker } else
5379*bbecb9d1SAndroid Build Coastguard Worker prog = sub_ctx->prog;
5380*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prog != prog) {
5381*bbecb9d1SAndroid Build Coastguard Worker new_program = true;
5382*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_VERTEX] = vs_id;
5383*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_FRAGMENT] = fs_id;
5384*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_GEOMETRY] = gs_id;
5385*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_TESS_CTRL] = tcs_id;
5386*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_TESS_EVAL] = tes_id;
5387*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_COMPUTE] = 0;
5388*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog = prog;
5389*bbecb9d1SAndroid Build Coastguard Worker
5390*bbecb9d1SAndroid Build Coastguard Worker /* mark all constbufs and sampler views as dirty */
5391*bbecb9d1SAndroid Build Coastguard Worker for (int stage = PIPE_SHADER_VERTEX; stage <= PIPE_SHADER_FRAGMENT; stage++) {
5392*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->const_bufs_dirty[stage] = ~0;
5393*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->sampler_views_dirty[stage] = ~0;
5394*bbecb9d1SAndroid Build Coastguard Worker }
5395*bbecb9d1SAndroid Build Coastguard Worker
5396*bbecb9d1SAndroid Build Coastguard Worker prog->ref_context = sub_ctx;
5397*bbecb9d1SAndroid Build Coastguard Worker }
5398*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->cs_shader_dirty = true;
5399*bbecb9d1SAndroid Build Coastguard Worker return new_program;
5400*bbecb9d1SAndroid Build Coastguard Worker
5401*bbecb9d1SAndroid Build Coastguard Worker fail:
5402*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failure to compile shader variants: %s\n", sub_ctx->parent->debug_name);
5403*bbecb9d1SAndroid Build Coastguard Worker return false;
5404*bbecb9d1SAndroid Build Coastguard Worker }
5405*bbecb9d1SAndroid Build Coastguard Worker
vrend_link_program_hook(struct vrend_context * ctx,uint32_t * handles)5406*bbecb9d1SAndroid Build Coastguard Worker void vrend_link_program_hook(struct vrend_context *ctx, uint32_t *handles)
5407*bbecb9d1SAndroid Build Coastguard Worker {
5408*bbecb9d1SAndroid Build Coastguard Worker /* Pre-compiling compute shaders needs some additional work */
5409*bbecb9d1SAndroid Build Coastguard Worker if (handles[PIPE_SHADER_COMPUTE])
5410*bbecb9d1SAndroid Build Coastguard Worker return;
5411*bbecb9d1SAndroid Build Coastguard Worker
5412*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *vs = vrend_object_lookup(ctx->sub->object_hash,
5413*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_VERTEX],
5414*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_SHADER);
5415*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *fs = vrend_object_lookup(ctx->sub->object_hash,
5416*bbecb9d1SAndroid Build Coastguard Worker handles[PIPE_SHADER_FRAGMENT],
5417*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_SHADER);
5418*bbecb9d1SAndroid Build Coastguard Worker
5419*bbecb9d1SAndroid Build Coastguard Worker /* If we can't force linking, exit early */
5420*bbecb9d1SAndroid Build Coastguard Worker if ((!handles[PIPE_SHADER_VERTEX] || !handles[PIPE_SHADER_FRAGMENT]) &&
5421*bbecb9d1SAndroid Build Coastguard Worker (!vs || !vs->sinfo.separable_program) && (!fs || !fs->sinfo.separable_program))
5422*bbecb9d1SAndroid Build Coastguard Worker return;
5423*bbecb9d1SAndroid Build Coastguard Worker
5424*bbecb9d1SAndroid Build Coastguard Worker /* We can't link a pre-link a TCS without a TES, exit early */
5425*bbecb9d1SAndroid Build Coastguard Worker if (handles[PIPE_SHADER_TESS_CTRL] && !handles[PIPE_SHADER_TESS_EVAL])
5426*bbecb9d1SAndroid Build Coastguard Worker return;
5427*bbecb9d1SAndroid Build Coastguard Worker
5428*bbecb9d1SAndroid Build Coastguard Worker struct vrend_shader_selector *prev_handles[PIPE_SHADER_TYPES];
5429*bbecb9d1SAndroid Build Coastguard Worker memset(prev_handles, 0, sizeof(prev_handles));
5430*bbecb9d1SAndroid Build Coastguard Worker uint32_t prev_shader_ids[PIPE_SHADER_TYPES];
5431*bbecb9d1SAndroid Build Coastguard Worker memcpy(prev_shader_ids, ctx->sub->prog_ids, PIPE_SHADER_TYPES * sizeof(uint32_t));
5432*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *prev_prog = ctx->sub->prog;
5433*bbecb9d1SAndroid Build Coastguard Worker
5434*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type type = 0; type < PIPE_SHADER_TYPES; ++type) {
5435*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&prev_handles[type], ctx->sub->shaders[type]);
5436*bbecb9d1SAndroid Build Coastguard Worker vrend_bind_shader(ctx, handles[type], type);
5437*bbecb9d1SAndroid Build Coastguard Worker }
5438*bbecb9d1SAndroid Build Coastguard Worker
5439*bbecb9d1SAndroid Build Coastguard Worker /* Force early-linking for separable shaders, since they don't depend on other stages */
5440*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t type = 0; type < PIPE_SHADER_TYPES; ++type) {
5441*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->shaders[type] && ctx->sub->shaders[type]->sinfo.separable_program) {
5442*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->sub->shaders[type]->current->is_compiled)
5443*bbecb9d1SAndroid Build Coastguard Worker vrend_compile_shader(ctx->sub, ctx->sub->shaders[type]->current);
5444*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->sub->shaders[type]->current->is_linked)
5445*bbecb9d1SAndroid Build Coastguard Worker vrend_link_separable_shader(ctx->sub, ctx->sub->shaders[type]->current, type);
5446*bbecb9d1SAndroid Build Coastguard Worker }
5447*bbecb9d1SAndroid Build Coastguard Worker }
5448*bbecb9d1SAndroid Build Coastguard Worker
5449*bbecb9d1SAndroid Build Coastguard Worker /* Force early-link of the whole shader program. */
5450*bbecb9d1SAndroid Build Coastguard Worker vrend_select_program(ctx->sub, 1);
5451*bbecb9d1SAndroid Build Coastguard Worker
5452*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->shader_dirty = true;
5453*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->cs_shader_dirty = true;
5454*bbecb9d1SAndroid Build Coastguard Worker
5455*bbecb9d1SAndroid Build Coastguard Worker /* undo state changes */
5456*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type type = 0; type < PIPE_SHADER_TYPES; ++type) {
5457*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&ctx->sub->shaders[type], prev_handles[type]);
5458*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&prev_handles[type], NULL);
5459*bbecb9d1SAndroid Build Coastguard Worker }
5460*bbecb9d1SAndroid Build Coastguard Worker memcpy(ctx->sub->prog_ids, prev_shader_ids, PIPE_SHADER_TYPES * sizeof(uint32_t));
5461*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->prog = prev_prog;
5462*bbecb9d1SAndroid Build Coastguard Worker }
5463*bbecb9d1SAndroid Build Coastguard Worker
vrend_draw_vbo(struct vrend_context * ctx,const struct pipe_draw_info * info,uint32_t cso,uint32_t indirect_handle,uint32_t indirect_draw_count_handle)5464*bbecb9d1SAndroid Build Coastguard Worker int vrend_draw_vbo(struct vrend_context *ctx,
5465*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_draw_info *info,
5466*bbecb9d1SAndroid Build Coastguard Worker uint32_t cso, uint32_t indirect_handle,
5467*bbecb9d1SAndroid Build Coastguard Worker uint32_t indirect_draw_count_handle)
5468*bbecb9d1SAndroid Build Coastguard Worker {
5469*bbecb9d1SAndroid Build Coastguard Worker bool new_program = false;
5470*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *indirect_res = NULL;
5471*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *indirect_params_res = NULL;
5472*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx = ctx->sub;
5473*bbecb9d1SAndroid Build Coastguard Worker
5474*bbecb9d1SAndroid Build Coastguard Worker if (ctx->in_error)
5475*bbecb9d1SAndroid Build Coastguard Worker return 0;
5476*bbecb9d1SAndroid Build Coastguard Worker
5477*bbecb9d1SAndroid Build Coastguard Worker if (info->instance_count && !has_feature(feat_draw_instance))
5478*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
5479*bbecb9d1SAndroid Build Coastguard Worker
5480*bbecb9d1SAndroid Build Coastguard Worker if (info->start_instance && !has_feature(feat_base_instance))
5481*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
5482*bbecb9d1SAndroid Build Coastguard Worker
5483*bbecb9d1SAndroid Build Coastguard Worker if (info->indirect.draw_count > 1 && !has_feature(feat_multi_draw_indirect))
5484*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
5485*bbecb9d1SAndroid Build Coastguard Worker
5486*bbecb9d1SAndroid Build Coastguard Worker if (indirect_handle) {
5487*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_indirect_draw))
5488*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
5489*bbecb9d1SAndroid Build Coastguard Worker indirect_res = vrend_renderer_ctx_res_lookup(ctx, indirect_handle);
5490*bbecb9d1SAndroid Build Coastguard Worker if (!indirect_res) {
5491*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_handle);
5492*bbecb9d1SAndroid Build Coastguard Worker return 0;
5493*bbecb9d1SAndroid Build Coastguard Worker }
5494*bbecb9d1SAndroid Build Coastguard Worker }
5495*bbecb9d1SAndroid Build Coastguard Worker
5496*bbecb9d1SAndroid Build Coastguard Worker /* this must be zero until we support the feature */
5497*bbecb9d1SAndroid Build Coastguard Worker if (indirect_draw_count_handle) {
5498*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_indirect_params))
5499*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
5500*bbecb9d1SAndroid Build Coastguard Worker
5501*bbecb9d1SAndroid Build Coastguard Worker indirect_params_res = vrend_renderer_ctx_res_lookup(ctx, indirect_draw_count_handle);
5502*bbecb9d1SAndroid Build Coastguard Worker if (!indirect_params_res){
5503*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_draw_count_handle);
5504*bbecb9d1SAndroid Build Coastguard Worker return 0;
5505*bbecb9d1SAndroid Build Coastguard Worker }
5506*bbecb9d1SAndroid Build Coastguard Worker }
5507*bbecb9d1SAndroid Build Coastguard Worker
5508*bbecb9d1SAndroid Build Coastguard Worker if (ctx->ctx_switch_pending)
5509*bbecb9d1SAndroid Build Coastguard Worker vrend_finish_context_switch(ctx);
5510*bbecb9d1SAndroid Build Coastguard Worker
5511*bbecb9d1SAndroid Build Coastguard Worker vrend_update_frontface_state(sub_ctx);
5512*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->stencil_state_dirty)
5513*bbecb9d1SAndroid Build Coastguard Worker vrend_update_stencil_state(sub_ctx);
5514*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->scissor_state_dirty)
5515*bbecb9d1SAndroid Build Coastguard Worker vrend_update_scissor_state(sub_ctx);
5516*bbecb9d1SAndroid Build Coastguard Worker
5517*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->viewport_state_dirty)
5518*bbecb9d1SAndroid Build Coastguard Worker vrend_update_viewport_state(sub_ctx);
5519*bbecb9d1SAndroid Build Coastguard Worker
5520*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->blend_state_dirty)
5521*bbecb9d1SAndroid Build Coastguard Worker vrend_patch_blend_state(sub_ctx);
5522*bbecb9d1SAndroid Build Coastguard Worker
5523*bbecb9d1SAndroid Build Coastguard Worker // enable primitive-mode-dependent shader variants
5524*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prim_mode != (int)info->mode) {
5525*bbecb9d1SAndroid Build Coastguard Worker // Only refresh shader program when switching in/out of GL_POINTS primitive mode
5526*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prim_mode == PIPE_PRIM_POINTS
5527*bbecb9d1SAndroid Build Coastguard Worker || (int)info->mode == PIPE_PRIM_POINTS)
5528*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shader_dirty = true;
5529*bbecb9d1SAndroid Build Coastguard Worker
5530*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prim_mode = (int)info->mode;
5531*bbecb9d1SAndroid Build Coastguard Worker }
5532*bbecb9d1SAndroid Build Coastguard Worker
5533*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->ve) {
5534*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("illegal VE setup - skipping renderering\n");
5535*bbecb9d1SAndroid Build Coastguard Worker return 0;
5536*bbecb9d1SAndroid Build Coastguard Worker }
5537*bbecb9d1SAndroid Build Coastguard Worker
5538*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->shader_dirty || sub_ctx->swizzle_output_rgb_to_bgr ||
5539*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->needs_manual_srgb_encode_bitmask || sub_ctx->vbo_dirty)
5540*bbecb9d1SAndroid Build Coastguard Worker new_program = vrend_select_program(sub_ctx, info->vertices_per_patch);
5541*bbecb9d1SAndroid Build Coastguard Worker
5542*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->prog) {
5543*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name);
5544*bbecb9d1SAndroid Build Coastguard Worker return 0;
5545*bbecb9d1SAndroid Build Coastguard Worker }
5546*bbecb9d1SAndroid Build Coastguard Worker
5547*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(sub_ctx, sub_ctx->prog);
5548*bbecb9d1SAndroid Build Coastguard Worker
5549*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
5550*bbecb9d1SAndroid Build Coastguard Worker /* PIPE_SHADER and TGSI_SHADER have different ordering, so use two
5551*bbecb9d1SAndroid Build Coastguard Worker * different prefix arrays */
5552*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type i = PIPE_SHADER_VERTEX; i < PIPE_SHADER_COMPUTE; ++i) {
5553*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prog->gles_use_query_texturelevel_mask & (1 << i)) {
5554*bbecb9d1SAndroid Build Coastguard Worker char loc_name[32];
5555*bbecb9d1SAndroid Build Coastguard Worker snprintf(loc_name, 32, "%s_texlod", pipe_shader_to_prefix(i));
5556*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog->tex_levels_uniform_id[i] =
5557*bbecb9d1SAndroid Build Coastguard Worker vrend_get_uniform_location(sub_ctx->prog, loc_name, i);
5558*bbecb9d1SAndroid Build Coastguard Worker } else {
5559*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog->tex_levels_uniform_id[i] = -1;
5560*bbecb9d1SAndroid Build Coastguard Worker }
5561*bbecb9d1SAndroid Build Coastguard Worker
5562*bbecb9d1SAndroid Build Coastguard Worker }
5563*bbecb9d1SAndroid Build Coastguard Worker }
5564*bbecb9d1SAndroid Build Coastguard Worker
5565*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_objects(sub_ctx, new_program);
5566*bbecb9d1SAndroid Build Coastguard Worker vrend_fill_sysval_uniform_block(sub_ctx);
5567*bbecb9d1SAndroid Build Coastguard Worker
5568*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gles31_vertex_attrib_binding))
5569*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_vertex_binding(ctx, sub_ctx->ve);
5570*bbecb9d1SAndroid Build Coastguard Worker else
5571*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_vertex_legacy(ctx, sub_ctx->ve);
5572*bbecb9d1SAndroid Build Coastguard Worker
5573*bbecb9d1SAndroid Build Coastguard Worker if (info->indexed) {
5574*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)sub_ctx->ib.buffer;
5575*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
5576*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "VBO missing indexed array buffer\n");
5577*bbecb9d1SAndroid Build Coastguard Worker return 0;
5578*bbecb9d1SAndroid Build Coastguard Worker }
5579*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, res->id);
5580*bbecb9d1SAndroid Build Coastguard Worker } else
5581*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
5582*bbecb9d1SAndroid Build Coastguard Worker
5583*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->current_so) {
5584*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->current_so->xfb_state == XFB_STATE_STARTED_NEED_BEGIN) {
5585*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->shaders[PIPE_SHADER_GEOMETRY])
5586*bbecb9d1SAndroid Build Coastguard Worker glBeginTransformFeedback(get_gs_xfb_mode(sub_ctx->shaders[PIPE_SHADER_GEOMETRY]->sinfo.gs_out_prim));
5587*bbecb9d1SAndroid Build Coastguard Worker else if (sub_ctx->shaders[PIPE_SHADER_TESS_EVAL])
5588*bbecb9d1SAndroid Build Coastguard Worker glBeginTransformFeedback(get_tess_xfb_mode(sub_ctx->shaders[PIPE_SHADER_TESS_EVAL]->sinfo.tes_prim,
5589*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shaders[PIPE_SHADER_TESS_EVAL]->sinfo.tes_point_mode));
5590*bbecb9d1SAndroid Build Coastguard Worker else
5591*bbecb9d1SAndroid Build Coastguard Worker glBeginTransformFeedback(get_xfb_mode(info->mode));
5592*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->current_so->xfb_state = XFB_STATE_STARTED;
5593*bbecb9d1SAndroid Build Coastguard Worker } else if (sub_ctx->current_so->xfb_state == XFB_STATE_PAUSED) {
5594*bbecb9d1SAndroid Build Coastguard Worker glResumeTransformFeedback();
5595*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->current_so->xfb_state = XFB_STATE_STARTED;
5596*bbecb9d1SAndroid Build Coastguard Worker }
5597*bbecb9d1SAndroid Build Coastguard Worker }
5598*bbecb9d1SAndroid Build Coastguard Worker
5599*bbecb9d1SAndroid Build Coastguard Worker if (info->primitive_restart) {
5600*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
5601*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
5602*bbecb9d1SAndroid Build Coastguard Worker } else if (has_feature(feat_nv_prim_restart)) {
5603*bbecb9d1SAndroid Build Coastguard Worker glEnableClientState(GL_PRIMITIVE_RESTART_NV);
5604*bbecb9d1SAndroid Build Coastguard Worker glPrimitiveRestartIndexNV(info->restart_index);
5605*bbecb9d1SAndroid Build Coastguard Worker } else if (has_feature(feat_gl_prim_restart)) {
5606*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_PRIMITIVE_RESTART);
5607*bbecb9d1SAndroid Build Coastguard Worker glPrimitiveRestartIndex(info->restart_index);
5608*bbecb9d1SAndroid Build Coastguard Worker }
5609*bbecb9d1SAndroid Build Coastguard Worker }
5610*bbecb9d1SAndroid Build Coastguard Worker
5611*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_indirect_draw)) {
5612*bbecb9d1SAndroid Build Coastguard Worker GLint buf = indirect_res ? indirect_res->id : 0;
5613*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->draw_indirect_buffer != buf) {
5614*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buf);
5615*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->draw_indirect_buffer = buf;
5616*bbecb9d1SAndroid Build Coastguard Worker }
5617*bbecb9d1SAndroid Build Coastguard Worker
5618*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_indirect_params)) {
5619*bbecb9d1SAndroid Build Coastguard Worker GLint buf = indirect_params_res ? indirect_params_res->id : 0;
5620*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->draw_indirect_params_buffer != buf) {
5621*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_PARAMETER_BUFFER_ARB, buf);
5622*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->draw_indirect_params_buffer = buf;
5623*bbecb9d1SAndroid Build Coastguard Worker }
5624*bbecb9d1SAndroid Build Coastguard Worker }
5625*bbecb9d1SAndroid Build Coastguard Worker }
5626*bbecb9d1SAndroid Build Coastguard Worker
5627*bbecb9d1SAndroid Build Coastguard Worker if (info->vertices_per_patch && has_feature(feat_tessellation))
5628*bbecb9d1SAndroid Build Coastguard Worker glPatchParameteri(GL_PATCH_VERTICES, info->vertices_per_patch);
5629*bbecb9d1SAndroid Build Coastguard Worker
5630*bbecb9d1SAndroid Build Coastguard Worker /* If the host support blend_equation_advanced but not fbfetch,
5631*bbecb9d1SAndroid Build Coastguard Worker * the guest driver will not lower the equation to fbfetch so we need to set up the renderer to
5632*bbecb9d1SAndroid Build Coastguard Worker * accept those blend equations.
5633*bbecb9d1SAndroid Build Coastguard Worker * When we transmit the blend mode through alpha_src_factor, alpha_dst_factor is always 0.
5634*bbecb9d1SAndroid Build Coastguard Worker */
5635*bbecb9d1SAndroid Build Coastguard Worker uint32_t blend_mask_shader = sub_ctx->shaders[PIPE_SHADER_FRAGMENT]->sinfo.fs_blend_equation_advanced;
5636*bbecb9d1SAndroid Build Coastguard Worker uint32_t blend_mode = sub_ctx->blend_state.rt[0].alpha_src_factor;
5637*bbecb9d1SAndroid Build Coastguard Worker uint32_t alpha_dst_factor = sub_ctx->blend_state.rt[0].alpha_dst_factor;
5638*bbecb9d1SAndroid Build Coastguard Worker bool use_advanced_blending = !has_feature(feat_framebuffer_fetch) &&
5639*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_blend_equation_advanced) &&
5640*bbecb9d1SAndroid Build Coastguard Worker blend_mask_shader != 0 &&
5641*bbecb9d1SAndroid Build Coastguard Worker blend_mode != 0 &&
5642*bbecb9d1SAndroid Build Coastguard Worker alpha_dst_factor == 0;
5643*bbecb9d1SAndroid Build Coastguard Worker if(use_advanced_blending) {
5644*bbecb9d1SAndroid Build Coastguard Worker GLenum blend = translate_blend_func_advanced(blend_mode);
5645*bbecb9d1SAndroid Build Coastguard Worker glBlendEquation(blend);
5646*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_BLEND);
5647*bbecb9d1SAndroid Build Coastguard Worker }
5648*bbecb9d1SAndroid Build Coastguard Worker
5649*bbecb9d1SAndroid Build Coastguard Worker /* set the vertex state up now on a delay */
5650*bbecb9d1SAndroid Build Coastguard Worker if (!info->indexed) {
5651*bbecb9d1SAndroid Build Coastguard Worker GLenum mode = info->mode;
5652*bbecb9d1SAndroid Build Coastguard Worker int count = cso ? cso : info->count;
5653*bbecb9d1SAndroid Build Coastguard Worker int start = cso ? 0 : info->start;
5654*bbecb9d1SAndroid Build Coastguard Worker
5655*bbecb9d1SAndroid Build Coastguard Worker if (indirect_handle) {
5656*bbecb9d1SAndroid Build Coastguard Worker if (indirect_params_res)
5657*bbecb9d1SAndroid Build Coastguard Worker glMultiDrawArraysIndirectCountARB(mode, (GLvoid const *)(uintptr_t)info->indirect.offset,
5658*bbecb9d1SAndroid Build Coastguard Worker info->indirect.indirect_draw_count_offset, info->indirect.draw_count, info->indirect.stride);
5659*bbecb9d1SAndroid Build Coastguard Worker else if (info->indirect.draw_count > 1)
5660*bbecb9d1SAndroid Build Coastguard Worker glMultiDrawArraysIndirect(mode, (GLvoid const *)(uintptr_t)info->indirect.offset, info->indirect.draw_count, info->indirect.stride);
5661*bbecb9d1SAndroid Build Coastguard Worker else
5662*bbecb9d1SAndroid Build Coastguard Worker glDrawArraysIndirect(mode, (GLvoid const *)(uintptr_t)info->indirect.offset);
5663*bbecb9d1SAndroid Build Coastguard Worker } else if (info->instance_count > 0) {
5664*bbecb9d1SAndroid Build Coastguard Worker if (info->start_instance > 0)
5665*bbecb9d1SAndroid Build Coastguard Worker glDrawArraysInstancedBaseInstance(mode, start, count, info->instance_count, info->start_instance);
5666*bbecb9d1SAndroid Build Coastguard Worker else
5667*bbecb9d1SAndroid Build Coastguard Worker glDrawArraysInstancedARB(mode, start, count, info->instance_count);
5668*bbecb9d1SAndroid Build Coastguard Worker } else
5669*bbecb9d1SAndroid Build Coastguard Worker glDrawArrays(mode, start, count);
5670*bbecb9d1SAndroid Build Coastguard Worker } else {
5671*bbecb9d1SAndroid Build Coastguard Worker GLenum elsz;
5672*bbecb9d1SAndroid Build Coastguard Worker GLenum mode = info->mode;
5673*bbecb9d1SAndroid Build Coastguard Worker switch (sub_ctx->ib.index_size) {
5674*bbecb9d1SAndroid Build Coastguard Worker case 1:
5675*bbecb9d1SAndroid Build Coastguard Worker elsz = GL_UNSIGNED_BYTE;
5676*bbecb9d1SAndroid Build Coastguard Worker break;
5677*bbecb9d1SAndroid Build Coastguard Worker case 2:
5678*bbecb9d1SAndroid Build Coastguard Worker elsz = GL_UNSIGNED_SHORT;
5679*bbecb9d1SAndroid Build Coastguard Worker break;
5680*bbecb9d1SAndroid Build Coastguard Worker case 4:
5681*bbecb9d1SAndroid Build Coastguard Worker default:
5682*bbecb9d1SAndroid Build Coastguard Worker elsz = GL_UNSIGNED_INT;
5683*bbecb9d1SAndroid Build Coastguard Worker break;
5684*bbecb9d1SAndroid Build Coastguard Worker }
5685*bbecb9d1SAndroid Build Coastguard Worker
5686*bbecb9d1SAndroid Build Coastguard Worker if (indirect_handle) {
5687*bbecb9d1SAndroid Build Coastguard Worker if (indirect_params_res)
5688*bbecb9d1SAndroid Build Coastguard Worker glMultiDrawElementsIndirectCountARB(mode, elsz, (GLvoid const *)(uintptr_t)info->indirect.offset,
5689*bbecb9d1SAndroid Build Coastguard Worker info->indirect.indirect_draw_count_offset, info->indirect.draw_count, info->indirect.stride);
5690*bbecb9d1SAndroid Build Coastguard Worker else if (info->indirect.draw_count > 1)
5691*bbecb9d1SAndroid Build Coastguard Worker glMultiDrawElementsIndirect(mode, elsz, (GLvoid const *)(uintptr_t)info->indirect.offset, info->indirect.draw_count, info->indirect.stride);
5692*bbecb9d1SAndroid Build Coastguard Worker else
5693*bbecb9d1SAndroid Build Coastguard Worker glDrawElementsIndirect(mode, elsz, (GLvoid const *)(uintptr_t)info->indirect.offset);
5694*bbecb9d1SAndroid Build Coastguard Worker } else if (info->index_bias) {
5695*bbecb9d1SAndroid Build Coastguard Worker if (info->instance_count > 0) {
5696*bbecb9d1SAndroid Build Coastguard Worker if (info->start_instance > 0)
5697*bbecb9d1SAndroid Build Coastguard Worker glDrawElementsInstancedBaseVertexBaseInstance(mode, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset,
5698*bbecb9d1SAndroid Build Coastguard Worker info->instance_count, info->index_bias, info->start_instance);
5699*bbecb9d1SAndroid Build Coastguard Worker else
5700*bbecb9d1SAndroid Build Coastguard Worker glDrawElementsInstancedBaseVertex(mode, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset, info->instance_count, info->index_bias);
5701*bbecb9d1SAndroid Build Coastguard Worker
5702*bbecb9d1SAndroid Build Coastguard Worker
5703*bbecb9d1SAndroid Build Coastguard Worker } else if (info->min_index != 0 || info->max_index != (unsigned)-1)
5704*bbecb9d1SAndroid Build Coastguard Worker glDrawRangeElementsBaseVertex(mode, info->min_index, info->max_index, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset, info->index_bias);
5705*bbecb9d1SAndroid Build Coastguard Worker else
5706*bbecb9d1SAndroid Build Coastguard Worker glDrawElementsBaseVertex(mode, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset, info->index_bias);
5707*bbecb9d1SAndroid Build Coastguard Worker } else if (info->instance_count > 0) {
5708*bbecb9d1SAndroid Build Coastguard Worker if (info->start_instance > 0) {
5709*bbecb9d1SAndroid Build Coastguard Worker glDrawElementsInstancedBaseInstance(mode, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset, info->instance_count, info->start_instance);
5710*bbecb9d1SAndroid Build Coastguard Worker } else
5711*bbecb9d1SAndroid Build Coastguard Worker glDrawElementsInstancedARB(mode, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset, info->instance_count);
5712*bbecb9d1SAndroid Build Coastguard Worker } else if (info->min_index != 0 || info->max_index != (unsigned)-1)
5713*bbecb9d1SAndroid Build Coastguard Worker glDrawRangeElements(mode, info->min_index, info->max_index, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset);
5714*bbecb9d1SAndroid Build Coastguard Worker else
5715*bbecb9d1SAndroid Build Coastguard Worker glDrawElements(mode, info->count, elsz, (void *)(uintptr_t)sub_ctx->ib.offset);
5716*bbecb9d1SAndroid Build Coastguard Worker }
5717*bbecb9d1SAndroid Build Coastguard Worker
5718*bbecb9d1SAndroid Build Coastguard Worker if (info->primitive_restart) {
5719*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
5720*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
5721*bbecb9d1SAndroid Build Coastguard Worker } else if (has_feature(feat_nv_prim_restart)) {
5722*bbecb9d1SAndroid Build Coastguard Worker glDisableClientState(GL_PRIMITIVE_RESTART_NV);
5723*bbecb9d1SAndroid Build Coastguard Worker } else if (has_feature(feat_gl_prim_restart)) {
5724*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_PRIMITIVE_RESTART);
5725*bbecb9d1SAndroid Build Coastguard Worker }
5726*bbecb9d1SAndroid Build Coastguard Worker }
5727*bbecb9d1SAndroid Build Coastguard Worker
5728*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->current_so && has_feature(feat_transform_feedback2)) {
5729*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->current_so->xfb_state == XFB_STATE_STARTED) {
5730*bbecb9d1SAndroid Build Coastguard Worker glPauseTransformFeedback();
5731*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->current_so->xfb_state = XFB_STATE_PAUSED;
5732*bbecb9d1SAndroid Build Coastguard Worker }
5733*bbecb9d1SAndroid Build Coastguard Worker }
5734*bbecb9d1SAndroid Build Coastguard Worker
5735*bbecb9d1SAndroid Build Coastguard Worker if (use_advanced_blending)
5736*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_BLEND);
5737*bbecb9d1SAndroid Build Coastguard Worker return 0;
5738*bbecb9d1SAndroid Build Coastguard Worker }
5739*bbecb9d1SAndroid Build Coastguard Worker
vrend_launch_grid(struct vrend_context * ctx,UNUSED uint32_t * block,uint32_t * grid,uint32_t indirect_handle,uint32_t indirect_offset)5740*bbecb9d1SAndroid Build Coastguard Worker void vrend_launch_grid(struct vrend_context *ctx,
5741*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t *block,
5742*bbecb9d1SAndroid Build Coastguard Worker uint32_t *grid,
5743*bbecb9d1SAndroid Build Coastguard Worker uint32_t indirect_handle,
5744*bbecb9d1SAndroid Build Coastguard Worker uint32_t indirect_offset)
5745*bbecb9d1SAndroid Build Coastguard Worker {
5746*bbecb9d1SAndroid Build Coastguard Worker bool new_program = false;
5747*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *indirect_res = NULL;
5748*bbecb9d1SAndroid Build Coastguard Worker
5749*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_compute_shader))
5750*bbecb9d1SAndroid Build Coastguard Worker return;
5751*bbecb9d1SAndroid Build Coastguard Worker
5752*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub_ctx = ctx->sub;
5753*bbecb9d1SAndroid Build Coastguard Worker
5754*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->cs_shader_dirty) {
5755*bbecb9d1SAndroid Build Coastguard Worker struct vrend_linked_shader_program *prog;
5756*bbecb9d1SAndroid Build Coastguard Worker bool cs_dirty;
5757*bbecb9d1SAndroid Build Coastguard Worker
5758*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->cs_shader_dirty = false;
5759*bbecb9d1SAndroid Build Coastguard Worker
5760*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->shaders[PIPE_SHADER_COMPUTE]) {
5761*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("dropping rendering due to missing shaders: %s\n", ctx->debug_name);
5762*bbecb9d1SAndroid Build Coastguard Worker return;
5763*bbecb9d1SAndroid Build Coastguard Worker }
5764*bbecb9d1SAndroid Build Coastguard Worker
5765*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_select(sub_ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE], &cs_dirty);
5766*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current) {
5767*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failure to select compute shader variant: %s\n", ctx->debug_name);
5768*bbecb9d1SAndroid Build Coastguard Worker return;
5769*bbecb9d1SAndroid Build Coastguard Worker }
5770*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->is_compiled) {
5771*bbecb9d1SAndroid Build Coastguard Worker if(!vrend_compile_shader(sub_ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current)) {
5772*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failure to compile compute shader variant: %s\n", ctx->debug_name);
5773*bbecb9d1SAndroid Build Coastguard Worker return;
5774*bbecb9d1SAndroid Build Coastguard Worker }
5775*bbecb9d1SAndroid Build Coastguard Worker }
5776*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->id != (GLuint)sub_ctx->prog_ids[PIPE_SHADER_COMPUTE]) {
5777*bbecb9d1SAndroid Build Coastguard Worker prog = lookup_cs_shader_program(ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->id);
5778*bbecb9d1SAndroid Build Coastguard Worker if (!prog) {
5779*bbecb9d1SAndroid Build Coastguard Worker prog = add_cs_shader_program(ctx, sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current);
5780*bbecb9d1SAndroid Build Coastguard Worker if (!prog)
5781*bbecb9d1SAndroid Build Coastguard Worker return;
5782*bbecb9d1SAndroid Build Coastguard Worker }
5783*bbecb9d1SAndroid Build Coastguard Worker } else
5784*bbecb9d1SAndroid Build Coastguard Worker prog = sub_ctx->prog;
5785*bbecb9d1SAndroid Build Coastguard Worker
5786*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->prog != prog) {
5787*bbecb9d1SAndroid Build Coastguard Worker new_program = true;
5788*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_VERTEX] = 0;
5789*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog_ids[PIPE_SHADER_COMPUTE] = sub_ctx->shaders[PIPE_SHADER_COMPUTE]->current->id;
5790*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->prog = prog;
5791*bbecb9d1SAndroid Build Coastguard Worker prog->ref_context = sub_ctx;
5792*bbecb9d1SAndroid Build Coastguard Worker }
5793*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shader_dirty = true;
5794*bbecb9d1SAndroid Build Coastguard Worker }
5795*bbecb9d1SAndroid Build Coastguard Worker
5796*bbecb9d1SAndroid Build Coastguard Worker if (!sub_ctx->prog) {
5797*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: Skipping compute shader execution due to missing shaders: %s\n",
5798*bbecb9d1SAndroid Build Coastguard Worker __func__, ctx->debug_name);
5799*bbecb9d1SAndroid Build Coastguard Worker return;
5800*bbecb9d1SAndroid Build Coastguard Worker }
5801*bbecb9d1SAndroid Build Coastguard Worker
5802*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(sub_ctx, sub_ctx->prog);
5803*bbecb9d1SAndroid Build Coastguard Worker
5804*bbecb9d1SAndroid Build Coastguard Worker vrend_set_active_pipeline_stage(sub_ctx->prog, PIPE_SHADER_COMPUTE);
5805*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_ubo_shader(sub_ctx, PIPE_SHADER_COMPUTE, 0);
5806*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_const_shader(sub_ctx, PIPE_SHADER_COMPUTE, new_program);
5807*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_samplers_shader(sub_ctx, PIPE_SHADER_COMPUTE, 0);
5808*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_images_shader(sub_ctx, PIPE_SHADER_COMPUTE);
5809*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_ssbo_shader(sub_ctx, PIPE_SHADER_COMPUTE);
5810*bbecb9d1SAndroid Build Coastguard Worker vrend_draw_bind_abo_shader(sub_ctx);
5811*bbecb9d1SAndroid Build Coastguard Worker
5812*bbecb9d1SAndroid Build Coastguard Worker if (indirect_handle) {
5813*bbecb9d1SAndroid Build Coastguard Worker indirect_res = vrend_renderer_ctx_res_lookup(ctx, indirect_handle);
5814*bbecb9d1SAndroid Build Coastguard Worker if (!indirect_res) {
5815*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, indirect_handle);
5816*bbecb9d1SAndroid Build Coastguard Worker return;
5817*bbecb9d1SAndroid Build Coastguard Worker }
5818*bbecb9d1SAndroid Build Coastguard Worker }
5819*bbecb9d1SAndroid Build Coastguard Worker
5820*bbecb9d1SAndroid Build Coastguard Worker if (indirect_res)
5821*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirect_res->id);
5822*bbecb9d1SAndroid Build Coastguard Worker else
5823*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
5824*bbecb9d1SAndroid Build Coastguard Worker
5825*bbecb9d1SAndroid Build Coastguard Worker if (indirect_res) {
5826*bbecb9d1SAndroid Build Coastguard Worker glDispatchComputeIndirect(indirect_offset);
5827*bbecb9d1SAndroid Build Coastguard Worker } else {
5828*bbecb9d1SAndroid Build Coastguard Worker glDispatchCompute(grid[0], grid[1], grid[2]);
5829*bbecb9d1SAndroid Build Coastguard Worker }
5830*bbecb9d1SAndroid Build Coastguard Worker }
5831*bbecb9d1SAndroid Build Coastguard Worker
translate_blend_func(uint32_t pipe_blend)5832*bbecb9d1SAndroid Build Coastguard Worker static GLenum translate_blend_func(uint32_t pipe_blend)
5833*bbecb9d1SAndroid Build Coastguard Worker {
5834*bbecb9d1SAndroid Build Coastguard Worker switch(pipe_blend){
5835*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLEND_ADD: return GL_FUNC_ADD;
5836*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLEND_SUBTRACT: return GL_FUNC_SUBTRACT;
5837*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLEND_REVERSE_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT;
5838*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLEND_MIN: return GL_MIN;
5839*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLEND_MAX: return GL_MAX;
5840*bbecb9d1SAndroid Build Coastguard Worker default:
5841*bbecb9d1SAndroid Build Coastguard Worker assert("invalid blend token()" == NULL);
5842*bbecb9d1SAndroid Build Coastguard Worker return 0;
5843*bbecb9d1SAndroid Build Coastguard Worker }
5844*bbecb9d1SAndroid Build Coastguard Worker }
5845*bbecb9d1SAndroid Build Coastguard Worker
translate_blend_factor(uint32_t pipe_factor)5846*bbecb9d1SAndroid Build Coastguard Worker static GLenum translate_blend_factor(uint32_t pipe_factor)
5847*bbecb9d1SAndroid Build Coastguard Worker {
5848*bbecb9d1SAndroid Build Coastguard Worker switch (pipe_factor) {
5849*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_ONE: return GL_ONE;
5850*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_SRC_COLOR: return GL_SRC_COLOR;
5851*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_SRC_ALPHA: return GL_SRC_ALPHA;
5852*bbecb9d1SAndroid Build Coastguard Worker
5853*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_DST_COLOR: return GL_DST_COLOR;
5854*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_DST_ALPHA: return GL_DST_ALPHA;
5855*bbecb9d1SAndroid Build Coastguard Worker
5856*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_CONST_COLOR: return GL_CONSTANT_COLOR;
5857*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_CONST_ALPHA: return GL_CONSTANT_ALPHA;
5858*bbecb9d1SAndroid Build Coastguard Worker
5859*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_SRC1_COLOR: return GL_SRC1_COLOR;
5860*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_SRC1_ALPHA: return GL_SRC1_ALPHA;
5861*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GL_SRC_ALPHA_SATURATE;
5862*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_ZERO: return GL_ZERO;
5863*bbecb9d1SAndroid Build Coastguard Worker
5864*bbecb9d1SAndroid Build Coastguard Worker
5865*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_SRC_COLOR: return GL_ONE_MINUS_SRC_COLOR;
5866*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return GL_ONE_MINUS_SRC_ALPHA;
5867*bbecb9d1SAndroid Build Coastguard Worker
5868*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_DST_COLOR: return GL_ONE_MINUS_DST_COLOR;
5869*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_DST_ALPHA: return GL_ONE_MINUS_DST_ALPHA;
5870*bbecb9d1SAndroid Build Coastguard Worker
5871*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_CONST_COLOR: return GL_ONE_MINUS_CONSTANT_COLOR;
5872*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return GL_ONE_MINUS_CONSTANT_ALPHA;
5873*bbecb9d1SAndroid Build Coastguard Worker
5874*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return GL_ONE_MINUS_SRC1_COLOR;
5875*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return GL_ONE_MINUS_SRC1_ALPHA;
5876*bbecb9d1SAndroid Build Coastguard Worker
5877*bbecb9d1SAndroid Build Coastguard Worker default:
5878*bbecb9d1SAndroid Build Coastguard Worker assert("invalid blend token()" == NULL);
5879*bbecb9d1SAndroid Build Coastguard Worker return 0;
5880*bbecb9d1SAndroid Build Coastguard Worker }
5881*bbecb9d1SAndroid Build Coastguard Worker }
5882*bbecb9d1SAndroid Build Coastguard Worker
5883*bbecb9d1SAndroid Build Coastguard Worker static GLenum
translate_logicop(GLuint pipe_logicop)5884*bbecb9d1SAndroid Build Coastguard Worker translate_logicop(GLuint pipe_logicop)
5885*bbecb9d1SAndroid Build Coastguard Worker {
5886*bbecb9d1SAndroid Build Coastguard Worker switch (pipe_logicop) {
5887*bbecb9d1SAndroid Build Coastguard Worker #define CASE(x) case PIPE_LOGICOP_##x: return GL_##x
5888*bbecb9d1SAndroid Build Coastguard Worker CASE(CLEAR);
5889*bbecb9d1SAndroid Build Coastguard Worker CASE(NOR);
5890*bbecb9d1SAndroid Build Coastguard Worker CASE(AND_INVERTED);
5891*bbecb9d1SAndroid Build Coastguard Worker CASE(COPY_INVERTED);
5892*bbecb9d1SAndroid Build Coastguard Worker CASE(AND_REVERSE);
5893*bbecb9d1SAndroid Build Coastguard Worker CASE(INVERT);
5894*bbecb9d1SAndroid Build Coastguard Worker CASE(XOR);
5895*bbecb9d1SAndroid Build Coastguard Worker CASE(NAND);
5896*bbecb9d1SAndroid Build Coastguard Worker CASE(AND);
5897*bbecb9d1SAndroid Build Coastguard Worker CASE(EQUIV);
5898*bbecb9d1SAndroid Build Coastguard Worker CASE(NOOP);
5899*bbecb9d1SAndroid Build Coastguard Worker CASE(OR_INVERTED);
5900*bbecb9d1SAndroid Build Coastguard Worker CASE(COPY);
5901*bbecb9d1SAndroid Build Coastguard Worker CASE(OR_REVERSE);
5902*bbecb9d1SAndroid Build Coastguard Worker CASE(OR);
5903*bbecb9d1SAndroid Build Coastguard Worker CASE(SET);
5904*bbecb9d1SAndroid Build Coastguard Worker default:
5905*bbecb9d1SAndroid Build Coastguard Worker assert("invalid logicop token()" == NULL);
5906*bbecb9d1SAndroid Build Coastguard Worker return 0;
5907*bbecb9d1SAndroid Build Coastguard Worker }
5908*bbecb9d1SAndroid Build Coastguard Worker #undef CASE
5909*bbecb9d1SAndroid Build Coastguard Worker }
5910*bbecb9d1SAndroid Build Coastguard Worker
5911*bbecb9d1SAndroid Build Coastguard Worker static GLenum
translate_stencil_op(GLuint op)5912*bbecb9d1SAndroid Build Coastguard Worker translate_stencil_op(GLuint op)
5913*bbecb9d1SAndroid Build Coastguard Worker {
5914*bbecb9d1SAndroid Build Coastguard Worker switch (op) {
5915*bbecb9d1SAndroid Build Coastguard Worker #define CASE(x) case PIPE_STENCIL_OP_##x: return GL_##x
5916*bbecb9d1SAndroid Build Coastguard Worker CASE(KEEP);
5917*bbecb9d1SAndroid Build Coastguard Worker CASE(ZERO);
5918*bbecb9d1SAndroid Build Coastguard Worker CASE(REPLACE);
5919*bbecb9d1SAndroid Build Coastguard Worker CASE(INCR);
5920*bbecb9d1SAndroid Build Coastguard Worker CASE(DECR);
5921*bbecb9d1SAndroid Build Coastguard Worker CASE(INCR_WRAP);
5922*bbecb9d1SAndroid Build Coastguard Worker CASE(DECR_WRAP);
5923*bbecb9d1SAndroid Build Coastguard Worker CASE(INVERT);
5924*bbecb9d1SAndroid Build Coastguard Worker default:
5925*bbecb9d1SAndroid Build Coastguard Worker assert("invalid stencilop token()" == NULL);
5926*bbecb9d1SAndroid Build Coastguard Worker return 0;
5927*bbecb9d1SAndroid Build Coastguard Worker }
5928*bbecb9d1SAndroid Build Coastguard Worker #undef CASE
5929*bbecb9d1SAndroid Build Coastguard Worker }
5930*bbecb9d1SAndroid Build Coastguard Worker
is_dst_blend(int blend_factor)5931*bbecb9d1SAndroid Build Coastguard Worker static inline bool is_dst_blend(int blend_factor)
5932*bbecb9d1SAndroid Build Coastguard Worker {
5933*bbecb9d1SAndroid Build Coastguard Worker return (blend_factor == PIPE_BLENDFACTOR_DST_ALPHA ||
5934*bbecb9d1SAndroid Build Coastguard Worker blend_factor == PIPE_BLENDFACTOR_INV_DST_ALPHA);
5935*bbecb9d1SAndroid Build Coastguard Worker }
5936*bbecb9d1SAndroid Build Coastguard Worker
conv_a8_blend(int blend_factor)5937*bbecb9d1SAndroid Build Coastguard Worker static inline int conv_a8_blend(int blend_factor)
5938*bbecb9d1SAndroid Build Coastguard Worker {
5939*bbecb9d1SAndroid Build Coastguard Worker if (blend_factor == PIPE_BLENDFACTOR_DST_ALPHA)
5940*bbecb9d1SAndroid Build Coastguard Worker return PIPE_BLENDFACTOR_DST_COLOR;
5941*bbecb9d1SAndroid Build Coastguard Worker if (blend_factor == PIPE_BLENDFACTOR_INV_DST_ALPHA)
5942*bbecb9d1SAndroid Build Coastguard Worker return PIPE_BLENDFACTOR_INV_DST_COLOR;
5943*bbecb9d1SAndroid Build Coastguard Worker return blend_factor;
5944*bbecb9d1SAndroid Build Coastguard Worker }
5945*bbecb9d1SAndroid Build Coastguard Worker
conv_dst_blend(int blend_factor)5946*bbecb9d1SAndroid Build Coastguard Worker static inline int conv_dst_blend(int blend_factor)
5947*bbecb9d1SAndroid Build Coastguard Worker {
5948*bbecb9d1SAndroid Build Coastguard Worker if (blend_factor == PIPE_BLENDFACTOR_DST_ALPHA)
5949*bbecb9d1SAndroid Build Coastguard Worker return PIPE_BLENDFACTOR_ONE;
5950*bbecb9d1SAndroid Build Coastguard Worker if (blend_factor == PIPE_BLENDFACTOR_INV_DST_ALPHA)
5951*bbecb9d1SAndroid Build Coastguard Worker return PIPE_BLENDFACTOR_ZERO;
5952*bbecb9d1SAndroid Build Coastguard Worker return blend_factor;
5953*bbecb9d1SAndroid Build Coastguard Worker }
5954*bbecb9d1SAndroid Build Coastguard Worker
is_const_blend(int blend_factor)5955*bbecb9d1SAndroid Build Coastguard Worker static inline bool is_const_blend(int blend_factor)
5956*bbecb9d1SAndroid Build Coastguard Worker {
5957*bbecb9d1SAndroid Build Coastguard Worker return (blend_factor == PIPE_BLENDFACTOR_CONST_COLOR ||
5958*bbecb9d1SAndroid Build Coastguard Worker blend_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
5959*bbecb9d1SAndroid Build Coastguard Worker blend_factor == PIPE_BLENDFACTOR_INV_CONST_COLOR ||
5960*bbecb9d1SAndroid Build Coastguard Worker blend_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA);
5961*bbecb9d1SAndroid Build Coastguard Worker }
5962*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_emit_blend(struct vrend_sub_context * sub_ctx,struct pipe_blend_state * state)5963*bbecb9d1SAndroid Build Coastguard Worker static void vrend_hw_emit_blend(struct vrend_sub_context *sub_ctx, struct pipe_blend_state *state)
5964*bbecb9d1SAndroid Build Coastguard Worker {
5965*bbecb9d1SAndroid Build Coastguard Worker if (state->logicop_enable != sub_ctx->hw_blend_state.logicop_enable) {
5966*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->hw_blend_state.logicop_enable = state->logicop_enable;
5967*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
5968*bbecb9d1SAndroid Build Coastguard Worker if (can_emulate_logicop(state->logicop_func))
5969*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->shader_dirty = true;
5970*bbecb9d1SAndroid Build Coastguard Worker else
5971*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(sub_ctx->parent, GLES_WARN_LOGIC_OP);
5972*bbecb9d1SAndroid Build Coastguard Worker } else if (state->logicop_enable) {
5973*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_COLOR_LOGIC_OP);
5974*bbecb9d1SAndroid Build Coastguard Worker glLogicOp(translate_logicop(state->logicop_func));
5975*bbecb9d1SAndroid Build Coastguard Worker } else {
5976*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_COLOR_LOGIC_OP);
5977*bbecb9d1SAndroid Build Coastguard Worker }
5978*bbecb9d1SAndroid Build Coastguard Worker }
5979*bbecb9d1SAndroid Build Coastguard Worker
5980*bbecb9d1SAndroid Build Coastguard Worker if (state->independent_blend_enable &&
5981*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_indep_blend) &&
5982*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_indep_blend_func)) {
5983*bbecb9d1SAndroid Build Coastguard Worker /* ARB_draw_buffers_blend is required for this */
5984*bbecb9d1SAndroid Build Coastguard Worker int i;
5985*bbecb9d1SAndroid Build Coastguard Worker
5986*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
5987*bbecb9d1SAndroid Build Coastguard Worker
5988*bbecb9d1SAndroid Build Coastguard Worker if (state->rt[i].blend_enable) {
5989*bbecb9d1SAndroid Build Coastguard Worker bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, i);
5990*bbecb9d1SAndroid Build Coastguard Worker if (dual_src && !has_feature(feat_dual_src_blend)) {
5991*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "dual src blend requested but not supported for rt %d\n", i);
5992*bbecb9d1SAndroid Build Coastguard Worker continue;
5993*bbecb9d1SAndroid Build Coastguard Worker }
5994*bbecb9d1SAndroid Build Coastguard Worker
5995*bbecb9d1SAndroid Build Coastguard Worker glBlendFuncSeparateiARB(i, translate_blend_factor(state->rt[i].rgb_src_factor),
5996*bbecb9d1SAndroid Build Coastguard Worker translate_blend_factor(state->rt[i].rgb_dst_factor),
5997*bbecb9d1SAndroid Build Coastguard Worker translate_blend_factor(state->rt[i].alpha_src_factor),
5998*bbecb9d1SAndroid Build Coastguard Worker translate_blend_factor(state->rt[i].alpha_dst_factor));
5999*bbecb9d1SAndroid Build Coastguard Worker glBlendEquationSeparateiARB(i, translate_blend_func(state->rt[i].rgb_func),
6000*bbecb9d1SAndroid Build Coastguard Worker translate_blend_func(state->rt[i].alpha_func));
6001*bbecb9d1SAndroid Build Coastguard Worker glEnableIndexedEXT(GL_BLEND, i);
6002*bbecb9d1SAndroid Build Coastguard Worker } else
6003*bbecb9d1SAndroid Build Coastguard Worker glDisableIndexedEXT(GL_BLEND, i);
6004*bbecb9d1SAndroid Build Coastguard Worker
6005*bbecb9d1SAndroid Build Coastguard Worker if (state->rt[i].colormask != sub_ctx->hw_blend_state.rt[i].colormask) {
6006*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->hw_blend_state.rt[i].colormask = state->rt[i].colormask;
6007*bbecb9d1SAndroid Build Coastguard Worker glColorMaskIndexedEXT(i, state->rt[i].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
6008*bbecb9d1SAndroid Build Coastguard Worker state->rt[i].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
6009*bbecb9d1SAndroid Build Coastguard Worker state->rt[i].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
6010*bbecb9d1SAndroid Build Coastguard Worker state->rt[i].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
6011*bbecb9d1SAndroid Build Coastguard Worker }
6012*bbecb9d1SAndroid Build Coastguard Worker }
6013*bbecb9d1SAndroid Build Coastguard Worker } else {
6014*bbecb9d1SAndroid Build Coastguard Worker if (state->rt[0].blend_enable) {
6015*bbecb9d1SAndroid Build Coastguard Worker bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, 0);
6016*bbecb9d1SAndroid Build Coastguard Worker if (dual_src && !has_feature(feat_dual_src_blend)) {
6017*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "dual src blend requested but not supported for rt 0\n");
6018*bbecb9d1SAndroid Build Coastguard Worker }
6019*bbecb9d1SAndroid Build Coastguard Worker glBlendFuncSeparate(translate_blend_factor(state->rt[0].rgb_src_factor),
6020*bbecb9d1SAndroid Build Coastguard Worker translate_blend_factor(state->rt[0].rgb_dst_factor),
6021*bbecb9d1SAndroid Build Coastguard Worker translate_blend_factor(state->rt[0].alpha_src_factor),
6022*bbecb9d1SAndroid Build Coastguard Worker translate_blend_factor(state->rt[0].alpha_dst_factor));
6023*bbecb9d1SAndroid Build Coastguard Worker glBlendEquationSeparate(translate_blend_func(state->rt[0].rgb_func),
6024*bbecb9d1SAndroid Build Coastguard Worker translate_blend_func(state->rt[0].alpha_func));
6025*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_BLEND);
6026*bbecb9d1SAndroid Build Coastguard Worker }
6027*bbecb9d1SAndroid Build Coastguard Worker else
6028*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_BLEND);
6029*bbecb9d1SAndroid Build Coastguard Worker
6030*bbecb9d1SAndroid Build Coastguard Worker if (state->rt[0].colormask != sub_ctx->hw_blend_state.rt[0].colormask ||
6031*bbecb9d1SAndroid Build Coastguard Worker (sub_ctx->hw_blend_state.independent_blend_enable &&
6032*bbecb9d1SAndroid Build Coastguard Worker !state->independent_blend_enable)) {
6033*bbecb9d1SAndroid Build Coastguard Worker glColorMask(state->rt[0].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
6034*bbecb9d1SAndroid Build Coastguard Worker state->rt[0].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
6035*bbecb9d1SAndroid Build Coastguard Worker state->rt[0].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
6036*bbecb9d1SAndroid Build Coastguard Worker state->rt[0].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
6037*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
6038*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->hw_blend_state.rt[i].colormask = state->rt[0].colormask;
6039*bbecb9d1SAndroid Build Coastguard Worker }
6040*bbecb9d1SAndroid Build Coastguard Worker }
6041*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->hw_blend_state.independent_blend_enable = state->independent_blend_enable;
6042*bbecb9d1SAndroid Build Coastguard Worker
6043*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_multisample)) {
6044*bbecb9d1SAndroid Build Coastguard Worker if (state->alpha_to_coverage)
6045*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
6046*bbecb9d1SAndroid Build Coastguard Worker else
6047*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
6048*bbecb9d1SAndroid Build Coastguard Worker
6049*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles) {
6050*bbecb9d1SAndroid Build Coastguard Worker if (state->alpha_to_one)
6051*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SAMPLE_ALPHA_TO_ONE);
6052*bbecb9d1SAndroid Build Coastguard Worker else
6053*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SAMPLE_ALPHA_TO_ONE);
6054*bbecb9d1SAndroid Build Coastguard Worker }
6055*bbecb9d1SAndroid Build Coastguard Worker }
6056*bbecb9d1SAndroid Build Coastguard Worker
6057*bbecb9d1SAndroid Build Coastguard Worker if (state->dither)
6058*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_DITHER);
6059*bbecb9d1SAndroid Build Coastguard Worker else
6060*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_DITHER);
6061*bbecb9d1SAndroid Build Coastguard Worker }
6062*bbecb9d1SAndroid Build Coastguard Worker
6063*bbecb9d1SAndroid Build Coastguard Worker /* there are a few reasons we might need to patch the blend state.
6064*bbecb9d1SAndroid Build Coastguard Worker a) patching blend factors for dst with no alpha
6065*bbecb9d1SAndroid Build Coastguard Worker b) patching colormask/blendcolor/blendfactors for A8/A16 format
6066*bbecb9d1SAndroid Build Coastguard Worker emulation using GL_R8/GL_R16.
6067*bbecb9d1SAndroid Build Coastguard Worker */
vrend_patch_blend_state(struct vrend_sub_context * sub_ctx)6068*bbecb9d1SAndroid Build Coastguard Worker static void vrend_patch_blend_state(struct vrend_sub_context *sub_ctx)
6069*bbecb9d1SAndroid Build Coastguard Worker {
6070*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_state new_state = sub_ctx->blend_state;
6071*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_state *state = &sub_ctx->blend_state;
6072*bbecb9d1SAndroid Build Coastguard Worker bool swizzle_blend_color = false;
6073*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_color blend_color = sub_ctx->blend_color;
6074*bbecb9d1SAndroid Build Coastguard Worker int i;
6075*bbecb9d1SAndroid Build Coastguard Worker
6076*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx->nr_cbufs == 0) {
6077*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->blend_state_dirty = false;
6078*bbecb9d1SAndroid Build Coastguard Worker return;
6079*bbecb9d1SAndroid Build Coastguard Worker }
6080*bbecb9d1SAndroid Build Coastguard Worker
6081*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < (state->independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1); i++) {
6082*bbecb9d1SAndroid Build Coastguard Worker if (i < sub_ctx->nr_cbufs && sub_ctx->surf[i]) {
6083*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_is_emulated_alpha(sub_ctx->surf[i]->format)) {
6084*bbecb9d1SAndroid Build Coastguard Worker if (state->rt[i].blend_enable) {
6085*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].rgb_src_factor = conv_a8_blend(state->rt[i].alpha_src_factor);
6086*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].rgb_dst_factor = conv_a8_blend(state->rt[i].alpha_dst_factor);
6087*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
6088*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
6089*bbecb9d1SAndroid Build Coastguard Worker }
6090*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].colormask = 0;
6091*bbecb9d1SAndroid Build Coastguard Worker if (state->rt[i].colormask & PIPE_MASK_A)
6092*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].colormask |= PIPE_MASK_R;
6093*bbecb9d1SAndroid Build Coastguard Worker if (is_const_blend(new_state.rt[i].rgb_src_factor) ||
6094*bbecb9d1SAndroid Build Coastguard Worker is_const_blend(new_state.rt[i].rgb_dst_factor)) {
6095*bbecb9d1SAndroid Build Coastguard Worker swizzle_blend_color = true;
6096*bbecb9d1SAndroid Build Coastguard Worker }
6097*bbecb9d1SAndroid Build Coastguard Worker } else if (!util_format_has_alpha(sub_ctx->surf[i]->format)) {
6098*bbecb9d1SAndroid Build Coastguard Worker if (!(is_dst_blend(state->rt[i].rgb_src_factor) ||
6099*bbecb9d1SAndroid Build Coastguard Worker is_dst_blend(state->rt[i].rgb_dst_factor) ||
6100*bbecb9d1SAndroid Build Coastguard Worker is_dst_blend(state->rt[i].alpha_src_factor) ||
6101*bbecb9d1SAndroid Build Coastguard Worker is_dst_blend(state->rt[i].alpha_dst_factor)))
6102*bbecb9d1SAndroid Build Coastguard Worker continue;
6103*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].rgb_src_factor = conv_dst_blend(state->rt[i].rgb_src_factor);
6104*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].rgb_dst_factor = conv_dst_blend(state->rt[i].rgb_dst_factor);
6105*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].alpha_src_factor = conv_dst_blend(state->rt[i].alpha_src_factor);
6106*bbecb9d1SAndroid Build Coastguard Worker new_state.rt[i].alpha_dst_factor = conv_dst_blend(state->rt[i].alpha_dst_factor);
6107*bbecb9d1SAndroid Build Coastguard Worker }
6108*bbecb9d1SAndroid Build Coastguard Worker }
6109*bbecb9d1SAndroid Build Coastguard Worker }
6110*bbecb9d1SAndroid Build Coastguard Worker
6111*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_emit_blend(sub_ctx, &new_state);
6112*bbecb9d1SAndroid Build Coastguard Worker
6113*bbecb9d1SAndroid Build Coastguard Worker if (swizzle_blend_color) {
6114*bbecb9d1SAndroid Build Coastguard Worker blend_color.color[0] = blend_color.color[3];
6115*bbecb9d1SAndroid Build Coastguard Worker blend_color.color[1] = 0.0f;
6116*bbecb9d1SAndroid Build Coastguard Worker blend_color.color[2] = 0.0f;
6117*bbecb9d1SAndroid Build Coastguard Worker blend_color.color[3] = 0.0f;
6118*bbecb9d1SAndroid Build Coastguard Worker }
6119*bbecb9d1SAndroid Build Coastguard Worker
6120*bbecb9d1SAndroid Build Coastguard Worker glBlendColor(blend_color.color[0],
6121*bbecb9d1SAndroid Build Coastguard Worker blend_color.color[1],
6122*bbecb9d1SAndroid Build Coastguard Worker blend_color.color[2],
6123*bbecb9d1SAndroid Build Coastguard Worker blend_color.color[3]);
6124*bbecb9d1SAndroid Build Coastguard Worker
6125*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->blend_state_dirty = false;
6126*bbecb9d1SAndroid Build Coastguard Worker }
6127*bbecb9d1SAndroid Build Coastguard Worker
vrend_object_bind_blend(struct vrend_context * ctx,uint32_t handle)6128*bbecb9d1SAndroid Build Coastguard Worker void vrend_object_bind_blend(struct vrend_context *ctx,
6129*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
6130*bbecb9d1SAndroid Build Coastguard Worker {
6131*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_state *state;
6132*bbecb9d1SAndroid Build Coastguard Worker
6133*bbecb9d1SAndroid Build Coastguard Worker if (handle == 0) {
6134*bbecb9d1SAndroid Build Coastguard Worker memset(&ctx->sub->blend_state, 0, sizeof(ctx->sub->blend_state));
6135*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_BLEND);
6136*bbecb9d1SAndroid Build Coastguard Worker return;
6137*bbecb9d1SAndroid Build Coastguard Worker }
6138*bbecb9d1SAndroid Build Coastguard Worker state = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_BLEND);
6139*bbecb9d1SAndroid Build Coastguard Worker if (!state) {
6140*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handle);
6141*bbecb9d1SAndroid Build Coastguard Worker return;
6142*bbecb9d1SAndroid Build Coastguard Worker }
6143*bbecb9d1SAndroid Build Coastguard Worker
6144*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->shader_dirty = true;
6145*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->blend_state = *state;
6146*bbecb9d1SAndroid Build Coastguard Worker
6147*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->blend_state_dirty = true;
6148*bbecb9d1SAndroid Build Coastguard Worker }
6149*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_emit_dsa(struct vrend_context * ctx)6150*bbecb9d1SAndroid Build Coastguard Worker static void vrend_hw_emit_dsa(struct vrend_context *ctx)
6151*bbecb9d1SAndroid Build Coastguard Worker {
6152*bbecb9d1SAndroid Build Coastguard Worker struct pipe_depth_stencil_alpha_state *state = &ctx->sub->dsa_state;
6153*bbecb9d1SAndroid Build Coastguard Worker
6154*bbecb9d1SAndroid Build Coastguard Worker if (state->depth.enabled) {
6155*bbecb9d1SAndroid Build Coastguard Worker vrend_depth_test_enable(ctx, true);
6156*bbecb9d1SAndroid Build Coastguard Worker glDepthFunc(GL_NEVER + state->depth.func);
6157*bbecb9d1SAndroid Build Coastguard Worker if (state->depth.writemask)
6158*bbecb9d1SAndroid Build Coastguard Worker glDepthMask(GL_TRUE);
6159*bbecb9d1SAndroid Build Coastguard Worker else
6160*bbecb9d1SAndroid Build Coastguard Worker glDepthMask(GL_FALSE);
6161*bbecb9d1SAndroid Build Coastguard Worker } else
6162*bbecb9d1SAndroid Build Coastguard Worker vrend_depth_test_enable(ctx, false);
6163*bbecb9d1SAndroid Build Coastguard Worker
6164*bbecb9d1SAndroid Build Coastguard Worker if (state->alpha.enabled) {
6165*bbecb9d1SAndroid Build Coastguard Worker vrend_alpha_test_enable(ctx, true);
6166*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_core_profile)
6167*bbecb9d1SAndroid Build Coastguard Worker glAlphaFunc(GL_NEVER + state->alpha.func, state->alpha.ref_value);
6168*bbecb9d1SAndroid Build Coastguard Worker } else
6169*bbecb9d1SAndroid Build Coastguard Worker vrend_alpha_test_enable(ctx, false);
6170*bbecb9d1SAndroid Build Coastguard Worker
6171*bbecb9d1SAndroid Build Coastguard Worker
6172*bbecb9d1SAndroid Build Coastguard Worker }
vrend_object_bind_dsa(struct vrend_context * ctx,uint32_t handle)6173*bbecb9d1SAndroid Build Coastguard Worker void vrend_object_bind_dsa(struct vrend_context *ctx,
6174*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
6175*bbecb9d1SAndroid Build Coastguard Worker {
6176*bbecb9d1SAndroid Build Coastguard Worker struct pipe_depth_stencil_alpha_state *state;
6177*bbecb9d1SAndroid Build Coastguard Worker
6178*bbecb9d1SAndroid Build Coastguard Worker if (handle == 0) {
6179*bbecb9d1SAndroid Build Coastguard Worker memset(&ctx->sub->dsa_state, 0, sizeof(ctx->sub->dsa_state));
6180*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->dsa = NULL;
6181*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->stencil_state_dirty = true;
6182*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->shader_dirty = true;
6183*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_emit_dsa(ctx);
6184*bbecb9d1SAndroid Build Coastguard Worker return;
6185*bbecb9d1SAndroid Build Coastguard Worker }
6186*bbecb9d1SAndroid Build Coastguard Worker
6187*bbecb9d1SAndroid Build Coastguard Worker state = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_DSA);
6188*bbecb9d1SAndroid Build Coastguard Worker if (!state) {
6189*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handle);
6190*bbecb9d1SAndroid Build Coastguard Worker return;
6191*bbecb9d1SAndroid Build Coastguard Worker }
6192*bbecb9d1SAndroid Build Coastguard Worker
6193*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->dsa != state) {
6194*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->stencil_state_dirty = true;
6195*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->shader_dirty = true;
6196*bbecb9d1SAndroid Build Coastguard Worker }
6197*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->dsa_state = *state;
6198*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->dsa = state;
6199*bbecb9d1SAndroid Build Coastguard Worker
6200*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->sysvalue_data.alpha_ref_val != state->alpha.ref_value) {
6201*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data.alpha_ref_val = state->alpha.ref_value;
6202*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data_cookie++;
6203*bbecb9d1SAndroid Build Coastguard Worker }
6204*bbecb9d1SAndroid Build Coastguard Worker
6205*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_emit_dsa(ctx);
6206*bbecb9d1SAndroid Build Coastguard Worker }
6207*bbecb9d1SAndroid Build Coastguard Worker
vrend_update_frontface_state(struct vrend_sub_context * sub_ctx)6208*bbecb9d1SAndroid Build Coastguard Worker static void vrend_update_frontface_state(struct vrend_sub_context *sub_ctx)
6209*bbecb9d1SAndroid Build Coastguard Worker {
6210*bbecb9d1SAndroid Build Coastguard Worker struct pipe_rasterizer_state *state = &sub_ctx->rs_state;
6211*bbecb9d1SAndroid Build Coastguard Worker int front_ccw = state->front_ccw;
6212*bbecb9d1SAndroid Build Coastguard Worker
6213*bbecb9d1SAndroid Build Coastguard Worker front_ccw ^= (sub_ctx->fbo_origin_upper_left ? 0 : 1);
6214*bbecb9d1SAndroid Build Coastguard Worker if (front_ccw)
6215*bbecb9d1SAndroid Build Coastguard Worker glFrontFace(GL_CCW);
6216*bbecb9d1SAndroid Build Coastguard Worker else
6217*bbecb9d1SAndroid Build Coastguard Worker glFrontFace(GL_CW);
6218*bbecb9d1SAndroid Build Coastguard Worker }
6219*bbecb9d1SAndroid Build Coastguard Worker
vrend_update_stencil_state(struct vrend_sub_context * sub_ctx)6220*bbecb9d1SAndroid Build Coastguard Worker void vrend_update_stencil_state(struct vrend_sub_context *sub_ctx)
6221*bbecb9d1SAndroid Build Coastguard Worker {
6222*bbecb9d1SAndroid Build Coastguard Worker struct pipe_depth_stencil_alpha_state *state = sub_ctx->dsa;
6223*bbecb9d1SAndroid Build Coastguard Worker int i;
6224*bbecb9d1SAndroid Build Coastguard Worker if (!state)
6225*bbecb9d1SAndroid Build Coastguard Worker return;
6226*bbecb9d1SAndroid Build Coastguard Worker
6227*bbecb9d1SAndroid Build Coastguard Worker if (!state->stencil[1].enabled) {
6228*bbecb9d1SAndroid Build Coastguard Worker if (state->stencil[0].enabled) {
6229*bbecb9d1SAndroid Build Coastguard Worker vrend_stencil_test_enable(sub_ctx, true);
6230*bbecb9d1SAndroid Build Coastguard Worker
6231*bbecb9d1SAndroid Build Coastguard Worker glStencilOp(translate_stencil_op(state->stencil[0].fail_op),
6232*bbecb9d1SAndroid Build Coastguard Worker translate_stencil_op(state->stencil[0].zfail_op),
6233*bbecb9d1SAndroid Build Coastguard Worker translate_stencil_op(state->stencil[0].zpass_op));
6234*bbecb9d1SAndroid Build Coastguard Worker
6235*bbecb9d1SAndroid Build Coastguard Worker glStencilFunc(GL_NEVER + state->stencil[0].func,
6236*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->stencil_refs[0],
6237*bbecb9d1SAndroid Build Coastguard Worker state->stencil[0].valuemask);
6238*bbecb9d1SAndroid Build Coastguard Worker glStencilMask(state->stencil[0].writemask);
6239*bbecb9d1SAndroid Build Coastguard Worker } else
6240*bbecb9d1SAndroid Build Coastguard Worker vrend_stencil_test_enable(sub_ctx, false);
6241*bbecb9d1SAndroid Build Coastguard Worker } else {
6242*bbecb9d1SAndroid Build Coastguard Worker vrend_stencil_test_enable(sub_ctx, true);
6243*bbecb9d1SAndroid Build Coastguard Worker
6244*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
6245*bbecb9d1SAndroid Build Coastguard Worker GLenum face = (i == 1) ? GL_BACK : GL_FRONT;
6246*bbecb9d1SAndroid Build Coastguard Worker glStencilOpSeparate(face,
6247*bbecb9d1SAndroid Build Coastguard Worker translate_stencil_op(state->stencil[i].fail_op),
6248*bbecb9d1SAndroid Build Coastguard Worker translate_stencil_op(state->stencil[i].zfail_op),
6249*bbecb9d1SAndroid Build Coastguard Worker translate_stencil_op(state->stencil[i].zpass_op));
6250*bbecb9d1SAndroid Build Coastguard Worker
6251*bbecb9d1SAndroid Build Coastguard Worker glStencilFuncSeparate(face, GL_NEVER + state->stencil[i].func,
6252*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->stencil_refs[i],
6253*bbecb9d1SAndroid Build Coastguard Worker state->stencil[i].valuemask);
6254*bbecb9d1SAndroid Build Coastguard Worker glStencilMaskSeparate(face, state->stencil[i].writemask);
6255*bbecb9d1SAndroid Build Coastguard Worker }
6256*bbecb9d1SAndroid Build Coastguard Worker }
6257*bbecb9d1SAndroid Build Coastguard Worker sub_ctx->stencil_state_dirty = false;
6258*bbecb9d1SAndroid Build Coastguard Worker }
6259*bbecb9d1SAndroid Build Coastguard Worker
translate_fill(uint32_t mode)6260*bbecb9d1SAndroid Build Coastguard Worker static inline GLenum translate_fill(uint32_t mode)
6261*bbecb9d1SAndroid Build Coastguard Worker {
6262*bbecb9d1SAndroid Build Coastguard Worker switch (mode) {
6263*bbecb9d1SAndroid Build Coastguard Worker case PIPE_POLYGON_MODE_POINT:
6264*bbecb9d1SAndroid Build Coastguard Worker return GL_POINT;
6265*bbecb9d1SAndroid Build Coastguard Worker case PIPE_POLYGON_MODE_LINE:
6266*bbecb9d1SAndroid Build Coastguard Worker return GL_LINE;
6267*bbecb9d1SAndroid Build Coastguard Worker case PIPE_POLYGON_MODE_FILL:
6268*bbecb9d1SAndroid Build Coastguard Worker return GL_FILL;
6269*bbecb9d1SAndroid Build Coastguard Worker default:
6270*bbecb9d1SAndroid Build Coastguard Worker assert(0);
6271*bbecb9d1SAndroid Build Coastguard Worker return 0;
6272*bbecb9d1SAndroid Build Coastguard Worker }
6273*bbecb9d1SAndroid Build Coastguard Worker }
6274*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_emit_rs(struct vrend_context * ctx)6275*bbecb9d1SAndroid Build Coastguard Worker static void vrend_hw_emit_rs(struct vrend_context *ctx)
6276*bbecb9d1SAndroid Build Coastguard Worker {
6277*bbecb9d1SAndroid Build Coastguard Worker struct pipe_rasterizer_state *state = &ctx->sub->rs_state;
6278*bbecb9d1SAndroid Build Coastguard Worker int i;
6279*bbecb9d1SAndroid Build Coastguard Worker
6280*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_depth_clamp)) {
6281*bbecb9d1SAndroid Build Coastguard Worker if (state->depth_clip)
6282*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_DEPTH_CLAMP);
6283*bbecb9d1SAndroid Build Coastguard Worker else
6284*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_DEPTH_CLAMP);
6285*bbecb9d1SAndroid Build Coastguard Worker }
6286*bbecb9d1SAndroid Build Coastguard Worker
6287*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
6288*bbecb9d1SAndroid Build Coastguard Worker /* guest send invalid glPointSize parameter */
6289*bbecb9d1SAndroid Build Coastguard Worker if (!state->point_size_per_vertex &&
6290*bbecb9d1SAndroid Build Coastguard Worker state->point_size != 1.0f &&
6291*bbecb9d1SAndroid Build Coastguard Worker state->point_size != 0.0f) {
6292*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_POINT_SIZE);
6293*bbecb9d1SAndroid Build Coastguard Worker }
6294*bbecb9d1SAndroid Build Coastguard Worker } else if (state->point_size_per_vertex) {
6295*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_PROGRAM_POINT_SIZE);
6296*bbecb9d1SAndroid Build Coastguard Worker } else {
6297*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_PROGRAM_POINT_SIZE);
6298*bbecb9d1SAndroid Build Coastguard Worker if (state->point_size) {
6299*bbecb9d1SAndroid Build Coastguard Worker glPointSize(state->point_size);
6300*bbecb9d1SAndroid Build Coastguard Worker }
6301*bbecb9d1SAndroid Build Coastguard Worker }
6302*bbecb9d1SAndroid Build Coastguard Worker
6303*bbecb9d1SAndroid Build Coastguard Worker /* line_width < 0 is invalid, the guest sometimes forgot to set it. */
6304*bbecb9d1SAndroid Build Coastguard Worker glLineWidth(state->line_width <= 0 ? 1.0f : state->line_width);
6305*bbecb9d1SAndroid Build Coastguard Worker
6306*bbecb9d1SAndroid Build Coastguard Worker if (state->rasterizer_discard != ctx->sub->hw_rs_state.rasterizer_discard) {
6307*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->hw_rs_state.rasterizer_discard = state->rasterizer_discard;
6308*bbecb9d1SAndroid Build Coastguard Worker if (state->rasterizer_discard)
6309*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_RASTERIZER_DISCARD);
6310*bbecb9d1SAndroid Build Coastguard Worker else
6311*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_RASTERIZER_DISCARD);
6312*bbecb9d1SAndroid Build Coastguard Worker }
6313*bbecb9d1SAndroid Build Coastguard Worker
6314*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles == true) {
6315*bbecb9d1SAndroid Build Coastguard Worker if (translate_fill(state->fill_front) != GL_FILL) {
6316*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_POLYGON_MODE);
6317*bbecb9d1SAndroid Build Coastguard Worker }
6318*bbecb9d1SAndroid Build Coastguard Worker if (translate_fill(state->fill_back) != GL_FILL) {
6319*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_POLYGON_MODE);
6320*bbecb9d1SAndroid Build Coastguard Worker }
6321*bbecb9d1SAndroid Build Coastguard Worker } else if (vrend_state.use_core_profile == false) {
6322*bbecb9d1SAndroid Build Coastguard Worker glPolygonMode(GL_FRONT, translate_fill(state->fill_front));
6323*bbecb9d1SAndroid Build Coastguard Worker glPolygonMode(GL_BACK, translate_fill(state->fill_back));
6324*bbecb9d1SAndroid Build Coastguard Worker } else if (state->fill_front == state->fill_back) {
6325*bbecb9d1SAndroid Build Coastguard Worker glPolygonMode(GL_FRONT_AND_BACK, translate_fill(state->fill_front));
6326*bbecb9d1SAndroid Build Coastguard Worker } else
6327*bbecb9d1SAndroid Build Coastguard Worker report_core_warn(ctx, CORE_PROFILE_WARN_POLYGON_MODE);
6328*bbecb9d1SAndroid Build Coastguard Worker
6329*bbecb9d1SAndroid Build Coastguard Worker if (state->offset_tri) {
6330*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_POLYGON_OFFSET_FILL);
6331*bbecb9d1SAndroid Build Coastguard Worker } else {
6332*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_POLYGON_OFFSET_FILL);
6333*bbecb9d1SAndroid Build Coastguard Worker }
6334*bbecb9d1SAndroid Build Coastguard Worker
6335*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
6336*bbecb9d1SAndroid Build Coastguard Worker if (state->offset_line) {
6337*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_OFFSET_LINE);
6338*bbecb9d1SAndroid Build Coastguard Worker }
6339*bbecb9d1SAndroid Build Coastguard Worker } else if (state->offset_line) {
6340*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_POLYGON_OFFSET_LINE);
6341*bbecb9d1SAndroid Build Coastguard Worker } else {
6342*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_POLYGON_OFFSET_LINE);
6343*bbecb9d1SAndroid Build Coastguard Worker }
6344*bbecb9d1SAndroid Build Coastguard Worker
6345*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
6346*bbecb9d1SAndroid Build Coastguard Worker if (state->offset_point) {
6347*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_OFFSET_POINT);
6348*bbecb9d1SAndroid Build Coastguard Worker }
6349*bbecb9d1SAndroid Build Coastguard Worker } else if (state->offset_point) {
6350*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_POLYGON_OFFSET_POINT);
6351*bbecb9d1SAndroid Build Coastguard Worker } else {
6352*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_POLYGON_OFFSET_POINT);
6353*bbecb9d1SAndroid Build Coastguard Worker }
6354*bbecb9d1SAndroid Build Coastguard Worker
6355*bbecb9d1SAndroid Build Coastguard Worker
6356*bbecb9d1SAndroid Build Coastguard Worker if (state->flatshade != ctx->sub->hw_rs_state.flatshade) {
6357*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->hw_rs_state.flatshade = state->flatshade;
6358*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false) {
6359*bbecb9d1SAndroid Build Coastguard Worker if (state->flatshade) {
6360*bbecb9d1SAndroid Build Coastguard Worker glShadeModel(GL_FLAT);
6361*bbecb9d1SAndroid Build Coastguard Worker } else {
6362*bbecb9d1SAndroid Build Coastguard Worker glShadeModel(GL_SMOOTH);
6363*bbecb9d1SAndroid Build Coastguard Worker }
6364*bbecb9d1SAndroid Build Coastguard Worker }
6365*bbecb9d1SAndroid Build Coastguard Worker }
6366*bbecb9d1SAndroid Build Coastguard Worker
6367*bbecb9d1SAndroid Build Coastguard Worker if (state->clip_halfz != ctx->sub->hw_rs_state.clip_halfz) {
6368*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_clip_control)) {
6369*bbecb9d1SAndroid Build Coastguard Worker /* We only need to handle clip_halfz here, the bottom_edge_rule is
6370*bbecb9d1SAndroid Build Coastguard Worker * already handled via Gallium */
6371*bbecb9d1SAndroid Build Coastguard Worker GLenum depthrule = state->clip_halfz ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE;
6372*bbecb9d1SAndroid Build Coastguard Worker glClipControl(GL_LOWER_LEFT, depthrule);
6373*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->hw_rs_state.clip_halfz = state->clip_halfz;
6374*bbecb9d1SAndroid Build Coastguard Worker } else {
6375*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("No clip control supported\n");
6376*bbecb9d1SAndroid Build Coastguard Worker }
6377*bbecb9d1SAndroid Build Coastguard Worker }
6378*bbecb9d1SAndroid Build Coastguard Worker if (state->flatshade_first != ctx->sub->hw_rs_state.flatshade_first) {
6379*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->hw_rs_state.flatshade_first = state->flatshade_first;
6380*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
6381*bbecb9d1SAndroid Build Coastguard Worker if (state->flatshade_first) {
6382*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_FLATSHADE_FIRST);
6383*bbecb9d1SAndroid Build Coastguard Worker }
6384*bbecb9d1SAndroid Build Coastguard Worker } else if (state->flatshade_first) {
6385*bbecb9d1SAndroid Build Coastguard Worker glProvokingVertexEXT(GL_FIRST_VERTEX_CONVENTION_EXT);
6386*bbecb9d1SAndroid Build Coastguard Worker } else {
6387*bbecb9d1SAndroid Build Coastguard Worker glProvokingVertexEXT(GL_LAST_VERTEX_CONVENTION_EXT);
6388*bbecb9d1SAndroid Build Coastguard Worker }
6389*bbecb9d1SAndroid Build Coastguard Worker }
6390*bbecb9d1SAndroid Build Coastguard Worker
6391*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles && has_feature(feat_polygon_offset_clamp))
6392*bbecb9d1SAndroid Build Coastguard Worker glPolygonOffsetClampEXT(state->offset_scale, state->offset_units, state->offset_clamp);
6393*bbecb9d1SAndroid Build Coastguard Worker else
6394*bbecb9d1SAndroid Build Coastguard Worker glPolygonOffset(state->offset_scale, state->offset_units);
6395*bbecb9d1SAndroid Build Coastguard Worker
6396*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false) {
6397*bbecb9d1SAndroid Build Coastguard Worker if (state->poly_stipple_enable)
6398*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_POLYGON_STIPPLE);
6399*bbecb9d1SAndroid Build Coastguard Worker else
6400*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_POLYGON_STIPPLE);
6401*bbecb9d1SAndroid Build Coastguard Worker }
6402*bbecb9d1SAndroid Build Coastguard Worker
6403*bbecb9d1SAndroid Build Coastguard Worker if (state->point_quad_rasterization) {
6404*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false &&
6405*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_gles == false) {
6406*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_POINT_SPRITE);
6407*bbecb9d1SAndroid Build Coastguard Worker }
6408*bbecb9d1SAndroid Build Coastguard Worker
6409*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles == false) {
6410*bbecb9d1SAndroid Build Coastguard Worker glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, state->sprite_coord_mode ? GL_UPPER_LEFT : GL_LOWER_LEFT);
6411*bbecb9d1SAndroid Build Coastguard Worker }
6412*bbecb9d1SAndroid Build Coastguard Worker } else {
6413*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false &&
6414*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_gles == false) {
6415*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_POINT_SPRITE);
6416*bbecb9d1SAndroid Build Coastguard Worker }
6417*bbecb9d1SAndroid Build Coastguard Worker }
6418*bbecb9d1SAndroid Build Coastguard Worker
6419*bbecb9d1SAndroid Build Coastguard Worker if (state->cull_face != PIPE_FACE_NONE) {
6420*bbecb9d1SAndroid Build Coastguard Worker switch (state->cull_face) {
6421*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FACE_FRONT:
6422*bbecb9d1SAndroid Build Coastguard Worker glCullFace(GL_FRONT);
6423*bbecb9d1SAndroid Build Coastguard Worker break;
6424*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FACE_BACK:
6425*bbecb9d1SAndroid Build Coastguard Worker glCullFace(GL_BACK);
6426*bbecb9d1SAndroid Build Coastguard Worker break;
6427*bbecb9d1SAndroid Build Coastguard Worker case PIPE_FACE_FRONT_AND_BACK:
6428*bbecb9d1SAndroid Build Coastguard Worker glCullFace(GL_FRONT_AND_BACK);
6429*bbecb9d1SAndroid Build Coastguard Worker break;
6430*bbecb9d1SAndroid Build Coastguard Worker default:
6431*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "unhandled cull-face: %x\n", state->cull_face);
6432*bbecb9d1SAndroid Build Coastguard Worker }
6433*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_CULL_FACE);
6434*bbecb9d1SAndroid Build Coastguard Worker } else
6435*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_CULL_FACE);
6436*bbecb9d1SAndroid Build Coastguard Worker
6437*bbecb9d1SAndroid Build Coastguard Worker /* two sided lighting handled in shader for core profile */
6438*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false) {
6439*bbecb9d1SAndroid Build Coastguard Worker if (state->light_twoside)
6440*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_VERTEX_PROGRAM_TWO_SIDE);
6441*bbecb9d1SAndroid Build Coastguard Worker else
6442*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_VERTEX_PROGRAM_TWO_SIDE);
6443*bbecb9d1SAndroid Build Coastguard Worker }
6444*bbecb9d1SAndroid Build Coastguard Worker
6445*bbecb9d1SAndroid Build Coastguard Worker if (state->clip_plane_enable != ctx->sub->hw_rs_state.clip_plane_enable) {
6446*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->hw_rs_state.clip_plane_enable = state->clip_plane_enable;
6447*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
6448*bbecb9d1SAndroid Build Coastguard Worker if (state->clip_plane_enable & (1 << i))
6449*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_CLIP_PLANE0 + i);
6450*bbecb9d1SAndroid Build Coastguard Worker else
6451*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_CLIP_PLANE0 + i);
6452*bbecb9d1SAndroid Build Coastguard Worker }
6453*bbecb9d1SAndroid Build Coastguard Worker
6454*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data_cookie++;
6455*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->rs_state.clip_plane_enable) {
6456*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data.clip_plane_enabled = 1.f;
6457*bbecb9d1SAndroid Build Coastguard Worker } else {
6458*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data.clip_plane_enabled = 0.f;
6459*bbecb9d1SAndroid Build Coastguard Worker }
6460*bbecb9d1SAndroid Build Coastguard Worker }
6461*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false) {
6462*bbecb9d1SAndroid Build Coastguard Worker glLineStipple(state->line_stipple_factor, state->line_stipple_pattern);
6463*bbecb9d1SAndroid Build Coastguard Worker if (state->line_stipple_enable)
6464*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_LINE_STIPPLE);
6465*bbecb9d1SAndroid Build Coastguard Worker else
6466*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_LINE_STIPPLE);
6467*bbecb9d1SAndroid Build Coastguard Worker } else if (state->line_stipple_enable) {
6468*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles)
6469*bbecb9d1SAndroid Build Coastguard Worker report_core_warn(ctx, GLES_WARN_STIPPLE);
6470*bbecb9d1SAndroid Build Coastguard Worker else
6471*bbecb9d1SAndroid Build Coastguard Worker report_core_warn(ctx, CORE_PROFILE_WARN_STIPPLE);
6472*bbecb9d1SAndroid Build Coastguard Worker }
6473*bbecb9d1SAndroid Build Coastguard Worker
6474*bbecb9d1SAndroid Build Coastguard Worker
6475*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
6476*bbecb9d1SAndroid Build Coastguard Worker if (state->line_smooth) {
6477*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_LINE_SMOOTH);
6478*bbecb9d1SAndroid Build Coastguard Worker }
6479*bbecb9d1SAndroid Build Coastguard Worker } else if (state->line_smooth) {
6480*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_LINE_SMOOTH);
6481*bbecb9d1SAndroid Build Coastguard Worker } else {
6482*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_LINE_SMOOTH);
6483*bbecb9d1SAndroid Build Coastguard Worker }
6484*bbecb9d1SAndroid Build Coastguard Worker
6485*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
6486*bbecb9d1SAndroid Build Coastguard Worker if (state->poly_smooth) {
6487*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_POLY_SMOOTH);
6488*bbecb9d1SAndroid Build Coastguard Worker }
6489*bbecb9d1SAndroid Build Coastguard Worker } else if (state->poly_smooth) {
6490*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_POLYGON_SMOOTH);
6491*bbecb9d1SAndroid Build Coastguard Worker } else {
6492*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_POLYGON_SMOOTH);
6493*bbecb9d1SAndroid Build Coastguard Worker }
6494*bbecb9d1SAndroid Build Coastguard Worker
6495*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == false) {
6496*bbecb9d1SAndroid Build Coastguard Worker if (state->clamp_vertex_color)
6497*bbecb9d1SAndroid Build Coastguard Worker glClampColor(GL_CLAMP_VERTEX_COLOR_ARB, GL_TRUE);
6498*bbecb9d1SAndroid Build Coastguard Worker else
6499*bbecb9d1SAndroid Build Coastguard Worker glClampColor(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE);
6500*bbecb9d1SAndroid Build Coastguard Worker
6501*bbecb9d1SAndroid Build Coastguard Worker if (state->clamp_fragment_color)
6502*bbecb9d1SAndroid Build Coastguard Worker glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_TRUE);
6503*bbecb9d1SAndroid Build Coastguard Worker else
6504*bbecb9d1SAndroid Build Coastguard Worker glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE);
6505*bbecb9d1SAndroid Build Coastguard Worker } else {
6506*bbecb9d1SAndroid Build Coastguard Worker if (state->clamp_vertex_color || state->clamp_fragment_color)
6507*bbecb9d1SAndroid Build Coastguard Worker report_core_warn(ctx, CORE_PROFILE_WARN_CLAMP);
6508*bbecb9d1SAndroid Build Coastguard Worker }
6509*bbecb9d1SAndroid Build Coastguard Worker
6510*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_multisample)) {
6511*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_sample_mask)) {
6512*bbecb9d1SAndroid Build Coastguard Worker if (state->multisample)
6513*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SAMPLE_MASK);
6514*bbecb9d1SAndroid Build Coastguard Worker else
6515*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SAMPLE_MASK);
6516*bbecb9d1SAndroid Build Coastguard Worker }
6517*bbecb9d1SAndroid Build Coastguard Worker
6518*bbecb9d1SAndroid Build Coastguard Worker /* GLES doesn't have GL_MULTISAMPLE */
6519*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles) {
6520*bbecb9d1SAndroid Build Coastguard Worker if (state->multisample)
6521*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_MULTISAMPLE);
6522*bbecb9d1SAndroid Build Coastguard Worker else
6523*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_MULTISAMPLE);
6524*bbecb9d1SAndroid Build Coastguard Worker }
6525*bbecb9d1SAndroid Build Coastguard Worker
6526*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_sample_shading)) {
6527*bbecb9d1SAndroid Build Coastguard Worker if (state->force_persample_interp)
6528*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SAMPLE_SHADING);
6529*bbecb9d1SAndroid Build Coastguard Worker else
6530*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SAMPLE_SHADING);
6531*bbecb9d1SAndroid Build Coastguard Worker }
6532*bbecb9d1SAndroid Build Coastguard Worker }
6533*bbecb9d1SAndroid Build Coastguard Worker
6534*bbecb9d1SAndroid Build Coastguard Worker if (state->scissor)
6535*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SCISSOR_TEST);
6536*bbecb9d1SAndroid Build Coastguard Worker else
6537*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SCISSOR_TEST);
6538*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->hw_rs_state.scissor = state->scissor;
6539*bbecb9d1SAndroid Build Coastguard Worker
6540*bbecb9d1SAndroid Build Coastguard Worker }
6541*bbecb9d1SAndroid Build Coastguard Worker
vrend_object_bind_rasterizer(struct vrend_context * ctx,uint32_t handle)6542*bbecb9d1SAndroid Build Coastguard Worker void vrend_object_bind_rasterizer(struct vrend_context *ctx,
6543*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle)
6544*bbecb9d1SAndroid Build Coastguard Worker {
6545*bbecb9d1SAndroid Build Coastguard Worker struct pipe_rasterizer_state *state;
6546*bbecb9d1SAndroid Build Coastguard Worker
6547*bbecb9d1SAndroid Build Coastguard Worker if (handle == 0) {
6548*bbecb9d1SAndroid Build Coastguard Worker memset(&ctx->sub->rs_state, 0, sizeof(ctx->sub->rs_state));
6549*bbecb9d1SAndroid Build Coastguard Worker return;
6550*bbecb9d1SAndroid Build Coastguard Worker }
6551*bbecb9d1SAndroid Build Coastguard Worker
6552*bbecb9d1SAndroid Build Coastguard Worker state = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_RASTERIZER);
6553*bbecb9d1SAndroid Build Coastguard Worker
6554*bbecb9d1SAndroid Build Coastguard Worker if (!state) {
6555*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handle);
6556*bbecb9d1SAndroid Build Coastguard Worker return;
6557*bbecb9d1SAndroid Build Coastguard Worker }
6558*bbecb9d1SAndroid Build Coastguard Worker
6559*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->rs_state = *state;
6560*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->shader_dirty = true;
6561*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_emit_rs(ctx);
6562*bbecb9d1SAndroid Build Coastguard Worker }
6563*bbecb9d1SAndroid Build Coastguard Worker
vrend_bind_sampler_states(struct vrend_context * ctx,enum pipe_shader_type shader_type,uint32_t start_slot,uint32_t num_states,const uint32_t * handles)6564*bbecb9d1SAndroid Build Coastguard Worker void vrend_bind_sampler_states(struct vrend_context *ctx,
6565*bbecb9d1SAndroid Build Coastguard Worker enum pipe_shader_type shader_type,
6566*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot,
6567*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_states,
6568*bbecb9d1SAndroid Build Coastguard Worker const uint32_t *handles)
6569*bbecb9d1SAndroid Build Coastguard Worker {
6570*bbecb9d1SAndroid Build Coastguard Worker uint32_t i;
6571*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_state *state;
6572*bbecb9d1SAndroid Build Coastguard Worker
6573*bbecb9d1SAndroid Build Coastguard Worker if (shader_type >= PIPE_SHADER_TYPES) {
6574*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, shader_type);
6575*bbecb9d1SAndroid Build Coastguard Worker return;
6576*bbecb9d1SAndroid Build Coastguard Worker }
6577*bbecb9d1SAndroid Build Coastguard Worker
6578*bbecb9d1SAndroid Build Coastguard Worker if (num_states > PIPE_MAX_SAMPLERS ||
6579*bbecb9d1SAndroid Build Coastguard Worker start_slot > (PIPE_MAX_SAMPLERS - num_states)) {
6580*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, num_states);
6581*bbecb9d1SAndroid Build Coastguard Worker return;
6582*bbecb9d1SAndroid Build Coastguard Worker }
6583*bbecb9d1SAndroid Build Coastguard Worker
6584*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->num_sampler_states[shader_type] = num_states;
6585*bbecb9d1SAndroid Build Coastguard Worker
6586*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_states; i++) {
6587*bbecb9d1SAndroid Build Coastguard Worker if (handles[i] == 0)
6588*bbecb9d1SAndroid Build Coastguard Worker state = NULL;
6589*bbecb9d1SAndroid Build Coastguard Worker else
6590*bbecb9d1SAndroid Build Coastguard Worker state = vrend_object_lookup(ctx->sub->object_hash, handles[i], VIRGL_OBJECT_SAMPLER_STATE);
6591*bbecb9d1SAndroid Build Coastguard Worker
6592*bbecb9d1SAndroid Build Coastguard Worker if (!state && handles[i])
6593*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Failed to bind sampler state (handle=%d)\n", handles[i]);
6594*bbecb9d1SAndroid Build Coastguard Worker
6595*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sampler_state[shader_type][start_slot + i] = state;
6596*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sampler_views_dirty[shader_type] |= (1 << (start_slot + i));
6597*bbecb9d1SAndroid Build Coastguard Worker }
6598*bbecb9d1SAndroid Build Coastguard Worker }
6599*bbecb9d1SAndroid Build Coastguard Worker
vrend_apply_sampler_state(struct vrend_sub_context * sub_ctx,struct vrend_resource * res,uint32_t shader_type,int id,int sampler_id,struct vrend_sampler_view * tview)6600*bbecb9d1SAndroid Build Coastguard Worker static void vrend_apply_sampler_state(struct vrend_sub_context *sub_ctx,
6601*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res,
6602*bbecb9d1SAndroid Build Coastguard Worker uint32_t shader_type,
6603*bbecb9d1SAndroid Build Coastguard Worker int id,
6604*bbecb9d1SAndroid Build Coastguard Worker int sampler_id,
6605*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_view *tview)
6606*bbecb9d1SAndroid Build Coastguard Worker {
6607*bbecb9d1SAndroid Build Coastguard Worker struct vrend_texture *tex = (struct vrend_texture *)res;
6608*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sampler_state *vstate = sub_ctx->sampler_state[shader_type][id];
6609*bbecb9d1SAndroid Build Coastguard Worker struct pipe_sampler_state *state = &vstate->base;
6610*bbecb9d1SAndroid Build Coastguard Worker bool set_all = false;
6611*bbecb9d1SAndroid Build Coastguard Worker GLenum target = tex->base.target;
6612*bbecb9d1SAndroid Build Coastguard Worker
6613*bbecb9d1SAndroid Build Coastguard Worker assert(offsetof(struct vrend_sampler_state, base) == 0);
6614*bbecb9d1SAndroid Build Coastguard Worker if (!state)
6615*bbecb9d1SAndroid Build Coastguard Worker return;
6616*bbecb9d1SAndroid Build Coastguard Worker
6617*bbecb9d1SAndroid Build Coastguard Worker if (res->base.nr_samples > 0) {
6618*bbecb9d1SAndroid Build Coastguard Worker tex->state = *state;
6619*bbecb9d1SAndroid Build Coastguard Worker return;
6620*bbecb9d1SAndroid Build Coastguard Worker }
6621*bbecb9d1SAndroid Build Coastguard Worker
6622*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(tex->base.storage_bits, VREND_STORAGE_GL_BUFFER)) {
6623*bbecb9d1SAndroid Build Coastguard Worker tex->state = *state;
6624*bbecb9d1SAndroid Build Coastguard Worker return;
6625*bbecb9d1SAndroid Build Coastguard Worker }
6626*bbecb9d1SAndroid Build Coastguard Worker
6627*bbecb9d1SAndroid Build Coastguard Worker /*
6628*bbecb9d1SAndroid Build Coastguard Worker * If we emulate alpha format with red, we need to tell
6629*bbecb9d1SAndroid Build Coastguard Worker * the sampler to use the red channel and not the alpha one
6630*bbecb9d1SAndroid Build Coastguard Worker * by swizzling the GL_TEXTURE_BORDER_COLOR parameter.
6631*bbecb9d1SAndroid Build Coastguard Worker */
6632*bbecb9d1SAndroid Build Coastguard Worker bool is_emulated_alpha = vrend_format_is_emulated_alpha(tview->format);
6633*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_samplers)) {
6634*bbecb9d1SAndroid Build Coastguard Worker int sampler = vstate->ids[tview->srgb_decode == GL_SKIP_DECODE_EXT ? 0 : 1];
6635*bbecb9d1SAndroid Build Coastguard Worker if (is_emulated_alpha) {
6636*bbecb9d1SAndroid Build Coastguard Worker union pipe_color_union border_color;
6637*bbecb9d1SAndroid Build Coastguard Worker border_color = state->border_color;
6638*bbecb9d1SAndroid Build Coastguard Worker border_color.ui[0] = border_color.ui[3];
6639*bbecb9d1SAndroid Build Coastguard Worker border_color.ui[3] = 0;
6640*bbecb9d1SAndroid Build Coastguard Worker apply_sampler_border_color(sampler, border_color.ui);
6641*bbecb9d1SAndroid Build Coastguard Worker }
6642*bbecb9d1SAndroid Build Coastguard Worker
6643*bbecb9d1SAndroid Build Coastguard Worker glBindSampler(sampler_id, sampler);
6644*bbecb9d1SAndroid Build Coastguard Worker return;
6645*bbecb9d1SAndroid Build Coastguard Worker }
6646*bbecb9d1SAndroid Build Coastguard Worker
6647*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.max_lod == -1)
6648*bbecb9d1SAndroid Build Coastguard Worker set_all = true;
6649*bbecb9d1SAndroid Build Coastguard Worker
6650*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.wrap_s != state->wrap_s || set_all)
6651*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(target, GL_TEXTURE_WRAP_S, convert_wrap(state->wrap_s));
6652*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.wrap_t != state->wrap_t || set_all)
6653*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(target, GL_TEXTURE_WRAP_T, convert_wrap(state->wrap_t));
6654*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.wrap_r != state->wrap_r || set_all)
6655*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(target, GL_TEXTURE_WRAP_R, convert_wrap(state->wrap_r));
6656*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.min_img_filter != state->min_img_filter ||
6657*bbecb9d1SAndroid Build Coastguard Worker tex->state.min_mip_filter != state->min_mip_filter || set_all)
6658*bbecb9d1SAndroid Build Coastguard Worker glTexParameterf(target, GL_TEXTURE_MIN_FILTER, convert_min_filter(state->min_img_filter, state->min_mip_filter));
6659*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.mag_img_filter != state->mag_img_filter || set_all)
6660*bbecb9d1SAndroid Build Coastguard Worker glTexParameterf(target, GL_TEXTURE_MAG_FILTER, convert_mag_filter(state->mag_img_filter));
6661*bbecb9d1SAndroid Build Coastguard Worker if (res->target != GL_TEXTURE_RECTANGLE) {
6662*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.min_lod != state->min_lod || set_all)
6663*bbecb9d1SAndroid Build Coastguard Worker glTexParameterf(target, GL_TEXTURE_MIN_LOD, state->min_lod);
6664*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.max_lod != state->max_lod || set_all)
6665*bbecb9d1SAndroid Build Coastguard Worker glTexParameterf(target, GL_TEXTURE_MAX_LOD, state->max_lod);
6666*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.lod_bias != state->lod_bias || set_all) {
6667*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
6668*bbecb9d1SAndroid Build Coastguard Worker if (state->lod_bias)
6669*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(sub_ctx->parent, GLES_WARN_LOD_BIAS);
6670*bbecb9d1SAndroid Build Coastguard Worker } else {
6671*bbecb9d1SAndroid Build Coastguard Worker glTexParameterf(target, GL_TEXTURE_LOD_BIAS, state->lod_bias);
6672*bbecb9d1SAndroid Build Coastguard Worker }
6673*bbecb9d1SAndroid Build Coastguard Worker }
6674*bbecb9d1SAndroid Build Coastguard Worker }
6675*bbecb9d1SAndroid Build Coastguard Worker
6676*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.compare_mode != state->compare_mode || set_all)
6677*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, state->compare_mode ? GL_COMPARE_R_TO_TEXTURE : GL_NONE);
6678*bbecb9d1SAndroid Build Coastguard Worker if (tex->state.compare_func != state->compare_func || set_all)
6679*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_NEVER + state->compare_func);
6680*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_anisotropic_filter) && (tex->state.max_anisotropy != state->max_anisotropy || set_all))
6681*bbecb9d1SAndroid Build Coastguard Worker glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY, state->max_anisotropy);
6682*bbecb9d1SAndroid Build Coastguard Worker
6683*bbecb9d1SAndroid Build Coastguard Worker /*
6684*bbecb9d1SAndroid Build Coastguard Worker * Oh this is a fun one. On GLES 2.0 all cubemap MUST NOT be seamless.
6685*bbecb9d1SAndroid Build Coastguard Worker * But on GLES 3.0 all cubemaps MUST be seamless. Either way there is no
6686*bbecb9d1SAndroid Build Coastguard Worker * way to toggle between the behaviour when running on GLES. And adding
6687*bbecb9d1SAndroid Build Coastguard Worker * warnings will spew the logs quite bad. Ignore and hope for the best.
6688*bbecb9d1SAndroid Build Coastguard Worker */
6689*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles) {
6690*bbecb9d1SAndroid Build Coastguard Worker if (state->seamless_cube_map) {
6691*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
6692*bbecb9d1SAndroid Build Coastguard Worker } else {
6693*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
6694*bbecb9d1SAndroid Build Coastguard Worker }
6695*bbecb9d1SAndroid Build Coastguard Worker }
6696*bbecb9d1SAndroid Build Coastguard Worker
6697*bbecb9d1SAndroid Build Coastguard Worker if (memcmp(&tex->state.border_color, &state->border_color, 16) || set_all ||
6698*bbecb9d1SAndroid Build Coastguard Worker is_emulated_alpha) {
6699*bbecb9d1SAndroid Build Coastguard Worker if (is_emulated_alpha) {
6700*bbecb9d1SAndroid Build Coastguard Worker union pipe_color_union border_color;
6701*bbecb9d1SAndroid Build Coastguard Worker border_color = state->border_color;
6702*bbecb9d1SAndroid Build Coastguard Worker border_color.ui[0] = border_color.ui[3];
6703*bbecb9d1SAndroid Build Coastguard Worker border_color.ui[3] = 0;
6704*bbecb9d1SAndroid Build Coastguard Worker glTexParameterIuiv(target, GL_TEXTURE_BORDER_COLOR, border_color.ui);
6705*bbecb9d1SAndroid Build Coastguard Worker } else {
6706*bbecb9d1SAndroid Build Coastguard Worker glTexParameterIuiv(target, GL_TEXTURE_BORDER_COLOR, state->border_color.ui);
6707*bbecb9d1SAndroid Build Coastguard Worker }
6708*bbecb9d1SAndroid Build Coastguard Worker
6709*bbecb9d1SAndroid Build Coastguard Worker }
6710*bbecb9d1SAndroid Build Coastguard Worker tex->state = *state;
6711*bbecb9d1SAndroid Build Coastguard Worker }
6712*bbecb9d1SAndroid Build Coastguard Worker
tgsitargettogltarget(const enum pipe_texture_target target,int nr_samples)6713*bbecb9d1SAndroid Build Coastguard Worker static GLenum tgsitargettogltarget(const enum pipe_texture_target target, int nr_samples)
6714*bbecb9d1SAndroid Build Coastguard Worker {
6715*bbecb9d1SAndroid Build Coastguard Worker switch(target) {
6716*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_1D:
6717*bbecb9d1SAndroid Build Coastguard Worker return GL_TEXTURE_1D;
6718*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_2D:
6719*bbecb9d1SAndroid Build Coastguard Worker return (nr_samples > 0) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
6720*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_3D:
6721*bbecb9d1SAndroid Build Coastguard Worker return GL_TEXTURE_3D;
6722*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_RECT:
6723*bbecb9d1SAndroid Build Coastguard Worker return GL_TEXTURE_RECTANGLE_NV;
6724*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_CUBE:
6725*bbecb9d1SAndroid Build Coastguard Worker return GL_TEXTURE_CUBE_MAP;
6726*bbecb9d1SAndroid Build Coastguard Worker
6727*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_1D_ARRAY:
6728*bbecb9d1SAndroid Build Coastguard Worker return GL_TEXTURE_1D_ARRAY;
6729*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_2D_ARRAY:
6730*bbecb9d1SAndroid Build Coastguard Worker return (nr_samples > 0) ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY;
6731*bbecb9d1SAndroid Build Coastguard Worker case PIPE_TEXTURE_CUBE_ARRAY:
6732*bbecb9d1SAndroid Build Coastguard Worker return GL_TEXTURE_CUBE_MAP_ARRAY;
6733*bbecb9d1SAndroid Build Coastguard Worker case PIPE_BUFFER:
6734*bbecb9d1SAndroid Build Coastguard Worker default:
6735*bbecb9d1SAndroid Build Coastguard Worker return PIPE_BUFFER;
6736*bbecb9d1SAndroid Build Coastguard Worker }
6737*bbecb9d1SAndroid Build Coastguard Worker return PIPE_BUFFER;
6738*bbecb9d1SAndroid Build Coastguard Worker }
6739*bbecb9d1SAndroid Build Coastguard Worker
vrend_free_sync_thread(void)6740*bbecb9d1SAndroid Build Coastguard Worker static void vrend_free_sync_thread(void)
6741*bbecb9d1SAndroid Build Coastguard Worker {
6742*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.sync_thread)
6743*bbecb9d1SAndroid Build Coastguard Worker return;
6744*bbecb9d1SAndroid Build Coastguard Worker
6745*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
6746*bbecb9d1SAndroid Build Coastguard Worker vrend_state.stop_sync_thread = true;
6747*bbecb9d1SAndroid Build Coastguard Worker cnd_signal(&vrend_state.fence_cond);
6748*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
6749*bbecb9d1SAndroid Build Coastguard Worker
6750*bbecb9d1SAndroid Build Coastguard Worker thrd_join(vrend_state.sync_thread, NULL);
6751*bbecb9d1SAndroid Build Coastguard Worker vrend_state.sync_thread = 0;
6752*bbecb9d1SAndroid Build Coastguard Worker
6753*bbecb9d1SAndroid Build Coastguard Worker cnd_destroy(&vrend_state.fence_cond);
6754*bbecb9d1SAndroid Build Coastguard Worker mtx_destroy(&vrend_state.fence_mutex);
6755*bbecb9d1SAndroid Build Coastguard Worker cnd_destroy(&vrend_state.poll_cond);
6756*bbecb9d1SAndroid Build Coastguard Worker mtx_destroy(&vrend_state.poll_mutex);
6757*bbecb9d1SAndroid Build Coastguard Worker }
6758*bbecb9d1SAndroid Build Coastguard Worker
free_fence_locked(struct vrend_fence * fence)6759*bbecb9d1SAndroid Build Coastguard Worker static void free_fence_locked(struct vrend_fence *fence)
6760*bbecb9d1SAndroid Build Coastguard Worker {
6761*bbecb9d1SAndroid Build Coastguard Worker list_del(&fence->fences);
6762*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
6763*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_egl_fence) {
6764*bbecb9d1SAndroid Build Coastguard Worker virgl_egl_fence_destroy(egl, fence->eglsyncobj);
6765*bbecb9d1SAndroid Build Coastguard Worker } else
6766*bbecb9d1SAndroid Build Coastguard Worker #endif
6767*bbecb9d1SAndroid Build Coastguard Worker {
6768*bbecb9d1SAndroid Build Coastguard Worker glDeleteSync(fence->glsyncobj);
6769*bbecb9d1SAndroid Build Coastguard Worker }
6770*bbecb9d1SAndroid Build Coastguard Worker free(fence);
6771*bbecb9d1SAndroid Build Coastguard Worker }
6772*bbecb9d1SAndroid Build Coastguard Worker
vrend_free_fences(void)6773*bbecb9d1SAndroid Build Coastguard Worker static void vrend_free_fences(void)
6774*bbecb9d1SAndroid Build Coastguard Worker {
6775*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *fence, *stor;
6776*bbecb9d1SAndroid Build Coastguard Worker
6777*bbecb9d1SAndroid Build Coastguard Worker /* this is called after vrend_free_sync_thread */
6778*bbecb9d1SAndroid Build Coastguard Worker assert(!vrend_state.sync_thread);
6779*bbecb9d1SAndroid Build Coastguard Worker
6780*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_list, fences)
6781*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
6782*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_wait_list, fences)
6783*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
6784*bbecb9d1SAndroid Build Coastguard Worker }
6785*bbecb9d1SAndroid Build Coastguard Worker
vrend_free_fences_for_context(struct vrend_context * ctx)6786*bbecb9d1SAndroid Build Coastguard Worker static void vrend_free_fences_for_context(struct vrend_context *ctx)
6787*bbecb9d1SAndroid Build Coastguard Worker {
6788*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *fence, *stor;
6789*bbecb9d1SAndroid Build Coastguard Worker
6790*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.sync_thread) {
6791*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
6792*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_list, fences) {
6793*bbecb9d1SAndroid Build Coastguard Worker if (fence->ctx == ctx)
6794*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
6795*bbecb9d1SAndroid Build Coastguard Worker }
6796*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_wait_list, fences) {
6797*bbecb9d1SAndroid Build Coastguard Worker if (fence->ctx == ctx)
6798*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
6799*bbecb9d1SAndroid Build Coastguard Worker }
6800*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.fence_waiting) {
6801*bbecb9d1SAndroid Build Coastguard Worker /* mark the fence invalid as the sync thread is still waiting on it */
6802*bbecb9d1SAndroid Build Coastguard Worker vrend_state.fence_waiting->ctx = NULL;
6803*bbecb9d1SAndroid Build Coastguard Worker }
6804*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
6805*bbecb9d1SAndroid Build Coastguard Worker } else {
6806*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_list, fences) {
6807*bbecb9d1SAndroid Build Coastguard Worker if (fence->ctx == ctx)
6808*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
6809*bbecb9d1SAndroid Build Coastguard Worker }
6810*bbecb9d1SAndroid Build Coastguard Worker }
6811*bbecb9d1SAndroid Build Coastguard Worker }
6812*bbecb9d1SAndroid Build Coastguard Worker
do_wait(struct vrend_fence * fence,bool can_block)6813*bbecb9d1SAndroid Build Coastguard Worker static bool do_wait(struct vrend_fence *fence, bool can_block)
6814*bbecb9d1SAndroid Build Coastguard Worker {
6815*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
6816*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_egl_fence)
6817*bbecb9d1SAndroid Build Coastguard Worker return virgl_egl_client_wait_fence(egl, fence->eglsyncobj, can_block);
6818*bbecb9d1SAndroid Build Coastguard Worker #endif
6819*bbecb9d1SAndroid Build Coastguard Worker
6820*bbecb9d1SAndroid Build Coastguard Worker bool done = false;
6821*bbecb9d1SAndroid Build Coastguard Worker int timeout = can_block ? 1000000000 : 0;
6822*bbecb9d1SAndroid Build Coastguard Worker do {
6823*bbecb9d1SAndroid Build Coastguard Worker GLenum glret = glClientWaitSync(fence->glsyncobj, 0, timeout);
6824*bbecb9d1SAndroid Build Coastguard Worker if (glret == GL_WAIT_FAILED) {
6825*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "wait sync failed: illegal fence object %p\n", fence->glsyncobj);
6826*bbecb9d1SAndroid Build Coastguard Worker }
6827*bbecb9d1SAndroid Build Coastguard Worker done = glret != GL_TIMEOUT_EXPIRED;
6828*bbecb9d1SAndroid Build Coastguard Worker } while (!done && can_block);
6829*bbecb9d1SAndroid Build Coastguard Worker
6830*bbecb9d1SAndroid Build Coastguard Worker return done;
6831*bbecb9d1SAndroid Build Coastguard Worker }
6832*bbecb9d1SAndroid Build Coastguard Worker
6833*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_check_queries(void);
6834*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_poll(void)6835*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_poll(void) {
6836*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_async_fence_cb) {
6837*bbecb9d1SAndroid Build Coastguard Worker flush_eventfd(vrend_state.eventfd);
6838*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.poll_mutex);
6839*bbecb9d1SAndroid Build Coastguard Worker
6840*bbecb9d1SAndroid Build Coastguard Worker /* queries must be checked before fences are retired. */
6841*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_check_queries();
6842*bbecb9d1SAndroid Build Coastguard Worker
6843*bbecb9d1SAndroid Build Coastguard Worker /* wake up the sync thread to keep doing work */
6844*bbecb9d1SAndroid Build Coastguard Worker vrend_state.polling = false;
6845*bbecb9d1SAndroid Build Coastguard Worker cnd_signal(&vrend_state.poll_cond);
6846*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.poll_mutex);
6847*bbecb9d1SAndroid Build Coastguard Worker } else {
6848*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_check_fences();
6849*bbecb9d1SAndroid Build Coastguard Worker }
6850*bbecb9d1SAndroid Build Coastguard Worker }
6851*bbecb9d1SAndroid Build Coastguard Worker
wait_sync(struct vrend_fence * fence)6852*bbecb9d1SAndroid Build Coastguard Worker static void wait_sync(struct vrend_fence *fence)
6853*bbecb9d1SAndroid Build Coastguard Worker {
6854*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *ctx = fence->ctx;
6855*bbecb9d1SAndroid Build Coastguard Worker
6856*bbecb9d1SAndroid Build Coastguard Worker bool signal_poll = atomic_load(&vrend_state.has_waiting_queries);
6857*bbecb9d1SAndroid Build Coastguard Worker do_wait(fence, /* can_block */ true);
6858*bbecb9d1SAndroid Build Coastguard Worker
6859*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
6860*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_async_fence_cb) {
6861*bbecb9d1SAndroid Build Coastguard Worker /* to be able to call free_fence_locked without locking */
6862*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&fence->fences);
6863*bbecb9d1SAndroid Build Coastguard Worker } else {
6864*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&fence->fences, &vrend_state.fence_list);
6865*bbecb9d1SAndroid Build Coastguard Worker }
6866*bbecb9d1SAndroid Build Coastguard Worker vrend_state.fence_waiting = NULL;
6867*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
6868*bbecb9d1SAndroid Build Coastguard Worker
6869*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_async_fence_cb) {
6870*bbecb9d1SAndroid Build Coastguard Worker if (write_eventfd(vrend_state.eventfd, 1))
6871*bbecb9d1SAndroid Build Coastguard Worker perror("failed to write to eventfd\n");
6872*bbecb9d1SAndroid Build Coastguard Worker return;
6873*bbecb9d1SAndroid Build Coastguard Worker }
6874*bbecb9d1SAndroid Build Coastguard Worker
6875*bbecb9d1SAndroid Build Coastguard Worker /* If the current GL fence completed while one or more query was pending,
6876*bbecb9d1SAndroid Build Coastguard Worker * check queries on the main thread before notifying the caller about fence
6877*bbecb9d1SAndroid Build Coastguard Worker * completion.
6878*bbecb9d1SAndroid Build Coastguard Worker * TODO: store seqno of first query in waiting_query_list and compare to
6879*bbecb9d1SAndroid Build Coastguard Worker * current fence to avoid polling when it (and all later queries) are after
6880*bbecb9d1SAndroid Build Coastguard Worker * the current fence. */
6881*bbecb9d1SAndroid Build Coastguard Worker if (signal_poll) {
6882*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.poll_mutex);
6883*bbecb9d1SAndroid Build Coastguard Worker if (write_eventfd(vrend_state.eventfd, 1))
6884*bbecb9d1SAndroid Build Coastguard Worker perror("failed to write to eventfd\n");
6885*bbecb9d1SAndroid Build Coastguard Worker
6886*bbecb9d1SAndroid Build Coastguard Worker struct timespec ts;
6887*bbecb9d1SAndroid Build Coastguard Worker int ret;
6888*bbecb9d1SAndroid Build Coastguard Worker vrend_state.polling = true;
6889*bbecb9d1SAndroid Build Coastguard Worker do {
6890*bbecb9d1SAndroid Build Coastguard Worker ret = timespec_get(&ts, TIME_UTC);
6891*bbecb9d1SAndroid Build Coastguard Worker assert(ret);
6892*bbecb9d1SAndroid Build Coastguard Worker ts.tv_sec += 5;
6893*bbecb9d1SAndroid Build Coastguard Worker ret = cnd_timedwait(&vrend_state.poll_cond, &vrend_state.poll_mutex, &ts);
6894*bbecb9d1SAndroid Build Coastguard Worker if (ret)
6895*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("timeout (5s) waiting for renderer poll() to finish.");
6896*bbecb9d1SAndroid Build Coastguard Worker } while (vrend_state.polling && ret);
6897*bbecb9d1SAndroid Build Coastguard Worker }
6898*bbecb9d1SAndroid Build Coastguard Worker
6899*bbecb9d1SAndroid Build Coastguard Worker /* vrend_free_fences_for_context might have marked the fence invalid
6900*bbecb9d1SAndroid Build Coastguard Worker * by setting fence->ctx to NULL
6901*bbecb9d1SAndroid Build Coastguard Worker */
6902*bbecb9d1SAndroid Build Coastguard Worker if (ctx) {
6903*bbecb9d1SAndroid Build Coastguard Worker ctx->fence_retire(fence->fence_id, ctx->fence_retire_data);
6904*bbecb9d1SAndroid Build Coastguard Worker }
6905*bbecb9d1SAndroid Build Coastguard Worker
6906*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
6907*bbecb9d1SAndroid Build Coastguard Worker
6908*bbecb9d1SAndroid Build Coastguard Worker if (signal_poll)
6909*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.poll_mutex);
6910*bbecb9d1SAndroid Build Coastguard Worker }
6911*bbecb9d1SAndroid Build Coastguard Worker
thread_sync(UNUSED void * arg)6912*bbecb9d1SAndroid Build Coastguard Worker static int thread_sync(UNUSED void *arg)
6913*bbecb9d1SAndroid Build Coastguard Worker {
6914*bbecb9d1SAndroid Build Coastguard Worker virgl_gl_context gl_context = vrend_state.sync_context;
6915*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *fence, *stor;
6916*bbecb9d1SAndroid Build Coastguard Worker
6917*bbecb9d1SAndroid Build Coastguard Worker u_thread_setname("vrend-sync");
6918*bbecb9d1SAndroid Build Coastguard Worker
6919*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
6920*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(gl_context);
6921*bbecb9d1SAndroid Build Coastguard Worker
6922*bbecb9d1SAndroid Build Coastguard Worker while (!vrend_state.stop_sync_thread) {
6923*bbecb9d1SAndroid Build Coastguard Worker if (LIST_IS_EMPTY(&vrend_state.fence_wait_list) &&
6924*bbecb9d1SAndroid Build Coastguard Worker cnd_wait(&vrend_state.fence_cond, &vrend_state.fence_mutex) != 0) {
6925*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "error while waiting on condition\n");
6926*bbecb9d1SAndroid Build Coastguard Worker break;
6927*bbecb9d1SAndroid Build Coastguard Worker }
6928*bbecb9d1SAndroid Build Coastguard Worker
6929*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_wait_list, fences) {
6930*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.stop_sync_thread)
6931*bbecb9d1SAndroid Build Coastguard Worker break;
6932*bbecb9d1SAndroid Build Coastguard Worker list_del(&fence->fences);
6933*bbecb9d1SAndroid Build Coastguard Worker vrend_state.fence_waiting = fence;
6934*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
6935*bbecb9d1SAndroid Build Coastguard Worker wait_sync(fence);
6936*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
6937*bbecb9d1SAndroid Build Coastguard Worker }
6938*bbecb9d1SAndroid Build Coastguard Worker }
6939*bbecb9d1SAndroid Build Coastguard Worker
6940*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(0);
6941*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->destroy_gl_context(vrend_state.sync_context);
6942*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
6943*bbecb9d1SAndroid Build Coastguard Worker return 0;
6944*bbecb9d1SAndroid Build Coastguard Worker }
6945*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_use_threaded_sync(void)6946*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_use_threaded_sync(void)
6947*bbecb9d1SAndroid Build Coastguard Worker {
6948*bbecb9d1SAndroid Build Coastguard Worker struct virgl_gl_ctx_param ctx_params;
6949*bbecb9d1SAndroid Build Coastguard Worker
6950*bbecb9d1SAndroid Build Coastguard Worker ctx_params.shared = true;
6951*bbecb9d1SAndroid Build Coastguard Worker ctx_params.major_ver = vrend_state.gl_major_ver;
6952*bbecb9d1SAndroid Build Coastguard Worker ctx_params.minor_ver = vrend_state.gl_minor_ver;
6953*bbecb9d1SAndroid Build Coastguard Worker
6954*bbecb9d1SAndroid Build Coastguard Worker vrend_state.stop_sync_thread = false;
6955*bbecb9d1SAndroid Build Coastguard Worker
6956*bbecb9d1SAndroid Build Coastguard Worker vrend_state.sync_context = vrend_clicbs->create_gl_context(0, &ctx_params);
6957*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.sync_context == NULL) {
6958*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failed to create sync opengl context\n");
6959*bbecb9d1SAndroid Build Coastguard Worker return;
6960*bbecb9d1SAndroid Build Coastguard Worker }
6961*bbecb9d1SAndroid Build Coastguard Worker
6962*bbecb9d1SAndroid Build Coastguard Worker vrend_state.eventfd = create_eventfd(0);
6963*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.eventfd == -1) {
6964*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "Failed to create eventfd\n");
6965*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->destroy_gl_context(vrend_state.sync_context);
6966*bbecb9d1SAndroid Build Coastguard Worker return;
6967*bbecb9d1SAndroid Build Coastguard Worker }
6968*bbecb9d1SAndroid Build Coastguard Worker
6969*bbecb9d1SAndroid Build Coastguard Worker cnd_init(&vrend_state.fence_cond);
6970*bbecb9d1SAndroid Build Coastguard Worker mtx_init(&vrend_state.fence_mutex, mtx_plain);
6971*bbecb9d1SAndroid Build Coastguard Worker cnd_init(&vrend_state.poll_cond);
6972*bbecb9d1SAndroid Build Coastguard Worker mtx_init(&vrend_state.poll_mutex, mtx_plain);
6973*bbecb9d1SAndroid Build Coastguard Worker vrend_state.polling = false;
6974*bbecb9d1SAndroid Build Coastguard Worker
6975*bbecb9d1SAndroid Build Coastguard Worker vrend_state.sync_thread = u_thread_create(thread_sync, NULL);
6976*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.sync_thread) {
6977*bbecb9d1SAndroid Build Coastguard Worker close(vrend_state.eventfd);
6978*bbecb9d1SAndroid Build Coastguard Worker vrend_state.eventfd = -1;
6979*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->destroy_gl_context(vrend_state.sync_context);
6980*bbecb9d1SAndroid Build Coastguard Worker cnd_destroy(&vrend_state.fence_cond);
6981*bbecb9d1SAndroid Build Coastguard Worker mtx_destroy(&vrend_state.fence_mutex);
6982*bbecb9d1SAndroid Build Coastguard Worker cnd_destroy(&vrend_state.poll_cond);
6983*bbecb9d1SAndroid Build Coastguard Worker mtx_destroy(&vrend_state.poll_mutex);
6984*bbecb9d1SAndroid Build Coastguard Worker }
6985*bbecb9d1SAndroid Build Coastguard Worker }
6986*bbecb9d1SAndroid Build Coastguard Worker
vrend_debug_cb(UNUSED GLenum source,GLenum type,UNUSED GLuint id,UNUSED GLenum severity,UNUSED GLsizei length,UNUSED const GLchar * message,UNUSED const void * userParam)6987*bbecb9d1SAndroid Build Coastguard Worker static void vrend_debug_cb(UNUSED GLenum source, GLenum type, UNUSED GLuint id,
6988*bbecb9d1SAndroid Build Coastguard Worker UNUSED GLenum severity, UNUSED GLsizei length,
6989*bbecb9d1SAndroid Build Coastguard Worker UNUSED const GLchar* message, UNUSED const void* userParam)
6990*bbecb9d1SAndroid Build Coastguard Worker {
6991*bbecb9d1SAndroid Build Coastguard Worker if (type != GL_DEBUG_TYPE_ERROR) {
6992*bbecb9d1SAndroid Build Coastguard Worker return;
6993*bbecb9d1SAndroid Build Coastguard Worker }
6994*bbecb9d1SAndroid Build Coastguard Worker
6995*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "ERROR: %s\n", message);
6996*bbecb9d1SAndroid Build Coastguard Worker }
6997*bbecb9d1SAndroid Build Coastguard Worker
vrend_pipe_resource_unref(struct pipe_resource * pres,UNUSED void * data)6998*bbecb9d1SAndroid Build Coastguard Worker static void vrend_pipe_resource_unref(struct pipe_resource *pres,
6999*bbecb9d1SAndroid Build Coastguard Worker UNUSED void *data)
7000*bbecb9d1SAndroid Build Coastguard Worker {
7001*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
7002*bbecb9d1SAndroid Build Coastguard Worker
7003*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.finishing || pipe_reference(&res->base.reference, NULL))
7004*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_resource_destroy(res);
7005*bbecb9d1SAndroid Build Coastguard Worker }
7006*bbecb9d1SAndroid Build Coastguard Worker
vrend_pipe_resource_attach_iov(struct pipe_resource * pres,const struct iovec * iov,int iov_count,UNUSED void * data)7007*bbecb9d1SAndroid Build Coastguard Worker static void vrend_pipe_resource_attach_iov(struct pipe_resource *pres,
7008*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov,
7009*bbecb9d1SAndroid Build Coastguard Worker int iov_count,
7010*bbecb9d1SAndroid Build Coastguard Worker UNUSED void *data)
7011*bbecb9d1SAndroid Build Coastguard Worker {
7012*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
7013*bbecb9d1SAndroid Build Coastguard Worker
7014*bbecb9d1SAndroid Build Coastguard Worker res->iov = iov;
7015*bbecb9d1SAndroid Build Coastguard Worker res->num_iovs = iov_count;
7016*bbecb9d1SAndroid Build Coastguard Worker
7017*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) {
7018*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(res->iov, res->num_iovs, 0,
7019*bbecb9d1SAndroid Build Coastguard Worker res->ptr, res->base.width0);
7020*bbecb9d1SAndroid Build Coastguard Worker }
7021*bbecb9d1SAndroid Build Coastguard Worker }
7022*bbecb9d1SAndroid Build Coastguard Worker
vrend_pipe_resource_detach_iov(struct pipe_resource * pres,UNUSED void * data)7023*bbecb9d1SAndroid Build Coastguard Worker static void vrend_pipe_resource_detach_iov(struct pipe_resource *pres,
7024*bbecb9d1SAndroid Build Coastguard Worker UNUSED void *data)
7025*bbecb9d1SAndroid Build Coastguard Worker {
7026*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
7027*bbecb9d1SAndroid Build Coastguard Worker
7028*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) {
7029*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(res->iov, res->num_iovs, 0,
7030*bbecb9d1SAndroid Build Coastguard Worker res->ptr, res->base.width0);
7031*bbecb9d1SAndroid Build Coastguard Worker }
7032*bbecb9d1SAndroid Build Coastguard Worker
7033*bbecb9d1SAndroid Build Coastguard Worker res->iov = NULL;
7034*bbecb9d1SAndroid Build Coastguard Worker res->num_iovs = 0;
7035*bbecb9d1SAndroid Build Coastguard Worker }
7036*bbecb9d1SAndroid Build Coastguard Worker
vrend_pipe_resource_export_fd(UNUSED struct pipe_resource * pres,UNUSED int * fd,UNUSED void * data)7037*bbecb9d1SAndroid Build Coastguard Worker static enum virgl_resource_fd_type vrend_pipe_resource_export_fd(UNUSED struct pipe_resource *pres,
7038*bbecb9d1SAndroid Build Coastguard Worker UNUSED int *fd,
7039*bbecb9d1SAndroid Build Coastguard Worker UNUSED void *data)
7040*bbecb9d1SAndroid Build Coastguard Worker {
7041*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
7042*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
7043*bbecb9d1SAndroid Build Coastguard Worker
7044*bbecb9d1SAndroid Build Coastguard Worker if (res->storage_bits & VREND_STORAGE_GBM_BUFFER) {
7045*bbecb9d1SAndroid Build Coastguard Worker int ret = virgl_gbm_export_fd(gbm->device,
7046*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_get_handle(res->gbm_bo).u32, fd);
7047*bbecb9d1SAndroid Build Coastguard Worker if (!ret)
7048*bbecb9d1SAndroid Build Coastguard Worker return VIRGL_RESOURCE_FD_DMABUF;
7049*bbecb9d1SAndroid Build Coastguard Worker }
7050*bbecb9d1SAndroid Build Coastguard Worker #endif
7051*bbecb9d1SAndroid Build Coastguard Worker
7052*bbecb9d1SAndroid Build Coastguard Worker return VIRGL_RESOURCE_FD_INVALID;
7053*bbecb9d1SAndroid Build Coastguard Worker }
7054*bbecb9d1SAndroid Build Coastguard Worker
vrend_pipe_resource_get_size(struct pipe_resource * pres,UNUSED void * data)7055*bbecb9d1SAndroid Build Coastguard Worker static uint64_t vrend_pipe_resource_get_size(struct pipe_resource *pres,
7056*bbecb9d1SAndroid Build Coastguard Worker UNUSED void *data)
7057*bbecb9d1SAndroid Build Coastguard Worker {
7058*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
7059*bbecb9d1SAndroid Build Coastguard Worker
7060*bbecb9d1SAndroid Build Coastguard Worker return res->size;
7061*bbecb9d1SAndroid Build Coastguard Worker }
7062*bbecb9d1SAndroid Build Coastguard Worker
vrend_check_no_error(struct vrend_context * ctx)7063*bbecb9d1SAndroid Build Coastguard Worker bool vrend_check_no_error(struct vrend_context *ctx)
7064*bbecb9d1SAndroid Build Coastguard Worker {
7065*bbecb9d1SAndroid Build Coastguard Worker GLenum err;
7066*bbecb9d1SAndroid Build Coastguard Worker
7067*bbecb9d1SAndroid Build Coastguard Worker err = glGetError();
7068*bbecb9d1SAndroid Build Coastguard Worker if (err == GL_NO_ERROR)
7069*bbecb9d1SAndroid Build Coastguard Worker return true;
7070*bbecb9d1SAndroid Build Coastguard Worker
7071*bbecb9d1SAndroid Build Coastguard Worker while (err != GL_NO_ERROR) {
7072*bbecb9d1SAndroid Build Coastguard Worker #ifdef CHECK_GL_ERRORS
7073*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_UNKNOWN, err);
7074*bbecb9d1SAndroid Build Coastguard Worker #else
7075*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("GL error reported (%d) for context %d\n", err, ctx->ctx_id);
7076*bbecb9d1SAndroid Build Coastguard Worker #endif
7077*bbecb9d1SAndroid Build Coastguard Worker err = glGetError();
7078*bbecb9d1SAndroid Build Coastguard Worker }
7079*bbecb9d1SAndroid Build Coastguard Worker
7080*bbecb9d1SAndroid Build Coastguard Worker #ifdef CHECK_GL_ERRORS
7081*bbecb9d1SAndroid Build Coastguard Worker return false;
7082*bbecb9d1SAndroid Build Coastguard Worker #else
7083*bbecb9d1SAndroid Build Coastguard Worker return true;
7084*bbecb9d1SAndroid Build Coastguard Worker #endif
7085*bbecb9d1SAndroid Build Coastguard Worker }
7086*bbecb9d1SAndroid Build Coastguard Worker
7087*bbecb9d1SAndroid Build Coastguard Worker const struct virgl_resource_pipe_callbacks *
vrend_renderer_get_pipe_callbacks(void)7088*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_get_pipe_callbacks(void)
7089*bbecb9d1SAndroid Build Coastguard Worker {
7090*bbecb9d1SAndroid Build Coastguard Worker static const struct virgl_resource_pipe_callbacks callbacks = {
7091*bbecb9d1SAndroid Build Coastguard Worker .unref = vrend_pipe_resource_unref,
7092*bbecb9d1SAndroid Build Coastguard Worker .attach_iov = vrend_pipe_resource_attach_iov,
7093*bbecb9d1SAndroid Build Coastguard Worker .detach_iov = vrend_pipe_resource_detach_iov,
7094*bbecb9d1SAndroid Build Coastguard Worker .export_fd = vrend_pipe_resource_export_fd,
7095*bbecb9d1SAndroid Build Coastguard Worker .get_size = vrend_pipe_resource_get_size,
7096*bbecb9d1SAndroid Build Coastguard Worker };
7097*bbecb9d1SAndroid Build Coastguard Worker
7098*bbecb9d1SAndroid Build Coastguard Worker return &callbacks;
7099*bbecb9d1SAndroid Build Coastguard Worker }
7100*bbecb9d1SAndroid Build Coastguard Worker
use_integer(void)7101*bbecb9d1SAndroid Build Coastguard Worker static bool use_integer(void) {
7102*bbecb9d1SAndroid Build Coastguard Worker if (getenv("VIRGL_USE_INTEGER"))
7103*bbecb9d1SAndroid Build Coastguard Worker return true;
7104*bbecb9d1SAndroid Build Coastguard Worker
7105*bbecb9d1SAndroid Build Coastguard Worker const char * a = (const char *) glGetString(GL_VENDOR);
7106*bbecb9d1SAndroid Build Coastguard Worker if (!a)
7107*bbecb9d1SAndroid Build Coastguard Worker return false;
7108*bbecb9d1SAndroid Build Coastguard Worker if (strcmp(a, "ARM") == 0)
7109*bbecb9d1SAndroid Build Coastguard Worker return true;
7110*bbecb9d1SAndroid Build Coastguard Worker return false;
7111*bbecb9d1SAndroid Build Coastguard Worker }
7112*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_init(const struct vrend_if_cbs * cbs,uint32_t flags)7113*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_init(const struct vrend_if_cbs *cbs, uint32_t flags)
7114*bbecb9d1SAndroid Build Coastguard Worker {
7115*bbecb9d1SAndroid Build Coastguard Worker bool gles;
7116*bbecb9d1SAndroid Build Coastguard Worker int gl_ver;
7117*bbecb9d1SAndroid Build Coastguard Worker virgl_gl_context gl_context;
7118*bbecb9d1SAndroid Build Coastguard Worker struct virgl_gl_ctx_param ctx_params;
7119*bbecb9d1SAndroid Build Coastguard Worker
7120*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs = cbs;
7121*bbecb9d1SAndroid Build Coastguard Worker
7122*bbecb9d1SAndroid Build Coastguard Worker /* Give some defaults to be able to run the tests */
7123*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_2d_size =
7124*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_3d_size =
7125*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_cube_size = 16384;
7126*bbecb9d1SAndroid Build Coastguard Worker
7127*bbecb9d1SAndroid Build Coastguard Worker if (VREND_DEBUG_ENABLED) {
7128*bbecb9d1SAndroid Build Coastguard Worker vrend_init_debug_flags();
7129*bbecb9d1SAndroid Build Coastguard Worker }
7130*bbecb9d1SAndroid Build Coastguard Worker
7131*bbecb9d1SAndroid Build Coastguard Worker ctx_params.shared = false;
7132*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ARRAY_SIZE(gl_versions); i++) {
7133*bbecb9d1SAndroid Build Coastguard Worker ctx_params.major_ver = gl_versions[i].major;
7134*bbecb9d1SAndroid Build Coastguard Worker ctx_params.minor_ver = gl_versions[i].minor;
7135*bbecb9d1SAndroid Build Coastguard Worker
7136*bbecb9d1SAndroid Build Coastguard Worker gl_context = vrend_clicbs->create_gl_context(0, &ctx_params);
7137*bbecb9d1SAndroid Build Coastguard Worker if (gl_context)
7138*bbecb9d1SAndroid Build Coastguard Worker break;
7139*bbecb9d1SAndroid Build Coastguard Worker }
7140*bbecb9d1SAndroid Build Coastguard Worker
7141*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(gl_context);
7142*bbecb9d1SAndroid Build Coastguard Worker gl_ver = epoxy_gl_version();
7143*bbecb9d1SAndroid Build Coastguard Worker
7144*bbecb9d1SAndroid Build Coastguard Worker /* enable error output as early as possible */
7145*bbecb9d1SAndroid Build Coastguard Worker if (vrend_debug(NULL, dbg_khr) && epoxy_has_gl_extension("GL_KHR_debug")) {
7146*bbecb9d1SAndroid Build Coastguard Worker glDebugMessageCallback(vrend_debug_cb, NULL);
7147*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_DEBUG_OUTPUT);
7148*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
7149*bbecb9d1SAndroid Build Coastguard Worker set_feature(feat_debug_cb);
7150*bbecb9d1SAndroid Build Coastguard Worker }
7151*bbecb9d1SAndroid Build Coastguard Worker
7152*bbecb9d1SAndroid Build Coastguard Worker /* make sure you have the latest version of libepoxy */
7153*bbecb9d1SAndroid Build Coastguard Worker gles = epoxy_is_desktop_gl() == 0;
7154*bbecb9d1SAndroid Build Coastguard Worker
7155*bbecb9d1SAndroid Build Coastguard Worker vrend_state.gl_major_ver = gl_ver / 10;
7156*bbecb9d1SAndroid Build Coastguard Worker vrend_state.gl_minor_ver = gl_ver % 10;
7157*bbecb9d1SAndroid Build Coastguard Worker
7158*bbecb9d1SAndroid Build Coastguard Worker if (gles) {
7159*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "gl_version %d - es profile enabled\n", gl_ver);
7160*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_gles = true;
7161*bbecb9d1SAndroid Build Coastguard Worker /* for now, makes the rest of the code use the most GLES 3.x like path */
7162*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_core_profile = true;
7163*bbecb9d1SAndroid Build Coastguard Worker } else if (gl_ver > 30 && !epoxy_has_gl_extension("GL_ARB_compatibility")) {
7164*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "gl_version %d - core profile enabled\n", gl_ver);
7165*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_core_profile = true;
7166*bbecb9d1SAndroid Build Coastguard Worker } else {
7167*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "gl_version %d - compat profile\n", gl_ver);
7168*bbecb9d1SAndroid Build Coastguard Worker }
7169*bbecb9d1SAndroid Build Coastguard Worker
7170*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_integer = use_integer();
7171*bbecb9d1SAndroid Build Coastguard Worker
7172*bbecb9d1SAndroid Build Coastguard Worker init_features(gles ? 0 : gl_ver,
7173*bbecb9d1SAndroid Build Coastguard Worker gles ? gl_ver : 0);
7174*bbecb9d1SAndroid Build Coastguard Worker
7175*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_winsys_has_gl_colorspace())
7176*bbecb9d1SAndroid Build Coastguard Worker clear_feature(feat_srgb_write_control) ;
7177*bbecb9d1SAndroid Build Coastguard Worker
7178*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_DRAW_BUFFERS, (GLint *) &vrend_state.max_draw_buffers);
7179*bbecb9d1SAndroid Build Coastguard Worker
7180*bbecb9d1SAndroid Build Coastguard Worker /* Mesa clamps this value to 8 anyway, so just make sure that this side
7181*bbecb9d1SAndroid Build Coastguard Worker * doesn't exceed the number to be on the save side when using 8-bit masks
7182*bbecb9d1SAndroid Build Coastguard Worker * for the color buffers */
7183*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.max_draw_buffers > 8)
7184*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_draw_buffers = 8;
7185*bbecb9d1SAndroid Build Coastguard Worker
7186*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_arb_robustness) &&
7187*bbecb9d1SAndroid Build Coastguard Worker !has_feature(feat_gles_khr_robustness)) {
7188*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("WARNING: running without ARB/KHR robustness in place may crash\n");
7189*bbecb9d1SAndroid Build Coastguard Worker }
7190*bbecb9d1SAndroid Build Coastguard Worker
7191*bbecb9d1SAndroid Build Coastguard Worker /* callbacks for when we are cleaning up the object table */
7192*bbecb9d1SAndroid Build Coastguard Worker vrend_object_set_destroy_callback(VIRGL_OBJECT_QUERY, vrend_destroy_query_object);
7193*bbecb9d1SAndroid Build Coastguard Worker vrend_object_set_destroy_callback(VIRGL_OBJECT_SURFACE, vrend_destroy_surface_object);
7194*bbecb9d1SAndroid Build Coastguard Worker vrend_object_set_destroy_callback(VIRGL_OBJECT_SHADER, vrend_destroy_shader_object);
7195*bbecb9d1SAndroid Build Coastguard Worker vrend_object_set_destroy_callback(VIRGL_OBJECT_SAMPLER_VIEW, vrend_destroy_sampler_view_object);
7196*bbecb9d1SAndroid Build Coastguard Worker vrend_object_set_destroy_callback(VIRGL_OBJECT_STREAMOUT_TARGET, vrend_destroy_so_target_object);
7197*bbecb9d1SAndroid Build Coastguard Worker vrend_object_set_destroy_callback(VIRGL_OBJECT_SAMPLER_STATE, vrend_destroy_sampler_state_object);
7198*bbecb9d1SAndroid Build Coastguard Worker vrend_object_set_destroy_callback(VIRGL_OBJECT_VERTEX_ELEMENTS, vrend_destroy_vertex_elements_object);
7199*bbecb9d1SAndroid Build Coastguard Worker
7200*bbecb9d1SAndroid Build Coastguard Worker /* disable for format testing, spews a lot of errors */
7201*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_debug_cb)) {
7202*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_DEBUG_OUTPUT);
7203*bbecb9d1SAndroid Build Coastguard Worker }
7204*bbecb9d1SAndroid Build Coastguard Worker
7205*bbecb9d1SAndroid Build Coastguard Worker vrend_build_format_list_common();
7206*bbecb9d1SAndroid Build Coastguard Worker
7207*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
7208*bbecb9d1SAndroid Build Coastguard Worker vrend_build_format_list_gles();
7209*bbecb9d1SAndroid Build Coastguard Worker } else {
7210*bbecb9d1SAndroid Build Coastguard Worker vrend_build_format_list_gl();
7211*bbecb9d1SAndroid Build Coastguard Worker }
7212*bbecb9d1SAndroid Build Coastguard Worker
7213*bbecb9d1SAndroid Build Coastguard Worker vrend_check_texture_storage(tex_conv_table);
7214*bbecb9d1SAndroid Build Coastguard Worker
7215*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_multisample)) {
7216*bbecb9d1SAndroid Build Coastguard Worker vrend_check_texture_multisample(tex_conv_table,
7217*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_storage_multisample));
7218*bbecb9d1SAndroid Build Coastguard Worker }
7219*bbecb9d1SAndroid Build Coastguard Worker
7220*bbecb9d1SAndroid Build Coastguard Worker /* disable for format testing */
7221*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_debug_cb)) {
7222*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_DEBUG_OUTPUT);
7223*bbecb9d1SAndroid Build Coastguard Worker }
7224*bbecb9d1SAndroid Build Coastguard Worker
7225*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->destroy_gl_context(gl_context);
7226*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&vrend_state.fence_list);
7227*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&vrend_state.fence_wait_list);
7228*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&vrend_state.waiting_query_list);
7229*bbecb9d1SAndroid Build Coastguard Worker atomic_store(&vrend_state.has_waiting_queries, false);
7230*bbecb9d1SAndroid Build Coastguard Worker
7231*bbecb9d1SAndroid Build Coastguard Worker /* create 0 context */
7232*bbecb9d1SAndroid Build Coastguard Worker vrend_state.ctx0 = vrend_create_context(0, strlen("HOST"), "HOST");
7233*bbecb9d1SAndroid Build Coastguard Worker
7234*bbecb9d1SAndroid Build Coastguard Worker vrend_state.eventfd = -1;
7235*bbecb9d1SAndroid Build Coastguard Worker if (flags & VREND_USE_THREAD_SYNC) {
7236*bbecb9d1SAndroid Build Coastguard Worker if (flags & VREND_USE_ASYNC_FENCE_CB)
7237*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_async_fence_cb = true;
7238*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_use_threaded_sync();
7239*bbecb9d1SAndroid Build Coastguard Worker }
7240*bbecb9d1SAndroid Build Coastguard Worker if (flags & VREND_USE_EXTERNAL_BLOB)
7241*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_external_blob = true;
7242*bbecb9d1SAndroid Build Coastguard Worker
7243*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
7244*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles)
7245*bbecb9d1SAndroid Build Coastguard Worker vrend_state.use_egl_fence = virgl_egl_supports_fences(egl);
7246*bbecb9d1SAndroid Build Coastguard Worker #endif
7247*bbecb9d1SAndroid Build Coastguard Worker
7248*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_check_no_error(vrend_state.ctx0) || !has_feature(feat_ubo)) {
7249*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_fini();
7250*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
7251*bbecb9d1SAndroid Build Coastguard Worker }
7252*bbecb9d1SAndroid Build Coastguard Worker
7253*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
7254*bbecb9d1SAndroid Build Coastguard Worker if (flags & VREND_USE_VIDEO) {
7255*bbecb9d1SAndroid Build Coastguard Worker if (vrend_clicbs->get_drm_fd)
7256*bbecb9d1SAndroid Build Coastguard Worker vrend_video_init(vrend_clicbs->get_drm_fd());
7257*bbecb9d1SAndroid Build Coastguard Worker else
7258*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("video disabled due to missing get_drm_fd\n");
7259*bbecb9d1SAndroid Build Coastguard Worker }
7260*bbecb9d1SAndroid Build Coastguard Worker #endif
7261*bbecb9d1SAndroid Build Coastguard Worker
7262*bbecb9d1SAndroid Build Coastguard Worker return 0;
7263*bbecb9d1SAndroid Build Coastguard Worker }
7264*bbecb9d1SAndroid Build Coastguard Worker
7265*bbecb9d1SAndroid Build Coastguard Worker void
vrend_renderer_fini(void)7266*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_fini(void)
7267*bbecb9d1SAndroid Build Coastguard Worker {
7268*bbecb9d1SAndroid Build Coastguard Worker vrend_state.finishing = true;
7269*bbecb9d1SAndroid Build Coastguard Worker
7270*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.eventfd != -1) {
7271*bbecb9d1SAndroid Build Coastguard Worker close(vrend_state.eventfd);
7272*bbecb9d1SAndroid Build Coastguard Worker vrend_state.eventfd = -1;
7273*bbecb9d1SAndroid Build Coastguard Worker }
7274*bbecb9d1SAndroid Build Coastguard Worker
7275*bbecb9d1SAndroid Build Coastguard Worker vrend_free_fences();
7276*bbecb9d1SAndroid Build Coastguard Worker vrend_blitter_fini();
7277*bbecb9d1SAndroid Build Coastguard Worker
7278*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
7279*bbecb9d1SAndroid Build Coastguard Worker vrend_video_fini();
7280*bbecb9d1SAndroid Build Coastguard Worker #endif
7281*bbecb9d1SAndroid Build Coastguard Worker
7282*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_context(vrend_state.ctx0);
7283*bbecb9d1SAndroid Build Coastguard Worker
7284*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_ctx = NULL;
7285*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_hw_ctx = NULL;
7286*bbecb9d1SAndroid Build Coastguard Worker
7287*bbecb9d1SAndroid Build Coastguard Worker vrend_state.finishing = false;
7288*bbecb9d1SAndroid Build Coastguard Worker }
7289*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_sub_context(struct vrend_sub_context * sub)7290*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_sub_context(struct vrend_sub_context *sub)
7291*bbecb9d1SAndroid Build Coastguard Worker {
7292*bbecb9d1SAndroid Build Coastguard Worker struct vrend_streamout_object *obj, *tmp;
7293*bbecb9d1SAndroid Build Coastguard Worker
7294*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(sub->gl_context);
7295*bbecb9d1SAndroid Build Coastguard Worker
7296*bbecb9d1SAndroid Build Coastguard Worker if (sub->fb_id)
7297*bbecb9d1SAndroid Build Coastguard Worker glDeleteFramebuffers(1, &sub->fb_id);
7298*bbecb9d1SAndroid Build Coastguard Worker
7299*bbecb9d1SAndroid Build Coastguard Worker if (sub->blit_fb_ids[0])
7300*bbecb9d1SAndroid Build Coastguard Worker glDeleteFramebuffers(2, sub->blit_fb_ids);
7301*bbecb9d1SAndroid Build Coastguard Worker
7302*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
7303*bbecb9d1SAndroid Build Coastguard Worker
7304*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_gles31_vertex_attrib_binding)) {
7305*bbecb9d1SAndroid Build Coastguard Worker while (sub->enabled_attribs_bitmask) {
7306*bbecb9d1SAndroid Build Coastguard Worker uint32_t i = u_bit_scan(&sub->enabled_attribs_bitmask);
7307*bbecb9d1SAndroid Build Coastguard Worker
7308*bbecb9d1SAndroid Build Coastguard Worker glDisableVertexAttribArray(i);
7309*bbecb9d1SAndroid Build Coastguard Worker }
7310*bbecb9d1SAndroid Build Coastguard Worker glDeleteVertexArrays(1, &sub->vaoid);
7311*bbecb9d1SAndroid Build Coastguard Worker }
7312*bbecb9d1SAndroid Build Coastguard Worker
7313*bbecb9d1SAndroid Build Coastguard Worker glBindVertexArray(0);
7314*bbecb9d1SAndroid Build Coastguard Worker
7315*bbecb9d1SAndroid Build Coastguard Worker if (sub->current_so)
7316*bbecb9d1SAndroid Build Coastguard Worker glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
7317*bbecb9d1SAndroid Build Coastguard Worker
7318*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(obj, tmp, &sub->streamout_list, head) {
7319*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_streamout_object(obj);
7320*bbecb9d1SAndroid Build Coastguard Worker }
7321*bbecb9d1SAndroid Build Coastguard Worker
7322*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_VERTEX], NULL);
7323*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_FRAGMENT], NULL);
7324*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_GEOMETRY], NULL);
7325*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_TESS_CTRL], NULL);
7326*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_TESS_EVAL], NULL);
7327*bbecb9d1SAndroid Build Coastguard Worker vrend_shader_state_reference(&sub->shaders[PIPE_SHADER_COMPUTE], NULL);
7328*bbecb9d1SAndroid Build Coastguard Worker
7329*bbecb9d1SAndroid Build Coastguard Worker if (sub->prog)
7330*bbecb9d1SAndroid Build Coastguard Worker sub->prog->ref_context = NULL;
7331*bbecb9d1SAndroid Build Coastguard Worker
7332*bbecb9d1SAndroid Build Coastguard Worker vrend_free_programs(sub);
7333*bbecb9d1SAndroid Build Coastguard Worker for (enum pipe_shader_type type = 0; type < PIPE_SHADER_TYPES; type++) {
7334*bbecb9d1SAndroid Build Coastguard Worker free(sub->consts[type].consts);
7335*bbecb9d1SAndroid Build Coastguard Worker sub->consts[type].consts = NULL;
7336*bbecb9d1SAndroid Build Coastguard Worker
7337*bbecb9d1SAndroid Build Coastguard Worker for (unsigned i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
7338*bbecb9d1SAndroid Build Coastguard Worker vrend_sampler_view_reference(&sub->views[type].views[i], NULL);
7339*bbecb9d1SAndroid Build Coastguard Worker }
7340*bbecb9d1SAndroid Build Coastguard Worker }
7341*bbecb9d1SAndroid Build Coastguard Worker
7342*bbecb9d1SAndroid Build Coastguard Worker if (sub->zsurf)
7343*bbecb9d1SAndroid Build Coastguard Worker vrend_surface_reference(&sub->zsurf, NULL);
7344*bbecb9d1SAndroid Build Coastguard Worker
7345*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < sub->nr_cbufs; i++) {
7346*bbecb9d1SAndroid Build Coastguard Worker if (!sub->surf[i])
7347*bbecb9d1SAndroid Build Coastguard Worker continue;
7348*bbecb9d1SAndroid Build Coastguard Worker vrend_surface_reference(&sub->surf[i], NULL);
7349*bbecb9d1SAndroid Build Coastguard Worker }
7350*bbecb9d1SAndroid Build Coastguard Worker
7351*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_vbo_sub(sub, 0);
7352*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference((struct vrend_resource **)&sub->ib.buffer, NULL);
7353*bbecb9d1SAndroid Build Coastguard Worker
7354*bbecb9d1SAndroid Build Coastguard Worker vrend_object_fini_ctx_table(sub->object_hash);
7355*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->destroy_gl_context(sub->gl_context);
7356*bbecb9d1SAndroid Build Coastguard Worker
7357*bbecb9d1SAndroid Build Coastguard Worker list_del(&sub->head);
7358*bbecb9d1SAndroid Build Coastguard Worker FREE(sub);
7359*bbecb9d1SAndroid Build Coastguard Worker
7360*bbecb9d1SAndroid Build Coastguard Worker }
7361*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_context(struct vrend_context * ctx)7362*bbecb9d1SAndroid Build Coastguard Worker void vrend_destroy_context(struct vrend_context *ctx)
7363*bbecb9d1SAndroid Build Coastguard Worker {
7364*bbecb9d1SAndroid Build Coastguard Worker bool switch_0 = (ctx == vrend_state.current_ctx);
7365*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *cur = vrend_state.current_ctx;
7366*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub, *tmp;
7367*bbecb9d1SAndroid Build Coastguard Worker struct vrend_untyped_resource *untyped_res, *untyped_res_tmp;
7368*bbecb9d1SAndroid Build Coastguard Worker if (switch_0) {
7369*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_ctx = NULL;
7370*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_hw_ctx = NULL;
7371*bbecb9d1SAndroid Build Coastguard Worker }
7372*bbecb9d1SAndroid Build Coastguard Worker
7373*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(ctx->sub->gl_context);
7374*bbecb9d1SAndroid Build Coastguard Worker /* reset references on framebuffers */
7375*bbecb9d1SAndroid Build Coastguard Worker vrend_set_framebuffer_state(ctx, 0, NULL, 0);
7376*bbecb9d1SAndroid Build Coastguard Worker
7377*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_sampler_views(ctx, PIPE_SHADER_VERTEX, 0, 0);
7378*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 0);
7379*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_sampler_views(ctx, PIPE_SHADER_GEOMETRY, 0, 0);
7380*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_sampler_views(ctx, PIPE_SHADER_TESS_CTRL, 0, 0);
7381*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_sampler_views(ctx, PIPE_SHADER_TESS_EVAL, 0, 0);
7382*bbecb9d1SAndroid Build Coastguard Worker vrend_set_num_sampler_views(ctx, PIPE_SHADER_COMPUTE, 0, 0);
7383*bbecb9d1SAndroid Build Coastguard Worker
7384*bbecb9d1SAndroid Build Coastguard Worker vrend_set_streamout_targets(ctx, 0, 0, NULL);
7385*bbecb9d1SAndroid Build Coastguard Worker
7386*bbecb9d1SAndroid Build Coastguard Worker vrend_set_index_buffer(ctx, 0, 0, 0);
7387*bbecb9d1SAndroid Build Coastguard Worker
7388*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(sub, tmp, &ctx->sub_ctxs, head)
7389*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_sub_context(sub);
7390*bbecb9d1SAndroid Build Coastguard Worker if(ctx->ctx_id)
7391*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_force_ctx_0();
7392*bbecb9d1SAndroid Build Coastguard Worker
7393*bbecb9d1SAndroid Build Coastguard Worker vrend_free_fences_for_context(ctx);
7394*bbecb9d1SAndroid Build Coastguard Worker
7395*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
7396*bbecb9d1SAndroid Build Coastguard Worker vrend_video_destroy_context(ctx->video);
7397*bbecb9d1SAndroid Build Coastguard Worker #endif
7398*bbecb9d1SAndroid Build Coastguard Worker
7399*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(untyped_res, untyped_res_tmp, &ctx->untyped_resources, head)
7400*bbecb9d1SAndroid Build Coastguard Worker free(untyped_res);
7401*bbecb9d1SAndroid Build Coastguard Worker vrend_ctx_resource_fini_table(ctx->res_hash);
7402*bbecb9d1SAndroid Build Coastguard Worker
7403*bbecb9d1SAndroid Build Coastguard Worker FREE(ctx);
7404*bbecb9d1SAndroid Build Coastguard Worker
7405*bbecb9d1SAndroid Build Coastguard Worker if (!switch_0 && cur)
7406*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_switch_context(cur, true);
7407*bbecb9d1SAndroid Build Coastguard Worker }
7408*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_context(int id,uint32_t nlen,const char * debug_name)7409*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *vrend_create_context(int id, uint32_t nlen, const char *debug_name)
7410*bbecb9d1SAndroid Build Coastguard Worker {
7411*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *grctx = CALLOC_STRUCT(vrend_context);
7412*bbecb9d1SAndroid Build Coastguard Worker
7413*bbecb9d1SAndroid Build Coastguard Worker if (!grctx)
7414*bbecb9d1SAndroid Build Coastguard Worker return NULL;
7415*bbecb9d1SAndroid Build Coastguard Worker
7416*bbecb9d1SAndroid Build Coastguard Worker if (nlen && debug_name) {
7417*bbecb9d1SAndroid Build Coastguard Worker strncpy(grctx->debug_name, debug_name,
7418*bbecb9d1SAndroid Build Coastguard Worker nlen < sizeof(grctx->debug_name) - 1 ?
7419*bbecb9d1SAndroid Build Coastguard Worker nlen : sizeof(grctx->debug_name) - 1);
7420*bbecb9d1SAndroid Build Coastguard Worker grctx->debug_name[sizeof(grctx->debug_name) - 1] = 0;
7421*bbecb9d1SAndroid Build Coastguard Worker }
7422*bbecb9d1SAndroid Build Coastguard Worker
7423*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_caller, grctx, "create context\n");
7424*bbecb9d1SAndroid Build Coastguard Worker
7425*bbecb9d1SAndroid Build Coastguard Worker grctx->ctx_id = id;
7426*bbecb9d1SAndroid Build Coastguard Worker
7427*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&grctx->sub_ctxs);
7428*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&grctx->vrend_resources);
7429*bbecb9d1SAndroid Build Coastguard Worker
7430*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
7431*bbecb9d1SAndroid Build Coastguard Worker grctx->video = vrend_video_create_context(grctx);
7432*bbecb9d1SAndroid Build Coastguard Worker #endif
7433*bbecb9d1SAndroid Build Coastguard Worker
7434*bbecb9d1SAndroid Build Coastguard Worker grctx->res_hash = vrend_ctx_resource_init_table();
7435*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&grctx->untyped_resources);
7436*bbecb9d1SAndroid Build Coastguard Worker
7437*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.max_shader_patch_varyings = vrend_state.max_shader_patch_varyings;
7438*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.use_gles = vrend_state.use_gles;
7439*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.use_core_profile = vrend_state.use_core_profile;
7440*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.use_explicit_locations = vrend_state.use_explicit_locations;
7441*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.max_draw_buffers = vrend_state.max_draw_buffers;
7442*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_arrays_of_arrays = has_feature(feat_arrays_of_arrays);
7443*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_gpu_shader5 = has_feature(feat_gpu_shader5);
7444*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_es31_compat = has_feature(feat_gles31_compatibility);
7445*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_conservative_depth = has_feature(feat_conservative_depth);
7446*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.use_integer = vrend_state.use_integer;
7447*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_dual_src_blend = has_feature(feat_dual_src_blend);
7448*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_fbfetch_coherent = has_feature(feat_framebuffer_fetch);
7449*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_cull_distance = has_feature(feat_cull_distance);
7450*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_nopersective = has_feature(feat_shader_noperspective_interpolation);
7451*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.has_texture_shadow_lod = has_feature(feat_texture_shadow_lod);
7452*bbecb9d1SAndroid Build Coastguard Worker
7453*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_create_sub_ctx(grctx, 0);
7454*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_set_sub_ctx(grctx, 0);
7455*bbecb9d1SAndroid Build Coastguard Worker
7456*bbecb9d1SAndroid Build Coastguard Worker grctx->shader_cfg.glsl_version = vrender_get_glsl_version();
7457*bbecb9d1SAndroid Build Coastguard Worker
7458*bbecb9d1SAndroid Build Coastguard Worker if (!grctx->ctx_id)
7459*bbecb9d1SAndroid Build Coastguard Worker grctx->fence_retire = vrend_clicbs->ctx0_fence_retire;
7460*bbecb9d1SAndroid Build Coastguard Worker
7461*bbecb9d1SAndroid Build Coastguard Worker return grctx;
7462*bbecb9d1SAndroid Build Coastguard Worker }
7463*bbecb9d1SAndroid Build Coastguard Worker
check_resource_valid(const struct vrend_renderer_resource_create_args * args,char errmsg[256])7464*bbecb9d1SAndroid Build Coastguard Worker static int check_resource_valid(const struct vrend_renderer_resource_create_args *args,
7465*bbecb9d1SAndroid Build Coastguard Worker char errmsg[256])
7466*bbecb9d1SAndroid Build Coastguard Worker {
7467*bbecb9d1SAndroid Build Coastguard Worker /* limit the target */
7468*bbecb9d1SAndroid Build Coastguard Worker if (args->target >= PIPE_MAX_TEXTURE_TYPES) {
7469*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Invalid texture target %d (>= %d)",
7470*bbecb9d1SAndroid Build Coastguard Worker args->target, PIPE_MAX_TEXTURE_TYPES);
7471*bbecb9d1SAndroid Build Coastguard Worker return -1;
7472*bbecb9d1SAndroid Build Coastguard Worker }
7473*bbecb9d1SAndroid Build Coastguard Worker
7474*bbecb9d1SAndroid Build Coastguard Worker if (args->format >= VIRGL_FORMAT_MAX) {
7475*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Invalid texture format %d (>=%d)",
7476*bbecb9d1SAndroid Build Coastguard Worker args->format, VIRGL_FORMAT_MAX);
7477*bbecb9d1SAndroid Build Coastguard Worker return -1;
7478*bbecb9d1SAndroid Build Coastguard Worker }
7479*bbecb9d1SAndroid Build Coastguard Worker
7480*bbecb9d1SAndroid Build Coastguard Worker bool format_can_texture_storage = has_feature(feat_texture_storage) &&
7481*bbecb9d1SAndroid Build Coastguard Worker (tex_conv_table[args->format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE);
7482*bbecb9d1SAndroid Build Coastguard Worker
7483*bbecb9d1SAndroid Build Coastguard Worker /* only texture 2d and 2d array can have multiple samples */
7484*bbecb9d1SAndroid Build Coastguard Worker if (args->nr_samples > 0) {
7485*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_format_can_multisample(args->format)) {
7486*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Unsupported multisample texture format %s",
7487*bbecb9d1SAndroid Build Coastguard Worker util_format_name(args->format));
7488*bbecb9d1SAndroid Build Coastguard Worker return -1;
7489*bbecb9d1SAndroid Build Coastguard Worker }
7490*bbecb9d1SAndroid Build Coastguard Worker
7491*bbecb9d1SAndroid Build Coastguard Worker if (args->target != PIPE_TEXTURE_2D && args->target != PIPE_TEXTURE_2D_ARRAY) {
7492*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Multisample textures not 2D (target:%d)", args->target);
7493*bbecb9d1SAndroid Build Coastguard Worker return -1;
7494*bbecb9d1SAndroid Build Coastguard Worker }
7495*bbecb9d1SAndroid Build Coastguard Worker /* multisample can't have miplevels */
7496*bbecb9d1SAndroid Build Coastguard Worker if (args->last_level > 0) {
7497*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Multisample textures don't support mipmaps");
7498*bbecb9d1SAndroid Build Coastguard Worker return -1;
7499*bbecb9d1SAndroid Build Coastguard Worker }
7500*bbecb9d1SAndroid Build Coastguard Worker }
7501*bbecb9d1SAndroid Build Coastguard Worker
7502*bbecb9d1SAndroid Build Coastguard Worker if (args->last_level > 0) {
7503*bbecb9d1SAndroid Build Coastguard Worker /* buffer and rect textures can't have mipmaps */
7504*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_BUFFER) {
7505*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Buffers don't support mipmaps");
7506*bbecb9d1SAndroid Build Coastguard Worker return -1;
7507*bbecb9d1SAndroid Build Coastguard Worker }
7508*bbecb9d1SAndroid Build Coastguard Worker
7509*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_RECT) {
7510*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "RECT textures don't support mipmaps");
7511*bbecb9d1SAndroid Build Coastguard Worker return -1;
7512*bbecb9d1SAndroid Build Coastguard Worker }
7513*bbecb9d1SAndroid Build Coastguard Worker
7514*bbecb9d1SAndroid Build Coastguard Worker if (args->last_level > (floor(log2(MAX2(args->width, args->height))) + 1)) {
7515*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Mipmap levels %d too large for texture size (%d, %d)",
7516*bbecb9d1SAndroid Build Coastguard Worker args->last_level, args->width, args->height);
7517*bbecb9d1SAndroid Build Coastguard Worker return -1;
7518*bbecb9d1SAndroid Build Coastguard Worker }
7519*bbecb9d1SAndroid Build Coastguard Worker }
7520*bbecb9d1SAndroid Build Coastguard Worker
7521*bbecb9d1SAndroid Build Coastguard Worker if (args->flags != 0) {
7522*bbecb9d1SAndroid Build Coastguard Worker uint32_t supported_mask = VIRGL_RESOURCE_Y_0_TOP | VIRGL_RESOURCE_FLAG_MAP_PERSISTENT
7523*bbecb9d1SAndroid Build Coastguard Worker | VIRGL_RESOURCE_FLAG_MAP_COHERENT;
7524*bbecb9d1SAndroid Build Coastguard Worker
7525*bbecb9d1SAndroid Build Coastguard Worker if (args->flags & ~supported_mask) {
7526*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Resource flags 0x%x not supported", args->flags);
7527*bbecb9d1SAndroid Build Coastguard Worker return -1;
7528*bbecb9d1SAndroid Build Coastguard Worker }
7529*bbecb9d1SAndroid Build Coastguard Worker }
7530*bbecb9d1SAndroid Build Coastguard Worker
7531*bbecb9d1SAndroid Build Coastguard Worker if (args->flags & VIRGL_RESOURCE_Y_0_TOP) {
7532*bbecb9d1SAndroid Build Coastguard Worker if (args->target != PIPE_TEXTURE_2D && args->target != PIPE_TEXTURE_RECT) {
7533*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "VIRGL_RESOURCE_Y_0_TOP only supported for 2D or RECT textures");
7534*bbecb9d1SAndroid Build Coastguard Worker return -1;
7535*bbecb9d1SAndroid Build Coastguard Worker }
7536*bbecb9d1SAndroid Build Coastguard Worker }
7537*bbecb9d1SAndroid Build Coastguard Worker
7538*bbecb9d1SAndroid Build Coastguard Worker /* array size for array textures only */
7539*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_CUBE) {
7540*bbecb9d1SAndroid Build Coastguard Worker if (args->array_size != 6) {
7541*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Cube map: unexpected array size %d", args->array_size);
7542*bbecb9d1SAndroid Build Coastguard Worker return -1;
7543*bbecb9d1SAndroid Build Coastguard Worker }
7544*bbecb9d1SAndroid Build Coastguard Worker } else if (args->target == PIPE_TEXTURE_CUBE_ARRAY) {
7545*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_cube_map_array)) {
7546*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Cube map arrays not supported");
7547*bbecb9d1SAndroid Build Coastguard Worker return -1;
7548*bbecb9d1SAndroid Build Coastguard Worker }
7549*bbecb9d1SAndroid Build Coastguard Worker if (args->array_size % 6) {
7550*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Cube map array: unexpected array size %d", args->array_size);
7551*bbecb9d1SAndroid Build Coastguard Worker return -1;
7552*bbecb9d1SAndroid Build Coastguard Worker }
7553*bbecb9d1SAndroid Build Coastguard Worker } else if (args->array_size > 1) {
7554*bbecb9d1SAndroid Build Coastguard Worker if (args->target != PIPE_TEXTURE_2D_ARRAY &&
7555*bbecb9d1SAndroid Build Coastguard Worker args->target != PIPE_TEXTURE_1D_ARRAY) {
7556*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Texture target %d can't be an array ", args->target);
7557*bbecb9d1SAndroid Build Coastguard Worker return -1;
7558*bbecb9d1SAndroid Build Coastguard Worker }
7559*bbecb9d1SAndroid Build Coastguard Worker
7560*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_texture_array)) {
7561*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Texture arrays are not supported");
7562*bbecb9d1SAndroid Build Coastguard Worker return -1;
7563*bbecb9d1SAndroid Build Coastguard Worker }
7564*bbecb9d1SAndroid Build Coastguard Worker }
7565*bbecb9d1SAndroid Build Coastguard Worker
7566*bbecb9d1SAndroid Build Coastguard Worker if (args->target != PIPE_BUFFER && !args->width) {
7567*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Texture width must be >0");
7568*bbecb9d1SAndroid Build Coastguard Worker return -1;
7569*bbecb9d1SAndroid Build Coastguard Worker }
7570*bbecb9d1SAndroid Build Coastguard Worker
7571*bbecb9d1SAndroid Build Coastguard Worker if (args->bind == 0 ||
7572*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_CUSTOM ||
7573*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_STAGING ||
7574*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_INDEX_BUFFER ||
7575*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_STREAM_OUTPUT ||
7576*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_VERTEX_BUFFER ||
7577*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_CONSTANT_BUFFER ||
7578*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_QUERY_BUFFER ||
7579*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_COMMAND_ARGS ||
7580*bbecb9d1SAndroid Build Coastguard Worker args->bind == VIRGL_BIND_SHADER_BUFFER) {
7581*bbecb9d1SAndroid Build Coastguard Worker if (args->target != PIPE_BUFFER) {
7582*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Buffer bind flags requre the buffer target but this is target %d", args->target);
7583*bbecb9d1SAndroid Build Coastguard Worker return -1;
7584*bbecb9d1SAndroid Build Coastguard Worker }
7585*bbecb9d1SAndroid Build Coastguard Worker if (args->height != 1 || args->depth != 1) {
7586*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Buffer target: Got height=%u, depth=%u, expect (1,1)", args->height, args->depth);
7587*bbecb9d1SAndroid Build Coastguard Worker return -1;
7588*bbecb9d1SAndroid Build Coastguard Worker }
7589*bbecb9d1SAndroid Build Coastguard Worker if (args->bind == VIRGL_BIND_QUERY_BUFFER && !has_feature(feat_qbo)) {
7590*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Query buffers are not supported");
7591*bbecb9d1SAndroid Build Coastguard Worker return -1;
7592*bbecb9d1SAndroid Build Coastguard Worker }
7593*bbecb9d1SAndroid Build Coastguard Worker if (args->bind == VIRGL_BIND_COMMAND_ARGS && !has_feature(feat_indirect_draw)) {
7594*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Command args buffer requested but indirect draw is not supported");
7595*bbecb9d1SAndroid Build Coastguard Worker return -1;
7596*bbecb9d1SAndroid Build Coastguard Worker }
7597*bbecb9d1SAndroid Build Coastguard Worker } else {
7598*bbecb9d1SAndroid Build Coastguard Worker if (!((args->bind & VIRGL_BIND_SAMPLER_VIEW) ||
7599*bbecb9d1SAndroid Build Coastguard Worker (args->bind & VIRGL_BIND_DEPTH_STENCIL) ||
7600*bbecb9d1SAndroid Build Coastguard Worker (args->bind & VIRGL_BIND_RENDER_TARGET) ||
7601*bbecb9d1SAndroid Build Coastguard Worker (args->bind & VIRGL_BIND_CURSOR) ||
7602*bbecb9d1SAndroid Build Coastguard Worker (args->bind & VIRGL_BIND_SHARED) ||
7603*bbecb9d1SAndroid Build Coastguard Worker (args->bind & VIRGL_BIND_LINEAR))) {
7604*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Invalid texture bind flags 0x%x", args->bind);
7605*bbecb9d1SAndroid Build Coastguard Worker return -1;
7606*bbecb9d1SAndroid Build Coastguard Worker }
7607*bbecb9d1SAndroid Build Coastguard Worker
7608*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
7609*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_gbm_gpu_import_required(args->bind)) {
7610*bbecb9d1SAndroid Build Coastguard Worker return 0;
7611*bbecb9d1SAndroid Build Coastguard Worker }
7612*bbecb9d1SAndroid Build Coastguard Worker #endif
7613*bbecb9d1SAndroid Build Coastguard Worker
7614*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_2D ||
7615*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_RECT ||
7616*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_CUBE ||
7617*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_2D_ARRAY ||
7618*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_CUBE_ARRAY) {
7619*bbecb9d1SAndroid Build Coastguard Worker if (args->depth != 1) {
7620*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "2D texture target with depth=%u != 1", args->depth);
7621*bbecb9d1SAndroid Build Coastguard Worker return -1;
7622*bbecb9d1SAndroid Build Coastguard Worker }
7623*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage && !args->height) {
7624*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "2D Texture storage requires non-zero height");
7625*bbecb9d1SAndroid Build Coastguard Worker return -1;
7626*bbecb9d1SAndroid Build Coastguard Worker }
7627*bbecb9d1SAndroid Build Coastguard Worker }
7628*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_1D ||
7629*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_1D_ARRAY) {
7630*bbecb9d1SAndroid Build Coastguard Worker if (args->height != 1 || args->depth != 1) {
7631*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Got height=%u, depth=%u, expect (1,1)",
7632*bbecb9d1SAndroid Build Coastguard Worker args->height, args->depth);
7633*bbecb9d1SAndroid Build Coastguard Worker return -1;
7634*bbecb9d1SAndroid Build Coastguard Worker }
7635*bbecb9d1SAndroid Build Coastguard Worker if (args->width > vrend_state.max_texture_2d_size) {
7636*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "1D Texture width (%u) exceeds supported value (%u)",
7637*bbecb9d1SAndroid Build Coastguard Worker args->width, vrend_state.max_texture_2d_size);
7638*bbecb9d1SAndroid Build Coastguard Worker return -1;
7639*bbecb9d1SAndroid Build Coastguard Worker }
7640*bbecb9d1SAndroid Build Coastguard Worker }
7641*bbecb9d1SAndroid Build Coastguard Worker
7642*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_2D ||
7643*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_RECT ||
7644*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_2D_ARRAY) {
7645*bbecb9d1SAndroid Build Coastguard Worker if (args->width > vrend_state.max_texture_2d_size ||
7646*bbecb9d1SAndroid Build Coastguard Worker args->height > vrend_state.max_texture_2d_size) {
7647*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "2D Texture size components (%u, %u) exceeds supported value (%u)",
7648*bbecb9d1SAndroid Build Coastguard Worker args->width, args->height, vrend_state.max_texture_2d_size);
7649*bbecb9d1SAndroid Build Coastguard Worker return -1;
7650*bbecb9d1SAndroid Build Coastguard Worker }
7651*bbecb9d1SAndroid Build Coastguard Worker }
7652*bbecb9d1SAndroid Build Coastguard Worker
7653*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_3D) {
7654*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage &&
7655*bbecb9d1SAndroid Build Coastguard Worker (!args->height || !args->depth)) {
7656*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Texture storage expects non-zero height (%u) and depth (%u)",
7657*bbecb9d1SAndroid Build Coastguard Worker args->height, args->depth);
7658*bbecb9d1SAndroid Build Coastguard Worker return -1;
7659*bbecb9d1SAndroid Build Coastguard Worker }
7660*bbecb9d1SAndroid Build Coastguard Worker if (args->width > vrend_state.max_texture_3d_size ||
7661*bbecb9d1SAndroid Build Coastguard Worker args->height > vrend_state.max_texture_3d_size ||
7662*bbecb9d1SAndroid Build Coastguard Worker args->depth > vrend_state.max_texture_3d_size) {
7663*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "3D Texture sizes (%u, %u, %u) exceeds supported value (%u)",
7664*bbecb9d1SAndroid Build Coastguard Worker args->width, args->height, args->depth,
7665*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_3d_size);
7666*bbecb9d1SAndroid Build Coastguard Worker return -1;
7667*bbecb9d1SAndroid Build Coastguard Worker }
7668*bbecb9d1SAndroid Build Coastguard Worker }
7669*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_2D_ARRAY ||
7670*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_CUBE_ARRAY ||
7671*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_1D_ARRAY) {
7672*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage &&
7673*bbecb9d1SAndroid Build Coastguard Worker !args->array_size) {
7674*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Texture arrays require a non-zero arrays size "
7675*bbecb9d1SAndroid Build Coastguard Worker "when allocated with glTexStorage");
7676*bbecb9d1SAndroid Build Coastguard Worker return -1;
7677*bbecb9d1SAndroid Build Coastguard Worker }
7678*bbecb9d1SAndroid Build Coastguard Worker }
7679*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_TEXTURE_CUBE ||
7680*bbecb9d1SAndroid Build Coastguard Worker args->target == PIPE_TEXTURE_CUBE_ARRAY) {
7681*bbecb9d1SAndroid Build Coastguard Worker if (args->width != args->height) {
7682*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Cube maps require width (%u) == height (%u)",
7683*bbecb9d1SAndroid Build Coastguard Worker args->width, args->height);
7684*bbecb9d1SAndroid Build Coastguard Worker return -1;
7685*bbecb9d1SAndroid Build Coastguard Worker }
7686*bbecb9d1SAndroid Build Coastguard Worker if (args->width > vrend_state.max_texture_cube_size) {
7687*bbecb9d1SAndroid Build Coastguard Worker snprintf(errmsg, 256, "Cube maps size (%u) exceeds supported value (%u)",
7688*bbecb9d1SAndroid Build Coastguard Worker args->width, vrend_state.max_texture_cube_size);
7689*bbecb9d1SAndroid Build Coastguard Worker return -1;
7690*bbecb9d1SAndroid Build Coastguard Worker }
7691*bbecb9d1SAndroid Build Coastguard Worker }
7692*bbecb9d1SAndroid Build Coastguard Worker }
7693*bbecb9d1SAndroid Build Coastguard Worker return 0;
7694*bbecb9d1SAndroid Build Coastguard Worker }
7695*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_buffer(struct vrend_resource * gr,uint32_t width,uint32_t flags)7696*bbecb9d1SAndroid Build Coastguard Worker static void vrend_create_buffer(struct vrend_resource *gr, uint32_t width, uint32_t flags)
7697*bbecb9d1SAndroid Build Coastguard Worker {
7698*bbecb9d1SAndroid Build Coastguard Worker
7699*bbecb9d1SAndroid Build Coastguard Worker GLbitfield buffer_storage_flags = 0;
7700*bbecb9d1SAndroid Build Coastguard Worker if (flags & VIRGL_RESOURCE_FLAG_MAP_PERSISTENT) {
7701*bbecb9d1SAndroid Build Coastguard Worker buffer_storage_flags |= GL_MAP_PERSISTENT_BIT;
7702*bbecb9d1SAndroid Build Coastguard Worker /* Gallium's storage_flags_to_buffer_flags seems to drop some information, but we have to
7703*bbecb9d1SAndroid Build Coastguard Worker * satisfy the following:
7704*bbecb9d1SAndroid Build Coastguard Worker *
7705*bbecb9d1SAndroid Build Coastguard Worker * "If flags contains GL_MAP_PERSISTENT_BIT, it must also contain at least one of
7706*bbecb9d1SAndroid Build Coastguard Worker * GL_MAP_READ_BIT or GL_MAP_WRITE_BIT."
7707*bbecb9d1SAndroid Build Coastguard Worker */
7708*bbecb9d1SAndroid Build Coastguard Worker buffer_storage_flags |= GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
7709*bbecb9d1SAndroid Build Coastguard Worker }
7710*bbecb9d1SAndroid Build Coastguard Worker if (flags & VIRGL_RESOURCE_FLAG_MAP_COHERENT)
7711*bbecb9d1SAndroid Build Coastguard Worker buffer_storage_flags |= GL_MAP_COHERENT_BIT;
7712*bbecb9d1SAndroid Build Coastguard Worker
7713*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_GL_BUFFER;
7714*bbecb9d1SAndroid Build Coastguard Worker glGenBuffersARB(1, &gr->id);
7715*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(gr->target, gr->id);
7716*bbecb9d1SAndroid Build Coastguard Worker
7717*bbecb9d1SAndroid Build Coastguard Worker if (buffer_storage_flags) {
7718*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_buffer_storage) && !vrend_state.use_external_blob) {
7719*bbecb9d1SAndroid Build Coastguard Worker glBufferStorage(gr->target, width, NULL, buffer_storage_flags);
7720*bbecb9d1SAndroid Build Coastguard Worker gr->map_info = vrend_state.inferred_gl_caching_type;
7721*bbecb9d1SAndroid Build Coastguard Worker }
7722*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
7723*bbecb9d1SAndroid Build Coastguard Worker else if (has_feature(feat_memory_object_fd) && has_feature(feat_memory_object)) {
7724*bbecb9d1SAndroid Build Coastguard Worker GLuint memobj = 0;
7725*bbecb9d1SAndroid Build Coastguard Worker int fd = -1;
7726*bbecb9d1SAndroid Build Coastguard Worker int ret;
7727*bbecb9d1SAndroid Build Coastguard Worker
7728*bbecb9d1SAndroid Build Coastguard Worker /* Could use VK too. */
7729*bbecb9d1SAndroid Build Coastguard Worker struct gbm_bo *bo = gbm_bo_create(gbm->device, width, 1,
7730*bbecb9d1SAndroid Build Coastguard Worker GBM_FORMAT_R8, GBM_BO_USE_LINEAR);
7731*bbecb9d1SAndroid Build Coastguard Worker if (!bo) {
7732*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Failed to allocate emulated GL buffer backing storage");
7733*bbecb9d1SAndroid Build Coastguard Worker return;
7734*bbecb9d1SAndroid Build Coastguard Worker }
7735*bbecb9d1SAndroid Build Coastguard Worker
7736*bbecb9d1SAndroid Build Coastguard Worker ret = virgl_gbm_export_fd(gbm->device, gbm_bo_get_handle(bo).u32, &fd);
7737*bbecb9d1SAndroid Build Coastguard Worker if (ret || fd < 0) {
7738*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Failed to get file descriptor\n");
7739*bbecb9d1SAndroid Build Coastguard Worker return;
7740*bbecb9d1SAndroid Build Coastguard Worker }
7741*bbecb9d1SAndroid Build Coastguard Worker
7742*bbecb9d1SAndroid Build Coastguard Worker glCreateMemoryObjectsEXT(1, &memobj);
7743*bbecb9d1SAndroid Build Coastguard Worker glImportMemoryFdEXT(memobj, width, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd);
7744*bbecb9d1SAndroid Build Coastguard Worker glBufferStorageMemEXT(gr->target, width, memobj, 0);
7745*bbecb9d1SAndroid Build Coastguard Worker gr->gbm_bo = bo;
7746*bbecb9d1SAndroid Build Coastguard Worker gr->memobj = memobj;
7747*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_GBM_BUFFER | VREND_STORAGE_GL_MEMOBJ;
7748*bbecb9d1SAndroid Build Coastguard Worker
7749*bbecb9d1SAndroid Build Coastguard Worker if (!strcmp(gbm_device_get_backend_name(gbm->device), "i915"))
7750*bbecb9d1SAndroid Build Coastguard Worker gr->map_info = VIRGL_RENDERER_MAP_CACHE_CACHED;
7751*bbecb9d1SAndroid Build Coastguard Worker else
7752*bbecb9d1SAndroid Build Coastguard Worker gr->map_info = VIRGL_RENDERER_MAP_CACHE_WC;
7753*bbecb9d1SAndroid Build Coastguard Worker }
7754*bbecb9d1SAndroid Build Coastguard Worker #endif
7755*bbecb9d1SAndroid Build Coastguard Worker else {
7756*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Missing buffer storage and interop extensions\n");
7757*bbecb9d1SAndroid Build Coastguard Worker return;
7758*bbecb9d1SAndroid Build Coastguard Worker }
7759*bbecb9d1SAndroid Build Coastguard Worker
7760*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_GL_IMMUTABLE;
7761*bbecb9d1SAndroid Build Coastguard Worker gr->buffer_storage_flags = buffer_storage_flags;
7762*bbecb9d1SAndroid Build Coastguard Worker gr->size = width;
7763*bbecb9d1SAndroid Build Coastguard Worker } else
7764*bbecb9d1SAndroid Build Coastguard Worker glBufferData(gr->target, width, NULL, GL_STREAM_DRAW);
7765*bbecb9d1SAndroid Build Coastguard Worker
7766*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(gr->target, 0);
7767*bbecb9d1SAndroid Build Coastguard Worker }
7768*bbecb9d1SAndroid Build Coastguard Worker
7769*bbecb9d1SAndroid Build Coastguard Worker static int
vrend_resource_alloc_buffer(struct vrend_resource * gr,uint32_t flags)7770*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_alloc_buffer(struct vrend_resource *gr, uint32_t flags)
7771*bbecb9d1SAndroid Build Coastguard Worker {
7772*bbecb9d1SAndroid Build Coastguard Worker const uint32_t bind = gr->base.bind;
7773*bbecb9d1SAndroid Build Coastguard Worker const uint32_t size = gr->base.width0;
7774*bbecb9d1SAndroid Build Coastguard Worker
7775*bbecb9d1SAndroid Build Coastguard Worker if (bind == VIRGL_BIND_CUSTOM) {
7776*bbecb9d1SAndroid Build Coastguard Worker /* use iovec directly when attached */
7777*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_HOST_SYSTEM_MEMORY;
7778*bbecb9d1SAndroid Build Coastguard Worker gr->ptr = calloc(1, size);
7779*bbecb9d1SAndroid Build Coastguard Worker if (!gr->ptr)
7780*bbecb9d1SAndroid Build Coastguard Worker return -ENOMEM;
7781*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == VIRGL_BIND_STAGING) {
7782*bbecb9d1SAndroid Build Coastguard Worker /* staging buffers only use guest memory -- nothing to do. */
7783*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == VIRGL_BIND_INDEX_BUFFER) {
7784*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_ELEMENT_ARRAY_BUFFER_ARB;
7785*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7786*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == VIRGL_BIND_STREAM_OUTPUT) {
7787*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_TRANSFORM_FEEDBACK_BUFFER;
7788*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7789*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == VIRGL_BIND_VERTEX_BUFFER) {
7790*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_ARRAY_BUFFER_ARB;
7791*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7792*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == VIRGL_BIND_CONSTANT_BUFFER) {
7793*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_UNIFORM_BUFFER;
7794*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7795*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == VIRGL_BIND_QUERY_BUFFER) {
7796*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_QUERY_BUFFER;
7797*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7798*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == VIRGL_BIND_COMMAND_ARGS) {
7799*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_DRAW_INDIRECT_BUFFER;
7800*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7801*bbecb9d1SAndroid Build Coastguard Worker } else if (bind == 0 || bind == VIRGL_BIND_SHADER_BUFFER) {
7802*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_ARRAY_BUFFER_ARB;
7803*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7804*bbecb9d1SAndroid Build Coastguard Worker } else if (bind & VIRGL_BIND_SAMPLER_VIEW) {
7805*bbecb9d1SAndroid Build Coastguard Worker /*
7806*bbecb9d1SAndroid Build Coastguard Worker * On Desktop we use GL_ARB_texture_buffer_object on GLES we use
7807*bbecb9d1SAndroid Build Coastguard Worker * GL_EXT_texture_buffer (it is in the ANDRIOD extension pack).
7808*bbecb9d1SAndroid Build Coastguard Worker */
7809*bbecb9d1SAndroid Build Coastguard Worker #if GL_TEXTURE_BUFFER != GL_TEXTURE_BUFFER_EXT
7810*bbecb9d1SAndroid Build Coastguard Worker #error "GL_TEXTURE_BUFFER enums differ, they shouldn't."
7811*bbecb9d1SAndroid Build Coastguard Worker #endif
7812*bbecb9d1SAndroid Build Coastguard Worker
7813*bbecb9d1SAndroid Build Coastguard Worker /* need to check GL version here */
7814*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_or_gles_ext_texture_buffer)) {
7815*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_TEXTURE_BUFFER;
7816*bbecb9d1SAndroid Build Coastguard Worker } else {
7817*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_PIXEL_PACK_BUFFER_ARB;
7818*bbecb9d1SAndroid Build Coastguard Worker }
7819*bbecb9d1SAndroid Build Coastguard Worker vrend_create_buffer(gr, size, flags);
7820*bbecb9d1SAndroid Build Coastguard Worker } else {
7821*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: Illegal buffer binding flags 0x%x\n", __func__, bind);
7822*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
7823*bbecb9d1SAndroid Build Coastguard Worker }
7824*bbecb9d1SAndroid Build Coastguard Worker
7825*bbecb9d1SAndroid Build Coastguard Worker return 0;
7826*bbecb9d1SAndroid Build Coastguard Worker }
7827*bbecb9d1SAndroid Build Coastguard Worker
7828*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_renderer_resource_copy_args(const struct vrend_renderer_resource_create_args * args,struct vrend_resource * gr)7829*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_resource_copy_args(const struct vrend_renderer_resource_create_args *args,
7830*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *gr)
7831*bbecb9d1SAndroid Build Coastguard Worker {
7832*bbecb9d1SAndroid Build Coastguard Worker assert(gr);
7833*bbecb9d1SAndroid Build Coastguard Worker assert(args);
7834*bbecb9d1SAndroid Build Coastguard Worker
7835*bbecb9d1SAndroid Build Coastguard Worker gr->base.bind = args->bind;
7836*bbecb9d1SAndroid Build Coastguard Worker gr->base.width0 = args->width;
7837*bbecb9d1SAndroid Build Coastguard Worker gr->base.height0 = args->height;
7838*bbecb9d1SAndroid Build Coastguard Worker gr->base.depth0 = args->depth;
7839*bbecb9d1SAndroid Build Coastguard Worker gr->base.format = args->format;
7840*bbecb9d1SAndroid Build Coastguard Worker gr->base.target = args->target;
7841*bbecb9d1SAndroid Build Coastguard Worker gr->base.last_level = args->last_level;
7842*bbecb9d1SAndroid Build Coastguard Worker gr->base.nr_samples = args->nr_samples;
7843*bbecb9d1SAndroid Build Coastguard Worker gr->base.array_size = args->array_size;
7844*bbecb9d1SAndroid Build Coastguard Worker }
7845*bbecb9d1SAndroid Build Coastguard Worker
7846*bbecb9d1SAndroid Build Coastguard Worker /*
7847*bbecb9d1SAndroid Build Coastguard Worker * When GBM allocation is enabled, this function creates a GBM buffer and
7848*bbecb9d1SAndroid Build Coastguard Worker * EGL image given certain flags.
7849*bbecb9d1SAndroid Build Coastguard Worker */
vrend_resource_gbm_init(struct vrend_resource * gr,uint32_t format)7850*bbecb9d1SAndroid Build Coastguard Worker static void vrend_resource_gbm_init(struct vrend_resource *gr, uint32_t format)
7851*bbecb9d1SAndroid Build Coastguard Worker {
7852*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
7853*bbecb9d1SAndroid Build Coastguard Worker uint32_t gbm_flags = virgl_gbm_convert_flags(gr->base.bind);
7854*bbecb9d1SAndroid Build Coastguard Worker uint32_t gbm_format = 0;
7855*bbecb9d1SAndroid Build Coastguard Worker if (virgl_gbm_convert_format(&format, &gbm_format))
7856*bbecb9d1SAndroid Build Coastguard Worker return;
7857*bbecb9d1SAndroid Build Coastguard Worker if (vrend_winsys_different_gpu())
7858*bbecb9d1SAndroid Build Coastguard Worker gbm_flags |= GBM_BO_USE_LINEAR;
7859*bbecb9d1SAndroid Build Coastguard Worker
7860*bbecb9d1SAndroid Build Coastguard Worker if (gr->base.depth0 != 1 || gr->base.last_level != 0 || gr->base.nr_samples != 0)
7861*bbecb9d1SAndroid Build Coastguard Worker return;
7862*bbecb9d1SAndroid Build Coastguard Worker
7863*bbecb9d1SAndroid Build Coastguard Worker if (!gbm || !gbm->device || !gbm_format || !gbm_flags)
7864*bbecb9d1SAndroid Build Coastguard Worker return;
7865*bbecb9d1SAndroid Build Coastguard Worker
7866*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_gbm_external_allocation_preferred(gr->base.bind))
7867*bbecb9d1SAndroid Build Coastguard Worker return;
7868*bbecb9d1SAndroid Build Coastguard Worker
7869*bbecb9d1SAndroid Build Coastguard Worker if (!gbm_device_is_format_supported(gbm->device, gbm_format, gbm_flags))
7870*bbecb9d1SAndroid Build Coastguard Worker return;
7871*bbecb9d1SAndroid Build Coastguard Worker
7872*bbecb9d1SAndroid Build Coastguard Worker struct gbm_bo *bo = gbm_bo_create(gbm->device, gr->base.width0, gr->base.height0,
7873*bbecb9d1SAndroid Build Coastguard Worker gbm_format, gbm_flags);
7874*bbecb9d1SAndroid Build Coastguard Worker if (!bo)
7875*bbecb9d1SAndroid Build Coastguard Worker return;
7876*bbecb9d1SAndroid Build Coastguard Worker
7877*bbecb9d1SAndroid Build Coastguard Worker gr->gbm_bo = bo;
7878*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_GBM_BUFFER;
7879*bbecb9d1SAndroid Build Coastguard Worker /* This is true so far, but maybe gbm_bo_get_caching_type is needed in the future. */
7880*bbecb9d1SAndroid Build Coastguard Worker if (!strcmp(gbm_device_get_backend_name(gbm->device), "i915"))
7881*bbecb9d1SAndroid Build Coastguard Worker gr->map_info = VIRGL_RENDERER_MAP_CACHE_CACHED;
7882*bbecb9d1SAndroid Build Coastguard Worker else
7883*bbecb9d1SAndroid Build Coastguard Worker gr->map_info = VIRGL_RENDERER_MAP_CACHE_WC;
7884*bbecb9d1SAndroid Build Coastguard Worker
7885*bbecb9d1SAndroid Build Coastguard Worker int num_planes = gbm_bo_get_plane_count(bo);
7886*bbecb9d1SAndroid Build Coastguard Worker for (int plane = 0; plane < num_planes; plane++)
7887*bbecb9d1SAndroid Build Coastguard Worker gr->size += gbm_bo_get_plane_size(bo, plane);
7888*bbecb9d1SAndroid Build Coastguard Worker
7889*bbecb9d1SAndroid Build Coastguard Worker if (!virgl_gbm_gpu_import_required(gr->base.bind))
7890*bbecb9d1SAndroid Build Coastguard Worker return;
7891*bbecb9d1SAndroid Build Coastguard Worker
7892*bbecb9d1SAndroid Build Coastguard Worker gr->egl_image = virgl_egl_image_from_gbm_bo(egl, bo);
7893*bbecb9d1SAndroid Build Coastguard Worker if (!gr->egl_image) {
7894*bbecb9d1SAndroid Build Coastguard Worker gr->gbm_bo = NULL;
7895*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_destroy(bo);
7896*bbecb9d1SAndroid Build Coastguard Worker }
7897*bbecb9d1SAndroid Build Coastguard Worker
7898*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_EGL_IMAGE;
7899*bbecb9d1SAndroid Build Coastguard Worker
7900*bbecb9d1SAndroid Build Coastguard Worker #else
7901*bbecb9d1SAndroid Build Coastguard Worker (void)format;
7902*bbecb9d1SAndroid Build Coastguard Worker (void)gr;
7903*bbecb9d1SAndroid Build Coastguard Worker #endif
7904*bbecb9d1SAndroid Build Coastguard Worker }
7905*bbecb9d1SAndroid Build Coastguard Worker
vrend_resource_alloc_texture(struct vrend_resource * gr,enum virgl_formats format,void * image_oes)7906*bbecb9d1SAndroid Build Coastguard Worker static int vrend_resource_alloc_texture(struct vrend_resource *gr,
7907*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats format,
7908*bbecb9d1SAndroid Build Coastguard Worker void *image_oes)
7909*bbecb9d1SAndroid Build Coastguard Worker {
7910*bbecb9d1SAndroid Build Coastguard Worker uint level;
7911*bbecb9d1SAndroid Build Coastguard Worker GLenum internalformat, glformat, gltype;
7912*bbecb9d1SAndroid Build Coastguard Worker struct vrend_texture *gt = (struct vrend_texture *)gr;
7913*bbecb9d1SAndroid Build Coastguard Worker struct pipe_resource *pr = &gr->base;
7914*bbecb9d1SAndroid Build Coastguard Worker
7915*bbecb9d1SAndroid Build Coastguard Worker const bool format_can_texture_storage = has_feature(feat_texture_storage) &&
7916*bbecb9d1SAndroid Build Coastguard Worker (tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE);
7917*bbecb9d1SAndroid Build Coastguard Worker
7918*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage)
7919*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_GL_IMMUTABLE;
7920*bbecb9d1SAndroid Build Coastguard Worker
7921*bbecb9d1SAndroid Build Coastguard Worker if (!image_oes) {
7922*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_gbm_init(gr, format);
7923*bbecb9d1SAndroid Build Coastguard Worker if (gr->gbm_bo && !has_bit(gr->storage_bits, VREND_STORAGE_EGL_IMAGE))
7924*bbecb9d1SAndroid Build Coastguard Worker return 0;
7925*bbecb9d1SAndroid Build Coastguard Worker
7926*bbecb9d1SAndroid Build Coastguard Worker image_oes = gr->egl_image;
7927*bbecb9d1SAndroid Build Coastguard Worker }
7928*bbecb9d1SAndroid Build Coastguard Worker
7929*bbecb9d1SAndroid Build Coastguard Worker gr->target = tgsitargettogltarget(pr->target, pr->nr_samples);
7930*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_GL_TEXTURE;
7931*bbecb9d1SAndroid Build Coastguard Worker
7932*bbecb9d1SAndroid Build Coastguard Worker /* ugly workaround for texture rectangle incompatibility */
7933*bbecb9d1SAndroid Build Coastguard Worker if (gr->target == GL_TEXTURE_RECTANGLE_NV &&
7934*bbecb9d1SAndroid Build Coastguard Worker !(tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TARGET_RECTANGLE)) {
7935*bbecb9d1SAndroid Build Coastguard Worker /* for some guests this is the only usage of rect */
7936*bbecb9d1SAndroid Build Coastguard Worker if (pr->width0 != 1 || pr->height0 != 1) {
7937*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("Warning: specifying format incompatible with GL_TEXTURE_RECTANGLE_NV\n");
7938*bbecb9d1SAndroid Build Coastguard Worker }
7939*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_TEXTURE_2D;
7940*bbecb9d1SAndroid Build Coastguard Worker }
7941*bbecb9d1SAndroid Build Coastguard Worker
7942*bbecb9d1SAndroid Build Coastguard Worker /* fallback for 1D textures */
7943*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && gr->target == GL_TEXTURE_1D) {
7944*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_TEXTURE_2D;
7945*bbecb9d1SAndroid Build Coastguard Worker }
7946*bbecb9d1SAndroid Build Coastguard Worker
7947*bbecb9d1SAndroid Build Coastguard Worker /* fallback for 1D array textures */
7948*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && gr->target == GL_TEXTURE_1D_ARRAY) {
7949*bbecb9d1SAndroid Build Coastguard Worker gr->target = GL_TEXTURE_2D_ARRAY;
7950*bbecb9d1SAndroid Build Coastguard Worker }
7951*bbecb9d1SAndroid Build Coastguard Worker
7952*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &gr->id);
7953*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(gr->target, gr->id);
7954*bbecb9d1SAndroid Build Coastguard Worker
7955*bbecb9d1SAndroid Build Coastguard Worker debug_texture(__func__, gr);
7956*bbecb9d1SAndroid Build Coastguard Worker
7957*bbecb9d1SAndroid Build Coastguard Worker if (image_oes) {
7958*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(gr->storage_bits, VREND_STORAGE_GL_IMMUTABLE) &&
7959*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_egl_image_storage)) {
7960*bbecb9d1SAndroid Build Coastguard Worker glEGLImageTargetTexStorageEXT(gr->target, (GLeglImageOES) image_oes, NULL);
7961*bbecb9d1SAndroid Build Coastguard Worker } else if (has_feature(feat_egl_image)) {
7962*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits &= ~VREND_STORAGE_GL_IMMUTABLE;
7963*bbecb9d1SAndroid Build Coastguard Worker assert(gr->target == GL_TEXTURE_2D);
7964*bbecb9d1SAndroid Build Coastguard Worker glEGLImageTargetTexture2DOES(gr->target, (GLeglImageOES) image_oes);
7965*bbecb9d1SAndroid Build Coastguard Worker if ((format == VIRGL_FORMAT_NV12 ||
7966*bbecb9d1SAndroid Build Coastguard Worker format == VIRGL_FORMAT_NV21 ||
7967*bbecb9d1SAndroid Build Coastguard Worker format == VIRGL_FORMAT_YV12 ||
7968*bbecb9d1SAndroid Build Coastguard Worker format == VIRGL_FORMAT_P010) && glGetError() != GL_NO_ERROR) {
7969*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("glEGLImageTargetTexture2DOES maybe fail\n");
7970*bbecb9d1SAndroid Build Coastguard Worker }
7971*bbecb9d1SAndroid Build Coastguard Worker } else {
7972*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "missing GL_OES_EGL_image extensions\n");
7973*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(gr->target, 0);
7974*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
7975*bbecb9d1SAndroid Build Coastguard Worker }
7976*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_EGL_IMAGE;
7977*bbecb9d1SAndroid Build Coastguard Worker } else {
7978*bbecb9d1SAndroid Build Coastguard Worker internalformat = tex_conv_table[format].internalformat;
7979*bbecb9d1SAndroid Build Coastguard Worker glformat = tex_conv_table[format].glformat;
7980*bbecb9d1SAndroid Build Coastguard Worker gltype = tex_conv_table[format].gltype;
7981*bbecb9d1SAndroid Build Coastguard Worker
7982*bbecb9d1SAndroid Build Coastguard Worker if (internalformat == 0) {
7983*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("unknown format is %d\n", pr->format);
7984*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(gr->target, 0);
7985*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
7986*bbecb9d1SAndroid Build Coastguard Worker }
7987*bbecb9d1SAndroid Build Coastguard Worker
7988*bbecb9d1SAndroid Build Coastguard Worker if (pr->nr_samples > 0) {
7989*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage) {
7990*bbecb9d1SAndroid Build Coastguard Worker if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) {
7991*bbecb9d1SAndroid Build Coastguard Worker glTexStorage2DMultisample(gr->target, pr->nr_samples,
7992*bbecb9d1SAndroid Build Coastguard Worker internalformat, pr->width0, pr->height0,
7993*bbecb9d1SAndroid Build Coastguard Worker GL_TRUE);
7994*bbecb9d1SAndroid Build Coastguard Worker } else {
7995*bbecb9d1SAndroid Build Coastguard Worker glTexStorage3DMultisample(gr->target, pr->nr_samples,
7996*bbecb9d1SAndroid Build Coastguard Worker internalformat, pr->width0, pr->height0, pr->array_size,
7997*bbecb9d1SAndroid Build Coastguard Worker GL_TRUE);
7998*bbecb9d1SAndroid Build Coastguard Worker }
7999*bbecb9d1SAndroid Build Coastguard Worker } else {
8000*bbecb9d1SAndroid Build Coastguard Worker if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) {
8001*bbecb9d1SAndroid Build Coastguard Worker glTexImage2DMultisample(gr->target, pr->nr_samples,
8002*bbecb9d1SAndroid Build Coastguard Worker internalformat, pr->width0, pr->height0,
8003*bbecb9d1SAndroid Build Coastguard Worker GL_TRUE);
8004*bbecb9d1SAndroid Build Coastguard Worker } else {
8005*bbecb9d1SAndroid Build Coastguard Worker glTexImage3DMultisample(gr->target, pr->nr_samples,
8006*bbecb9d1SAndroid Build Coastguard Worker internalformat, pr->width0, pr->height0, pr->array_size,
8007*bbecb9d1SAndroid Build Coastguard Worker GL_TRUE);
8008*bbecb9d1SAndroid Build Coastguard Worker }
8009*bbecb9d1SAndroid Build Coastguard Worker }
8010*bbecb9d1SAndroid Build Coastguard Worker } else if (gr->target == GL_TEXTURE_CUBE_MAP) {
8011*bbecb9d1SAndroid Build Coastguard Worker int i;
8012*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage)
8013*bbecb9d1SAndroid Build Coastguard Worker glTexStorage2D(GL_TEXTURE_CUBE_MAP, pr->last_level + 1, internalformat, pr->width0, pr->height0);
8014*bbecb9d1SAndroid Build Coastguard Worker else {
8015*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 6; i++) {
8016*bbecb9d1SAndroid Build Coastguard Worker GLenum ctarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
8017*bbecb9d1SAndroid Build Coastguard Worker for (level = 0; level <= pr->last_level; level++) {
8018*bbecb9d1SAndroid Build Coastguard Worker unsigned mwidth = u_minify(pr->width0, level);
8019*bbecb9d1SAndroid Build Coastguard Worker unsigned mheight = u_minify(pr->height0, level);
8020*bbecb9d1SAndroid Build Coastguard Worker
8021*bbecb9d1SAndroid Build Coastguard Worker glTexImage2D(ctarget, level, internalformat, mwidth, mheight, 0, glformat,
8022*bbecb9d1SAndroid Build Coastguard Worker gltype, NULL);
8023*bbecb9d1SAndroid Build Coastguard Worker }
8024*bbecb9d1SAndroid Build Coastguard Worker }
8025*bbecb9d1SAndroid Build Coastguard Worker }
8026*bbecb9d1SAndroid Build Coastguard Worker } else if (gr->target == GL_TEXTURE_3D ||
8027*bbecb9d1SAndroid Build Coastguard Worker gr->target == GL_TEXTURE_2D_ARRAY ||
8028*bbecb9d1SAndroid Build Coastguard Worker gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) {
8029*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage) {
8030*bbecb9d1SAndroid Build Coastguard Worker unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ?
8031*bbecb9d1SAndroid Build Coastguard Worker pr->array_size : pr->depth0;
8032*bbecb9d1SAndroid Build Coastguard Worker glTexStorage3D(gr->target, pr->last_level + 1, internalformat, pr->width0, pr->height0, depth_param);
8033*bbecb9d1SAndroid Build Coastguard Worker } else {
8034*bbecb9d1SAndroid Build Coastguard Worker for (level = 0; level <= pr->last_level; level++) {
8035*bbecb9d1SAndroid Build Coastguard Worker unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ?
8036*bbecb9d1SAndroid Build Coastguard Worker pr->array_size : u_minify(pr->depth0, level);
8037*bbecb9d1SAndroid Build Coastguard Worker unsigned mwidth = u_minify(pr->width0, level);
8038*bbecb9d1SAndroid Build Coastguard Worker unsigned mheight = u_minify(pr->height0, level);
8039*bbecb9d1SAndroid Build Coastguard Worker glTexImage3D(gr->target, level, internalformat, mwidth, mheight,
8040*bbecb9d1SAndroid Build Coastguard Worker depth_param, 0, glformat, gltype, NULL);
8041*bbecb9d1SAndroid Build Coastguard Worker }
8042*bbecb9d1SAndroid Build Coastguard Worker }
8043*bbecb9d1SAndroid Build Coastguard Worker } else if (gr->target == GL_TEXTURE_1D && vrend_state.use_gles) {
8044*bbecb9d1SAndroid Build Coastguard Worker report_gles_missing_func(NULL, "glTexImage1D");
8045*bbecb9d1SAndroid Build Coastguard Worker } else if (gr->target == GL_TEXTURE_1D) {
8046*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage) {
8047*bbecb9d1SAndroid Build Coastguard Worker glTexStorage1D(gr->target, pr->last_level + 1, internalformat, pr->width0);
8048*bbecb9d1SAndroid Build Coastguard Worker } else {
8049*bbecb9d1SAndroid Build Coastguard Worker for (level = 0; level <= pr->last_level; level++) {
8050*bbecb9d1SAndroid Build Coastguard Worker unsigned mwidth = u_minify(pr->width0, level);
8051*bbecb9d1SAndroid Build Coastguard Worker glTexImage1D(gr->target, level, internalformat, mwidth, 0,
8052*bbecb9d1SAndroid Build Coastguard Worker glformat, gltype, NULL);
8053*bbecb9d1SAndroid Build Coastguard Worker }
8054*bbecb9d1SAndroid Build Coastguard Worker }
8055*bbecb9d1SAndroid Build Coastguard Worker } else {
8056*bbecb9d1SAndroid Build Coastguard Worker if (format_can_texture_storage)
8057*bbecb9d1SAndroid Build Coastguard Worker glTexStorage2D(gr->target, pr->last_level + 1, internalformat, pr->width0,
8058*bbecb9d1SAndroid Build Coastguard Worker gr->target == GL_TEXTURE_1D_ARRAY ? pr->array_size : pr->height0);
8059*bbecb9d1SAndroid Build Coastguard Worker else {
8060*bbecb9d1SAndroid Build Coastguard Worker for (level = 0; level <= pr->last_level; level++) {
8061*bbecb9d1SAndroid Build Coastguard Worker unsigned mwidth = u_minify(pr->width0, level);
8062*bbecb9d1SAndroid Build Coastguard Worker unsigned mheight = u_minify(pr->height0, level);
8063*bbecb9d1SAndroid Build Coastguard Worker glTexImage2D(gr->target, level, internalformat, mwidth,
8064*bbecb9d1SAndroid Build Coastguard Worker gr->target == GL_TEXTURE_1D_ARRAY ? pr->array_size : mheight,
8065*bbecb9d1SAndroid Build Coastguard Worker 0, glformat, gltype, NULL);
8066*bbecb9d1SAndroid Build Coastguard Worker }
8067*bbecb9d1SAndroid Build Coastguard Worker }
8068*bbecb9d1SAndroid Build Coastguard Worker }
8069*bbecb9d1SAndroid Build Coastguard Worker }
8070*bbecb9d1SAndroid Build Coastguard Worker
8071*bbecb9d1SAndroid Build Coastguard Worker if (!format_can_texture_storage) {
8072*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(gr->target, GL_TEXTURE_BASE_LEVEL, 0);
8073*bbecb9d1SAndroid Build Coastguard Worker glTexParameteri(gr->target, GL_TEXTURE_MAX_LEVEL, pr->last_level);
8074*bbecb9d1SAndroid Build Coastguard Worker }
8075*bbecb9d1SAndroid Build Coastguard Worker
8076*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(gr->target, 0);
8077*bbecb9d1SAndroid Build Coastguard Worker
8078*bbecb9d1SAndroid Build Coastguard Worker if (image_oes && gr->gbm_bo) {
8079*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
8080*bbecb9d1SAndroid Build Coastguard Worker if (!has_bit(gr->storage_bits, VREND_STORAGE_GL_BUFFER) &&
8081*bbecb9d1SAndroid Build Coastguard Worker !vrend_format_can_texture_view(gr->base.format)) {
8082*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < gbm_bo_get_plane_count(gr->gbm_bo); i++) {
8083*bbecb9d1SAndroid Build Coastguard Worker gr->aux_plane_egl_image[i] =
8084*bbecb9d1SAndroid Build Coastguard Worker virgl_egl_aux_plane_image_from_gbm_bo(egl, gr->gbm_bo, i);
8085*bbecb9d1SAndroid Build Coastguard Worker }
8086*bbecb9d1SAndroid Build Coastguard Worker }
8087*bbecb9d1SAndroid Build Coastguard Worker #endif
8088*bbecb9d1SAndroid Build Coastguard Worker }
8089*bbecb9d1SAndroid Build Coastguard Worker
8090*bbecb9d1SAndroid Build Coastguard Worker gt->state.max_lod = -1;
8091*bbecb9d1SAndroid Build Coastguard Worker gt->cur_swizzle[0] = gt->cur_swizzle[1] = gt->cur_swizzle[2] = gt->cur_swizzle[3] = -1;
8092*bbecb9d1SAndroid Build Coastguard Worker gt->cur_base = -1;
8093*bbecb9d1SAndroid Build Coastguard Worker gt->cur_max = 10000;
8094*bbecb9d1SAndroid Build Coastguard Worker return 0;
8095*bbecb9d1SAndroid Build Coastguard Worker }
8096*bbecb9d1SAndroid Build Coastguard Worker
8097*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_resource *
vrend_resource_create(const struct vrend_renderer_resource_create_args * args)8098*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_create(const struct vrend_renderer_resource_create_args *args)
8099*bbecb9d1SAndroid Build Coastguard Worker {
8100*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *gr;
8101*bbecb9d1SAndroid Build Coastguard Worker int ret;
8102*bbecb9d1SAndroid Build Coastguard Worker char error_string[256];
8103*bbecb9d1SAndroid Build Coastguard Worker
8104*bbecb9d1SAndroid Build Coastguard Worker ret = check_resource_valid(args, error_string);
8105*bbecb9d1SAndroid Build Coastguard Worker if (ret) {
8106*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s, Illegal resource parameters, error: %s\n", __func__, error_string);
8107*bbecb9d1SAndroid Build Coastguard Worker return NULL;
8108*bbecb9d1SAndroid Build Coastguard Worker }
8109*bbecb9d1SAndroid Build Coastguard Worker
8110*bbecb9d1SAndroid Build Coastguard Worker gr = (struct vrend_resource *)CALLOC_STRUCT(vrend_texture);
8111*bbecb9d1SAndroid Build Coastguard Worker if (!gr)
8112*bbecb9d1SAndroid Build Coastguard Worker return NULL;
8113*bbecb9d1SAndroid Build Coastguard Worker
8114*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_resource_copy_args(args, gr);
8115*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits = VREND_STORAGE_GUEST_MEMORY;
8116*bbecb9d1SAndroid Build Coastguard Worker
8117*bbecb9d1SAndroid Build Coastguard Worker if (args->flags & VIRGL_RESOURCE_Y_0_TOP)
8118*bbecb9d1SAndroid Build Coastguard Worker gr->y_0_top = true;
8119*bbecb9d1SAndroid Build Coastguard Worker
8120*bbecb9d1SAndroid Build Coastguard Worker pipe_reference_init(&gr->base.reference, 1);
8121*bbecb9d1SAndroid Build Coastguard Worker
8122*bbecb9d1SAndroid Build Coastguard Worker return gr;
8123*bbecb9d1SAndroid Build Coastguard Worker }
8124*bbecb9d1SAndroid Build Coastguard Worker
8125*bbecb9d1SAndroid Build Coastguard Worker struct pipe_resource *
vrend_renderer_resource_create(const struct vrend_renderer_resource_create_args * args,void * image_oes)8126*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_resource_create(const struct vrend_renderer_resource_create_args *args,
8127*bbecb9d1SAndroid Build Coastguard Worker void *image_oes)
8128*bbecb9d1SAndroid Build Coastguard Worker {
8129*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *gr;
8130*bbecb9d1SAndroid Build Coastguard Worker int ret;
8131*bbecb9d1SAndroid Build Coastguard Worker
8132*bbecb9d1SAndroid Build Coastguard Worker gr = vrend_resource_create(args);
8133*bbecb9d1SAndroid Build Coastguard Worker if (!gr)
8134*bbecb9d1SAndroid Build Coastguard Worker return NULL;
8135*bbecb9d1SAndroid Build Coastguard Worker
8136*bbecb9d1SAndroid Build Coastguard Worker if (args->target == PIPE_BUFFER) {
8137*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_resource_alloc_buffer(gr, args->flags);
8138*bbecb9d1SAndroid Build Coastguard Worker } else {
8139*bbecb9d1SAndroid Build Coastguard Worker const enum virgl_formats format = gr->base.format;
8140*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_resource_alloc_texture(gr, format, image_oes);
8141*bbecb9d1SAndroid Build Coastguard Worker }
8142*bbecb9d1SAndroid Build Coastguard Worker
8143*bbecb9d1SAndroid Build Coastguard Worker if (ret) {
8144*bbecb9d1SAndroid Build Coastguard Worker FREE(gr);
8145*bbecb9d1SAndroid Build Coastguard Worker return NULL;
8146*bbecb9d1SAndroid Build Coastguard Worker }
8147*bbecb9d1SAndroid Build Coastguard Worker
8148*bbecb9d1SAndroid Build Coastguard Worker return &gr->base;
8149*bbecb9d1SAndroid Build Coastguard Worker }
8150*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_resource_destroy(struct vrend_resource * res)8151*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_resource_destroy(struct vrend_resource *res)
8152*bbecb9d1SAndroid Build Coastguard Worker {
8153*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_GL_TEXTURE)) {
8154*bbecb9d1SAndroid Build Coastguard Worker glDeleteTextures(1, &res->id);
8155*bbecb9d1SAndroid Build Coastguard Worker } else if (has_bit(res->storage_bits, VREND_STORAGE_GL_BUFFER)) {
8156*bbecb9d1SAndroid Build Coastguard Worker glDeleteBuffers(1, &res->id);
8157*bbecb9d1SAndroid Build Coastguard Worker if (res->tbo_tex_id)
8158*bbecb9d1SAndroid Build Coastguard Worker glDeleteTextures(1, &res->tbo_tex_id);
8159*bbecb9d1SAndroid Build Coastguard Worker } else if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) {
8160*bbecb9d1SAndroid Build Coastguard Worker free(res->ptr);
8161*bbecb9d1SAndroid Build Coastguard Worker }
8162*bbecb9d1SAndroid Build Coastguard Worker
8163*bbecb9d1SAndroid Build Coastguard Worker if (res->rbo_id) {
8164*bbecb9d1SAndroid Build Coastguard Worker glDeleteRenderbuffers(1, &res->rbo_id);
8165*bbecb9d1SAndroid Build Coastguard Worker }
8166*bbecb9d1SAndroid Build Coastguard Worker
8167*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_GL_MEMOBJ)) {
8168*bbecb9d1SAndroid Build Coastguard Worker glDeleteMemoryObjectsEXT(1, &res->memobj);
8169*bbecb9d1SAndroid Build Coastguard Worker }
8170*bbecb9d1SAndroid Build Coastguard Worker
8171*bbecb9d1SAndroid Build Coastguard Worker #if HAVE_EPOXY_EGL_H
8172*bbecb9d1SAndroid Build Coastguard Worker if (res->egl_image) {
8173*bbecb9d1SAndroid Build Coastguard Worker virgl_egl_image_destroy(egl, res->egl_image);
8174*bbecb9d1SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(res->aux_plane_egl_image); i++) {
8175*bbecb9d1SAndroid Build Coastguard Worker if (res->aux_plane_egl_image[i]) {
8176*bbecb9d1SAndroid Build Coastguard Worker virgl_egl_image_destroy(egl, res->aux_plane_egl_image[i]);
8177*bbecb9d1SAndroid Build Coastguard Worker }
8178*bbecb9d1SAndroid Build Coastguard Worker }
8179*bbecb9d1SAndroid Build Coastguard Worker }
8180*bbecb9d1SAndroid Build Coastguard Worker #endif
8181*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
8182*bbecb9d1SAndroid Build Coastguard Worker if (res->gbm_bo)
8183*bbecb9d1SAndroid Build Coastguard Worker gbm_bo_destroy(res->gbm_bo);
8184*bbecb9d1SAndroid Build Coastguard Worker #endif
8185*bbecb9d1SAndroid Build Coastguard Worker
8186*bbecb9d1SAndroid Build Coastguard Worker free(res);
8187*bbecb9d1SAndroid Build Coastguard Worker }
8188*bbecb9d1SAndroid Build Coastguard Worker
8189*bbecb9d1SAndroid Build Coastguard Worker struct virgl_sub_upload_data {
8190*bbecb9d1SAndroid Build Coastguard Worker GLenum target;
8191*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box *box;
8192*bbecb9d1SAndroid Build Coastguard Worker };
8193*bbecb9d1SAndroid Build Coastguard Worker
iov_buffer_upload(void * cookie,uint32_t doff,void * src,int len)8194*bbecb9d1SAndroid Build Coastguard Worker static void iov_buffer_upload(void *cookie, uint32_t doff, void *src, int len)
8195*bbecb9d1SAndroid Build Coastguard Worker {
8196*bbecb9d1SAndroid Build Coastguard Worker struct virgl_sub_upload_data *d = cookie;
8197*bbecb9d1SAndroid Build Coastguard Worker glBufferSubData(d->target, d->box->x + doff, len, src);
8198*bbecb9d1SAndroid Build Coastguard Worker }
8199*bbecb9d1SAndroid Build Coastguard Worker
vrend_scale_depth(void * ptr,int size,float scale_val)8200*bbecb9d1SAndroid Build Coastguard Worker static void vrend_scale_depth(void *ptr, int size, float scale_val)
8201*bbecb9d1SAndroid Build Coastguard Worker {
8202*bbecb9d1SAndroid Build Coastguard Worker GLuint *ival = ptr;
8203*bbecb9d1SAndroid Build Coastguard Worker const GLfloat myscale = 1.0f / 0xffffff;
8204*bbecb9d1SAndroid Build Coastguard Worker int i;
8205*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < size / 4; i++) {
8206*bbecb9d1SAndroid Build Coastguard Worker GLuint value = ival[i];
8207*bbecb9d1SAndroid Build Coastguard Worker GLfloat d = ((float)(value >> 8) * myscale) * scale_val;
8208*bbecb9d1SAndroid Build Coastguard Worker d = CLAMP(d, 0.0F, 1.0F);
8209*bbecb9d1SAndroid Build Coastguard Worker ival[i] = (int)(d / myscale) << 8;
8210*bbecb9d1SAndroid Build Coastguard Worker }
8211*bbecb9d1SAndroid Build Coastguard Worker }
8212*bbecb9d1SAndroid Build Coastguard Worker
read_transfer_data(const struct iovec * iov,unsigned int num_iovs,char * data,enum virgl_formats format,uint64_t offset,uint32_t src_stride,uint32_t src_layer_stride,struct pipe_box * box,bool invert)8213*bbecb9d1SAndroid Build Coastguard Worker static void read_transfer_data(const struct iovec *iov,
8214*bbecb9d1SAndroid Build Coastguard Worker unsigned int num_iovs,
8215*bbecb9d1SAndroid Build Coastguard Worker char *data,
8216*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats format,
8217*bbecb9d1SAndroid Build Coastguard Worker uint64_t offset,
8218*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_stride,
8219*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_layer_stride,
8220*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box *box,
8221*bbecb9d1SAndroid Build Coastguard Worker bool invert)
8222*bbecb9d1SAndroid Build Coastguard Worker {
8223*bbecb9d1SAndroid Build Coastguard Worker int blsize = util_format_get_blocksize(format);
8224*bbecb9d1SAndroid Build Coastguard Worker uint32_t size = vrend_get_iovec_size(iov, num_iovs);
8225*bbecb9d1SAndroid Build Coastguard Worker uint32_t send_size = util_format_get_nblocks(format, box->width,
8226*bbecb9d1SAndroid Build Coastguard Worker box->height) * blsize * box->depth;
8227*bbecb9d1SAndroid Build Coastguard Worker uint32_t bwx = util_format_get_nblocksx(format, box->width) * blsize;
8228*bbecb9d1SAndroid Build Coastguard Worker int32_t bh = util_format_get_nblocksy(format, box->height);
8229*bbecb9d1SAndroid Build Coastguard Worker int d, h;
8230*bbecb9d1SAndroid Build Coastguard Worker
8231*bbecb9d1SAndroid Build Coastguard Worker if ((send_size == size || bh == 1) && !invert && box->depth == 1)
8232*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(iov, num_iovs, offset, data, send_size);
8233*bbecb9d1SAndroid Build Coastguard Worker else {
8234*bbecb9d1SAndroid Build Coastguard Worker if (invert) {
8235*bbecb9d1SAndroid Build Coastguard Worker for (d = 0; d < box->depth; d++) {
8236*bbecb9d1SAndroid Build Coastguard Worker uint32_t myoffset = offset + d * src_layer_stride;
8237*bbecb9d1SAndroid Build Coastguard Worker for (h = bh - 1; h >= 0; h--) {
8238*bbecb9d1SAndroid Build Coastguard Worker void *ptr = data + (h * bwx) + d * (bh * bwx);
8239*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(iov, num_iovs, myoffset, ptr, bwx);
8240*bbecb9d1SAndroid Build Coastguard Worker myoffset += src_stride;
8241*bbecb9d1SAndroid Build Coastguard Worker }
8242*bbecb9d1SAndroid Build Coastguard Worker }
8243*bbecb9d1SAndroid Build Coastguard Worker } else {
8244*bbecb9d1SAndroid Build Coastguard Worker for (d = 0; d < box->depth; d++) {
8245*bbecb9d1SAndroid Build Coastguard Worker uint32_t myoffset = offset + d * src_layer_stride;
8246*bbecb9d1SAndroid Build Coastguard Worker for (h = 0; h < bh; h++) {
8247*bbecb9d1SAndroid Build Coastguard Worker void *ptr = data + (h * bwx) + d * (bh * bwx);
8248*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(iov, num_iovs, myoffset, ptr, bwx);
8249*bbecb9d1SAndroid Build Coastguard Worker myoffset += src_stride;
8250*bbecb9d1SAndroid Build Coastguard Worker }
8251*bbecb9d1SAndroid Build Coastguard Worker }
8252*bbecb9d1SAndroid Build Coastguard Worker }
8253*bbecb9d1SAndroid Build Coastguard Worker }
8254*bbecb9d1SAndroid Build Coastguard Worker }
8255*bbecb9d1SAndroid Build Coastguard Worker
write_transfer_data(struct pipe_resource * res,const struct iovec * iov,unsigned num_iovs,char * data,uint32_t dst_stride,struct pipe_box * box,uint32_t level,uint64_t offset,bool invert)8256*bbecb9d1SAndroid Build Coastguard Worker static void write_transfer_data(struct pipe_resource *res,
8257*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov,
8258*bbecb9d1SAndroid Build Coastguard Worker unsigned num_iovs,
8259*bbecb9d1SAndroid Build Coastguard Worker char *data,
8260*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_stride,
8261*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box *box,
8262*bbecb9d1SAndroid Build Coastguard Worker uint32_t level,
8263*bbecb9d1SAndroid Build Coastguard Worker uint64_t offset,
8264*bbecb9d1SAndroid Build Coastguard Worker bool invert)
8265*bbecb9d1SAndroid Build Coastguard Worker {
8266*bbecb9d1SAndroid Build Coastguard Worker int blsize = util_format_get_blocksize(res->format);
8267*bbecb9d1SAndroid Build Coastguard Worker uint32_t size = vrend_get_iovec_size(iov, num_iovs);
8268*bbecb9d1SAndroid Build Coastguard Worker uint32_t send_size = util_format_get_nblocks(res->format, box->width,
8269*bbecb9d1SAndroid Build Coastguard Worker box->height) * blsize * box->depth;
8270*bbecb9d1SAndroid Build Coastguard Worker uint32_t bwx = util_format_get_nblocksx(res->format, box->width) * blsize;
8271*bbecb9d1SAndroid Build Coastguard Worker int32_t bh = util_format_get_nblocksy(res->format, box->height);
8272*bbecb9d1SAndroid Build Coastguard Worker int d, h;
8273*bbecb9d1SAndroid Build Coastguard Worker uint32_t stride = dst_stride ? dst_stride : util_format_get_nblocksx(res->format, u_minify(res->width0, level)) * blsize;
8274*bbecb9d1SAndroid Build Coastguard Worker
8275*bbecb9d1SAndroid Build Coastguard Worker if ((send_size == size || bh == 1) && !invert && box->depth == 1) {
8276*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(iov, num_iovs, offset, data, send_size);
8277*bbecb9d1SAndroid Build Coastguard Worker } else if (invert) {
8278*bbecb9d1SAndroid Build Coastguard Worker for (d = 0; d < box->depth; d++) {
8279*bbecb9d1SAndroid Build Coastguard Worker uint32_t myoffset = offset + d * stride * u_minify(res->height0, level);
8280*bbecb9d1SAndroid Build Coastguard Worker for (h = bh - 1; h >= 0; h--) {
8281*bbecb9d1SAndroid Build Coastguard Worker void *ptr = data + (h * bwx) + d * (bh * bwx);
8282*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(iov, num_iovs, myoffset, ptr, bwx);
8283*bbecb9d1SAndroid Build Coastguard Worker myoffset += stride;
8284*bbecb9d1SAndroid Build Coastguard Worker }
8285*bbecb9d1SAndroid Build Coastguard Worker }
8286*bbecb9d1SAndroid Build Coastguard Worker } else {
8287*bbecb9d1SAndroid Build Coastguard Worker for (d = 0; d < box->depth; d++) {
8288*bbecb9d1SAndroid Build Coastguard Worker uint32_t myoffset = offset + d * stride * u_minify(res->height0, level);
8289*bbecb9d1SAndroid Build Coastguard Worker for (h = 0; h < bh; h++) {
8290*bbecb9d1SAndroid Build Coastguard Worker void *ptr = data + (h * bwx) + d * (bh * bwx);
8291*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(iov, num_iovs, myoffset, ptr, bwx);
8292*bbecb9d1SAndroid Build Coastguard Worker myoffset += stride;
8293*bbecb9d1SAndroid Build Coastguard Worker }
8294*bbecb9d1SAndroid Build Coastguard Worker }
8295*bbecb9d1SAndroid Build Coastguard Worker }
8296*bbecb9d1SAndroid Build Coastguard Worker }
8297*bbecb9d1SAndroid Build Coastguard Worker
check_transfer_iovec(struct vrend_resource * res,const struct vrend_transfer_info * info)8298*bbecb9d1SAndroid Build Coastguard Worker static bool check_transfer_iovec(struct vrend_resource *res,
8299*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
8300*bbecb9d1SAndroid Build Coastguard Worker {
8301*bbecb9d1SAndroid Build Coastguard Worker return (info->iovec && info->iovec_cnt) || res->iov;
8302*bbecb9d1SAndroid Build Coastguard Worker }
8303*bbecb9d1SAndroid Build Coastguard Worker
check_transfer_bounds(struct vrend_resource * res,const struct vrend_transfer_info * info)8304*bbecb9d1SAndroid Build Coastguard Worker static bool check_transfer_bounds(struct vrend_resource *res,
8305*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
8306*bbecb9d1SAndroid Build Coastguard Worker {
8307*bbecb9d1SAndroid Build Coastguard Worker int lwidth, lheight;
8308*bbecb9d1SAndroid Build Coastguard Worker
8309*bbecb9d1SAndroid Build Coastguard Worker /* check mipmap level is in bounds */
8310*bbecb9d1SAndroid Build Coastguard Worker if (info->level > res->base.last_level)
8311*bbecb9d1SAndroid Build Coastguard Worker return false;
8312*bbecb9d1SAndroid Build Coastguard Worker if (info->box->x < 0 || info->box->y < 0)
8313*bbecb9d1SAndroid Build Coastguard Worker return false;
8314*bbecb9d1SAndroid Build Coastguard Worker /* these will catch bad y/z/w/d with 1D textures etc */
8315*bbecb9d1SAndroid Build Coastguard Worker lwidth = u_minify(res->base.width0, info->level);
8316*bbecb9d1SAndroid Build Coastguard Worker if (info->box->width > lwidth || info->box->width < 0)
8317*bbecb9d1SAndroid Build Coastguard Worker return false;
8318*bbecb9d1SAndroid Build Coastguard Worker if (info->box->x > lwidth)
8319*bbecb9d1SAndroid Build Coastguard Worker return false;
8320*bbecb9d1SAndroid Build Coastguard Worker if (info->box->width + info->box->x > lwidth)
8321*bbecb9d1SAndroid Build Coastguard Worker return false;
8322*bbecb9d1SAndroid Build Coastguard Worker
8323*bbecb9d1SAndroid Build Coastguard Worker lheight = u_minify(res->base.height0, info->level);
8324*bbecb9d1SAndroid Build Coastguard Worker if (info->box->height > lheight || info->box->height < 0)
8325*bbecb9d1SAndroid Build Coastguard Worker return false;
8326*bbecb9d1SAndroid Build Coastguard Worker if (info->box->y > lheight)
8327*bbecb9d1SAndroid Build Coastguard Worker return false;
8328*bbecb9d1SAndroid Build Coastguard Worker if (info->box->height + info->box->y > lheight)
8329*bbecb9d1SAndroid Build Coastguard Worker return false;
8330*bbecb9d1SAndroid Build Coastguard Worker
8331*bbecb9d1SAndroid Build Coastguard Worker if (res->base.target == PIPE_TEXTURE_3D) {
8332*bbecb9d1SAndroid Build Coastguard Worker int ldepth = u_minify(res->base.depth0, info->level);
8333*bbecb9d1SAndroid Build Coastguard Worker if (info->box->depth > ldepth || info->box->depth < 0)
8334*bbecb9d1SAndroid Build Coastguard Worker return false;
8335*bbecb9d1SAndroid Build Coastguard Worker if (info->box->z > ldepth)
8336*bbecb9d1SAndroid Build Coastguard Worker return false;
8337*bbecb9d1SAndroid Build Coastguard Worker if (info->box->z + info->box->depth > ldepth)
8338*bbecb9d1SAndroid Build Coastguard Worker return false;
8339*bbecb9d1SAndroid Build Coastguard Worker } else {
8340*bbecb9d1SAndroid Build Coastguard Worker if (info->box->depth > (int)res->base.array_size)
8341*bbecb9d1SAndroid Build Coastguard Worker return false;
8342*bbecb9d1SAndroid Build Coastguard Worker if (info->box->z > (int)res->base.array_size)
8343*bbecb9d1SAndroid Build Coastguard Worker return false;
8344*bbecb9d1SAndroid Build Coastguard Worker if (info->box->z + info->box->depth > (int)res->base.array_size)
8345*bbecb9d1SAndroid Build Coastguard Worker return false;
8346*bbecb9d1SAndroid Build Coastguard Worker }
8347*bbecb9d1SAndroid Build Coastguard Worker
8348*bbecb9d1SAndroid Build Coastguard Worker return true;
8349*bbecb9d1SAndroid Build Coastguard Worker }
8350*bbecb9d1SAndroid Build Coastguard Worker
8351*bbecb9d1SAndroid Build Coastguard Worker /* Calculate the size of the memory needed to hold all the data of a
8352*bbecb9d1SAndroid Build Coastguard Worker * transfer for particular stride values.
8353*bbecb9d1SAndroid Build Coastguard Worker */
vrend_transfer_size(struct vrend_resource * vres,const struct vrend_transfer_info * info,uint32_t stride,uint32_t layer_stride)8354*bbecb9d1SAndroid Build Coastguard Worker static uint64_t vrend_transfer_size(struct vrend_resource *vres,
8355*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info,
8356*bbecb9d1SAndroid Build Coastguard Worker uint32_t stride, uint32_t layer_stride)
8357*bbecb9d1SAndroid Build Coastguard Worker {
8358*bbecb9d1SAndroid Build Coastguard Worker struct pipe_resource *pres = &vres->base;
8359*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box *box = info->box;
8360*bbecb9d1SAndroid Build Coastguard Worker uint64_t size;
8361*bbecb9d1SAndroid Build Coastguard Worker /* For purposes of size calculation, assume that invalid dimension values
8362*bbecb9d1SAndroid Build Coastguard Worker * correspond to 1.
8363*bbecb9d1SAndroid Build Coastguard Worker */
8364*bbecb9d1SAndroid Build Coastguard Worker int w = box->width > 0 ? box->width : 1;
8365*bbecb9d1SAndroid Build Coastguard Worker int h = box->height > 0 ? box->height : 1;
8366*bbecb9d1SAndroid Build Coastguard Worker uint64_t d = box->depth > 0 ? box->depth : 1;
8367*bbecb9d1SAndroid Build Coastguard Worker uint64_t nblocksx = util_format_get_nblocksx(pres->format, w);
8368*bbecb9d1SAndroid Build Coastguard Worker uint64_t nblocksy = util_format_get_nblocksy(pres->format, h);
8369*bbecb9d1SAndroid Build Coastguard Worker
8370*bbecb9d1SAndroid Build Coastguard Worker /* Calculate the box size, not including the last layer. The last layer
8371*bbecb9d1SAndroid Build Coastguard Worker * is the only one which may be incomplete, and is the only layer for
8372*bbecb9d1SAndroid Build Coastguard Worker * non 3d/2d-array formats.
8373*bbecb9d1SAndroid Build Coastguard Worker */
8374*bbecb9d1SAndroid Build Coastguard Worker size = (d - 1) * layer_stride;
8375*bbecb9d1SAndroid Build Coastguard Worker /* Calculate the size of the last (or only) layer, not including the last
8376*bbecb9d1SAndroid Build Coastguard Worker * block row. The last block row is the only one which may be incomplete and
8377*bbecb9d1SAndroid Build Coastguard Worker * is the only block row for non 2d/1d-array formats.
8378*bbecb9d1SAndroid Build Coastguard Worker */
8379*bbecb9d1SAndroid Build Coastguard Worker size += (nblocksy - 1) * stride;
8380*bbecb9d1SAndroid Build Coastguard Worker /* Calculate the size of the the last (or only) block row. */
8381*bbecb9d1SAndroid Build Coastguard Worker size += nblocksx * util_format_get_blocksize(pres->format);
8382*bbecb9d1SAndroid Build Coastguard Worker
8383*bbecb9d1SAndroid Build Coastguard Worker return size;
8384*bbecb9d1SAndroid Build Coastguard Worker }
8385*bbecb9d1SAndroid Build Coastguard Worker
check_iov_bounds(struct vrend_resource * res,const struct vrend_transfer_info * info,const struct iovec * iov,int num_iovs)8386*bbecb9d1SAndroid Build Coastguard Worker static bool check_iov_bounds(struct vrend_resource *res,
8387*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info,
8388*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov, int num_iovs)
8389*bbecb9d1SAndroid Build Coastguard Worker {
8390*bbecb9d1SAndroid Build Coastguard Worker GLuint transfer_size;
8391*bbecb9d1SAndroid Build Coastguard Worker GLuint iovsize = vrend_get_iovec_size(iov, num_iovs);
8392*bbecb9d1SAndroid Build Coastguard Worker GLuint valid_stride, valid_layer_stride;
8393*bbecb9d1SAndroid Build Coastguard Worker
8394*bbecb9d1SAndroid Build Coastguard Worker /* If the transfer specifies a stride, verify that it's at least as large as
8395*bbecb9d1SAndroid Build Coastguard Worker * the minimum required for the transfer. If no stride is specified use the
8396*bbecb9d1SAndroid Build Coastguard Worker * image stride for the specified level.
8397*bbecb9d1SAndroid Build Coastguard Worker */
8398*bbecb9d1SAndroid Build Coastguard Worker if (info->stride) {
8399*bbecb9d1SAndroid Build Coastguard Worker GLuint min_stride = util_format_get_stride(res->base.format, info->box->width);
8400*bbecb9d1SAndroid Build Coastguard Worker if (info->stride < min_stride)
8401*bbecb9d1SAndroid Build Coastguard Worker return false;
8402*bbecb9d1SAndroid Build Coastguard Worker valid_stride = info->stride;
8403*bbecb9d1SAndroid Build Coastguard Worker } else {
8404*bbecb9d1SAndroid Build Coastguard Worker valid_stride = util_format_get_stride(res->base.format,
8405*bbecb9d1SAndroid Build Coastguard Worker u_minify(res->base.width0, info->level));
8406*bbecb9d1SAndroid Build Coastguard Worker }
8407*bbecb9d1SAndroid Build Coastguard Worker
8408*bbecb9d1SAndroid Build Coastguard Worker /* If the transfer specifies a layer_stride, verify that it's at least as
8409*bbecb9d1SAndroid Build Coastguard Worker * large as the minimum required for the transfer. If no layer_stride is
8410*bbecb9d1SAndroid Build Coastguard Worker * specified use the image layer_stride for the specified level.
8411*bbecb9d1SAndroid Build Coastguard Worker */
8412*bbecb9d1SAndroid Build Coastguard Worker if (info->layer_stride) {
8413*bbecb9d1SAndroid Build Coastguard Worker GLuint min_layer_stride = util_format_get_2d_size(res->base.format,
8414*bbecb9d1SAndroid Build Coastguard Worker valid_stride,
8415*bbecb9d1SAndroid Build Coastguard Worker info->box->height);
8416*bbecb9d1SAndroid Build Coastguard Worker if (info->layer_stride < min_layer_stride)
8417*bbecb9d1SAndroid Build Coastguard Worker return false;
8418*bbecb9d1SAndroid Build Coastguard Worker valid_layer_stride = info->layer_stride;
8419*bbecb9d1SAndroid Build Coastguard Worker } else {
8420*bbecb9d1SAndroid Build Coastguard Worker valid_layer_stride =
8421*bbecb9d1SAndroid Build Coastguard Worker util_format_get_2d_size(res->base.format, valid_stride,
8422*bbecb9d1SAndroid Build Coastguard Worker u_minify(res->base.height0, info->level));
8423*bbecb9d1SAndroid Build Coastguard Worker }
8424*bbecb9d1SAndroid Build Coastguard Worker
8425*bbecb9d1SAndroid Build Coastguard Worker /* Calculate the size required for the transferred data, based on the
8426*bbecb9d1SAndroid Build Coastguard Worker * calculated or provided strides, and ensure that the iov, starting at the
8427*bbecb9d1SAndroid Build Coastguard Worker * specified offset, is able to hold at least that size.
8428*bbecb9d1SAndroid Build Coastguard Worker */
8429*bbecb9d1SAndroid Build Coastguard Worker transfer_size = vrend_transfer_size(res, info,
8430*bbecb9d1SAndroid Build Coastguard Worker valid_stride,
8431*bbecb9d1SAndroid Build Coastguard Worker valid_layer_stride);
8432*bbecb9d1SAndroid Build Coastguard Worker if (iovsize < info->offset)
8433*bbecb9d1SAndroid Build Coastguard Worker return false;
8434*bbecb9d1SAndroid Build Coastguard Worker if (iovsize < transfer_size)
8435*bbecb9d1SAndroid Build Coastguard Worker return false;
8436*bbecb9d1SAndroid Build Coastguard Worker if (iovsize < info->offset + transfer_size)
8437*bbecb9d1SAndroid Build Coastguard Worker return false;
8438*bbecb9d1SAndroid Build Coastguard Worker
8439*bbecb9d1SAndroid Build Coastguard Worker return true;
8440*bbecb9d1SAndroid Build Coastguard Worker }
8441*bbecb9d1SAndroid Build Coastguard Worker
vrend_swizzle_data_bgra(uint64_t size,void * data)8442*bbecb9d1SAndroid Build Coastguard Worker static void vrend_swizzle_data_bgra(uint64_t size, void *data) {
8443*bbecb9d1SAndroid Build Coastguard Worker const size_t bpp = 4;
8444*bbecb9d1SAndroid Build Coastguard Worker const size_t num_pixels = size / bpp;
8445*bbecb9d1SAndroid Build Coastguard Worker for (size_t i = 0; i < num_pixels; ++i) {
8446*bbecb9d1SAndroid Build Coastguard Worker unsigned char *pixel = ((unsigned char*)data) + i * bpp;
8447*bbecb9d1SAndroid Build Coastguard Worker unsigned char first = *pixel;
8448*bbecb9d1SAndroid Build Coastguard Worker *pixel = *(pixel + 2);
8449*bbecb9d1SAndroid Build Coastguard Worker *(pixel + 2) = first;
8450*bbecb9d1SAndroid Build Coastguard Worker }
8451*bbecb9d1SAndroid Build Coastguard Worker }
8452*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_transfer_write_iov(struct vrend_context * ctx,struct vrend_resource * res,const struct iovec * iov,int num_iovs,const struct vrend_transfer_info * info)8453*bbecb9d1SAndroid Build Coastguard Worker static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
8454*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res,
8455*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov, int num_iovs,
8456*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
8457*bbecb9d1SAndroid Build Coastguard Worker {
8458*bbecb9d1SAndroid Build Coastguard Worker void *data;
8459*bbecb9d1SAndroid Build Coastguard Worker
8460*bbecb9d1SAndroid Build Coastguard Worker if ((is_only_bit(res->storage_bits, VREND_STORAGE_GUEST_MEMORY) ||
8461*bbecb9d1SAndroid Build Coastguard Worker has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) && res->iov) {
8462*bbecb9d1SAndroid Build Coastguard Worker return vrend_copy_iovec(iov, num_iovs, info->offset,
8463*bbecb9d1SAndroid Build Coastguard Worker res->iov, res->num_iovs, info->box->x,
8464*bbecb9d1SAndroid Build Coastguard Worker info->box->width, res->ptr);
8465*bbecb9d1SAndroid Build Coastguard Worker }
8466*bbecb9d1SAndroid Build Coastguard Worker
8467*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) {
8468*bbecb9d1SAndroid Build Coastguard Worker assert(!res->iov);
8469*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(iov, num_iovs, info->offset,
8470*bbecb9d1SAndroid Build Coastguard Worker res->ptr + info->box->x, info->box->width);
8471*bbecb9d1SAndroid Build Coastguard Worker return 0;
8472*bbecb9d1SAndroid Build Coastguard Worker }
8473*bbecb9d1SAndroid Build Coastguard Worker
8474*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_GL_BUFFER)) {
8475*bbecb9d1SAndroid Build Coastguard Worker GLuint map_flags = GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT;
8476*bbecb9d1SAndroid Build Coastguard Worker struct virgl_sub_upload_data d;
8477*bbecb9d1SAndroid Build Coastguard Worker d.box = info->box;
8478*bbecb9d1SAndroid Build Coastguard Worker d.target = res->target;
8479*bbecb9d1SAndroid Build Coastguard Worker
8480*bbecb9d1SAndroid Build Coastguard Worker if (!info->synchronized)
8481*bbecb9d1SAndroid Build Coastguard Worker map_flags |= GL_MAP_UNSYNCHRONIZED_BIT;
8482*bbecb9d1SAndroid Build Coastguard Worker
8483*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, res->id);
8484*bbecb9d1SAndroid Build Coastguard Worker data = glMapBufferRange(res->target, info->box->x, info->box->width, map_flags);
8485*bbecb9d1SAndroid Build Coastguard Worker if (data == NULL) {
8486*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("map failed for element buffer\n");
8487*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec_cb(iov, num_iovs, info->offset, info->box->width, &iov_buffer_upload, &d);
8488*bbecb9d1SAndroid Build Coastguard Worker } else {
8489*bbecb9d1SAndroid Build Coastguard Worker vrend_read_from_iovec(iov, num_iovs, info->offset, data, info->box->width);
8490*bbecb9d1SAndroid Build Coastguard Worker glUnmapBuffer(res->target);
8491*bbecb9d1SAndroid Build Coastguard Worker }
8492*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, 0);
8493*bbecb9d1SAndroid Build Coastguard Worker } else {
8494*bbecb9d1SAndroid Build Coastguard Worker GLenum glformat;
8495*bbecb9d1SAndroid Build Coastguard Worker GLenum gltype;
8496*bbecb9d1SAndroid Build Coastguard Worker int need_temp = 0;
8497*bbecb9d1SAndroid Build Coastguard Worker int elsize = util_format_get_blocksize(res->base.format);
8498*bbecb9d1SAndroid Build Coastguard Worker int x = 0, y = 0;
8499*bbecb9d1SAndroid Build Coastguard Worker bool compressed;
8500*bbecb9d1SAndroid Build Coastguard Worker bool invert = false;
8501*bbecb9d1SAndroid Build Coastguard Worker float depth_scale;
8502*bbecb9d1SAndroid Build Coastguard Worker GLuint send_size = 0;
8503*bbecb9d1SAndroid Build Coastguard Worker uint32_t stride = info->stride;
8504*bbecb9d1SAndroid Build Coastguard Worker uint32_t layer_stride = info->layer_stride;
8505*bbecb9d1SAndroid Build Coastguard Worker
8506*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(ctx->sub, 0);
8507*bbecb9d1SAndroid Build Coastguard Worker
8508*bbecb9d1SAndroid Build Coastguard Worker if (!stride)
8509*bbecb9d1SAndroid Build Coastguard Worker stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, info->level)) * elsize;
8510*bbecb9d1SAndroid Build Coastguard Worker
8511*bbecb9d1SAndroid Build Coastguard Worker if (!layer_stride)
8512*bbecb9d1SAndroid Build Coastguard Worker layer_stride = util_format_get_2d_size(res->base.format, stride,
8513*bbecb9d1SAndroid Build Coastguard Worker u_minify(res->base.height0, info->level));
8514*bbecb9d1SAndroid Build Coastguard Worker
8515*bbecb9d1SAndroid Build Coastguard Worker compressed = util_format_is_compressed(res->base.format);
8516*bbecb9d1SAndroid Build Coastguard Worker if (num_iovs > 1 || compressed) {
8517*bbecb9d1SAndroid Build Coastguard Worker need_temp = true;
8518*bbecb9d1SAndroid Build Coastguard Worker }
8519*bbecb9d1SAndroid Build Coastguard Worker
8520*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && vrend_format_is_bgra(res->base.format))
8521*bbecb9d1SAndroid Build Coastguard Worker need_temp = true;
8522*bbecb9d1SAndroid Build Coastguard Worker
8523*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile == true &&
8524*bbecb9d1SAndroid Build Coastguard Worker (res->y_0_top || (res->base.format == VIRGL_FORMAT_Z24X8_UNORM))) {
8525*bbecb9d1SAndroid Build Coastguard Worker need_temp = true;
8526*bbecb9d1SAndroid Build Coastguard Worker if (res->y_0_top)
8527*bbecb9d1SAndroid Build Coastguard Worker invert = true;
8528*bbecb9d1SAndroid Build Coastguard Worker }
8529*bbecb9d1SAndroid Build Coastguard Worker
8530*bbecb9d1SAndroid Build Coastguard Worker send_size = util_format_get_nblocks(res->base.format, info->box->width,
8531*bbecb9d1SAndroid Build Coastguard Worker info->box->height) * elsize;
8532*bbecb9d1SAndroid Build Coastguard Worker if (res->target == GL_TEXTURE_3D ||
8533*bbecb9d1SAndroid Build Coastguard Worker res->target == GL_TEXTURE_2D_ARRAY ||
8534*bbecb9d1SAndroid Build Coastguard Worker res->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
8535*bbecb9d1SAndroid Build Coastguard Worker res->target == GL_TEXTURE_CUBE_MAP_ARRAY)
8536*bbecb9d1SAndroid Build Coastguard Worker send_size *= info->box->depth;
8537*bbecb9d1SAndroid Build Coastguard Worker else if (need_temp && info->box->depth != 1)
8538*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
8539*bbecb9d1SAndroid Build Coastguard Worker
8540*bbecb9d1SAndroid Build Coastguard Worker if (need_temp) {
8541*bbecb9d1SAndroid Build Coastguard Worker data = malloc(send_size);
8542*bbecb9d1SAndroid Build Coastguard Worker if (!data)
8543*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
8544*bbecb9d1SAndroid Build Coastguard Worker read_transfer_data(iov, num_iovs, data, res->base.format, info->offset,
8545*bbecb9d1SAndroid Build Coastguard Worker stride, layer_stride, info->box, invert);
8546*bbecb9d1SAndroid Build Coastguard Worker } else {
8547*bbecb9d1SAndroid Build Coastguard Worker if (send_size > iov[0].iov_len - info->offset)
8548*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
8549*bbecb9d1SAndroid Build Coastguard Worker data = (char*)iov[0].iov_base + info->offset;
8550*bbecb9d1SAndroid Build Coastguard Worker }
8551*bbecb9d1SAndroid Build Coastguard Worker
8552*bbecb9d1SAndroid Build Coastguard Worker if (!need_temp) {
8553*bbecb9d1SAndroid Build Coastguard Worker assert(stride);
8554*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / elsize);
8555*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, layer_stride / stride);
8556*bbecb9d1SAndroid Build Coastguard Worker } else
8557*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
8558*bbecb9d1SAndroid Build Coastguard Worker
8559*bbecb9d1SAndroid Build Coastguard Worker switch (elsize) {
8560*bbecb9d1SAndroid Build Coastguard Worker case 1:
8561*bbecb9d1SAndroid Build Coastguard Worker case 3:
8562*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
8563*bbecb9d1SAndroid Build Coastguard Worker break;
8564*bbecb9d1SAndroid Build Coastguard Worker case 2:
8565*bbecb9d1SAndroid Build Coastguard Worker case 6:
8566*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
8567*bbecb9d1SAndroid Build Coastguard Worker break;
8568*bbecb9d1SAndroid Build Coastguard Worker case 4:
8569*bbecb9d1SAndroid Build Coastguard Worker default:
8570*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
8571*bbecb9d1SAndroid Build Coastguard Worker break;
8572*bbecb9d1SAndroid Build Coastguard Worker case 8:
8573*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
8574*bbecb9d1SAndroid Build Coastguard Worker break;
8575*bbecb9d1SAndroid Build Coastguard Worker }
8576*bbecb9d1SAndroid Build Coastguard Worker
8577*bbecb9d1SAndroid Build Coastguard Worker glformat = tex_conv_table[res->base.format].glformat;
8578*bbecb9d1SAndroid Build Coastguard Worker gltype = tex_conv_table[res->base.format].gltype;
8579*bbecb9d1SAndroid Build Coastguard Worker
8580*bbecb9d1SAndroid Build Coastguard Worker if ((!vrend_state.use_core_profile) && (res->y_0_top)) {
8581*bbecb9d1SAndroid Build Coastguard Worker GLuint buffers;
8582*bbecb9d1SAndroid Build Coastguard Worker GLuint fb_id;
8583*bbecb9d1SAndroid Build Coastguard Worker
8584*bbecb9d1SAndroid Build Coastguard Worker glGenFramebuffers(1, &fb_id);
8585*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb_id);
8586*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture(res, 0, info->level, 0);
8587*bbecb9d1SAndroid Build Coastguard Worker
8588*bbecb9d1SAndroid Build Coastguard Worker buffers = GL_COLOR_ATTACHMENT0;
8589*bbecb9d1SAndroid Build Coastguard Worker glDrawBuffers(1, &buffers);
8590*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_BLEND);
8591*bbecb9d1SAndroid Build Coastguard Worker
8592*bbecb9d1SAndroid Build Coastguard Worker vrend_depth_test_enable(ctx, false);
8593*bbecb9d1SAndroid Build Coastguard Worker vrend_alpha_test_enable(ctx, false);
8594*bbecb9d1SAndroid Build Coastguard Worker vrend_stencil_test_enable(ctx->sub, false);
8595*bbecb9d1SAndroid Build Coastguard Worker
8596*bbecb9d1SAndroid Build Coastguard Worker glPixelZoom(1.0f, res->y_0_top ? -1.0f : 1.0f);
8597*bbecb9d1SAndroid Build Coastguard Worker glWindowPos2i(info->box->x, res->y_0_top ? (int)res->base.height0 - info->box->y : info->box->y);
8598*bbecb9d1SAndroid Build Coastguard Worker glDrawPixels(info->box->width, info->box->height, glformat, gltype,
8599*bbecb9d1SAndroid Build Coastguard Worker data);
8600*bbecb9d1SAndroid Build Coastguard Worker glDeleteFramebuffers(1, &fb_id);
8601*bbecb9d1SAndroid Build Coastguard Worker } else {
8602*bbecb9d1SAndroid Build Coastguard Worker uint32_t comp_size;
8603*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(res->target, res->id);
8604*bbecb9d1SAndroid Build Coastguard Worker
8605*bbecb9d1SAndroid Build Coastguard Worker if (compressed) {
8606*bbecb9d1SAndroid Build Coastguard Worker glformat = tex_conv_table[res->base.format].internalformat;
8607*bbecb9d1SAndroid Build Coastguard Worker comp_size = util_format_get_nblocks(res->base.format, info->box->width,
8608*bbecb9d1SAndroid Build Coastguard Worker info->box->height) * util_format_get_blocksize(res->base.format);
8609*bbecb9d1SAndroid Build Coastguard Worker }
8610*bbecb9d1SAndroid Build Coastguard Worker
8611*bbecb9d1SAndroid Build Coastguard Worker if (glformat == 0) {
8612*bbecb9d1SAndroid Build Coastguard Worker glformat = GL_BGRA;
8613*bbecb9d1SAndroid Build Coastguard Worker gltype = GL_UNSIGNED_BYTE;
8614*bbecb9d1SAndroid Build Coastguard Worker }
8615*bbecb9d1SAndroid Build Coastguard Worker
8616*bbecb9d1SAndroid Build Coastguard Worker x = info->box->x;
8617*bbecb9d1SAndroid Build Coastguard Worker y = invert ? (int)res->base.height0 - info->box->y - info->box->height : info->box->y;
8618*bbecb9d1SAndroid Build Coastguard Worker
8619*bbecb9d1SAndroid Build Coastguard Worker /* GLES doesn't allow format conversions, which we need for BGRA resources with RGBA
8620*bbecb9d1SAndroid Build Coastguard Worker * internal format. So we fallback to performing a CPU swizzle before uploading. */
8621*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && vrend_format_is_bgra(res->base.format)) {
8622*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_bgra, ctx, "manually swizzling bgra->rgba on upload since gles+bgra\n");
8623*bbecb9d1SAndroid Build Coastguard Worker vrend_swizzle_data_bgra(send_size, data);
8624*bbecb9d1SAndroid Build Coastguard Worker }
8625*bbecb9d1SAndroid Build Coastguard Worker
8626*bbecb9d1SAndroid Build Coastguard Worker /* mipmaps are usually passed in one iov, and we need to keep the offset
8627*bbecb9d1SAndroid Build Coastguard Worker * into the data in case we want to read back the data of a surface
8628*bbecb9d1SAndroid Build Coastguard Worker * that can not be rendered. Since we can not assume that the whole texture
8629*bbecb9d1SAndroid Build Coastguard Worker * is filled, we evaluate the offset for origin (0,0,0). Since it is also
8630*bbecb9d1SAndroid Build Coastguard Worker * possible that a resource is reused and resized update the offset every time.
8631*bbecb9d1SAndroid Build Coastguard Worker */
8632*bbecb9d1SAndroid Build Coastguard Worker if (info->level < VR_MAX_TEXTURE_2D_LEVELS) {
8633*bbecb9d1SAndroid Build Coastguard Worker int64_t level_height = u_minify(res->base.height0, info->level);
8634*bbecb9d1SAndroid Build Coastguard Worker res->mipmap_offsets[info->level] = info->offset -
8635*bbecb9d1SAndroid Build Coastguard Worker ((info->box->z * level_height + y) * stride + x * elsize);
8636*bbecb9d1SAndroid Build Coastguard Worker }
8637*bbecb9d1SAndroid Build Coastguard Worker
8638*bbecb9d1SAndroid Build Coastguard Worker if (res->base.format == VIRGL_FORMAT_Z24X8_UNORM) {
8639*bbecb9d1SAndroid Build Coastguard Worker /* we get values from the guest as 24-bit scaled integers
8640*bbecb9d1SAndroid Build Coastguard Worker but we give them to the host GL and it interprets them
8641*bbecb9d1SAndroid Build Coastguard Worker as 32-bit scaled integers, so we need to scale them here */
8642*bbecb9d1SAndroid Build Coastguard Worker depth_scale = 256.0;
8643*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_core_profile)
8644*bbecb9d1SAndroid Build Coastguard Worker glPixelTransferf(GL_DEPTH_SCALE, depth_scale);
8645*bbecb9d1SAndroid Build Coastguard Worker else
8646*bbecb9d1SAndroid Build Coastguard Worker vrend_scale_depth(data, send_size, depth_scale);
8647*bbecb9d1SAndroid Build Coastguard Worker }
8648*bbecb9d1SAndroid Build Coastguard Worker if (res->target == GL_TEXTURE_CUBE_MAP) {
8649*bbecb9d1SAndroid Build Coastguard Worker GLenum ctarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + info->box->z;
8650*bbecb9d1SAndroid Build Coastguard Worker if (compressed) {
8651*bbecb9d1SAndroid Build Coastguard Worker glCompressedTexSubImage2D(ctarget, info->level, x, y,
8652*bbecb9d1SAndroid Build Coastguard Worker info->box->width, info->box->height,
8653*bbecb9d1SAndroid Build Coastguard Worker glformat, comp_size, data);
8654*bbecb9d1SAndroid Build Coastguard Worker } else {
8655*bbecb9d1SAndroid Build Coastguard Worker glTexSubImage2D(ctarget, info->level, x, y, info->box->width, info->box->height,
8656*bbecb9d1SAndroid Build Coastguard Worker glformat, gltype, data);
8657*bbecb9d1SAndroid Build Coastguard Worker }
8658*bbecb9d1SAndroid Build Coastguard Worker } else if (res->target == GL_TEXTURE_3D || res->target == GL_TEXTURE_2D_ARRAY || res->target == GL_TEXTURE_CUBE_MAP_ARRAY) {
8659*bbecb9d1SAndroid Build Coastguard Worker if (compressed) {
8660*bbecb9d1SAndroid Build Coastguard Worker glCompressedTexSubImage3D(res->target, info->level, x, y, info->box->z,
8661*bbecb9d1SAndroid Build Coastguard Worker info->box->width, info->box->height, info->box->depth,
8662*bbecb9d1SAndroid Build Coastguard Worker glformat, comp_size, data);
8663*bbecb9d1SAndroid Build Coastguard Worker } else {
8664*bbecb9d1SAndroid Build Coastguard Worker glTexSubImage3D(res->target, info->level, x, y, info->box->z,
8665*bbecb9d1SAndroid Build Coastguard Worker info->box->width, info->box->height, info->box->depth,
8666*bbecb9d1SAndroid Build Coastguard Worker glformat, gltype, data);
8667*bbecb9d1SAndroid Build Coastguard Worker }
8668*bbecb9d1SAndroid Build Coastguard Worker } else if (res->target == GL_TEXTURE_1D) {
8669*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
8670*bbecb9d1SAndroid Build Coastguard Worker /* Covers both compressed and none compressed. */
8671*bbecb9d1SAndroid Build Coastguard Worker report_gles_missing_func(ctx, "gl[Compressed]TexSubImage1D");
8672*bbecb9d1SAndroid Build Coastguard Worker } else if (compressed) {
8673*bbecb9d1SAndroid Build Coastguard Worker glCompressedTexSubImage1D(res->target, info->level, info->box->x,
8674*bbecb9d1SAndroid Build Coastguard Worker info->box->width,
8675*bbecb9d1SAndroid Build Coastguard Worker glformat, comp_size, data);
8676*bbecb9d1SAndroid Build Coastguard Worker } else {
8677*bbecb9d1SAndroid Build Coastguard Worker glTexSubImage1D(res->target, info->level, info->box->x, info->box->width,
8678*bbecb9d1SAndroid Build Coastguard Worker glformat, gltype, data);
8679*bbecb9d1SAndroid Build Coastguard Worker }
8680*bbecb9d1SAndroid Build Coastguard Worker } else {
8681*bbecb9d1SAndroid Build Coastguard Worker if (compressed) {
8682*bbecb9d1SAndroid Build Coastguard Worker glCompressedTexSubImage2D(res->target, info->level, x, res->target == GL_TEXTURE_1D_ARRAY ? info->box->z : y,
8683*bbecb9d1SAndroid Build Coastguard Worker info->box->width, info->box->height,
8684*bbecb9d1SAndroid Build Coastguard Worker glformat, comp_size, data);
8685*bbecb9d1SAndroid Build Coastguard Worker } else {
8686*bbecb9d1SAndroid Build Coastguard Worker glTexSubImage2D(res->target, info->level, x, res->target == GL_TEXTURE_1D_ARRAY ? info->box->z : y,
8687*bbecb9d1SAndroid Build Coastguard Worker info->box->width,
8688*bbecb9d1SAndroid Build Coastguard Worker res->target == GL_TEXTURE_1D_ARRAY ? info->box->depth : info->box->height,
8689*bbecb9d1SAndroid Build Coastguard Worker glformat, gltype, data);
8690*bbecb9d1SAndroid Build Coastguard Worker }
8691*bbecb9d1SAndroid Build Coastguard Worker }
8692*bbecb9d1SAndroid Build Coastguard Worker if (res->base.format == VIRGL_FORMAT_Z24X8_UNORM) {
8693*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_core_profile)
8694*bbecb9d1SAndroid Build Coastguard Worker glPixelTransferf(GL_DEPTH_SCALE, 1.0);
8695*bbecb9d1SAndroid Build Coastguard Worker }
8696*bbecb9d1SAndroid Build Coastguard Worker }
8697*bbecb9d1SAndroid Build Coastguard Worker
8698*bbecb9d1SAndroid Build Coastguard Worker if (stride && !need_temp) {
8699*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
8700*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
8701*bbecb9d1SAndroid Build Coastguard Worker }
8702*bbecb9d1SAndroid Build Coastguard Worker
8703*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
8704*bbecb9d1SAndroid Build Coastguard Worker
8705*bbecb9d1SAndroid Build Coastguard Worker if (need_temp)
8706*bbecb9d1SAndroid Build Coastguard Worker free(data);
8707*bbecb9d1SAndroid Build Coastguard Worker }
8708*bbecb9d1SAndroid Build Coastguard Worker return 0;
8709*bbecb9d1SAndroid Build Coastguard Worker }
8710*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_texture_depth(struct vrend_resource * res,uint32_t level)8711*bbecb9d1SAndroid Build Coastguard Worker static uint32_t vrend_get_texture_depth(struct vrend_resource *res, uint32_t level)
8712*bbecb9d1SAndroid Build Coastguard Worker {
8713*bbecb9d1SAndroid Build Coastguard Worker uint32_t depth = 1;
8714*bbecb9d1SAndroid Build Coastguard Worker if (res->target == GL_TEXTURE_3D)
8715*bbecb9d1SAndroid Build Coastguard Worker depth = u_minify(res->base.depth0, level);
8716*bbecb9d1SAndroid Build Coastguard Worker else if (res->target == GL_TEXTURE_1D_ARRAY || res->target == GL_TEXTURE_2D_ARRAY ||
8717*bbecb9d1SAndroid Build Coastguard Worker res->target == GL_TEXTURE_CUBE_MAP || res->target == GL_TEXTURE_CUBE_MAP_ARRAY)
8718*bbecb9d1SAndroid Build Coastguard Worker depth = res->base.array_size;
8719*bbecb9d1SAndroid Build Coastguard Worker
8720*bbecb9d1SAndroid Build Coastguard Worker return depth;
8721*bbecb9d1SAndroid Build Coastguard Worker }
8722*bbecb9d1SAndroid Build Coastguard Worker
vrend_transfer_send_getteximage(struct vrend_resource * res,const struct iovec * iov,int num_iovs,const struct vrend_transfer_info * info)8723*bbecb9d1SAndroid Build Coastguard Worker static int vrend_transfer_send_getteximage(struct vrend_resource *res,
8724*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov, int num_iovs,
8725*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
8726*bbecb9d1SAndroid Build Coastguard Worker {
8727*bbecb9d1SAndroid Build Coastguard Worker GLenum format, type;
8728*bbecb9d1SAndroid Build Coastguard Worker uint32_t tex_size;
8729*bbecb9d1SAndroid Build Coastguard Worker char *data;
8730*bbecb9d1SAndroid Build Coastguard Worker int elsize = util_format_get_blocksize(res->base.format);
8731*bbecb9d1SAndroid Build Coastguard Worker int compressed = util_format_is_compressed(res->base.format);
8732*bbecb9d1SAndroid Build Coastguard Worker GLenum target;
8733*bbecb9d1SAndroid Build Coastguard Worker uint32_t send_offset = 0;
8734*bbecb9d1SAndroid Build Coastguard Worker format = tex_conv_table[res->base.format].glformat;
8735*bbecb9d1SAndroid Build Coastguard Worker type = tex_conv_table[res->base.format].gltype;
8736*bbecb9d1SAndroid Build Coastguard Worker
8737*bbecb9d1SAndroid Build Coastguard Worker if (compressed)
8738*bbecb9d1SAndroid Build Coastguard Worker format = tex_conv_table[res->base.format].internalformat;
8739*bbecb9d1SAndroid Build Coastguard Worker
8740*bbecb9d1SAndroid Build Coastguard Worker tex_size = util_format_get_nblocks(res->base.format, u_minify(res->base.width0, info->level), u_minify(res->base.height0, info->level)) *
8741*bbecb9d1SAndroid Build Coastguard Worker util_format_get_blocksize(res->base.format) * vrend_get_texture_depth(res, info->level);
8742*bbecb9d1SAndroid Build Coastguard Worker
8743*bbecb9d1SAndroid Build Coastguard Worker if (info->box->z && res->target != GL_TEXTURE_CUBE_MAP) {
8744*bbecb9d1SAndroid Build Coastguard Worker send_offset = util_format_get_nblocks(res->base.format, u_minify(res->base.width0, info->level), u_minify(res->base.height0, info->level)) * util_format_get_blocksize(res->base.format) * info->box->z;
8745*bbecb9d1SAndroid Build Coastguard Worker }
8746*bbecb9d1SAndroid Build Coastguard Worker
8747*bbecb9d1SAndroid Build Coastguard Worker data = malloc(tex_size);
8748*bbecb9d1SAndroid Build Coastguard Worker if (!data)
8749*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
8750*bbecb9d1SAndroid Build Coastguard Worker
8751*bbecb9d1SAndroid Build Coastguard Worker switch (elsize) {
8752*bbecb9d1SAndroid Build Coastguard Worker case 1:
8753*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 1);
8754*bbecb9d1SAndroid Build Coastguard Worker break;
8755*bbecb9d1SAndroid Build Coastguard Worker case 2:
8756*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 2);
8757*bbecb9d1SAndroid Build Coastguard Worker break;
8758*bbecb9d1SAndroid Build Coastguard Worker case 4:
8759*bbecb9d1SAndroid Build Coastguard Worker default:
8760*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 4);
8761*bbecb9d1SAndroid Build Coastguard Worker break;
8762*bbecb9d1SAndroid Build Coastguard Worker case 8:
8763*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 8);
8764*bbecb9d1SAndroid Build Coastguard Worker break;
8765*bbecb9d1SAndroid Build Coastguard Worker }
8766*bbecb9d1SAndroid Build Coastguard Worker
8767*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(res->target, res->id);
8768*bbecb9d1SAndroid Build Coastguard Worker if (res->target == GL_TEXTURE_CUBE_MAP) {
8769*bbecb9d1SAndroid Build Coastguard Worker target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + info->box->z;
8770*bbecb9d1SAndroid Build Coastguard Worker } else
8771*bbecb9d1SAndroid Build Coastguard Worker target = res->target;
8772*bbecb9d1SAndroid Build Coastguard Worker
8773*bbecb9d1SAndroid Build Coastguard Worker if (compressed) {
8774*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_robustness)) {
8775*bbecb9d1SAndroid Build Coastguard Worker glGetnCompressedTexImageARB(target, info->level, tex_size, data);
8776*bbecb9d1SAndroid Build Coastguard Worker } else if (vrend_state.use_gles) {
8777*bbecb9d1SAndroid Build Coastguard Worker report_gles_missing_func(NULL, "glGetCompressedTexImage");
8778*bbecb9d1SAndroid Build Coastguard Worker } else {
8779*bbecb9d1SAndroid Build Coastguard Worker glGetCompressedTexImage(target, info->level, data);
8780*bbecb9d1SAndroid Build Coastguard Worker }
8781*bbecb9d1SAndroid Build Coastguard Worker } else {
8782*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_robustness)) {
8783*bbecb9d1SAndroid Build Coastguard Worker glGetnTexImageARB(target, info->level, format, type, tex_size, data);
8784*bbecb9d1SAndroid Build Coastguard Worker } else if (vrend_state.use_gles) {
8785*bbecb9d1SAndroid Build Coastguard Worker report_gles_missing_func(NULL, "glGetTexImage");
8786*bbecb9d1SAndroid Build Coastguard Worker } else {
8787*bbecb9d1SAndroid Build Coastguard Worker glGetTexImage(target, info->level, format, type, data);
8788*bbecb9d1SAndroid Build Coastguard Worker }
8789*bbecb9d1SAndroid Build Coastguard Worker }
8790*bbecb9d1SAndroid Build Coastguard Worker
8791*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 4);
8792*bbecb9d1SAndroid Build Coastguard Worker
8793*bbecb9d1SAndroid Build Coastguard Worker write_transfer_data(&res->base, iov, num_iovs, data + send_offset,
8794*bbecb9d1SAndroid Build Coastguard Worker info->stride, info->box, info->level, info->offset,
8795*bbecb9d1SAndroid Build Coastguard Worker false);
8796*bbecb9d1SAndroid Build Coastguard Worker free(data);
8797*bbecb9d1SAndroid Build Coastguard Worker return 0;
8798*bbecb9d1SAndroid Build Coastguard Worker }
8799*bbecb9d1SAndroid Build Coastguard Worker
do_readpixels(struct vrend_resource * res,int idx,uint32_t level,uint32_t layer,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,void * data)8800*bbecb9d1SAndroid Build Coastguard Worker static void do_readpixels(struct vrend_resource *res,
8801*bbecb9d1SAndroid Build Coastguard Worker int idx, uint32_t level, uint32_t layer,
8802*bbecb9d1SAndroid Build Coastguard Worker GLint x, GLint y,
8803*bbecb9d1SAndroid Build Coastguard Worker GLsizei width, GLsizei height,
8804*bbecb9d1SAndroid Build Coastguard Worker GLenum format, GLenum type,
8805*bbecb9d1SAndroid Build Coastguard Worker GLsizei bufSize, void *data)
8806*bbecb9d1SAndroid Build Coastguard Worker {
8807*bbecb9d1SAndroid Build Coastguard Worker GLuint fb_id;
8808*bbecb9d1SAndroid Build Coastguard Worker
8809*bbecb9d1SAndroid Build Coastguard Worker glGenFramebuffers(1, &fb_id);
8810*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, fb_id);
8811*bbecb9d1SAndroid Build Coastguard Worker
8812*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture(res, idx, level, layer);
8813*bbecb9d1SAndroid Build Coastguard Worker
8814*bbecb9d1SAndroid Build Coastguard Worker /* Warn if the driver doesn't agree about the read format and type.
8815*bbecb9d1SAndroid Build Coastguard Worker On desktop GL we can use basically any format and type to glReadPixels,
8816*bbecb9d1SAndroid Build Coastguard Worker so we picked the format and type that matches the native format.
8817*bbecb9d1SAndroid Build Coastguard Worker
8818*bbecb9d1SAndroid Build Coastguard Worker But on GLES we are limited to a very few set, luckily most GLES
8819*bbecb9d1SAndroid Build Coastguard Worker implementations should return type and format that match the native
8820*bbecb9d1SAndroid Build Coastguard Worker formats, and can be used for glReadPixels acording to the GLES spec.
8821*bbecb9d1SAndroid Build Coastguard Worker
8822*bbecb9d1SAndroid Build Coastguard Worker But we have found that at least Mesa returned the wrong formats, again
8823*bbecb9d1SAndroid Build Coastguard Worker luckily we are able to change Mesa. But just in case there are more bad
8824*bbecb9d1SAndroid Build Coastguard Worker drivers out there, or we mess up the format somewhere, we warn here. */
8825*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && !vrend_format_is_ds(res->base.format)) {
8826*bbecb9d1SAndroid Build Coastguard Worker GLint imp;
8827*bbecb9d1SAndroid Build Coastguard Worker if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_INT &&
8828*bbecb9d1SAndroid Build Coastguard Worker type != GL_INT && type != GL_FLOAT) {
8829*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &imp);
8830*bbecb9d1SAndroid Build Coastguard Worker if (imp != (GLint)type) {
8831*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "GL_IMPLEMENTATION_COLOR_READ_TYPE is not expected native type 0x%x != imp 0x%x\n", type, imp);
8832*bbecb9d1SAndroid Build Coastguard Worker }
8833*bbecb9d1SAndroid Build Coastguard Worker }
8834*bbecb9d1SAndroid Build Coastguard Worker if (format != GL_RGBA && format != GL_RGBA_INTEGER) {
8835*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &imp);
8836*bbecb9d1SAndroid Build Coastguard Worker if (imp != (GLint)format) {
8837*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "GL_IMPLEMENTATION_COLOR_READ_FORMAT is not expected native format 0x%x != imp 0x%x\n", format, imp);
8838*bbecb9d1SAndroid Build Coastguard Worker }
8839*bbecb9d1SAndroid Build Coastguard Worker }
8840*bbecb9d1SAndroid Build Coastguard Worker }
8841*bbecb9d1SAndroid Build Coastguard Worker
8842*bbecb9d1SAndroid Build Coastguard Worker /* read-color clamping is handled in the mesa frontend */
8843*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles) {
8844*bbecb9d1SAndroid Build Coastguard Worker glClampColor(GL_CLAMP_READ_COLOR_ARB, GL_FALSE);
8845*bbecb9d1SAndroid Build Coastguard Worker }
8846*bbecb9d1SAndroid Build Coastguard Worker
8847*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_robustness))
8848*bbecb9d1SAndroid Build Coastguard Worker glReadnPixelsARB(x, y, width, height, format, type, bufSize, data);
8849*bbecb9d1SAndroid Build Coastguard Worker else if (has_feature(feat_gles_khr_robustness))
8850*bbecb9d1SAndroid Build Coastguard Worker glReadnPixelsKHR(x, y, width, height, format, type, bufSize, data);
8851*bbecb9d1SAndroid Build Coastguard Worker else
8852*bbecb9d1SAndroid Build Coastguard Worker glReadPixels(x, y, width, height, format, type, data);
8853*bbecb9d1SAndroid Build Coastguard Worker
8854*bbecb9d1SAndroid Build Coastguard Worker glDeleteFramebuffers(1, &fb_id);
8855*bbecb9d1SAndroid Build Coastguard Worker }
8856*bbecb9d1SAndroid Build Coastguard Worker
vrend_transfer_send_readpixels(struct vrend_context * ctx,struct vrend_resource * res,const struct iovec * iov,int num_iovs,const struct vrend_transfer_info * info)8857*bbecb9d1SAndroid Build Coastguard Worker static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
8858*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res,
8859*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov, int num_iovs,
8860*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
8861*bbecb9d1SAndroid Build Coastguard Worker {
8862*bbecb9d1SAndroid Build Coastguard Worker char *myptr = (char*)iov[0].iov_base + info->offset;
8863*bbecb9d1SAndroid Build Coastguard Worker int need_temp = 0;
8864*bbecb9d1SAndroid Build Coastguard Worker char *data;
8865*bbecb9d1SAndroid Build Coastguard Worker bool actually_invert, separate_invert = false;
8866*bbecb9d1SAndroid Build Coastguard Worker GLenum format, type;
8867*bbecb9d1SAndroid Build Coastguard Worker GLint y1;
8868*bbecb9d1SAndroid Build Coastguard Worker uint32_t send_size = 0;
8869*bbecb9d1SAndroid Build Coastguard Worker uint32_t h = u_minify(res->base.height0, info->level);
8870*bbecb9d1SAndroid Build Coastguard Worker int elsize = util_format_get_blocksize(res->base.format);
8871*bbecb9d1SAndroid Build Coastguard Worker float depth_scale;
8872*bbecb9d1SAndroid Build Coastguard Worker int row_stride = info->stride / elsize;
8873*bbecb9d1SAndroid Build Coastguard Worker GLint old_fbo;
8874*bbecb9d1SAndroid Build Coastguard Worker
8875*bbecb9d1SAndroid Build Coastguard Worker vrend_use_program(ctx->sub, 0);
8876*bbecb9d1SAndroid Build Coastguard Worker
8877*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats fmt = res->base.format;
8878*bbecb9d1SAndroid Build Coastguard Worker
8879*bbecb9d1SAndroid Build Coastguard Worker format = tex_conv_table[fmt].glformat;
8880*bbecb9d1SAndroid Build Coastguard Worker type = tex_conv_table[fmt].gltype;
8881*bbecb9d1SAndroid Build Coastguard Worker /* if we are asked to invert and reading from a front then don't */
8882*bbecb9d1SAndroid Build Coastguard Worker
8883*bbecb9d1SAndroid Build Coastguard Worker actually_invert = res->y_0_top;
8884*bbecb9d1SAndroid Build Coastguard Worker
8885*bbecb9d1SAndroid Build Coastguard Worker if (actually_invert && !has_feature(feat_mesa_invert))
8886*bbecb9d1SAndroid Build Coastguard Worker separate_invert = true;
8887*bbecb9d1SAndroid Build Coastguard Worker
8888*bbecb9d1SAndroid Build Coastguard Worker #if UTIL_ARCH_BIG_ENDIAN
8889*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_SWAP_BYTES, 1);
8890*bbecb9d1SAndroid Build Coastguard Worker #endif
8891*bbecb9d1SAndroid Build Coastguard Worker
8892*bbecb9d1SAndroid Build Coastguard Worker if (num_iovs > 1 || separate_invert)
8893*bbecb9d1SAndroid Build Coastguard Worker need_temp = 1;
8894*bbecb9d1SAndroid Build Coastguard Worker
8895*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && vrend_format_is_bgra(res->base.format))
8896*bbecb9d1SAndroid Build Coastguard Worker need_temp = true;
8897*bbecb9d1SAndroid Build Coastguard Worker
8898*bbecb9d1SAndroid Build Coastguard Worker if (need_temp) {
8899*bbecb9d1SAndroid Build Coastguard Worker send_size = util_format_get_nblocks(res->base.format, info->box->width, info->box->height) * info->box->depth * util_format_get_blocksize(res->base.format);
8900*bbecb9d1SAndroid Build Coastguard Worker data = malloc(send_size);
8901*bbecb9d1SAndroid Build Coastguard Worker if (!data) {
8902*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("malloc failed %d\n", send_size);
8903*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
8904*bbecb9d1SAndroid Build Coastguard Worker }
8905*bbecb9d1SAndroid Build Coastguard Worker } else {
8906*bbecb9d1SAndroid Build Coastguard Worker send_size = iov[0].iov_len - info->offset;
8907*bbecb9d1SAndroid Build Coastguard Worker data = myptr;
8908*bbecb9d1SAndroid Build Coastguard Worker if (!row_stride)
8909*bbecb9d1SAndroid Build Coastguard Worker row_stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, info->level));
8910*bbecb9d1SAndroid Build Coastguard Worker }
8911*bbecb9d1SAndroid Build Coastguard Worker
8912*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_fbo);
8913*bbecb9d1SAndroid Build Coastguard Worker
8914*bbecb9d1SAndroid Build Coastguard Worker if (actually_invert)
8915*bbecb9d1SAndroid Build Coastguard Worker y1 = h - info->box->y - info->box->height;
8916*bbecb9d1SAndroid Build Coastguard Worker else
8917*bbecb9d1SAndroid Build Coastguard Worker y1 = info->box->y;
8918*bbecb9d1SAndroid Build Coastguard Worker
8919*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_mesa_invert) && actually_invert)
8920*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_INVERT_MESA, 1);
8921*bbecb9d1SAndroid Build Coastguard Worker if (!need_temp && row_stride)
8922*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ROW_LENGTH, row_stride);
8923*bbecb9d1SAndroid Build Coastguard Worker
8924*bbecb9d1SAndroid Build Coastguard Worker switch (elsize) {
8925*bbecb9d1SAndroid Build Coastguard Worker case 1:
8926*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 1);
8927*bbecb9d1SAndroid Build Coastguard Worker break;
8928*bbecb9d1SAndroid Build Coastguard Worker case 2:
8929*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 2);
8930*bbecb9d1SAndroid Build Coastguard Worker break;
8931*bbecb9d1SAndroid Build Coastguard Worker case 4:
8932*bbecb9d1SAndroid Build Coastguard Worker default:
8933*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 4);
8934*bbecb9d1SAndroid Build Coastguard Worker break;
8935*bbecb9d1SAndroid Build Coastguard Worker case 8:
8936*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 8);
8937*bbecb9d1SAndroid Build Coastguard Worker break;
8938*bbecb9d1SAndroid Build Coastguard Worker }
8939*bbecb9d1SAndroid Build Coastguard Worker
8940*bbecb9d1SAndroid Build Coastguard Worker if (res->base.format == VIRGL_FORMAT_Z24X8_UNORM) {
8941*bbecb9d1SAndroid Build Coastguard Worker /* we get values from the guest as 24-bit scaled integers
8942*bbecb9d1SAndroid Build Coastguard Worker but we give them to the host GL and it interprets them
8943*bbecb9d1SAndroid Build Coastguard Worker as 32-bit scaled integers, so we need to scale them here */
8944*bbecb9d1SAndroid Build Coastguard Worker depth_scale = 1.0 / 256.0;
8945*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_core_profile) {
8946*bbecb9d1SAndroid Build Coastguard Worker glPixelTransferf(GL_DEPTH_SCALE, depth_scale);
8947*bbecb9d1SAndroid Build Coastguard Worker }
8948*bbecb9d1SAndroid Build Coastguard Worker }
8949*bbecb9d1SAndroid Build Coastguard Worker
8950*bbecb9d1SAndroid Build Coastguard Worker do_readpixels(res, 0, info->level, info->box->z, info->box->x, y1,
8951*bbecb9d1SAndroid Build Coastguard Worker info->box->width, info->box->height, format, type, send_size, data);
8952*bbecb9d1SAndroid Build Coastguard Worker
8953*bbecb9d1SAndroid Build Coastguard Worker /* on GLES, texture-backed BGR* resources are always stored with RGB* internal format, but
8954*bbecb9d1SAndroid Build Coastguard Worker * the guest will expect to readback the data in BGRA format.
8955*bbecb9d1SAndroid Build Coastguard Worker * Since the GLES API doesn't allow format conversions like GL, we CPU-swizzle the data
8956*bbecb9d1SAndroid Build Coastguard Worker * on upload and need to do the same on readback.
8957*bbecb9d1SAndroid Build Coastguard Worker * The notable exception is externally-stored (GBM/EGL) BGR* resources, for which BGR*
8958*bbecb9d1SAndroid Build Coastguard Worker * byte-ordering is used instead to match external access patterns. */
8959*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && vrend_format_is_bgra(res->base.format)) {
8960*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_bgra, ctx, "manually swizzling rgba->bgra on readback since gles+bgra\n");
8961*bbecb9d1SAndroid Build Coastguard Worker vrend_swizzle_data_bgra(send_size, data);
8962*bbecb9d1SAndroid Build Coastguard Worker }
8963*bbecb9d1SAndroid Build Coastguard Worker
8964*bbecb9d1SAndroid Build Coastguard Worker if (res->base.format == VIRGL_FORMAT_Z24X8_UNORM) {
8965*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_core_profile)
8966*bbecb9d1SAndroid Build Coastguard Worker glPixelTransferf(GL_DEPTH_SCALE, 1.0);
8967*bbecb9d1SAndroid Build Coastguard Worker else
8968*bbecb9d1SAndroid Build Coastguard Worker vrend_scale_depth(data, send_size, depth_scale);
8969*bbecb9d1SAndroid Build Coastguard Worker }
8970*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_mesa_invert) && actually_invert)
8971*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_INVERT_MESA, 0);
8972*bbecb9d1SAndroid Build Coastguard Worker if (!need_temp && row_stride)
8973*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ROW_LENGTH, 0);
8974*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 4);
8975*bbecb9d1SAndroid Build Coastguard Worker
8976*bbecb9d1SAndroid Build Coastguard Worker #if UTIL_ARCH_BIG_ENDIAN
8977*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_SWAP_BYTES, 0);
8978*bbecb9d1SAndroid Build Coastguard Worker #endif
8979*bbecb9d1SAndroid Build Coastguard Worker
8980*bbecb9d1SAndroid Build Coastguard Worker if (need_temp) {
8981*bbecb9d1SAndroid Build Coastguard Worker write_transfer_data(&res->base, iov, num_iovs, data,
8982*bbecb9d1SAndroid Build Coastguard Worker info->stride, info->box, info->level, info->offset,
8983*bbecb9d1SAndroid Build Coastguard Worker separate_invert);
8984*bbecb9d1SAndroid Build Coastguard Worker free(data);
8985*bbecb9d1SAndroid Build Coastguard Worker }
8986*bbecb9d1SAndroid Build Coastguard Worker
8987*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
8988*bbecb9d1SAndroid Build Coastguard Worker
8989*bbecb9d1SAndroid Build Coastguard Worker return 0;
8990*bbecb9d1SAndroid Build Coastguard Worker }
8991*bbecb9d1SAndroid Build Coastguard Worker
vrend_transfer_send_readonly(struct vrend_resource * res,const struct iovec * iov,int num_iovs,UNUSED const struct vrend_transfer_info * info)8992*bbecb9d1SAndroid Build Coastguard Worker static int vrend_transfer_send_readonly(struct vrend_resource *res,
8993*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov, int num_iovs,
8994*bbecb9d1SAndroid Build Coastguard Worker UNUSED const struct vrend_transfer_info *info)
8995*bbecb9d1SAndroid Build Coastguard Worker {
8996*bbecb9d1SAndroid Build Coastguard Worker bool same_iov = true;
8997*bbecb9d1SAndroid Build Coastguard Worker uint i;
8998*bbecb9d1SAndroid Build Coastguard Worker
8999*bbecb9d1SAndroid Build Coastguard Worker if (res->num_iovs == (uint32_t)num_iovs) {
9000*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < res->num_iovs; i++) {
9001*bbecb9d1SAndroid Build Coastguard Worker if (res->iov[i].iov_len != iov[i].iov_len ||
9002*bbecb9d1SAndroid Build Coastguard Worker res->iov[i].iov_base != iov[i].iov_base) {
9003*bbecb9d1SAndroid Build Coastguard Worker same_iov = false;
9004*bbecb9d1SAndroid Build Coastguard Worker }
9005*bbecb9d1SAndroid Build Coastguard Worker }
9006*bbecb9d1SAndroid Build Coastguard Worker } else {
9007*bbecb9d1SAndroid Build Coastguard Worker same_iov = false;
9008*bbecb9d1SAndroid Build Coastguard Worker }
9009*bbecb9d1SAndroid Build Coastguard Worker
9010*bbecb9d1SAndroid Build Coastguard Worker /*
9011*bbecb9d1SAndroid Build Coastguard Worker * When we detect that we are reading back to the same iovs that are
9012*bbecb9d1SAndroid Build Coastguard Worker * attached to the resource and we know that the resource can not
9013*bbecb9d1SAndroid Build Coastguard Worker * be rendered to (as this function is only called then), we do not
9014*bbecb9d1SAndroid Build Coastguard Worker * need to do anything more.
9015*bbecb9d1SAndroid Build Coastguard Worker */
9016*bbecb9d1SAndroid Build Coastguard Worker if (same_iov) {
9017*bbecb9d1SAndroid Build Coastguard Worker return 0;
9018*bbecb9d1SAndroid Build Coastguard Worker }
9019*bbecb9d1SAndroid Build Coastguard Worker
9020*bbecb9d1SAndroid Build Coastguard Worker return -1;
9021*bbecb9d1SAndroid Build Coastguard Worker }
9022*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_transfer_send_iov(struct vrend_context * ctx,struct vrend_resource * res,const struct iovec * iov,int num_iovs,const struct vrend_transfer_info * info)9023*bbecb9d1SAndroid Build Coastguard Worker static int vrend_renderer_transfer_send_iov(struct vrend_context *ctx,
9024*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res,
9025*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov, int num_iovs,
9026*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
9027*bbecb9d1SAndroid Build Coastguard Worker {
9028*bbecb9d1SAndroid Build Coastguard Worker if (is_only_bit(res->storage_bits, VREND_STORAGE_GUEST_MEMORY) ||
9029*bbecb9d1SAndroid Build Coastguard Worker (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY) && res->iov)) {
9030*bbecb9d1SAndroid Build Coastguard Worker return vrend_copy_iovec(res->iov, res->num_iovs, info->box->x,
9031*bbecb9d1SAndroid Build Coastguard Worker iov, num_iovs, info->offset,
9032*bbecb9d1SAndroid Build Coastguard Worker info->box->width, res->ptr);
9033*bbecb9d1SAndroid Build Coastguard Worker }
9034*bbecb9d1SAndroid Build Coastguard Worker
9035*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) {
9036*bbecb9d1SAndroid Build Coastguard Worker assert(!res->iov);
9037*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(iov, num_iovs, info->offset,
9038*bbecb9d1SAndroid Build Coastguard Worker res->ptr + info->box->x, info->box->width);
9039*bbecb9d1SAndroid Build Coastguard Worker return 0;
9040*bbecb9d1SAndroid Build Coastguard Worker }
9041*bbecb9d1SAndroid Build Coastguard Worker
9042*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_GL_BUFFER)) {
9043*bbecb9d1SAndroid Build Coastguard Worker uint32_t send_size = info->box->width * util_format_get_blocksize(res->base.format);
9044*bbecb9d1SAndroid Build Coastguard Worker void *data;
9045*bbecb9d1SAndroid Build Coastguard Worker
9046*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, res->id);
9047*bbecb9d1SAndroid Build Coastguard Worker data = glMapBufferRange(res->target, info->box->x, info->box->width, GL_MAP_READ_BIT);
9048*bbecb9d1SAndroid Build Coastguard Worker if (!data)
9049*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("unable to open buffer for reading %d\n", res->target);
9050*bbecb9d1SAndroid Build Coastguard Worker else
9051*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(iov, num_iovs, info->offset, data, send_size);
9052*bbecb9d1SAndroid Build Coastguard Worker glUnmapBuffer(res->target);
9053*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, 0);
9054*bbecb9d1SAndroid Build Coastguard Worker } else {
9055*bbecb9d1SAndroid Build Coastguard Worker int ret = -1;
9056*bbecb9d1SAndroid Build Coastguard Worker bool can_readpixels = true;
9057*bbecb9d1SAndroid Build Coastguard Worker
9058*bbecb9d1SAndroid Build Coastguard Worker can_readpixels = vrend_format_can_render(res->base.format) || vrend_format_is_ds(res->base.format);
9059*bbecb9d1SAndroid Build Coastguard Worker
9060*bbecb9d1SAndroid Build Coastguard Worker if (can_readpixels)
9061*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_transfer_send_readpixels(ctx, res, iov, num_iovs, info);
9062*bbecb9d1SAndroid Build Coastguard Worker
9063*bbecb9d1SAndroid Build Coastguard Worker /* Can hit this on a non-error path as well. */
9064*bbecb9d1SAndroid Build Coastguard Worker if (ret) {
9065*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles)
9066*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_transfer_send_getteximage(res, iov, num_iovs, info);
9067*bbecb9d1SAndroid Build Coastguard Worker else
9068*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_transfer_send_readonly(res, iov, num_iovs, info);
9069*bbecb9d1SAndroid Build Coastguard Worker }
9070*bbecb9d1SAndroid Build Coastguard Worker
9071*bbecb9d1SAndroid Build Coastguard Worker return ret;
9072*bbecb9d1SAndroid Build Coastguard Worker }
9073*bbecb9d1SAndroid Build Coastguard Worker return 0;
9074*bbecb9d1SAndroid Build Coastguard Worker }
9075*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_transfer_internal(struct vrend_context * ctx,struct vrend_resource * res,const struct vrend_transfer_info * info,int transfer_mode)9076*bbecb9d1SAndroid Build Coastguard Worker static int vrend_renderer_transfer_internal(struct vrend_context *ctx,
9077*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res,
9078*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info,
9079*bbecb9d1SAndroid Build Coastguard Worker int transfer_mode)
9080*bbecb9d1SAndroid Build Coastguard Worker {
9081*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov;
9082*bbecb9d1SAndroid Build Coastguard Worker int num_iovs;
9083*bbecb9d1SAndroid Build Coastguard Worker
9084*bbecb9d1SAndroid Build Coastguard Worker if (!info->box)
9085*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9086*bbecb9d1SAndroid Build Coastguard Worker
9087*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_hw_switch_context(ctx, true))
9088*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9089*bbecb9d1SAndroid Build Coastguard Worker
9090*bbecb9d1SAndroid Build Coastguard Worker assert(check_transfer_iovec(res, info));
9091*bbecb9d1SAndroid Build Coastguard Worker if (info->iovec && info->iovec_cnt) {
9092*bbecb9d1SAndroid Build Coastguard Worker iov = info->iovec;
9093*bbecb9d1SAndroid Build Coastguard Worker num_iovs = info->iovec_cnt;
9094*bbecb9d1SAndroid Build Coastguard Worker } else {
9095*bbecb9d1SAndroid Build Coastguard Worker iov = res->iov;
9096*bbecb9d1SAndroid Build Coastguard Worker num_iovs = res->num_iovs;
9097*bbecb9d1SAndroid Build Coastguard Worker }
9098*bbecb9d1SAndroid Build Coastguard Worker
9099*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
9100*bbecb9d1SAndroid Build Coastguard Worker if (res->gbm_bo && (transfer_mode == VIRGL_TRANSFER_TO_HOST ||
9101*bbecb9d1SAndroid Build Coastguard Worker !has_bit(res->storage_bits, VREND_STORAGE_EGL_IMAGE))) {
9102*bbecb9d1SAndroid Build Coastguard Worker assert(!info->synchronized);
9103*bbecb9d1SAndroid Build Coastguard Worker return virgl_gbm_transfer(res->gbm_bo, transfer_mode, iov, num_iovs, info);
9104*bbecb9d1SAndroid Build Coastguard Worker }
9105*bbecb9d1SAndroid Build Coastguard Worker #endif
9106*bbecb9d1SAndroid Build Coastguard Worker
9107*bbecb9d1SAndroid Build Coastguard Worker if (!check_transfer_bounds(res, info)) {
9108*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS, res->id);
9109*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9110*bbecb9d1SAndroid Build Coastguard Worker }
9111*bbecb9d1SAndroid Build Coastguard Worker
9112*bbecb9d1SAndroid Build Coastguard Worker if (!check_iov_bounds(res, info, iov, num_iovs)) {
9113*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS, res->id);
9114*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9115*bbecb9d1SAndroid Build Coastguard Worker }
9116*bbecb9d1SAndroid Build Coastguard Worker
9117*bbecb9d1SAndroid Build Coastguard Worker switch (transfer_mode) {
9118*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_TRANSFER_TO_HOST:
9119*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_write_iov(ctx, res, iov, num_iovs, info);
9120*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_TRANSFER_FROM_HOST:
9121*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_send_iov(ctx, res, iov, num_iovs, info);
9122*bbecb9d1SAndroid Build Coastguard Worker
9123*bbecb9d1SAndroid Build Coastguard Worker default:
9124*bbecb9d1SAndroid Build Coastguard Worker assert(0);
9125*bbecb9d1SAndroid Build Coastguard Worker }
9126*bbecb9d1SAndroid Build Coastguard Worker return 0;
9127*bbecb9d1SAndroid Build Coastguard Worker }
9128*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_transfer_iov(struct vrend_context * ctx,uint32_t dst_handle,const struct vrend_transfer_info * info,int transfer_mode)9129*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_transfer_iov(struct vrend_context *ctx,
9130*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle,
9131*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info,
9132*bbecb9d1SAndroid Build Coastguard Worker int transfer_mode)
9133*bbecb9d1SAndroid Build Coastguard Worker {
9134*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
9135*bbecb9d1SAndroid Build Coastguard Worker
9136*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
9137*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
9138*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9139*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9140*bbecb9d1SAndroid Build Coastguard Worker }
9141*bbecb9d1SAndroid Build Coastguard Worker
9142*bbecb9d1SAndroid Build Coastguard Worker if (!check_transfer_iovec(res, info)) {
9143*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(res->storage_bits, VREND_STORAGE_EGL_IMAGE))
9144*bbecb9d1SAndroid Build Coastguard Worker return 0;
9145*bbecb9d1SAndroid Build Coastguard Worker else {
9146*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9147*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9148*bbecb9d1SAndroid Build Coastguard Worker }
9149*bbecb9d1SAndroid Build Coastguard Worker }
9150*bbecb9d1SAndroid Build Coastguard Worker
9151*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_internal(ctx, res, info,
9152*bbecb9d1SAndroid Build Coastguard Worker transfer_mode);
9153*bbecb9d1SAndroid Build Coastguard Worker }
9154*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_transfer_pipe(struct pipe_resource * pres,const struct vrend_transfer_info * info,int transfer_mode)9155*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_transfer_pipe(struct pipe_resource *pres,
9156*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info,
9157*bbecb9d1SAndroid Build Coastguard Worker int transfer_mode)
9158*bbecb9d1SAndroid Build Coastguard Worker {
9159*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
9160*bbecb9d1SAndroid Build Coastguard Worker if (!check_transfer_iovec(res, info))
9161*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9162*bbecb9d1SAndroid Build Coastguard Worker
9163*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_internal(vrend_state.ctx0, res, info,
9164*bbecb9d1SAndroid Build Coastguard Worker transfer_mode);
9165*bbecb9d1SAndroid Build Coastguard Worker }
9166*bbecb9d1SAndroid Build Coastguard Worker
vrend_transfer_inline_write(struct vrend_context * ctx,uint32_t dst_handle,const struct vrend_transfer_info * info)9167*bbecb9d1SAndroid Build Coastguard Worker int vrend_transfer_inline_write(struct vrend_context *ctx,
9168*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle,
9169*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
9170*bbecb9d1SAndroid Build Coastguard Worker {
9171*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
9172*bbecb9d1SAndroid Build Coastguard Worker
9173*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
9174*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
9175*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9176*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9177*bbecb9d1SAndroid Build Coastguard Worker }
9178*bbecb9d1SAndroid Build Coastguard Worker
9179*bbecb9d1SAndroid Build Coastguard Worker if (!check_transfer_bounds(res, info)) {
9180*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, dst_handle);
9181*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9182*bbecb9d1SAndroid Build Coastguard Worker }
9183*bbecb9d1SAndroid Build Coastguard Worker
9184*bbecb9d1SAndroid Build Coastguard Worker if (!check_iov_bounds(res, info, info->iovec, info->iovec_cnt)) {
9185*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, dst_handle);
9186*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9187*bbecb9d1SAndroid Build Coastguard Worker }
9188*bbecb9d1SAndroid Build Coastguard Worker
9189*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
9190*bbecb9d1SAndroid Build Coastguard Worker if (res->gbm_bo) {
9191*bbecb9d1SAndroid Build Coastguard Worker assert(!info->synchronized);
9192*bbecb9d1SAndroid Build Coastguard Worker return virgl_gbm_transfer(res->gbm_bo,
9193*bbecb9d1SAndroid Build Coastguard Worker VIRGL_TRANSFER_TO_HOST,
9194*bbecb9d1SAndroid Build Coastguard Worker info->iovec,
9195*bbecb9d1SAndroid Build Coastguard Worker info->iovec_cnt,
9196*bbecb9d1SAndroid Build Coastguard Worker info);
9197*bbecb9d1SAndroid Build Coastguard Worker }
9198*bbecb9d1SAndroid Build Coastguard Worker #endif
9199*bbecb9d1SAndroid Build Coastguard Worker
9200*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_write_iov(ctx, res, info->iovec, info->iovec_cnt, info);
9201*bbecb9d1SAndroid Build Coastguard Worker
9202*bbecb9d1SAndroid Build Coastguard Worker }
9203*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_copy_transfer3d(struct vrend_context * ctx,uint32_t dst_handle,uint32_t src_handle,const struct vrend_transfer_info * info)9204*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_copy_transfer3d(struct vrend_context *ctx,
9205*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle,
9206*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_handle,
9207*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
9208*bbecb9d1SAndroid Build Coastguard Worker {
9209*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res, *dst_res;
9210*bbecb9d1SAndroid Build Coastguard Worker
9211*bbecb9d1SAndroid Build Coastguard Worker src_res = vrend_renderer_ctx_res_lookup(ctx, src_handle);
9212*bbecb9d1SAndroid Build Coastguard Worker dst_res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
9213*bbecb9d1SAndroid Build Coastguard Worker
9214*bbecb9d1SAndroid Build Coastguard Worker if (!src_res) {
9215*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, src_handle);
9216*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9217*bbecb9d1SAndroid Build Coastguard Worker }
9218*bbecb9d1SAndroid Build Coastguard Worker
9219*bbecb9d1SAndroid Build Coastguard Worker if (!dst_res) {
9220*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9221*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9222*bbecb9d1SAndroid Build Coastguard Worker }
9223*bbecb9d1SAndroid Build Coastguard Worker
9224*bbecb9d1SAndroid Build Coastguard Worker if (!src_res->iov) {
9225*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9226*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9227*bbecb9d1SAndroid Build Coastguard Worker }
9228*bbecb9d1SAndroid Build Coastguard Worker
9229*bbecb9d1SAndroid Build Coastguard Worker if (!check_transfer_bounds(dst_res, info)) {
9230*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, dst_handle);
9231*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9232*bbecb9d1SAndroid Build Coastguard Worker }
9233*bbecb9d1SAndroid Build Coastguard Worker
9234*bbecb9d1SAndroid Build Coastguard Worker if (!check_iov_bounds(dst_res, info, src_res->iov, src_res->num_iovs)) {
9235*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, dst_handle);
9236*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9237*bbecb9d1SAndroid Build Coastguard Worker }
9238*bbecb9d1SAndroid Build Coastguard Worker
9239*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
9240*bbecb9d1SAndroid Build Coastguard Worker if (dst_res->gbm_bo) {
9241*bbecb9d1SAndroid Build Coastguard Worker bool use_gbm = true;
9242*bbecb9d1SAndroid Build Coastguard Worker
9243*bbecb9d1SAndroid Build Coastguard Worker /* The guest uses copy transfers against busy resources to avoid
9244*bbecb9d1SAndroid Build Coastguard Worker * waiting. The host GL driver is usually smart enough to avoid
9245*bbecb9d1SAndroid Build Coastguard Worker * blocking by putting the data in a staging buffer and doing a
9246*bbecb9d1SAndroid Build Coastguard Worker * pipelined copy. But when there is a GBM bo, we can only do that when
9247*bbecb9d1SAndroid Build Coastguard Worker * VREND_STORAGE_GL_IMMUTABLE is set because it implies that the
9248*bbecb9d1SAndroid Build Coastguard Worker * internal format is known and is known to be compatible with the
9249*bbecb9d1SAndroid Build Coastguard Worker * subsequence glTexSubImage2D. Otherwise, we glFinish and use GBM.
9250*bbecb9d1SAndroid Build Coastguard Worker * Also, EGL images with BGRX format are not compatible with
9251*bbecb9d1SAndroid Build Coastguard Worker * glTexSubImage2D, since they are stored with only 3bpp, so gbm
9252*bbecb9d1SAndroid Build Coastguard Worker * transfer is required.
9253*bbecb9d1SAndroid Build Coastguard Worker */
9254*bbecb9d1SAndroid Build Coastguard Worker if (info->synchronized) {
9255*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(dst_res->storage_bits, VREND_STORAGE_GL_IMMUTABLE) &&
9256*bbecb9d1SAndroid Build Coastguard Worker dst_res->base.format != VIRGL_FORMAT_B8G8R8X8_UNORM)
9257*bbecb9d1SAndroid Build Coastguard Worker use_gbm = false;
9258*bbecb9d1SAndroid Build Coastguard Worker else
9259*bbecb9d1SAndroid Build Coastguard Worker glFinish();
9260*bbecb9d1SAndroid Build Coastguard Worker }
9261*bbecb9d1SAndroid Build Coastguard Worker
9262*bbecb9d1SAndroid Build Coastguard Worker if (use_gbm) {
9263*bbecb9d1SAndroid Build Coastguard Worker return virgl_gbm_transfer(dst_res->gbm_bo,
9264*bbecb9d1SAndroid Build Coastguard Worker VIRGL_TRANSFER_TO_HOST,
9265*bbecb9d1SAndroid Build Coastguard Worker src_res->iov,
9266*bbecb9d1SAndroid Build Coastguard Worker src_res->num_iovs,
9267*bbecb9d1SAndroid Build Coastguard Worker info);
9268*bbecb9d1SAndroid Build Coastguard Worker }
9269*bbecb9d1SAndroid Build Coastguard Worker }
9270*bbecb9d1SAndroid Build Coastguard Worker #endif
9271*bbecb9d1SAndroid Build Coastguard Worker
9272*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_write_iov(ctx, dst_res, src_res->iov,
9273*bbecb9d1SAndroid Build Coastguard Worker src_res->num_iovs, info);
9274*bbecb9d1SAndroid Build Coastguard Worker }
9275*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_copy_transfer3d_from_host(struct vrend_context * ctx,uint32_t dst_handle,uint32_t src_handle,const struct vrend_transfer_info * info)9276*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_copy_transfer3d_from_host(struct vrend_context *ctx,
9277*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle,
9278*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_handle,
9279*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_transfer_info *info)
9280*bbecb9d1SAndroid Build Coastguard Worker {
9281*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res, *dst_res;
9282*bbecb9d1SAndroid Build Coastguard Worker
9283*bbecb9d1SAndroid Build Coastguard Worker src_res = vrend_renderer_ctx_res_lookup(ctx, src_handle);
9284*bbecb9d1SAndroid Build Coastguard Worker dst_res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
9285*bbecb9d1SAndroid Build Coastguard Worker
9286*bbecb9d1SAndroid Build Coastguard Worker if (!src_res) {
9287*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, src_handle);
9288*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9289*bbecb9d1SAndroid Build Coastguard Worker }
9290*bbecb9d1SAndroid Build Coastguard Worker
9291*bbecb9d1SAndroid Build Coastguard Worker if (!dst_res) {
9292*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9293*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9294*bbecb9d1SAndroid Build Coastguard Worker }
9295*bbecb9d1SAndroid Build Coastguard Worker
9296*bbecb9d1SAndroid Build Coastguard Worker if (!dst_res->iov) {
9297*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9298*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9299*bbecb9d1SAndroid Build Coastguard Worker }
9300*bbecb9d1SAndroid Build Coastguard Worker
9301*bbecb9d1SAndroid Build Coastguard Worker if (!check_transfer_bounds(src_res, info)) {
9302*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, dst_handle);
9303*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9304*bbecb9d1SAndroid Build Coastguard Worker }
9305*bbecb9d1SAndroid Build Coastguard Worker
9306*bbecb9d1SAndroid Build Coastguard Worker if (!check_iov_bounds(src_res, info, dst_res->iov, dst_res->num_iovs)) {
9307*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, dst_handle);
9308*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
9309*bbecb9d1SAndroid Build Coastguard Worker }
9310*bbecb9d1SAndroid Build Coastguard Worker
9311*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
9312*bbecb9d1SAndroid Build Coastguard Worker if (src_res->gbm_bo) {
9313*bbecb9d1SAndroid Build Coastguard Worker bool use_gbm = true;
9314*bbecb9d1SAndroid Build Coastguard Worker
9315*bbecb9d1SAndroid Build Coastguard Worker /* The guest uses copy transfers against busy resources to avoid
9316*bbecb9d1SAndroid Build Coastguard Worker * waiting. The host GL driver is usually smart enough to avoid
9317*bbecb9d1SAndroid Build Coastguard Worker * blocking by putting the data in a staging buffer and doing a
9318*bbecb9d1SAndroid Build Coastguard Worker * pipelined copy. But when there is a GBM bo, we can only do
9319*bbecb9d1SAndroid Build Coastguard Worker * that if the format is renderable, because we use glReadPixels,
9320*bbecb9d1SAndroid Build Coastguard Worker * or on OpenGL glGetTexImage.
9321*bbecb9d1SAndroid Build Coastguard Worker * Otherwise, if the format has a gbm bo we glFinish and use GBM.
9322*bbecb9d1SAndroid Build Coastguard Worker * Also, EGL images with BGRX format are not compatible with this
9323*bbecb9d1SAndroid Build Coastguard Worker * transfer type since they are stored with only 3bpp, so gbm transfer
9324*bbecb9d1SAndroid Build Coastguard Worker * is required.
9325*bbecb9d1SAndroid Build Coastguard Worker * For now the guest can knows than a texture is backed by a gbm buffer
9326*bbecb9d1SAndroid Build Coastguard Worker * if it was created with the VIRGL_BIND_SCANOUT flag,
9327*bbecb9d1SAndroid Build Coastguard Worker */
9328*bbecb9d1SAndroid Build Coastguard Worker if (info->synchronized) {
9329*bbecb9d1SAndroid Build Coastguard Worker bool can_readpixels = vrend_format_can_render(src_res->base.format) ||
9330*bbecb9d1SAndroid Build Coastguard Worker vrend_format_is_ds(src_res->base.format);
9331*bbecb9d1SAndroid Build Coastguard Worker
9332*bbecb9d1SAndroid Build Coastguard Worker if ((can_readpixels || !vrend_state.use_gles) &&
9333*bbecb9d1SAndroid Build Coastguard Worker src_res->base.format != VIRGL_FORMAT_B8G8R8X8_UNORM)
9334*bbecb9d1SAndroid Build Coastguard Worker use_gbm = false;
9335*bbecb9d1SAndroid Build Coastguard Worker else
9336*bbecb9d1SAndroid Build Coastguard Worker glFinish();
9337*bbecb9d1SAndroid Build Coastguard Worker }
9338*bbecb9d1SAndroid Build Coastguard Worker
9339*bbecb9d1SAndroid Build Coastguard Worker if (use_gbm) {
9340*bbecb9d1SAndroid Build Coastguard Worker return virgl_gbm_transfer(src_res->gbm_bo,
9341*bbecb9d1SAndroid Build Coastguard Worker VIRGL_TRANSFER_FROM_HOST,
9342*bbecb9d1SAndroid Build Coastguard Worker dst_res->iov,
9343*bbecb9d1SAndroid Build Coastguard Worker dst_res->num_iovs,
9344*bbecb9d1SAndroid Build Coastguard Worker info);
9345*bbecb9d1SAndroid Build Coastguard Worker }
9346*bbecb9d1SAndroid Build Coastguard Worker }
9347*bbecb9d1SAndroid Build Coastguard Worker #endif
9348*bbecb9d1SAndroid Build Coastguard Worker
9349*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_transfer_send_iov(ctx, src_res, dst_res->iov,
9350*bbecb9d1SAndroid Build Coastguard Worker dst_res->num_iovs, info);
9351*bbecb9d1SAndroid Build Coastguard Worker }
9352*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_stencil_ref(struct vrend_context * ctx,struct pipe_stencil_ref * ref)9353*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_stencil_ref(struct vrend_context *ctx,
9354*bbecb9d1SAndroid Build Coastguard Worker struct pipe_stencil_ref *ref)
9355*bbecb9d1SAndroid Build Coastguard Worker {
9356*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->stencil_refs[0] != ref->ref_value[0] ||
9357*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->stencil_refs[1] != ref->ref_value[1]) {
9358*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->stencil_refs[0] = ref->ref_value[0];
9359*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->stencil_refs[1] = ref->ref_value[1];
9360*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->stencil_state_dirty = true;
9361*bbecb9d1SAndroid Build Coastguard Worker }
9362*bbecb9d1SAndroid Build Coastguard Worker }
9363*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_blend_color(struct vrend_context * ctx,struct pipe_blend_color * color)9364*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_blend_color(struct vrend_context *ctx,
9365*bbecb9d1SAndroid Build Coastguard Worker struct pipe_blend_color *color)
9366*bbecb9d1SAndroid Build Coastguard Worker {
9367*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->blend_color = *color;
9368*bbecb9d1SAndroid Build Coastguard Worker glBlendColor(color->color[0], color->color[1], color->color[2],
9369*bbecb9d1SAndroid Build Coastguard Worker color->color[3]);
9370*bbecb9d1SAndroid Build Coastguard Worker }
9371*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_scissor_state(struct vrend_context * ctx,uint32_t start_slot,uint32_t num_scissor,struct pipe_scissor_state * ss)9372*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_scissor_state(struct vrend_context *ctx,
9373*bbecb9d1SAndroid Build Coastguard Worker uint32_t start_slot,
9374*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_scissor,
9375*bbecb9d1SAndroid Build Coastguard Worker struct pipe_scissor_state *ss)
9376*bbecb9d1SAndroid Build Coastguard Worker {
9377*bbecb9d1SAndroid Build Coastguard Worker if (start_slot < PIPE_MAX_VIEWPORTS &&
9378*bbecb9d1SAndroid Build Coastguard Worker start_slot + num_scissor <= PIPE_MAX_VIEWPORTS) {
9379*bbecb9d1SAndroid Build Coastguard Worker for (uint i = 0; i < num_scissor; i++) {
9380*bbecb9d1SAndroid Build Coastguard Worker uint idx = start_slot + i;
9381*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ss[idx] = ss[i];
9382*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->scissor_state_dirty |= (1 << idx);
9383*bbecb9d1SAndroid Build Coastguard Worker }
9384*bbecb9d1SAndroid Build Coastguard Worker } else
9385*bbecb9d1SAndroid Build Coastguard Worker vrend_report_buffer_error(ctx, 0);
9386*bbecb9d1SAndroid Build Coastguard Worker }
9387*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_polygon_stipple(struct vrend_context * ctx,struct pipe_poly_stipple * ps)9388*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_polygon_stipple(struct vrend_context *ctx,
9389*bbecb9d1SAndroid Build Coastguard Worker struct pipe_poly_stipple *ps)
9390*bbecb9d1SAndroid Build Coastguard Worker {
9391*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile) {
9392*bbecb9d1SAndroid Build Coastguard Worker
9393*bbecb9d1SAndroid Build Coastguard Worker /* std140 aligns array elements at 16 byte */
9394*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < VREND_POLYGON_STIPPLE_SIZE ; ++i)
9395*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data.stipple_pattern[i][0] = ps->stipple[i];
9396*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data_cookie++;
9397*bbecb9d1SAndroid Build Coastguard Worker } else {
9398*bbecb9d1SAndroid Build Coastguard Worker glPolygonStipple((const GLubyte *)ps->stipple);
9399*bbecb9d1SAndroid Build Coastguard Worker }
9400*bbecb9d1SAndroid Build Coastguard Worker }
9401*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_clip_state(struct vrend_context * ctx,struct pipe_clip_state * ucp)9402*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_clip_state(struct vrend_context *ctx, struct pipe_clip_state *ucp)
9403*bbecb9d1SAndroid Build Coastguard Worker {
9404*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_core_profile) {
9405*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->ucp_state = *ucp;
9406*bbecb9d1SAndroid Build Coastguard Worker
9407*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->sysvalue_data_cookie++;
9408*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0 ; i < VIRGL_NUM_CLIP_PLANES; i++) {
9409*bbecb9d1SAndroid Build Coastguard Worker memcpy(&ctx->sub->sysvalue_data.clipp[i],
9410*bbecb9d1SAndroid Build Coastguard Worker (const GLfloat *) &ctx->sub->ucp_state.ucp[i], sizeof(GLfloat) * 4);
9411*bbecb9d1SAndroid Build Coastguard Worker }
9412*bbecb9d1SAndroid Build Coastguard Worker } else {
9413*bbecb9d1SAndroid Build Coastguard Worker int i, j;
9414*bbecb9d1SAndroid Build Coastguard Worker GLdouble val[4];
9415*bbecb9d1SAndroid Build Coastguard Worker
9416*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < 8; i++) {
9417*bbecb9d1SAndroid Build Coastguard Worker for (j = 0; j < 4; j++)
9418*bbecb9d1SAndroid Build Coastguard Worker val[j] = ucp->ucp[i][j];
9419*bbecb9d1SAndroid Build Coastguard Worker glClipPlane(GL_CLIP_PLANE0 + i, val);
9420*bbecb9d1SAndroid Build Coastguard Worker }
9421*bbecb9d1SAndroid Build Coastguard Worker }
9422*bbecb9d1SAndroid Build Coastguard Worker }
9423*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_sample_mask(UNUSED struct vrend_context * ctx,unsigned sample_mask)9424*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_sample_mask(UNUSED struct vrend_context *ctx, unsigned sample_mask)
9425*bbecb9d1SAndroid Build Coastguard Worker {
9426*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_sample_mask))
9427*bbecb9d1SAndroid Build Coastguard Worker glSampleMaski(0, sample_mask);
9428*bbecb9d1SAndroid Build Coastguard Worker }
9429*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_min_samples(struct vrend_context * ctx,unsigned min_samples)9430*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_min_samples(struct vrend_context *ctx, unsigned min_samples)
9431*bbecb9d1SAndroid Build Coastguard Worker {
9432*bbecb9d1SAndroid Build Coastguard Worker float min_sample_shading = (float)min_samples;
9433*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->nr_cbufs > 0 && ctx->sub->surf[0]) {
9434*bbecb9d1SAndroid Build Coastguard Worker assert(ctx->sub->surf[0]->texture);
9435*bbecb9d1SAndroid Build Coastguard Worker min_sample_shading /= MAX2(1, ctx->sub->surf[0]->texture->base.nr_samples);
9436*bbecb9d1SAndroid Build Coastguard Worker }
9437*bbecb9d1SAndroid Build Coastguard Worker
9438*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_sample_shading))
9439*bbecb9d1SAndroid Build Coastguard Worker glMinSampleShading(min_sample_shading);
9440*bbecb9d1SAndroid Build Coastguard Worker }
9441*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_tess_state(UNUSED struct vrend_context * ctx,const float tess_factors[6])9442*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_tess_state(UNUSED struct vrend_context *ctx, const float tess_factors[6])
9443*bbecb9d1SAndroid Build Coastguard Worker {
9444*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_tessellation)) {
9445*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_gles) {
9446*bbecb9d1SAndroid Build Coastguard Worker glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, tess_factors);
9447*bbecb9d1SAndroid Build Coastguard Worker glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, &tess_factors[4]);
9448*bbecb9d1SAndroid Build Coastguard Worker } else {
9449*bbecb9d1SAndroid Build Coastguard Worker memcpy(vrend_state.tess_factors, tess_factors, 6 * sizeof (float));
9450*bbecb9d1SAndroid Build Coastguard Worker }
9451*bbecb9d1SAndroid Build Coastguard Worker }
9452*bbecb9d1SAndroid Build Coastguard Worker }
9453*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_emit_streamout_targets(UNUSED struct vrend_context * ctx,struct vrend_streamout_object * so_obj)9454*bbecb9d1SAndroid Build Coastguard Worker static void vrend_hw_emit_streamout_targets(UNUSED struct vrend_context *ctx, struct vrend_streamout_object *so_obj)
9455*bbecb9d1SAndroid Build Coastguard Worker {
9456*bbecb9d1SAndroid Build Coastguard Worker uint i;
9457*bbecb9d1SAndroid Build Coastguard Worker
9458*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < so_obj->num_targets; i++) {
9459*bbecb9d1SAndroid Build Coastguard Worker if (!so_obj->so_targets[i])
9460*bbecb9d1SAndroid Build Coastguard Worker glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, 0);
9461*bbecb9d1SAndroid Build Coastguard Worker else if (so_obj->so_targets[i]->buffer_offset || so_obj->so_targets[i]->buffer_size < so_obj->so_targets[i]->buffer->base.width0)
9462*bbecb9d1SAndroid Build Coastguard Worker glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, so_obj->so_targets[i]->buffer->id, so_obj->so_targets[i]->buffer_offset, so_obj->so_targets[i]->buffer_size);
9463*bbecb9d1SAndroid Build Coastguard Worker else
9464*bbecb9d1SAndroid Build Coastguard Worker glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, so_obj->so_targets[i]->buffer->id);
9465*bbecb9d1SAndroid Build Coastguard Worker }
9466*bbecb9d1SAndroid Build Coastguard Worker }
9467*bbecb9d1SAndroid Build Coastguard Worker
vrend_set_streamout_targets(struct vrend_context * ctx,UNUSED uint32_t append_bitmask,uint32_t num_targets,uint32_t * handles)9468*bbecb9d1SAndroid Build Coastguard Worker void vrend_set_streamout_targets(struct vrend_context *ctx,
9469*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t append_bitmask,
9470*bbecb9d1SAndroid Build Coastguard Worker uint32_t num_targets,
9471*bbecb9d1SAndroid Build Coastguard Worker uint32_t *handles)
9472*bbecb9d1SAndroid Build Coastguard Worker {
9473*bbecb9d1SAndroid Build Coastguard Worker struct vrend_so_target *target;
9474*bbecb9d1SAndroid Build Coastguard Worker uint i;
9475*bbecb9d1SAndroid Build Coastguard Worker
9476*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_transform_feedback))
9477*bbecb9d1SAndroid Build Coastguard Worker return;
9478*bbecb9d1SAndroid Build Coastguard Worker
9479*bbecb9d1SAndroid Build Coastguard Worker if (num_targets) {
9480*bbecb9d1SAndroid Build Coastguard Worker bool found = false;
9481*bbecb9d1SAndroid Build Coastguard Worker struct vrend_streamout_object *obj;
9482*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(obj, &ctx->sub->streamout_list, head) {
9483*bbecb9d1SAndroid Build Coastguard Worker if (obj->num_targets == num_targets) {
9484*bbecb9d1SAndroid Build Coastguard Worker if (!memcmp(handles, obj->handles, num_targets * 4)) {
9485*bbecb9d1SAndroid Build Coastguard Worker found = true;
9486*bbecb9d1SAndroid Build Coastguard Worker break;
9487*bbecb9d1SAndroid Build Coastguard Worker }
9488*bbecb9d1SAndroid Build Coastguard Worker }
9489*bbecb9d1SAndroid Build Coastguard Worker }
9490*bbecb9d1SAndroid Build Coastguard Worker if (found) {
9491*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->current_so = obj;
9492*bbecb9d1SAndroid Build Coastguard Worker glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, obj->id);
9493*bbecb9d1SAndroid Build Coastguard Worker return;
9494*bbecb9d1SAndroid Build Coastguard Worker }
9495*bbecb9d1SAndroid Build Coastguard Worker
9496*bbecb9d1SAndroid Build Coastguard Worker obj = CALLOC_STRUCT(vrend_streamout_object);
9497*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback2)) {
9498*bbecb9d1SAndroid Build Coastguard Worker glGenTransformFeedbacks(1, &obj->id);
9499*bbecb9d1SAndroid Build Coastguard Worker glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, obj->id);
9500*bbecb9d1SAndroid Build Coastguard Worker }
9501*bbecb9d1SAndroid Build Coastguard Worker obj->num_targets = num_targets;
9502*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < num_targets; i++) {
9503*bbecb9d1SAndroid Build Coastguard Worker obj->handles[i] = handles[i];
9504*bbecb9d1SAndroid Build Coastguard Worker if (handles[i] == 0)
9505*bbecb9d1SAndroid Build Coastguard Worker continue;
9506*bbecb9d1SAndroid Build Coastguard Worker target = vrend_object_lookup(ctx->sub->object_hash, handles[i], VIRGL_OBJECT_STREAMOUT_TARGET);
9507*bbecb9d1SAndroid Build Coastguard Worker if (!target) {
9508*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_HANDLE, handles[i]);
9509*bbecb9d1SAndroid Build Coastguard Worker free(obj);
9510*bbecb9d1SAndroid Build Coastguard Worker return;
9511*bbecb9d1SAndroid Build Coastguard Worker }
9512*bbecb9d1SAndroid Build Coastguard Worker vrend_so_target_reference(&obj->so_targets[i], target);
9513*bbecb9d1SAndroid Build Coastguard Worker }
9514*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_emit_streamout_targets(ctx, obj);
9515*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&obj->head, &ctx->sub->streamout_list);
9516*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->current_so = obj;
9517*bbecb9d1SAndroid Build Coastguard Worker obj->xfb_state = XFB_STATE_STARTED_NEED_BEGIN;
9518*bbecb9d1SAndroid Build Coastguard Worker } else {
9519*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback2))
9520*bbecb9d1SAndroid Build Coastguard Worker glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
9521*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->current_so = NULL;
9522*bbecb9d1SAndroid Build Coastguard Worker }
9523*bbecb9d1SAndroid Build Coastguard Worker }
9524*bbecb9d1SAndroid Build Coastguard Worker
vrend_resource_buffer_copy(UNUSED struct vrend_context * ctx,struct vrend_resource * src_res,struct vrend_resource * dst_res,uint32_t dstx,uint32_t srcx,uint32_t width)9525*bbecb9d1SAndroid Build Coastguard Worker static void vrend_resource_buffer_copy(UNUSED struct vrend_context *ctx,
9526*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res,
9527*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dst_res,
9528*bbecb9d1SAndroid Build Coastguard Worker uint32_t dstx, uint32_t srcx,
9529*bbecb9d1SAndroid Build Coastguard Worker uint32_t width)
9530*bbecb9d1SAndroid Build Coastguard Worker {
9531*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_COPY_READ_BUFFER, src_res->id);
9532*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_COPY_WRITE_BUFFER, dst_res->id);
9533*bbecb9d1SAndroid Build Coastguard Worker
9534*bbecb9d1SAndroid Build Coastguard Worker glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcx, dstx, width);
9535*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_COPY_READ_BUFFER, 0);
9536*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
9537*bbecb9d1SAndroid Build Coastguard Worker }
9538*bbecb9d1SAndroid Build Coastguard Worker
vrend_resource_copy_fallback(struct vrend_resource * src_res,struct vrend_resource * dst_res,uint32_t dst_level,uint32_t dstx,uint32_t dsty,uint32_t dstz,uint32_t src_level,const struct pipe_box * src_box)9539*bbecb9d1SAndroid Build Coastguard Worker static void vrend_resource_copy_fallback(struct vrend_resource *src_res,
9540*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dst_res,
9541*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_level,
9542*bbecb9d1SAndroid Build Coastguard Worker uint32_t dstx, uint32_t dsty,
9543*bbecb9d1SAndroid Build Coastguard Worker uint32_t dstz, uint32_t src_level,
9544*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_box *src_box)
9545*bbecb9d1SAndroid Build Coastguard Worker {
9546*bbecb9d1SAndroid Build Coastguard Worker char *tptr;
9547*bbecb9d1SAndroid Build Coastguard Worker uint32_t total_size, src_stride, dst_stride, src_layer_stride;
9548*bbecb9d1SAndroid Build Coastguard Worker GLenum glformat, gltype;
9549*bbecb9d1SAndroid Build Coastguard Worker int elsize = util_format_get_blocksize(dst_res->base.format);
9550*bbecb9d1SAndroid Build Coastguard Worker int compressed = util_format_is_compressed(dst_res->base.format);
9551*bbecb9d1SAndroid Build Coastguard Worker int cube_slice = 1;
9552*bbecb9d1SAndroid Build Coastguard Worker uint32_t slice_size, slice_offset;
9553*bbecb9d1SAndroid Build Coastguard Worker int i;
9554*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box box;
9555*bbecb9d1SAndroid Build Coastguard Worker
9556*bbecb9d1SAndroid Build Coastguard Worker if (src_res->target == GL_TEXTURE_CUBE_MAP)
9557*bbecb9d1SAndroid Build Coastguard Worker cube_slice = 6;
9558*bbecb9d1SAndroid Build Coastguard Worker
9559*bbecb9d1SAndroid Build Coastguard Worker if (src_res->base.format != dst_res->base.format) {
9560*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "copy fallback failed due to mismatched formats %d %d\n", src_res->base.format, dst_res->base.format);
9561*bbecb9d1SAndroid Build Coastguard Worker return;
9562*bbecb9d1SAndroid Build Coastguard Worker }
9563*bbecb9d1SAndroid Build Coastguard Worker
9564*bbecb9d1SAndroid Build Coastguard Worker box = *src_box;
9565*bbecb9d1SAndroid Build Coastguard Worker box.depth = vrend_get_texture_depth(src_res, src_level);
9566*bbecb9d1SAndroid Build Coastguard Worker dst_stride = util_format_get_stride(dst_res->base.format, dst_res->base.width0);
9567*bbecb9d1SAndroid Build Coastguard Worker
9568*bbecb9d1SAndroid Build Coastguard Worker /* this is ugly need to do a full GetTexImage */
9569*bbecb9d1SAndroid Build Coastguard Worker slice_size = util_format_get_nblocks(src_res->base.format, u_minify(src_res->base.width0, src_level), u_minify(src_res->base.height0, src_level)) *
9570*bbecb9d1SAndroid Build Coastguard Worker util_format_get_blocksize(src_res->base.format);
9571*bbecb9d1SAndroid Build Coastguard Worker total_size = slice_size * vrend_get_texture_depth(src_res, src_level);
9572*bbecb9d1SAndroid Build Coastguard Worker
9573*bbecb9d1SAndroid Build Coastguard Worker tptr = malloc(total_size);
9574*bbecb9d1SAndroid Build Coastguard Worker if (!tptr)
9575*bbecb9d1SAndroid Build Coastguard Worker return;
9576*bbecb9d1SAndroid Build Coastguard Worker
9577*bbecb9d1SAndroid Build Coastguard Worker glformat = tex_conv_table[src_res->base.format].glformat;
9578*bbecb9d1SAndroid Build Coastguard Worker gltype = tex_conv_table[src_res->base.format].gltype;
9579*bbecb9d1SAndroid Build Coastguard Worker
9580*bbecb9d1SAndroid Build Coastguard Worker if (compressed)
9581*bbecb9d1SAndroid Build Coastguard Worker glformat = tex_conv_table[src_res->base.format].internalformat;
9582*bbecb9d1SAndroid Build Coastguard Worker
9583*bbecb9d1SAndroid Build Coastguard Worker /* If we are on gles we need to rely on the textures backing
9584*bbecb9d1SAndroid Build Coastguard Worker * iovec to have the data we need, otherwise we can use glGetTexture
9585*bbecb9d1SAndroid Build Coastguard Worker */
9586*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
9587*bbecb9d1SAndroid Build Coastguard Worker uint64_t src_offset = 0;
9588*bbecb9d1SAndroid Build Coastguard Worker uint64_t dst_offset = 0;
9589*bbecb9d1SAndroid Build Coastguard Worker if (src_level < VR_MAX_TEXTURE_2D_LEVELS) {
9590*bbecb9d1SAndroid Build Coastguard Worker src_offset = src_res->mipmap_offsets[src_level];
9591*bbecb9d1SAndroid Build Coastguard Worker dst_offset = dst_res->mipmap_offsets[src_level];
9592*bbecb9d1SAndroid Build Coastguard Worker }
9593*bbecb9d1SAndroid Build Coastguard Worker
9594*bbecb9d1SAndroid Build Coastguard Worker src_stride = util_format_get_nblocksx(src_res->base.format,
9595*bbecb9d1SAndroid Build Coastguard Worker u_minify(src_res->base.width0, src_level)) * elsize;
9596*bbecb9d1SAndroid Build Coastguard Worker src_layer_stride = util_format_get_2d_size(src_res->base.format,
9597*bbecb9d1SAndroid Build Coastguard Worker src_stride,
9598*bbecb9d1SAndroid Build Coastguard Worker u_minify(src_res->base.height0, src_level));
9599*bbecb9d1SAndroid Build Coastguard Worker read_transfer_data(src_res->iov, src_res->num_iovs, tptr,
9600*bbecb9d1SAndroid Build Coastguard Worker src_res->base.format, src_offset,
9601*bbecb9d1SAndroid Build Coastguard Worker src_stride, src_layer_stride, &box, false);
9602*bbecb9d1SAndroid Build Coastguard Worker /* When on GLES sync the iov that backs the dst resource because
9603*bbecb9d1SAndroid Build Coastguard Worker * we might need it in a chain copy A->B, B->C */
9604*bbecb9d1SAndroid Build Coastguard Worker write_transfer_data(&dst_res->base, dst_res->iov, dst_res->num_iovs, tptr,
9605*bbecb9d1SAndroid Build Coastguard Worker dst_stride, &box, src_level, dst_offset, false);
9606*bbecb9d1SAndroid Build Coastguard Worker /* we get values from the guest as 24-bit scaled integers
9607*bbecb9d1SAndroid Build Coastguard Worker but we give them to the host GL and it interprets them
9608*bbecb9d1SAndroid Build Coastguard Worker as 32-bit scaled integers, so we need to scale them here */
9609*bbecb9d1SAndroid Build Coastguard Worker if (dst_res->base.format == VIRGL_FORMAT_Z24X8_UNORM) {
9610*bbecb9d1SAndroid Build Coastguard Worker float depth_scale = 256.0;
9611*bbecb9d1SAndroid Build Coastguard Worker vrend_scale_depth(tptr, total_size, depth_scale);
9612*bbecb9d1SAndroid Build Coastguard Worker }
9613*bbecb9d1SAndroid Build Coastguard Worker
9614*bbecb9d1SAndroid Build Coastguard Worker /* if this is a BGR* resource on GLES, the data needs to be manually swizzled to RGB* before
9615*bbecb9d1SAndroid Build Coastguard Worker * storing in a texture. Iovec data is assumed to have the original byte-order, namely BGR*,
9616*bbecb9d1SAndroid Build Coastguard Worker * and needs to be reordered when storing in the host's texture memory as RGB*.
9617*bbecb9d1SAndroid Build Coastguard Worker * On the contrary, externally-stored BGR* resources are assumed to remain in BGR* format at
9618*bbecb9d1SAndroid Build Coastguard Worker * all times.
9619*bbecb9d1SAndroid Build Coastguard Worker */
9620*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles && vrend_format_is_bgra(dst_res->base.format))
9621*bbecb9d1SAndroid Build Coastguard Worker vrend_swizzle_data_bgra(total_size, tptr);
9622*bbecb9d1SAndroid Build Coastguard Worker } else {
9623*bbecb9d1SAndroid Build Coastguard Worker uint32_t read_chunk_size;
9624*bbecb9d1SAndroid Build Coastguard Worker switch (elsize) {
9625*bbecb9d1SAndroid Build Coastguard Worker case 1:
9626*bbecb9d1SAndroid Build Coastguard Worker case 3:
9627*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 1);
9628*bbecb9d1SAndroid Build Coastguard Worker break;
9629*bbecb9d1SAndroid Build Coastguard Worker case 2:
9630*bbecb9d1SAndroid Build Coastguard Worker case 6:
9631*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 2);
9632*bbecb9d1SAndroid Build Coastguard Worker break;
9633*bbecb9d1SAndroid Build Coastguard Worker case 4:
9634*bbecb9d1SAndroid Build Coastguard Worker default:
9635*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 4);
9636*bbecb9d1SAndroid Build Coastguard Worker break;
9637*bbecb9d1SAndroid Build Coastguard Worker case 8:
9638*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 8);
9639*bbecb9d1SAndroid Build Coastguard Worker break;
9640*bbecb9d1SAndroid Build Coastguard Worker }
9641*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(src_res->target, src_res->id);
9642*bbecb9d1SAndroid Build Coastguard Worker slice_offset = 0;
9643*bbecb9d1SAndroid Build Coastguard Worker read_chunk_size = (src_res->target == GL_TEXTURE_CUBE_MAP) ? slice_size : total_size;
9644*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < cube_slice; i++) {
9645*bbecb9d1SAndroid Build Coastguard Worker GLenum ctarget = src_res->target == GL_TEXTURE_CUBE_MAP ?
9646*bbecb9d1SAndroid Build Coastguard Worker (GLenum)(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : src_res->target;
9647*bbecb9d1SAndroid Build Coastguard Worker if (compressed) {
9648*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_robustness))
9649*bbecb9d1SAndroid Build Coastguard Worker glGetnCompressedTexImageARB(ctarget, src_level, read_chunk_size, tptr + slice_offset);
9650*bbecb9d1SAndroid Build Coastguard Worker else
9651*bbecb9d1SAndroid Build Coastguard Worker glGetCompressedTexImage(ctarget, src_level, tptr + slice_offset);
9652*bbecb9d1SAndroid Build Coastguard Worker } else {
9653*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_robustness))
9654*bbecb9d1SAndroid Build Coastguard Worker glGetnTexImageARB(ctarget, src_level, glformat, gltype, read_chunk_size, tptr + slice_offset);
9655*bbecb9d1SAndroid Build Coastguard Worker else
9656*bbecb9d1SAndroid Build Coastguard Worker glGetTexImage(ctarget, src_level, glformat, gltype, tptr + slice_offset);
9657*bbecb9d1SAndroid Build Coastguard Worker }
9658*bbecb9d1SAndroid Build Coastguard Worker slice_offset += slice_size;
9659*bbecb9d1SAndroid Build Coastguard Worker }
9660*bbecb9d1SAndroid Build Coastguard Worker }
9661*bbecb9d1SAndroid Build Coastguard Worker
9662*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_PACK_ALIGNMENT, 4);
9663*bbecb9d1SAndroid Build Coastguard Worker switch (elsize) {
9664*bbecb9d1SAndroid Build Coastguard Worker case 1:
9665*bbecb9d1SAndroid Build Coastguard Worker case 3:
9666*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
9667*bbecb9d1SAndroid Build Coastguard Worker break;
9668*bbecb9d1SAndroid Build Coastguard Worker case 2:
9669*bbecb9d1SAndroid Build Coastguard Worker case 6:
9670*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
9671*bbecb9d1SAndroid Build Coastguard Worker break;
9672*bbecb9d1SAndroid Build Coastguard Worker case 4:
9673*bbecb9d1SAndroid Build Coastguard Worker default:
9674*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
9675*bbecb9d1SAndroid Build Coastguard Worker break;
9676*bbecb9d1SAndroid Build Coastguard Worker case 8:
9677*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
9678*bbecb9d1SAndroid Build Coastguard Worker break;
9679*bbecb9d1SAndroid Build Coastguard Worker }
9680*bbecb9d1SAndroid Build Coastguard Worker
9681*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(dst_res->target, dst_res->id);
9682*bbecb9d1SAndroid Build Coastguard Worker slice_offset = src_box->z * slice_size;
9683*bbecb9d1SAndroid Build Coastguard Worker cube_slice = (src_res->target == GL_TEXTURE_CUBE_MAP) ? src_box->z + src_box->depth : cube_slice;
9684*bbecb9d1SAndroid Build Coastguard Worker i = (src_res->target == GL_TEXTURE_CUBE_MAP) ? src_box->z : 0;
9685*bbecb9d1SAndroid Build Coastguard Worker for (; i < cube_slice; i++) {
9686*bbecb9d1SAndroid Build Coastguard Worker GLenum ctarget = dst_res->target == GL_TEXTURE_CUBE_MAP ?
9687*bbecb9d1SAndroid Build Coastguard Worker (GLenum)(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : dst_res->target;
9688*bbecb9d1SAndroid Build Coastguard Worker if (compressed) {
9689*bbecb9d1SAndroid Build Coastguard Worker if (ctarget == GL_TEXTURE_1D) {
9690*bbecb9d1SAndroid Build Coastguard Worker glCompressedTexSubImage1D(ctarget, dst_level, dstx,
9691*bbecb9d1SAndroid Build Coastguard Worker src_box->width,
9692*bbecb9d1SAndroid Build Coastguard Worker glformat, slice_size, tptr + slice_offset);
9693*bbecb9d1SAndroid Build Coastguard Worker } else {
9694*bbecb9d1SAndroid Build Coastguard Worker glCompressedTexSubImage2D(ctarget, dst_level, dstx, dsty,
9695*bbecb9d1SAndroid Build Coastguard Worker src_box->width, src_box->height,
9696*bbecb9d1SAndroid Build Coastguard Worker glformat, slice_size, tptr + slice_offset);
9697*bbecb9d1SAndroid Build Coastguard Worker }
9698*bbecb9d1SAndroid Build Coastguard Worker } else {
9699*bbecb9d1SAndroid Build Coastguard Worker if (ctarget == GL_TEXTURE_1D) {
9700*bbecb9d1SAndroid Build Coastguard Worker glTexSubImage1D(ctarget, dst_level, dstx, src_box->width, glformat, gltype, tptr + slice_offset);
9701*bbecb9d1SAndroid Build Coastguard Worker } else if (ctarget == GL_TEXTURE_3D ||
9702*bbecb9d1SAndroid Build Coastguard Worker ctarget == GL_TEXTURE_2D_ARRAY ||
9703*bbecb9d1SAndroid Build Coastguard Worker ctarget == GL_TEXTURE_CUBE_MAP_ARRAY) {
9704*bbecb9d1SAndroid Build Coastguard Worker glTexSubImage3D(ctarget, dst_level, dstx, dsty, dstz, src_box->width, src_box->height, src_box->depth, glformat, gltype, tptr + slice_offset);
9705*bbecb9d1SAndroid Build Coastguard Worker } else {
9706*bbecb9d1SAndroid Build Coastguard Worker glTexSubImage2D(ctarget, dst_level, dstx, dsty, src_box->width, src_box->height, glformat, gltype, tptr + slice_offset);
9707*bbecb9d1SAndroid Build Coastguard Worker }
9708*bbecb9d1SAndroid Build Coastguard Worker }
9709*bbecb9d1SAndroid Build Coastguard Worker slice_offset += slice_size;
9710*bbecb9d1SAndroid Build Coastguard Worker }
9711*bbecb9d1SAndroid Build Coastguard Worker
9712*bbecb9d1SAndroid Build Coastguard Worker glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
9713*bbecb9d1SAndroid Build Coastguard Worker free(tptr);
9714*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(GL_TEXTURE_2D, 0);
9715*bbecb9d1SAndroid Build Coastguard Worker }
9716*bbecb9d1SAndroid Build Coastguard Worker
9717*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_copy_sub_image(struct vrend_resource * src_res,struct vrend_resource * dst_res,uint32_t src_level,const struct pipe_box * src_box,uint32_t dst_level,uint32_t dstx,uint32_t dsty,uint32_t dstz)9718*bbecb9d1SAndroid Build Coastguard Worker vrend_copy_sub_image(struct vrend_resource* src_res, struct vrend_resource * dst_res,
9719*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_level, const struct pipe_box *src_box,
9720*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_level, uint32_t dstx, uint32_t dsty, uint32_t dstz)
9721*bbecb9d1SAndroid Build Coastguard Worker {
9722*bbecb9d1SAndroid Build Coastguard Worker glCopyImageSubData(src_res->id, src_res->target, src_level,
9723*bbecb9d1SAndroid Build Coastguard Worker src_box->x, src_box->y, src_box->z,
9724*bbecb9d1SAndroid Build Coastguard Worker dst_res->id, dst_res->target, dst_level,
9725*bbecb9d1SAndroid Build Coastguard Worker dstx, dsty, dstz,
9726*bbecb9d1SAndroid Build Coastguard Worker src_box->width, src_box->height,src_box->depth);
9727*bbecb9d1SAndroid Build Coastguard Worker
9728*bbecb9d1SAndroid Build Coastguard Worker // temporarily added to disable strict error checking and fix guests that are still using pre 20.x
9729*bbecb9d1SAndroid Build Coastguard Worker // mesa/virgl drivers that generate an error here during window resizes:
9730*bbecb9d1SAndroid Build Coastguard Worker // "ERROR: GL_INVALID_VALUE in glCopyImageSubData(srcX or srcWidth exceeds image bounds)"
9731*bbecb9d1SAndroid Build Coastguard Worker if (has_bit(src_res->storage_bits, VREND_STORAGE_GBM_BUFFER) &&
9732*bbecb9d1SAndroid Build Coastguard Worker glGetError() != GL_NO_ERROR) {
9733*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("glCopyImageSubData maybe fail\n");
9734*bbecb9d1SAndroid Build Coastguard Worker }
9735*bbecb9d1SAndroid Build Coastguard Worker }
9736*bbecb9d1SAndroid Build Coastguard Worker
9737*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_resource_copy_region(struct vrend_context * ctx,uint32_t dst_handle,uint32_t dst_level,uint32_t dstx,uint32_t dsty,uint32_t dstz,uint32_t src_handle,uint32_t src_level,const struct pipe_box * src_box)9738*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
9739*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle, uint32_t dst_level,
9740*bbecb9d1SAndroid Build Coastguard Worker uint32_t dstx, uint32_t dsty, uint32_t dstz,
9741*bbecb9d1SAndroid Build Coastguard Worker uint32_t src_handle, uint32_t src_level,
9742*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_box *src_box)
9743*bbecb9d1SAndroid Build Coastguard Worker {
9744*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res, *dst_res;
9745*bbecb9d1SAndroid Build Coastguard Worker GLbitfield glmask = 0;
9746*bbecb9d1SAndroid Build Coastguard Worker GLint sy1, sy2, dy1, dy2;
9747*bbecb9d1SAndroid Build Coastguard Worker unsigned int comp_flags;
9748*bbecb9d1SAndroid Build Coastguard Worker
9749*bbecb9d1SAndroid Build Coastguard Worker if (ctx->in_error)
9750*bbecb9d1SAndroid Build Coastguard Worker return;
9751*bbecb9d1SAndroid Build Coastguard Worker
9752*bbecb9d1SAndroid Build Coastguard Worker src_res = vrend_renderer_ctx_res_lookup(ctx, src_handle);
9753*bbecb9d1SAndroid Build Coastguard Worker dst_res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
9754*bbecb9d1SAndroid Build Coastguard Worker
9755*bbecb9d1SAndroid Build Coastguard Worker if (!src_res) {
9756*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, src_handle);
9757*bbecb9d1SAndroid Build Coastguard Worker return;
9758*bbecb9d1SAndroid Build Coastguard Worker }
9759*bbecb9d1SAndroid Build Coastguard Worker if (!dst_res) {
9760*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
9761*bbecb9d1SAndroid Build Coastguard Worker return;
9762*bbecb9d1SAndroid Build Coastguard Worker }
9763*bbecb9d1SAndroid Build Coastguard Worker
9764*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: From %s ms:%d [%d, %d, %d]+[%d, %d, %d] lvl:%d "
9765*bbecb9d1SAndroid Build Coastguard Worker "To %s ms:%d [%d, %d, %d]\n",
9766*bbecb9d1SAndroid Build Coastguard Worker util_format_name(src_res->base.format), src_res->base.nr_samples,
9767*bbecb9d1SAndroid Build Coastguard Worker src_box->x, src_box->y, src_box->z,
9768*bbecb9d1SAndroid Build Coastguard Worker src_box->width, src_box->height, src_box->depth,
9769*bbecb9d1SAndroid Build Coastguard Worker src_level,
9770*bbecb9d1SAndroid Build Coastguard Worker util_format_name(dst_res->base.format), dst_res->base.nr_samples,
9771*bbecb9d1SAndroid Build Coastguard Worker dstx, dsty, dstz);
9772*bbecb9d1SAndroid Build Coastguard Worker
9773*bbecb9d1SAndroid Build Coastguard Worker if (src_res->base.target == PIPE_BUFFER && dst_res->base.target == PIPE_BUFFER) {
9774*bbecb9d1SAndroid Build Coastguard Worker /* do a buffer copy */
9775*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: buffer copy %d+%d\n",
9776*bbecb9d1SAndroid Build Coastguard Worker src_box->x, src_box->width);
9777*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_buffer_copy(ctx, src_res, dst_res, dstx,
9778*bbecb9d1SAndroid Build Coastguard Worker src_box->x, src_box->width);
9779*bbecb9d1SAndroid Build Coastguard Worker return;
9780*bbecb9d1SAndroid Build Coastguard Worker }
9781*bbecb9d1SAndroid Build Coastguard Worker
9782*bbecb9d1SAndroid Build Coastguard Worker comp_flags = VREND_COPY_COMPAT_FLAG_ALLOW_COMPRESSED;
9783*bbecb9d1SAndroid Build Coastguard Worker if (src_res->egl_image)
9784*bbecb9d1SAndroid Build Coastguard Worker comp_flags |= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
9785*bbecb9d1SAndroid Build Coastguard Worker if (dst_res->egl_image)
9786*bbecb9d1SAndroid Build Coastguard Worker comp_flags ^= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
9787*bbecb9d1SAndroid Build Coastguard Worker
9788*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_copy_image) &&
9789*bbecb9d1SAndroid Build Coastguard Worker format_is_copy_compatible(src_res->base.format,dst_res->base.format, comp_flags) &&
9790*bbecb9d1SAndroid Build Coastguard Worker src_res->base.nr_samples == dst_res->base.nr_samples) {
9791*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: use glCopyImageSubData\n");
9792*bbecb9d1SAndroid Build Coastguard Worker vrend_copy_sub_image(src_res, dst_res, src_level, src_box,
9793*bbecb9d1SAndroid Build Coastguard Worker dst_level, dstx, dsty, dstz);
9794*bbecb9d1SAndroid Build Coastguard Worker return;
9795*bbecb9d1SAndroid Build Coastguard Worker }
9796*bbecb9d1SAndroid Build Coastguard Worker
9797*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_format_can_render(src_res->base.format) ||
9798*bbecb9d1SAndroid Build Coastguard Worker !vrend_format_can_render(dst_res->base.format)) {
9799*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: use resource_copy_fallback\n");
9800*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_copy_fallback(src_res, dst_res, dst_level, dstx,
9801*bbecb9d1SAndroid Build Coastguard Worker dsty, dstz, src_level, src_box);
9802*bbecb9d1SAndroid Build Coastguard Worker return;
9803*bbecb9d1SAndroid Build Coastguard Worker }
9804*bbecb9d1SAndroid Build Coastguard Worker
9805*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
9806*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: use glBlitFramebuffer\n");
9807*bbecb9d1SAndroid Build Coastguard Worker
9808*bbecb9d1SAndroid Build Coastguard Worker /* clean out fb ids */
9809*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
9810*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
9811*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture(src_res, 0, src_level, src_box->z);
9812*bbecb9d1SAndroid Build Coastguard Worker
9813*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
9814*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
9815*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
9816*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture(dst_res, 0, dst_level, dstz);
9817*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
9818*bbecb9d1SAndroid Build Coastguard Worker
9819*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
9820*bbecb9d1SAndroid Build Coastguard Worker
9821*bbecb9d1SAndroid Build Coastguard Worker glmask = GL_COLOR_BUFFER_BIT;
9822*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SCISSOR_TEST);
9823*bbecb9d1SAndroid Build Coastguard Worker
9824*bbecb9d1SAndroid Build Coastguard Worker if (!src_res->y_0_top) {
9825*bbecb9d1SAndroid Build Coastguard Worker sy1 = src_box->y;
9826*bbecb9d1SAndroid Build Coastguard Worker sy2 = src_box->y + src_box->height;
9827*bbecb9d1SAndroid Build Coastguard Worker } else {
9828*bbecb9d1SAndroid Build Coastguard Worker sy1 = src_res->base.height0 - src_box->y - src_box->height;
9829*bbecb9d1SAndroid Build Coastguard Worker sy2 = src_res->base.height0 - src_box->y;
9830*bbecb9d1SAndroid Build Coastguard Worker }
9831*bbecb9d1SAndroid Build Coastguard Worker
9832*bbecb9d1SAndroid Build Coastguard Worker if (!dst_res->y_0_top) {
9833*bbecb9d1SAndroid Build Coastguard Worker dy1 = dsty;
9834*bbecb9d1SAndroid Build Coastguard Worker dy2 = dsty + src_box->height;
9835*bbecb9d1SAndroid Build Coastguard Worker } else {
9836*bbecb9d1SAndroid Build Coastguard Worker dy1 = dst_res->base.height0 - dsty - src_box->height;
9837*bbecb9d1SAndroid Build Coastguard Worker dy2 = dst_res->base.height0 - dsty;
9838*bbecb9d1SAndroid Build Coastguard Worker }
9839*bbecb9d1SAndroid Build Coastguard Worker
9840*bbecb9d1SAndroid Build Coastguard Worker glBlitFramebuffer(src_box->x, sy1,
9841*bbecb9d1SAndroid Build Coastguard Worker src_box->x + src_box->width,
9842*bbecb9d1SAndroid Build Coastguard Worker sy2,
9843*bbecb9d1SAndroid Build Coastguard Worker dstx, dy1,
9844*bbecb9d1SAndroid Build Coastguard Worker dstx + src_box->width,
9845*bbecb9d1SAndroid Build Coastguard Worker dy2,
9846*bbecb9d1SAndroid Build Coastguard Worker glmask, GL_NEAREST);
9847*bbecb9d1SAndroid Build Coastguard Worker
9848*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
9849*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9850*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
9851*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
9852*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9853*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
9854*bbecb9d1SAndroid Build Coastguard Worker
9855*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->fb_id);
9856*bbecb9d1SAndroid Build Coastguard Worker
9857*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->rs_state.scissor)
9858*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SCISSOR_TEST);
9859*bbecb9d1SAndroid Build Coastguard Worker }
9860*bbecb9d1SAndroid Build Coastguard Worker
vrend_make_view(struct vrend_resource * res,enum virgl_formats format)9861*bbecb9d1SAndroid Build Coastguard Worker static GLuint vrend_make_view(struct vrend_resource *res, enum virgl_formats format)
9862*bbecb9d1SAndroid Build Coastguard Worker {
9863*bbecb9d1SAndroid Build Coastguard Worker GLuint view_id;
9864*bbecb9d1SAndroid Build Coastguard Worker
9865*bbecb9d1SAndroid Build Coastguard Worker GLenum tex_ifmt = tex_conv_table[res->base.format].internalformat;
9866*bbecb9d1SAndroid Build Coastguard Worker GLenum view_ifmt = tex_conv_table[format].internalformat;
9867*bbecb9d1SAndroid Build Coastguard Worker
9868*bbecb9d1SAndroid Build Coastguard Worker if (tex_ifmt == view_ifmt)
9869*bbecb9d1SAndroid Build Coastguard Worker return res->id;
9870*bbecb9d1SAndroid Build Coastguard Worker
9871*bbecb9d1SAndroid Build Coastguard Worker /* If the format doesn't support TextureStorage it is not immutable, so no TextureView*/
9872*bbecb9d1SAndroid Build Coastguard Worker if (!has_bit(res->storage_bits, VREND_STORAGE_GL_IMMUTABLE))
9873*bbecb9d1SAndroid Build Coastguard Worker return res->id;
9874*bbecb9d1SAndroid Build Coastguard Worker
9875*bbecb9d1SAndroid Build Coastguard Worker assert(vrend_resource_supports_view(res, format));
9876*bbecb9d1SAndroid Build Coastguard Worker
9877*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, NULL, "Create texture view from %s as %s\n",
9878*bbecb9d1SAndroid Build Coastguard Worker util_format_name(res->base.format),
9879*bbecb9d1SAndroid Build Coastguard Worker util_format_name(format));
9880*bbecb9d1SAndroid Build Coastguard Worker
9881*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
9882*bbecb9d1SAndroid Build Coastguard Worker assert(res->target != GL_TEXTURE_RECTANGLE_NV);
9883*bbecb9d1SAndroid Build Coastguard Worker assert(res->target != GL_TEXTURE_1D);
9884*bbecb9d1SAndroid Build Coastguard Worker assert(res->target != GL_TEXTURE_1D_ARRAY);
9885*bbecb9d1SAndroid Build Coastguard Worker }
9886*bbecb9d1SAndroid Build Coastguard Worker
9887*bbecb9d1SAndroid Build Coastguard Worker glGenTextures(1, &view_id);
9888*bbecb9d1SAndroid Build Coastguard Worker glTextureView(view_id, res->target, res->id, view_ifmt, 0, res->base.last_level + 1,
9889*bbecb9d1SAndroid Build Coastguard Worker 0, res->base.array_size);
9890*bbecb9d1SAndroid Build Coastguard Worker return view_id;
9891*bbecb9d1SAndroid Build Coastguard Worker }
9892*bbecb9d1SAndroid Build Coastguard Worker
vrend_blit_needs_redblue_swizzle(struct vrend_resource * src_res,struct vrend_resource * dst_res,const struct pipe_blit_info * info)9893*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_blit_needs_redblue_swizzle(struct vrend_resource *src_res,
9894*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dst_res,
9895*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_blit_info *info)
9896*bbecb9d1SAndroid Build Coastguard Worker {
9897*bbecb9d1SAndroid Build Coastguard Worker /* EGL-backed bgr* resources are always stored with BGR* internal format,
9898*bbecb9d1SAndroid Build Coastguard Worker * despite Virgl's use of the GL_RGBA8 internal format, so special care must
9899*bbecb9d1SAndroid Build Coastguard Worker * be taken when determining the swizzling. */
9900*bbecb9d1SAndroid Build Coastguard Worker bool src_needs_swizzle = vrend_resource_needs_redblue_swizzle(src_res, info->src.format);
9901*bbecb9d1SAndroid Build Coastguard Worker bool dst_needs_swizzle = vrend_resource_needs_redblue_swizzle(dst_res, info->dst.format);
9902*bbecb9d1SAndroid Build Coastguard Worker return src_needs_swizzle ^ dst_needs_swizzle;
9903*bbecb9d1SAndroid Build Coastguard Worker }
9904*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_prepare_blit_extra_info(struct vrend_context * ctx,struct vrend_resource * src_res,struct vrend_resource * dst_res,struct vrend_blit_info * info)9905*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_prepare_blit_extra_info(struct vrend_context *ctx,
9906*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res,
9907*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dst_res,
9908*bbecb9d1SAndroid Build Coastguard Worker struct vrend_blit_info *info)
9909*bbecb9d1SAndroid Build Coastguard Worker {
9910*bbecb9d1SAndroid Build Coastguard Worker info->can_fbo_blit = true;
9911*bbecb9d1SAndroid Build Coastguard Worker
9912*bbecb9d1SAndroid Build Coastguard Worker info->gl_filter = convert_mag_filter(info->b.filter);
9913*bbecb9d1SAndroid Build Coastguard Worker
9914*bbecb9d1SAndroid Build Coastguard Worker if (!dst_res->y_0_top) {
9915*bbecb9d1SAndroid Build Coastguard Worker info->dst_y1 = info->b.dst.box.y + info->b.dst.box.height;
9916*bbecb9d1SAndroid Build Coastguard Worker info->dst_y2 = info->b.dst.box.y;
9917*bbecb9d1SAndroid Build Coastguard Worker } else {
9918*bbecb9d1SAndroid Build Coastguard Worker info->dst_y1 = dst_res->base.height0 - info->b.dst.box.y - info->b.dst.box.height;
9919*bbecb9d1SAndroid Build Coastguard Worker info->dst_y2 = dst_res->base.height0 - info->b.dst.box.y;
9920*bbecb9d1SAndroid Build Coastguard Worker }
9921*bbecb9d1SAndroid Build Coastguard Worker
9922*bbecb9d1SAndroid Build Coastguard Worker if (!src_res->y_0_top) {
9923*bbecb9d1SAndroid Build Coastguard Worker info->src_y1 = info->b.src.box.y + info->b.src.box.height;
9924*bbecb9d1SAndroid Build Coastguard Worker info->src_y2 = info->b.src.box.y;
9925*bbecb9d1SAndroid Build Coastguard Worker } else {
9926*bbecb9d1SAndroid Build Coastguard Worker info->src_y1 = src_res->base.height0 - info->b.src.box.y - info->b.src.box.height;
9927*bbecb9d1SAndroid Build Coastguard Worker info->src_y2 = src_res->base.height0 - info->b.src.box.y;
9928*bbecb9d1SAndroid Build Coastguard Worker }
9929*bbecb9d1SAndroid Build Coastguard Worker
9930*bbecb9d1SAndroid Build Coastguard Worker if (vrend_blit_needs_swizzle(info->b.dst.format, info->b.src.format)) {
9931*bbecb9d1SAndroid Build Coastguard Worker info->needs_swizzle = true;
9932*bbecb9d1SAndroid Build Coastguard Worker info->can_fbo_blit = false;
9933*bbecb9d1SAndroid Build Coastguard Worker }
9934*bbecb9d1SAndroid Build Coastguard Worker
9935*bbecb9d1SAndroid Build Coastguard Worker if (info->needs_swizzle && vrend_get_format_table_entry(dst_res->base.format)->flags & VIRGL_TEXTURE_NEED_SWIZZLE)
9936*bbecb9d1SAndroid Build Coastguard Worker memcpy(info->swizzle, tex_conv_table[dst_res->base.format].swizzle, sizeof(info->swizzle));
9937*bbecb9d1SAndroid Build Coastguard Worker
9938*bbecb9d1SAndroid Build Coastguard Worker if (vrend_blit_needs_redblue_swizzle(src_res, dst_res, &info->b)) {
9939*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, ctx, "Applying red/blue swizzle during blit involving an external BGR* resource\n");
9940*bbecb9d1SAndroid Build Coastguard Worker uint8_t temp = info->swizzle[0];
9941*bbecb9d1SAndroid Build Coastguard Worker info->swizzle[0] = info->swizzle[2];
9942*bbecb9d1SAndroid Build Coastguard Worker info->swizzle[2] = temp;
9943*bbecb9d1SAndroid Build Coastguard Worker info->can_fbo_blit = false;
9944*bbecb9d1SAndroid Build Coastguard Worker }
9945*bbecb9d1SAndroid Build Coastguard Worker
9946*bbecb9d1SAndroid Build Coastguard Worker /* for scaled MS blits we either need extensions or hand roll */
9947*bbecb9d1SAndroid Build Coastguard Worker if (info->b.mask & PIPE_MASK_RGBA &&
9948*bbecb9d1SAndroid Build Coastguard Worker src_res->base.nr_samples > 0 &&
9949*bbecb9d1SAndroid Build Coastguard Worker src_res->base.nr_samples != dst_res->base.nr_samples &&
9950*bbecb9d1SAndroid Build Coastguard Worker (info->b.src.box.width != info->b.dst.box.width ||
9951*bbecb9d1SAndroid Build Coastguard Worker info->b.src.box.height != info->b.dst.box.height)) {
9952*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_ms_scaled_blit))
9953*bbecb9d1SAndroid Build Coastguard Worker info->gl_filter = GL_SCALED_RESOLVE_NICEST_EXT;
9954*bbecb9d1SAndroid Build Coastguard Worker else
9955*bbecb9d1SAndroid Build Coastguard Worker info->can_fbo_blit = false;
9956*bbecb9d1SAndroid Build Coastguard Worker }
9957*bbecb9d1SAndroid Build Coastguard Worker
9958*bbecb9d1SAndroid Build Coastguard Worker /* need to apply manual gamma correction in the blitter for external
9959*bbecb9d1SAndroid Build Coastguard Worker * resources that don't support colorspace conversion via views
9960*bbecb9d1SAndroid Build Coastguard Worker * (EGL-image bgr* textures). */
9961*bbecb9d1SAndroid Build Coastguard Worker if (vrend_resource_needs_srgb_decode(src_res, info->b.src.format)) {
9962*bbecb9d1SAndroid Build Coastguard Worker info->needs_manual_srgb_decode = true;
9963*bbecb9d1SAndroid Build Coastguard Worker info->can_fbo_blit = false;
9964*bbecb9d1SAndroid Build Coastguard Worker }
9965*bbecb9d1SAndroid Build Coastguard Worker if (vrend_resource_needs_srgb_encode(dst_res, info->b.dst.format)) {
9966*bbecb9d1SAndroid Build Coastguard Worker info->needs_manual_srgb_encode = true;
9967*bbecb9d1SAndroid Build Coastguard Worker info->can_fbo_blit = false;
9968*bbecb9d1SAndroid Build Coastguard Worker }
9969*bbecb9d1SAndroid Build Coastguard Worker }
9970*bbecb9d1SAndroid Build Coastguard Worker
9971*bbecb9d1SAndroid Build Coastguard Worker /* Prepare the extra blit info and return true if a FBO blit can be used. */
vrend_renderer_prepare_blit(struct vrend_context * ctx,struct vrend_resource * src_res,struct vrend_resource * dst_res,const struct vrend_blit_info * info)9972*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_renderer_prepare_blit(struct vrend_context *ctx,
9973*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res,
9974*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dst_res,
9975*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_blit_info *info)
9976*bbecb9d1SAndroid Build Coastguard Worker {
9977*bbecb9d1SAndroid Build Coastguard Worker if (!info->can_fbo_blit)
9978*bbecb9d1SAndroid Build Coastguard Worker return false;
9979*bbecb9d1SAndroid Build Coastguard Worker
9980*bbecb9d1SAndroid Build Coastguard Worker /* if we can't make FBO's use the fallback path */
9981*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_format_can_render(src_res->base.format) &&
9982*bbecb9d1SAndroid Build Coastguard Worker !vrend_format_is_ds(src_res->base.format))
9983*bbecb9d1SAndroid Build Coastguard Worker return false;
9984*bbecb9d1SAndroid Build Coastguard Worker
9985*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_format_can_render(src_res->base.format) &&
9986*bbecb9d1SAndroid Build Coastguard Worker !vrend_format_is_ds(src_res->base.format))
9987*bbecb9d1SAndroid Build Coastguard Worker return false;
9988*bbecb9d1SAndroid Build Coastguard Worker
9989*bbecb9d1SAndroid Build Coastguard Worker /* different depth formats */
9990*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_is_ds(src_res->base.format) &&
9991*bbecb9d1SAndroid Build Coastguard Worker vrend_format_is_ds(dst_res->base.format)) {
9992*bbecb9d1SAndroid Build Coastguard Worker if (src_res->base.format != dst_res->base.format) {
9993*bbecb9d1SAndroid Build Coastguard Worker if (!(src_res->base.format == PIPE_FORMAT_S8_UINT_Z24_UNORM &&
9994*bbecb9d1SAndroid Build Coastguard Worker (dst_res->base.format == PIPE_FORMAT_Z24X8_UNORM))) {
9995*bbecb9d1SAndroid Build Coastguard Worker return false;
9996*bbecb9d1SAndroid Build Coastguard Worker }
9997*bbecb9d1SAndroid Build Coastguard Worker }
9998*bbecb9d1SAndroid Build Coastguard Worker }
9999*bbecb9d1SAndroid Build Coastguard Worker /* glBlitFramebuffer - can support depth stencil with NEAREST
10000*bbecb9d1SAndroid Build Coastguard Worker which we use for mipmaps */
10001*bbecb9d1SAndroid Build Coastguard Worker if ((info->b.mask & (PIPE_MASK_Z | PIPE_MASK_S)) && info->gl_filter != GL_NEAREST)
10002*bbecb9d1SAndroid Build Coastguard Worker return false;
10003*bbecb9d1SAndroid Build Coastguard Worker
10004*bbecb9d1SAndroid Build Coastguard Worker /* since upstream mesa change
10005*bbecb9d1SAndroid Build Coastguard Worker * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5034
10006*bbecb9d1SAndroid Build Coastguard Worker * an imported RGBX texture uses GL_RGB8 as internal format while
10007*bbecb9d1SAndroid Build Coastguard Worker * in virgl_formats, we use GL_RGBA8 internal format for RGBX texutre.
10008*bbecb9d1SAndroid Build Coastguard Worker * on GLES host, glBlitFramebuffer doesn't work in such case. */
10009*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles &&
10010*bbecb9d1SAndroid Build Coastguard Worker info->b.mask & PIPE_MASK_RGBA &&
10011*bbecb9d1SAndroid Build Coastguard Worker src_res->base.format == VIRGL_FORMAT_R8G8B8X8_UNORM &&
10012*bbecb9d1SAndroid Build Coastguard Worker dst_res->base.format == VIRGL_FORMAT_R8G8B8X8_UNORM &&
10013*bbecb9d1SAndroid Build Coastguard Worker has_bit(src_res->storage_bits, VREND_STORAGE_EGL_IMAGE) !=
10014*bbecb9d1SAndroid Build Coastguard Worker has_bit(dst_res->storage_bits, VREND_STORAGE_EGL_IMAGE) &&
10015*bbecb9d1SAndroid Build Coastguard Worker (src_res->base.nr_samples || dst_res->base.nr_samples)) {
10016*bbecb9d1SAndroid Build Coastguard Worker return false;
10017*bbecb9d1SAndroid Build Coastguard Worker }
10018*bbecb9d1SAndroid Build Coastguard Worker
10019*bbecb9d1SAndroid Build Coastguard Worker /* GLES generally doesn't support blitting to a multi-sample FB, and also not
10020*bbecb9d1SAndroid Build Coastguard Worker * from a multi-sample FB where the regions are not exatly the same or the
10021*bbecb9d1SAndroid Build Coastguard Worker * source and target format are different. For
10022*bbecb9d1SAndroid Build Coastguard Worker * downsampling DS blits to zero samples we solve this by doing two blits */
10023*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles &&
10024*bbecb9d1SAndroid Build Coastguard Worker ((dst_res->base.nr_samples > 0) ||
10025*bbecb9d1SAndroid Build Coastguard Worker ((info->b.mask & PIPE_MASK_RGBA) &&
10026*bbecb9d1SAndroid Build Coastguard Worker (src_res->base.nr_samples > 0) &&
10027*bbecb9d1SAndroid Build Coastguard Worker (info->b.src.box.x != info->b.dst.box.x ||
10028*bbecb9d1SAndroid Build Coastguard Worker info->b.src.box.width != info->b.dst.box.width ||
10029*bbecb9d1SAndroid Build Coastguard Worker info->dst_y1 != info->src_y1 || info->dst_y2 != info->src_y2 ||
10030*bbecb9d1SAndroid Build Coastguard Worker info->b.src.format != info->b.dst.format))
10031*bbecb9d1SAndroid Build Coastguard Worker )) {
10032*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, ctx, "Use GL fallback because dst:ms:%d src:ms:%d (%d %d %d %d) -> (%d %d %d %d)\n",
10033*bbecb9d1SAndroid Build Coastguard Worker dst_res->base.nr_samples, src_res->base.nr_samples, info->b.src.box.x, info->b.src.box.x + info->b.src.box.width,
10034*bbecb9d1SAndroid Build Coastguard Worker info->src_y1, info->src_y2, info->b.dst.box.x, info->b.dst.box.x + info->b.dst.box.width, info->dst_y1, info->dst_y2);
10035*bbecb9d1SAndroid Build Coastguard Worker return false;
10036*bbecb9d1SAndroid Build Coastguard Worker }
10037*bbecb9d1SAndroid Build Coastguard Worker
10038*bbecb9d1SAndroid Build Coastguard Worker /* for 3D mipmapped blits - hand roll time */
10039*bbecb9d1SAndroid Build Coastguard Worker if (info->b.src.box.depth != info->b.dst.box.depth)
10040*bbecb9d1SAndroid Build Coastguard Worker return false;
10041*bbecb9d1SAndroid Build Coastguard Worker
10042*bbecb9d1SAndroid Build Coastguard Worker return true;
10043*bbecb9d1SAndroid Build Coastguard Worker }
10044*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_blit_fbo(struct vrend_context * ctx,struct vrend_resource * src_res,struct vrend_resource * dst_res,const struct vrend_blit_info * info)10045*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_blit_fbo(struct vrend_context *ctx,
10046*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res,
10047*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dst_res,
10048*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_blit_info *info)
10049*bbecb9d1SAndroid Build Coastguard Worker {
10050*bbecb9d1SAndroid Build Coastguard Worker GLbitfield glmask = 0;
10051*bbecb9d1SAndroid Build Coastguard Worker if (info->b.mask & PIPE_MASK_Z)
10052*bbecb9d1SAndroid Build Coastguard Worker glmask |= GL_DEPTH_BUFFER_BIT;
10053*bbecb9d1SAndroid Build Coastguard Worker if (info->b.mask & PIPE_MASK_S)
10054*bbecb9d1SAndroid Build Coastguard Worker glmask |= GL_STENCIL_BUFFER_BIT;
10055*bbecb9d1SAndroid Build Coastguard Worker if (info->b.mask & PIPE_MASK_RGBA)
10056*bbecb9d1SAndroid Build Coastguard Worker glmask |= GL_COLOR_BUFFER_BIT;
10057*bbecb9d1SAndroid Build Coastguard Worker
10058*bbecb9d1SAndroid Build Coastguard Worker
10059*bbecb9d1SAndroid Build Coastguard Worker if (info->b.scissor_enable) {
10060*bbecb9d1SAndroid Build Coastguard Worker glScissor(info->b.scissor.minx, info->b.scissor.miny,
10061*bbecb9d1SAndroid Build Coastguard Worker info->b.scissor.maxx - info->b.scissor.minx,
10062*bbecb9d1SAndroid Build Coastguard Worker info->b.scissor.maxy - info->b.scissor.miny);
10063*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->scissor_state_dirty = (1 << 0);
10064*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SCISSOR_TEST);
10065*bbecb9d1SAndroid Build Coastguard Worker } else
10066*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SCISSOR_TEST);
10067*bbecb9d1SAndroid Build Coastguard Worker
10068*bbecb9d1SAndroid Build Coastguard Worker /* An GLES GL_INVALID_OPERATION is generated if one wants to blit from a
10069*bbecb9d1SAndroid Build Coastguard Worker * multi-sample fbo to a non multi-sample fbo and the source and destination
10070*bbecb9d1SAndroid Build Coastguard Worker * rectangles are not defined with the same (X0, Y0) and (X1, Y1) bounds.
10071*bbecb9d1SAndroid Build Coastguard Worker *
10072*bbecb9d1SAndroid Build Coastguard Worker * Since stencil data can only be written in a fragment shader when
10073*bbecb9d1SAndroid Build Coastguard Worker * ARB_shader_stencil_export is available, the workaround using GL as given
10074*bbecb9d1SAndroid Build Coastguard Worker * above is usually not available. Instead, to work around the blit
10075*bbecb9d1SAndroid Build Coastguard Worker * limitations on GLES first copy the full frame to a non-multisample
10076*bbecb9d1SAndroid Build Coastguard Worker * surface and then copy the according area to the final target surface.
10077*bbecb9d1SAndroid Build Coastguard Worker */
10078*bbecb9d1SAndroid Build Coastguard Worker bool make_intermediate_copy = false;
10079*bbecb9d1SAndroid Build Coastguard Worker GLuint intermediate_fbo = 0;
10080*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *intermediate_copy = 0;
10081*bbecb9d1SAndroid Build Coastguard Worker
10082*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles &&
10083*bbecb9d1SAndroid Build Coastguard Worker (info->b.mask & PIPE_MASK_ZS) &&
10084*bbecb9d1SAndroid Build Coastguard Worker ((src_res->base.nr_samples > 0) &&
10085*bbecb9d1SAndroid Build Coastguard Worker (src_res->base.nr_samples != dst_res->base.nr_samples)) &&
10086*bbecb9d1SAndroid Build Coastguard Worker ((info->b.src.box.x != info->b.dst.box.x) ||
10087*bbecb9d1SAndroid Build Coastguard Worker (info->src_y1 != info->dst_y1) ||
10088*bbecb9d1SAndroid Build Coastguard Worker (info->b.src.box.width != info->b.dst.box.width) ||
10089*bbecb9d1SAndroid Build Coastguard Worker (info->src_y2 != info->dst_y2))) {
10090*bbecb9d1SAndroid Build Coastguard Worker
10091*bbecb9d1SAndroid Build Coastguard Worker make_intermediate_copy = true;
10092*bbecb9d1SAndroid Build Coastguard Worker
10093*bbecb9d1SAndroid Build Coastguard Worker /* Create a texture that is the same like the src_res texture, but
10094*bbecb9d1SAndroid Build Coastguard Worker * without multi-sample */
10095*bbecb9d1SAndroid Build Coastguard Worker struct vrend_renderer_resource_create_args args;
10096*bbecb9d1SAndroid Build Coastguard Worker memset(&args, 0, sizeof(struct vrend_renderer_resource_create_args));
10097*bbecb9d1SAndroid Build Coastguard Worker args.width = src_res->base.width0;
10098*bbecb9d1SAndroid Build Coastguard Worker args.height = src_res->base.height0;
10099*bbecb9d1SAndroid Build Coastguard Worker args.depth = src_res->base.depth0;
10100*bbecb9d1SAndroid Build Coastguard Worker args.format = info->b.src.format;
10101*bbecb9d1SAndroid Build Coastguard Worker args.target = src_res->base.target;
10102*bbecb9d1SAndroid Build Coastguard Worker args.last_level = src_res->base.last_level;
10103*bbecb9d1SAndroid Build Coastguard Worker args.array_size = src_res->base.array_size;
10104*bbecb9d1SAndroid Build Coastguard Worker intermediate_copy = (struct vrend_resource *)CALLOC_STRUCT(vrend_texture);
10105*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_resource_copy_args(&args, intermediate_copy);
10106*bbecb9d1SAndroid Build Coastguard Worker /* this is PIPE_MASK_ZS and bgra fixup is not needed */
10107*bbecb9d1SAndroid Build Coastguard Worker ASSERTED int r = vrend_resource_alloc_texture(intermediate_copy, args.format, NULL);
10108*bbecb9d1SAndroid Build Coastguard Worker assert(!r);
10109*bbecb9d1SAndroid Build Coastguard Worker
10110*bbecb9d1SAndroid Build Coastguard Worker glGenFramebuffers(1, &intermediate_fbo);
10111*bbecb9d1SAndroid Build Coastguard Worker } else {
10112*bbecb9d1SAndroid Build Coastguard Worker /* If no intermediate copy is needed make the variables point to the
10113*bbecb9d1SAndroid Build Coastguard Worker * original source to simplify the code below.
10114*bbecb9d1SAndroid Build Coastguard Worker */
10115*bbecb9d1SAndroid Build Coastguard Worker intermediate_fbo = ctx->sub->blit_fb_ids[0];
10116*bbecb9d1SAndroid Build Coastguard Worker intermediate_copy = src_res;
10117*bbecb9d1SAndroid Build Coastguard Worker }
10118*bbecb9d1SAndroid Build Coastguard Worker
10119*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
10120*bbecb9d1SAndroid Build Coastguard Worker if (info->b.mask & PIPE_MASK_RGBA)
10121*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
10122*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10123*bbecb9d1SAndroid Build Coastguard Worker else
10124*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
10125*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10126*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
10127*bbecb9d1SAndroid Build Coastguard Worker if (info->b.mask & PIPE_MASK_RGBA)
10128*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
10129*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10130*bbecb9d1SAndroid Build Coastguard Worker else if (info->b.mask & (PIPE_MASK_Z | PIPE_MASK_S))
10131*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
10132*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10133*bbecb9d1SAndroid Build Coastguard Worker
10134*bbecb9d1SAndroid Build Coastguard Worker int n_layers = info->b.src.box.depth == info->b.dst.box.depth ? info->b.dst.box.depth : 1;
10135*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < n_layers; i++) {
10136*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
10137*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture_id(src_res, info->src_view, 0, info->b.src.level, info->b.src.box.z + i, 0);
10138*bbecb9d1SAndroid Build Coastguard Worker
10139*bbecb9d1SAndroid Build Coastguard Worker if (make_intermediate_copy) {
10140*bbecb9d1SAndroid Build Coastguard Worker int level_width = u_minify(src_res->base.width0, info->b.src.level);
10141*bbecb9d1SAndroid Build Coastguard Worker int level_height = u_minify(src_res->base.width0, info->b.src.level);
10142*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, intermediate_fbo);
10143*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
10144*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10145*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture(intermediate_copy, 0, info->b.src.level, info->b.src.box.z + i);
10146*bbecb9d1SAndroid Build Coastguard Worker
10147*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_fbo);
10148*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
10149*bbecb9d1SAndroid Build Coastguard Worker glBlitFramebuffer(0, 0, level_width, level_height,
10150*bbecb9d1SAndroid Build Coastguard Worker 0, 0, level_width, level_height,
10151*bbecb9d1SAndroid Build Coastguard Worker glmask, info->gl_filter);
10152*bbecb9d1SAndroid Build Coastguard Worker }
10153*bbecb9d1SAndroid Build Coastguard Worker
10154*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
10155*bbecb9d1SAndroid Build Coastguard Worker vrend_fb_bind_texture_id(dst_res, info->dst_view, 0, info->b.dst.level, info->b.dst.box.z + i, 0);
10156*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
10157*bbecb9d1SAndroid Build Coastguard Worker
10158*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_srgb_write_control)) {
10159*bbecb9d1SAndroid Build Coastguard Worker if (util_format_is_srgb(info->b.dst.format) ||
10160*bbecb9d1SAndroid Build Coastguard Worker util_format_is_srgb(info->b.src.format))
10161*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_FRAMEBUFFER_SRGB);
10162*bbecb9d1SAndroid Build Coastguard Worker else
10163*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_FRAMEBUFFER_SRGB);
10164*bbecb9d1SAndroid Build Coastguard Worker }
10165*bbecb9d1SAndroid Build Coastguard Worker
10166*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_READ_FRAMEBUFFER, intermediate_fbo);
10167*bbecb9d1SAndroid Build Coastguard Worker
10168*bbecb9d1SAndroid Build Coastguard Worker glBlitFramebuffer(info->b.src.box.x,
10169*bbecb9d1SAndroid Build Coastguard Worker info->src_y1,
10170*bbecb9d1SAndroid Build Coastguard Worker info->b.src.box.x + info->b.src.box.width,
10171*bbecb9d1SAndroid Build Coastguard Worker info->src_y2,
10172*bbecb9d1SAndroid Build Coastguard Worker info->b.dst.box.x,
10173*bbecb9d1SAndroid Build Coastguard Worker info->dst_y1,
10174*bbecb9d1SAndroid Build Coastguard Worker info->b.dst.box.x + info->b.dst.box.width,
10175*bbecb9d1SAndroid Build Coastguard Worker info->dst_y2,
10176*bbecb9d1SAndroid Build Coastguard Worker glmask, info->gl_filter);
10177*bbecb9d1SAndroid Build Coastguard Worker }
10178*bbecb9d1SAndroid Build Coastguard Worker
10179*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[1]);
10180*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
10181*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10182*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
10183*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10184*bbecb9d1SAndroid Build Coastguard Worker
10185*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->blit_fb_ids[0]);
10186*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
10187*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10188*bbecb9d1SAndroid Build Coastguard Worker glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
10189*bbecb9d1SAndroid Build Coastguard Worker GL_TEXTURE_2D, 0, 0);
10190*bbecb9d1SAndroid Build Coastguard Worker
10191*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, ctx->sub->fb_id);
10192*bbecb9d1SAndroid Build Coastguard Worker
10193*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_srgb_write_control)) {
10194*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->framebuffer_srgb_enabled)
10195*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_FRAMEBUFFER_SRGB);
10196*bbecb9d1SAndroid Build Coastguard Worker else
10197*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_FRAMEBUFFER_SRGB);
10198*bbecb9d1SAndroid Build Coastguard Worker }
10199*bbecb9d1SAndroid Build Coastguard Worker
10200*bbecb9d1SAndroid Build Coastguard Worker if (make_intermediate_copy) {
10201*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_resource_destroy(intermediate_copy);
10202*bbecb9d1SAndroid Build Coastguard Worker glDeleteFramebuffers(1, &intermediate_fbo);
10203*bbecb9d1SAndroid Build Coastguard Worker }
10204*bbecb9d1SAndroid Build Coastguard Worker
10205*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->rs_state.scissor)
10206*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_SCISSOR_TEST);
10207*bbecb9d1SAndroid Build Coastguard Worker else
10208*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_SCISSOR_TEST);
10209*bbecb9d1SAndroid Build Coastguard Worker
10210*bbecb9d1SAndroid Build Coastguard Worker }
10211*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_blit_int(struct vrend_context * ctx,struct vrend_resource * src_res,struct vrend_resource * dst_res,const struct pipe_blit_info * info)10212*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_blit_int(struct vrend_context *ctx,
10213*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res,
10214*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *dst_res,
10215*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_blit_info *info)
10216*bbecb9d1SAndroid Build Coastguard Worker {
10217*bbecb9d1SAndroid Build Coastguard Worker struct vrend_blit_info blit_info = {
10218*bbecb9d1SAndroid Build Coastguard Worker .b = *info,
10219*bbecb9d1SAndroid Build Coastguard Worker .src_view = src_res->id,
10220*bbecb9d1SAndroid Build Coastguard Worker .dst_view = dst_res->id,
10221*bbecb9d1SAndroid Build Coastguard Worker .swizzle = {0, 1, 2, 3}
10222*bbecb9d1SAndroid Build Coastguard Worker };
10223*bbecb9d1SAndroid Build Coastguard Worker
10224*bbecb9d1SAndroid Build Coastguard Worker /* We create the texture views in this function instead of doing it in
10225*bbecb9d1SAndroid Build Coastguard Worker * vrend_renderer_prepare_blit_extra_info because we also delete them here */
10226*bbecb9d1SAndroid Build Coastguard Worker if ((src_res->base.format != info->src.format) && has_feature(feat_texture_view) &&
10227*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_supports_view(src_res, info->src.format))
10228*bbecb9d1SAndroid Build Coastguard Worker blit_info.src_view = vrend_make_view(src_res, info->src.format);
10229*bbecb9d1SAndroid Build Coastguard Worker
10230*bbecb9d1SAndroid Build Coastguard Worker if ((dst_res->base.format != info->dst.format) && has_feature(feat_texture_view) &&
10231*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_supports_view(dst_res, info->dst.format))
10232*bbecb9d1SAndroid Build Coastguard Worker blit_info.dst_view = vrend_make_view(dst_res, info->dst.format);
10233*bbecb9d1SAndroid Build Coastguard Worker
10234*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_prepare_blit_extra_info(ctx, src_res, dst_res, &blit_info);
10235*bbecb9d1SAndroid Build Coastguard Worker
10236*bbecb9d1SAndroid Build Coastguard Worker if (vrend_renderer_prepare_blit(ctx, src_res, dst_res, &blit_info)) {
10237*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, ctx, "BLIT_INT: use FBO blit\n");
10238*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_blit_fbo(ctx, src_res, dst_res, &blit_info);
10239*bbecb9d1SAndroid Build Coastguard Worker } else {
10240*bbecb9d1SAndroid Build Coastguard Worker blit_info.has_srgb_write_control = has_feature(feat_texture_srgb_decode);
10241*bbecb9d1SAndroid Build Coastguard Worker blit_info.has_texture_srgb_decode = has_feature(feat_srgb_write_control);
10242*bbecb9d1SAndroid Build Coastguard Worker
10243*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, ctx, "BLIT_INT: use GL fallback\n");
10244*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_blit_gl(ctx, src_res, dst_res, &blit_info);
10245*bbecb9d1SAndroid Build Coastguard Worker vrend_sync_make_current(ctx->sub->gl_context);
10246*bbecb9d1SAndroid Build Coastguard Worker }
10247*bbecb9d1SAndroid Build Coastguard Worker
10248*bbecb9d1SAndroid Build Coastguard Worker if (blit_info.src_view != src_res->id)
10249*bbecb9d1SAndroid Build Coastguard Worker glDeleteTextures(1, &blit_info.src_view);
10250*bbecb9d1SAndroid Build Coastguard Worker
10251*bbecb9d1SAndroid Build Coastguard Worker if (blit_info.dst_view != dst_res->id)
10252*bbecb9d1SAndroid Build Coastguard Worker glDeleteTextures(1, &blit_info.dst_view);
10253*bbecb9d1SAndroid Build Coastguard Worker }
10254*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_blit(struct vrend_context * ctx,uint32_t dst_handle,uint32_t src_handle,const struct pipe_blit_info * info)10255*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_blit(struct vrend_context *ctx,
10256*bbecb9d1SAndroid Build Coastguard Worker uint32_t dst_handle, uint32_t src_handle,
10257*bbecb9d1SAndroid Build Coastguard Worker const struct pipe_blit_info *info)
10258*bbecb9d1SAndroid Build Coastguard Worker {
10259*bbecb9d1SAndroid Build Coastguard Worker unsigned int comp_flags = 0;
10260*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *src_res, *dst_res;
10261*bbecb9d1SAndroid Build Coastguard Worker int src_width, src_height, dst_width, dst_height;
10262*bbecb9d1SAndroid Build Coastguard Worker src_res = vrend_renderer_ctx_res_lookup(ctx, src_handle);
10263*bbecb9d1SAndroid Build Coastguard Worker dst_res = vrend_renderer_ctx_res_lookup(ctx, dst_handle);
10264*bbecb9d1SAndroid Build Coastguard Worker
10265*bbecb9d1SAndroid Build Coastguard Worker if (!src_res) {
10266*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, src_handle);
10267*bbecb9d1SAndroid Build Coastguard Worker return;
10268*bbecb9d1SAndroid Build Coastguard Worker }
10269*bbecb9d1SAndroid Build Coastguard Worker if (!dst_res) {
10270*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, dst_handle);
10271*bbecb9d1SAndroid Build Coastguard Worker return;
10272*bbecb9d1SAndroid Build Coastguard Worker }
10273*bbecb9d1SAndroid Build Coastguard Worker
10274*bbecb9d1SAndroid Build Coastguard Worker if (ctx->in_error)
10275*bbecb9d1SAndroid Build Coastguard Worker return;
10276*bbecb9d1SAndroid Build Coastguard Worker
10277*bbecb9d1SAndroid Build Coastguard Worker if (!info->src.format || info->src.format >= VIRGL_FORMAT_MAX) {
10278*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_FORMAT, info->src.format);
10279*bbecb9d1SAndroid Build Coastguard Worker return;
10280*bbecb9d1SAndroid Build Coastguard Worker }
10281*bbecb9d1SAndroid Build Coastguard Worker
10282*bbecb9d1SAndroid Build Coastguard Worker if (!info->dst.format || info->dst.format >= VIRGL_FORMAT_MAX) {
10283*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_FORMAT, info->dst.format);
10284*bbecb9d1SAndroid Build Coastguard Worker return;
10285*bbecb9d1SAndroid Build Coastguard Worker }
10286*bbecb9d1SAndroid Build Coastguard Worker
10287*bbecb9d1SAndroid Build Coastguard Worker if (info->render_condition_enable == false)
10288*bbecb9d1SAndroid Build Coastguard Worker vrend_pause_render_condition(ctx, true);
10289*bbecb9d1SAndroid Build Coastguard Worker
10290*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, ctx, "BLIT: rc:%d scissor:%d filter:%d alpha:%d mask:0x%x\n"
10291*bbecb9d1SAndroid Build Coastguard Worker " From %s(%s) ms:%d egl:%d gbm:%d [%d, %d, %d]+[%d, %d, %d] lvl:%d\n"
10292*bbecb9d1SAndroid Build Coastguard Worker " To %s(%s) ms:%d egl:%d gbm:%d [%d, %d, %d]+[%d, %d, %d] lvl:%d\n",
10293*bbecb9d1SAndroid Build Coastguard Worker info->render_condition_enable, info->scissor_enable,
10294*bbecb9d1SAndroid Build Coastguard Worker info->filter, info->alpha_blend, info->mask,
10295*bbecb9d1SAndroid Build Coastguard Worker util_format_name(src_res->base.format),
10296*bbecb9d1SAndroid Build Coastguard Worker util_format_name(info->src.format),
10297*bbecb9d1SAndroid Build Coastguard Worker src_res->base.nr_samples,
10298*bbecb9d1SAndroid Build Coastguard Worker has_bit(src_res->storage_bits, VREND_STORAGE_EGL_IMAGE),
10299*bbecb9d1SAndroid Build Coastguard Worker has_bit(src_res->storage_bits, VREND_STORAGE_GBM_BUFFER),
10300*bbecb9d1SAndroid Build Coastguard Worker info->src.box.x, info->src.box.y, info->src.box.z,
10301*bbecb9d1SAndroid Build Coastguard Worker info->src.box.width, info->src.box.height, info->src.box.depth,
10302*bbecb9d1SAndroid Build Coastguard Worker info->src.level,
10303*bbecb9d1SAndroid Build Coastguard Worker util_format_name(dst_res->base.format),
10304*bbecb9d1SAndroid Build Coastguard Worker util_format_name(info->dst.format),
10305*bbecb9d1SAndroid Build Coastguard Worker dst_res->base.nr_samples,
10306*bbecb9d1SAndroid Build Coastguard Worker has_bit(dst_res->storage_bits, VREND_STORAGE_EGL_IMAGE),
10307*bbecb9d1SAndroid Build Coastguard Worker has_bit(dst_res->storage_bits, VREND_STORAGE_GBM_BUFFER),
10308*bbecb9d1SAndroid Build Coastguard Worker info->dst.box.x, info->dst.box.y, info->dst.box.z,
10309*bbecb9d1SAndroid Build Coastguard Worker info->dst.box.width, info->dst.box.height, info->dst.box.depth,
10310*bbecb9d1SAndroid Build Coastguard Worker info->dst.level);
10311*bbecb9d1SAndroid Build Coastguard Worker
10312*bbecb9d1SAndroid Build Coastguard Worker if (src_res->egl_image)
10313*bbecb9d1SAndroid Build Coastguard Worker comp_flags |= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
10314*bbecb9d1SAndroid Build Coastguard Worker if (dst_res->egl_image)
10315*bbecb9d1SAndroid Build Coastguard Worker comp_flags ^= VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE;
10316*bbecb9d1SAndroid Build Coastguard Worker
10317*bbecb9d1SAndroid Build Coastguard Worker /* resources that don't support texture views but require colorspace conversion
10318*bbecb9d1SAndroid Build Coastguard Worker * must have it applied manually in a shader, i.e. require following the
10319*bbecb9d1SAndroid Build Coastguard Worker * vrend_renderer_blit_int() path. */
10320*bbecb9d1SAndroid Build Coastguard Worker bool eglimage_copy_compatible =
10321*bbecb9d1SAndroid Build Coastguard Worker !(vrend_resource_needs_srgb_decode(src_res, info->src.format) ||
10322*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_needs_srgb_encode(dst_res, info->dst.format));
10323*bbecb9d1SAndroid Build Coastguard Worker
10324*bbecb9d1SAndroid Build Coastguard Worker src_width = u_minify(src_res->base.width0, info->src.level);
10325*bbecb9d1SAndroid Build Coastguard Worker src_height = u_minify(src_res->base.height0, info->src.level);
10326*bbecb9d1SAndroid Build Coastguard Worker dst_width = u_minify(dst_res->base.width0, info->dst.level);
10327*bbecb9d1SAndroid Build Coastguard Worker dst_height = u_minify(dst_res->base.height0, info->dst.level);
10328*bbecb9d1SAndroid Build Coastguard Worker
10329*bbecb9d1SAndroid Build Coastguard Worker /* The Gallium blit function can be called for a general blit that may
10330*bbecb9d1SAndroid Build Coastguard Worker * scale, convert the data, and apply some rander states, or it is called via
10331*bbecb9d1SAndroid Build Coastguard Worker * glCopyImageSubData. If the src or the dst image are equal, or the two
10332*bbecb9d1SAndroid Build Coastguard Worker * images formats are the same, then Galliums such calles are redirected
10333*bbecb9d1SAndroid Build Coastguard Worker * to resource_copy_region, in this case and if no render states etx need
10334*bbecb9d1SAndroid Build Coastguard Worker * to be applied, forward the call to glCopyImageSubData, otherwise do a
10335*bbecb9d1SAndroid Build Coastguard Worker * normal blit. */
10336*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_copy_image) &&
10337*bbecb9d1SAndroid Build Coastguard Worker (!info->render_condition_enable || !ctx->sub->cond_render_gl_mode) &&
10338*bbecb9d1SAndroid Build Coastguard Worker format_is_copy_compatible(info->src.format,info->dst.format, comp_flags) &&
10339*bbecb9d1SAndroid Build Coastguard Worker eglimage_copy_compatible &&
10340*bbecb9d1SAndroid Build Coastguard Worker !info->scissor_enable && (info->filter == PIPE_TEX_FILTER_NEAREST) &&
10341*bbecb9d1SAndroid Build Coastguard Worker !info->alpha_blend && (info->mask == PIPE_MASK_RGBA) &&
10342*bbecb9d1SAndroid Build Coastguard Worker src_res->base.nr_samples == dst_res->base.nr_samples &&
10343*bbecb9d1SAndroid Build Coastguard Worker info->src.box.x + info->src.box.width <= src_width &&
10344*bbecb9d1SAndroid Build Coastguard Worker info->dst.box.x + info->dst.box.width <= dst_width &&
10345*bbecb9d1SAndroid Build Coastguard Worker info->src.box.y + info->src.box.height <= src_height &&
10346*bbecb9d1SAndroid Build Coastguard Worker info->dst.box.y + info->dst.box.height <= dst_height &&
10347*bbecb9d1SAndroid Build Coastguard Worker info->src.box.width == info->dst.box.width &&
10348*bbecb9d1SAndroid Build Coastguard Worker info->src.box.height == info->dst.box.height &&
10349*bbecb9d1SAndroid Build Coastguard Worker info->src.box.depth == info->dst.box.depth) {
10350*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, ctx, " Use glCopyImageSubData\n");
10351*bbecb9d1SAndroid Build Coastguard Worker vrend_copy_sub_image(src_res, dst_res, info->src.level, &info->src.box,
10352*bbecb9d1SAndroid Build Coastguard Worker info->dst.level, info->dst.box.x, info->dst.box.y,
10353*bbecb9d1SAndroid Build Coastguard Worker info->dst.box.z);
10354*bbecb9d1SAndroid Build Coastguard Worker } else {
10355*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_blit, ctx, " Use blit_int\n");
10356*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_blit_int(ctx, src_res, dst_res, info);
10357*bbecb9d1SAndroid Build Coastguard Worker }
10358*bbecb9d1SAndroid Build Coastguard Worker
10359*bbecb9d1SAndroid Build Coastguard Worker if (info->render_condition_enable == false)
10360*bbecb9d1SAndroid Build Coastguard Worker vrend_pause_render_condition(ctx, false);
10361*bbecb9d1SAndroid Build Coastguard Worker }
10362*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_set_fence_retire(struct vrend_context * ctx,vrend_context_fence_retire retire,void * retire_data)10363*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_set_fence_retire(struct vrend_context *ctx,
10364*bbecb9d1SAndroid Build Coastguard Worker vrend_context_fence_retire retire,
10365*bbecb9d1SAndroid Build Coastguard Worker void *retire_data)
10366*bbecb9d1SAndroid Build Coastguard Worker {
10367*bbecb9d1SAndroid Build Coastguard Worker assert(ctx->ctx_id);
10368*bbecb9d1SAndroid Build Coastguard Worker ctx->fence_retire = retire;
10369*bbecb9d1SAndroid Build Coastguard Worker ctx->fence_retire_data = retire_data;
10370*bbecb9d1SAndroid Build Coastguard Worker }
10371*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_create_fence(struct vrend_context * ctx,uint32_t flags,uint64_t fence_id)10372*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_create_fence(struct vrend_context *ctx,
10373*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags,
10374*bbecb9d1SAndroid Build Coastguard Worker uint64_t fence_id)
10375*bbecb9d1SAndroid Build Coastguard Worker {
10376*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *fence;
10377*bbecb9d1SAndroid Build Coastguard Worker
10378*bbecb9d1SAndroid Build Coastguard Worker if (!ctx)
10379*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
10380*bbecb9d1SAndroid Build Coastguard Worker
10381*bbecb9d1SAndroid Build Coastguard Worker fence = malloc(sizeof(struct vrend_fence));
10382*bbecb9d1SAndroid Build Coastguard Worker if (!fence)
10383*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
10384*bbecb9d1SAndroid Build Coastguard Worker
10385*bbecb9d1SAndroid Build Coastguard Worker fence->ctx = ctx;
10386*bbecb9d1SAndroid Build Coastguard Worker fence->flags = flags;
10387*bbecb9d1SAndroid Build Coastguard Worker fence->fence_id = fence_id;
10388*bbecb9d1SAndroid Build Coastguard Worker
10389*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
10390*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_egl_fence) {
10391*bbecb9d1SAndroid Build Coastguard Worker fence->eglsyncobj = virgl_egl_fence_create(egl);
10392*bbecb9d1SAndroid Build Coastguard Worker } else
10393*bbecb9d1SAndroid Build Coastguard Worker #endif
10394*bbecb9d1SAndroid Build Coastguard Worker {
10395*bbecb9d1SAndroid Build Coastguard Worker fence->glsyncobj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
10396*bbecb9d1SAndroid Build Coastguard Worker }
10397*bbecb9d1SAndroid Build Coastguard Worker glFlush();
10398*bbecb9d1SAndroid Build Coastguard Worker
10399*bbecb9d1SAndroid Build Coastguard Worker if (fence->glsyncobj == NULL)
10400*bbecb9d1SAndroid Build Coastguard Worker goto fail;
10401*bbecb9d1SAndroid Build Coastguard Worker
10402*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.sync_thread) {
10403*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
10404*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&fence->fences, &vrend_state.fence_wait_list);
10405*bbecb9d1SAndroid Build Coastguard Worker cnd_signal(&vrend_state.fence_cond);
10406*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
10407*bbecb9d1SAndroid Build Coastguard Worker } else
10408*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&fence->fences, &vrend_state.fence_list);
10409*bbecb9d1SAndroid Build Coastguard Worker return 0;
10410*bbecb9d1SAndroid Build Coastguard Worker
10411*bbecb9d1SAndroid Build Coastguard Worker fail:
10412*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "failed to create fence sync object\n");
10413*bbecb9d1SAndroid Build Coastguard Worker free(fence);
10414*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
10415*bbecb9d1SAndroid Build Coastguard Worker }
10416*bbecb9d1SAndroid Build Coastguard Worker
need_fence_retire_signal_locked(struct vrend_fence * fence,const struct list_head * signaled_list)10417*bbecb9d1SAndroid Build Coastguard Worker static bool need_fence_retire_signal_locked(struct vrend_fence *fence,
10418*bbecb9d1SAndroid Build Coastguard Worker const struct list_head *signaled_list)
10419*bbecb9d1SAndroid Build Coastguard Worker {
10420*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *next;
10421*bbecb9d1SAndroid Build Coastguard Worker
10422*bbecb9d1SAndroid Build Coastguard Worker /* last fence */
10423*bbecb9d1SAndroid Build Coastguard Worker if (fence->fences.next == signaled_list)
10424*bbecb9d1SAndroid Build Coastguard Worker return true;
10425*bbecb9d1SAndroid Build Coastguard Worker
10426*bbecb9d1SAndroid Build Coastguard Worker /* next fence belongs to a different context */
10427*bbecb9d1SAndroid Build Coastguard Worker next = LIST_ENTRY(struct vrend_fence, fence->fences.next, fences);
10428*bbecb9d1SAndroid Build Coastguard Worker if (next->ctx != fence->ctx)
10429*bbecb9d1SAndroid Build Coastguard Worker return true;
10430*bbecb9d1SAndroid Build Coastguard Worker
10431*bbecb9d1SAndroid Build Coastguard Worker /* not mergeable */
10432*bbecb9d1SAndroid Build Coastguard Worker if (!(fence->flags & VIRGL_RENDERER_FENCE_FLAG_MERGEABLE))
10433*bbecb9d1SAndroid Build Coastguard Worker return true;
10434*bbecb9d1SAndroid Build Coastguard Worker
10435*bbecb9d1SAndroid Build Coastguard Worker return false;
10436*bbecb9d1SAndroid Build Coastguard Worker }
10437*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_check_fences(void)10438*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_check_fences(void)
10439*bbecb9d1SAndroid Build Coastguard Worker {
10440*bbecb9d1SAndroid Build Coastguard Worker struct list_head retired_fences;
10441*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *fence, *stor;
10442*bbecb9d1SAndroid Build Coastguard Worker
10443*bbecb9d1SAndroid Build Coastguard Worker assert(!vrend_state.use_async_fence_cb);
10444*bbecb9d1SAndroid Build Coastguard Worker
10445*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&retired_fences);
10446*bbecb9d1SAndroid Build Coastguard Worker
10447*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.sync_thread) {
10448*bbecb9d1SAndroid Build Coastguard Worker flush_eventfd(vrend_state.eventfd);
10449*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
10450*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_list, fences) {
10451*bbecb9d1SAndroid Build Coastguard Worker /* vrend_free_fences_for_context might have marked the fence invalid
10452*bbecb9d1SAndroid Build Coastguard Worker * by setting fence->ctx to NULL
10453*bbecb9d1SAndroid Build Coastguard Worker */
10454*bbecb9d1SAndroid Build Coastguard Worker if (!fence->ctx) {
10455*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
10456*bbecb9d1SAndroid Build Coastguard Worker continue;
10457*bbecb9d1SAndroid Build Coastguard Worker }
10458*bbecb9d1SAndroid Build Coastguard Worker
10459*bbecb9d1SAndroid Build Coastguard Worker if (need_fence_retire_signal_locked(fence, &vrend_state.fence_list)) {
10460*bbecb9d1SAndroid Build Coastguard Worker list_del(&fence->fences);
10461*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&fence->fences, &retired_fences);
10462*bbecb9d1SAndroid Build Coastguard Worker } else {
10463*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
10464*bbecb9d1SAndroid Build Coastguard Worker }
10465*bbecb9d1SAndroid Build Coastguard Worker }
10466*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
10467*bbecb9d1SAndroid Build Coastguard Worker } else {
10468*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_force_ctx_0();
10469*bbecb9d1SAndroid Build Coastguard Worker
10470*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &vrend_state.fence_list, fences) {
10471*bbecb9d1SAndroid Build Coastguard Worker if (do_wait(fence, /* can_block */ false)) {
10472*bbecb9d1SAndroid Build Coastguard Worker list_del(&fence->fences);
10473*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&fence->fences, &retired_fences);
10474*bbecb9d1SAndroid Build Coastguard Worker } else {
10475*bbecb9d1SAndroid Build Coastguard Worker /* don't bother checking any subsequent ones */
10476*bbecb9d1SAndroid Build Coastguard Worker break;
10477*bbecb9d1SAndroid Build Coastguard Worker }
10478*bbecb9d1SAndroid Build Coastguard Worker }
10479*bbecb9d1SAndroid Build Coastguard Worker
10480*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &retired_fences, fences) {
10481*bbecb9d1SAndroid Build Coastguard Worker if (!need_fence_retire_signal_locked(fence, &retired_fences))
10482*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
10483*bbecb9d1SAndroid Build Coastguard Worker }
10484*bbecb9d1SAndroid Build Coastguard Worker }
10485*bbecb9d1SAndroid Build Coastguard Worker
10486*bbecb9d1SAndroid Build Coastguard Worker if (LIST_IS_EMPTY(&retired_fences))
10487*bbecb9d1SAndroid Build Coastguard Worker return;
10488*bbecb9d1SAndroid Build Coastguard Worker
10489*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_check_queries();
10490*bbecb9d1SAndroid Build Coastguard Worker
10491*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(fence, stor, &retired_fences, fences) {
10492*bbecb9d1SAndroid Build Coastguard Worker struct vrend_context *ctx = fence->ctx;
10493*bbecb9d1SAndroid Build Coastguard Worker ctx->fence_retire(fence->fence_id, ctx->fence_retire_data);
10494*bbecb9d1SAndroid Build Coastguard Worker
10495*bbecb9d1SAndroid Build Coastguard Worker free_fence_locked(fence);
10496*bbecb9d1SAndroid Build Coastguard Worker }
10497*bbecb9d1SAndroid Build Coastguard Worker }
10498*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_one_query_result(GLuint query_id,bool use_64,uint64_t * result)10499*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_get_one_query_result(GLuint query_id, bool use_64, uint64_t *result)
10500*bbecb9d1SAndroid Build Coastguard Worker {
10501*bbecb9d1SAndroid Build Coastguard Worker GLuint ready;
10502*bbecb9d1SAndroid Build Coastguard Worker GLuint passed;
10503*bbecb9d1SAndroid Build Coastguard Worker GLuint64 pass64;
10504*bbecb9d1SAndroid Build Coastguard Worker
10505*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectuiv(query_id, GL_QUERY_RESULT_AVAILABLE_ARB, &ready);
10506*bbecb9d1SAndroid Build Coastguard Worker
10507*bbecb9d1SAndroid Build Coastguard Worker if (!ready)
10508*bbecb9d1SAndroid Build Coastguard Worker return false;
10509*bbecb9d1SAndroid Build Coastguard Worker
10510*bbecb9d1SAndroid Build Coastguard Worker if (use_64) {
10511*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectui64v(query_id, GL_QUERY_RESULT_ARB, &pass64);
10512*bbecb9d1SAndroid Build Coastguard Worker *result = pass64;
10513*bbecb9d1SAndroid Build Coastguard Worker } else {
10514*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectuiv(query_id, GL_QUERY_RESULT_ARB, &passed);
10515*bbecb9d1SAndroid Build Coastguard Worker *result = passed;
10516*bbecb9d1SAndroid Build Coastguard Worker }
10517*bbecb9d1SAndroid Build Coastguard Worker return true;
10518*bbecb9d1SAndroid Build Coastguard Worker }
10519*bbecb9d1SAndroid Build Coastguard Worker
10520*bbecb9d1SAndroid Build Coastguard Worker static inline void
vrend_update_oq_samples_multiplier(struct vrend_context * ctx)10521*bbecb9d1SAndroid Build Coastguard Worker vrend_update_oq_samples_multiplier(struct vrend_context *ctx)
10522*bbecb9d1SAndroid Build Coastguard Worker {
10523*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->sub->fake_occlusion_query_samples_passed_multiplier) {
10524*bbecb9d1SAndroid Build Coastguard Worker uint32_t multiplier = 0;
10525*bbecb9d1SAndroid Build Coastguard Worker bool tweaked = vrend_get_tweak_is_active_with_params(vrend_get_context_tweaks(ctx),
10526*bbecb9d1SAndroid Build Coastguard Worker virgl_tweak_gles_tf3_samples_passes_multiplier, &multiplier);
10527*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->fake_occlusion_query_samples_passed_multiplier =
10528*bbecb9d1SAndroid Build Coastguard Worker tweaked ? multiplier: fake_occlusion_query_samples_passed_default;
10529*bbecb9d1SAndroid Build Coastguard Worker }
10530*bbecb9d1SAndroid Build Coastguard Worker }
10531*bbecb9d1SAndroid Build Coastguard Worker
10532*bbecb9d1SAndroid Build Coastguard Worker
vrend_check_query(struct vrend_query * query)10533*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_check_query(struct vrend_query *query)
10534*bbecb9d1SAndroid Build Coastguard Worker {
10535*bbecb9d1SAndroid Build Coastguard Worker struct virgl_host_query_state state;
10536*bbecb9d1SAndroid Build Coastguard Worker bool ret;
10537*bbecb9d1SAndroid Build Coastguard Worker
10538*bbecb9d1SAndroid Build Coastguard Worker state.result_size = vrend_is_timer_query(query->gltype) ? 8 : 4;
10539*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_get_one_query_result(query->id, state.result_size == 8,
10540*bbecb9d1SAndroid Build Coastguard Worker &state.result);
10541*bbecb9d1SAndroid Build Coastguard Worker if (ret == false)
10542*bbecb9d1SAndroid Build Coastguard Worker return false;
10543*bbecb9d1SAndroid Build Coastguard Worker
10544*bbecb9d1SAndroid Build Coastguard Worker /* We got a boolean, but the client wanted the actual number of samples
10545*bbecb9d1SAndroid Build Coastguard Worker * blow the number up so that the client doesn't think it was just one pixel
10546*bbecb9d1SAndroid Build Coastguard Worker * and discards an object that might be bigger */
10547*bbecb9d1SAndroid Build Coastguard Worker if (query->fake_samples_passed) {
10548*bbecb9d1SAndroid Build Coastguard Worker vrend_update_oq_samples_multiplier(query->ctx);
10549*bbecb9d1SAndroid Build Coastguard Worker state.result *= query->ctx->sub->fake_occlusion_query_samples_passed_multiplier;
10550*bbecb9d1SAndroid Build Coastguard Worker }
10551*bbecb9d1SAndroid Build Coastguard Worker
10552*bbecb9d1SAndroid Build Coastguard Worker state.query_state = VIRGL_QUERY_STATE_DONE;
10553*bbecb9d1SAndroid Build Coastguard Worker
10554*bbecb9d1SAndroid Build Coastguard Worker if (query->res->iov) {
10555*bbecb9d1SAndroid Build Coastguard Worker vrend_write_to_iovec(query->res->iov, query->res->num_iovs, 0,
10556*bbecb9d1SAndroid Build Coastguard Worker (const void *) &state, sizeof(state));
10557*bbecb9d1SAndroid Build Coastguard Worker } else {
10558*bbecb9d1SAndroid Build Coastguard Worker *((struct virgl_host_query_state *) query->res->ptr) = state;
10559*bbecb9d1SAndroid Build Coastguard Worker }
10560*bbecb9d1SAndroid Build Coastguard Worker
10561*bbecb9d1SAndroid Build Coastguard Worker return true;
10562*bbecb9d1SAndroid Build Coastguard Worker }
10563*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_find_sub_ctx(struct vrend_context * ctx,int sub_ctx_id)10564*bbecb9d1SAndroid Build Coastguard Worker static struct vrend_sub_context *vrend_renderer_find_sub_ctx(struct vrend_context *ctx,
10565*bbecb9d1SAndroid Build Coastguard Worker int sub_ctx_id)
10566*bbecb9d1SAndroid Build Coastguard Worker {
10567*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub;
10568*bbecb9d1SAndroid Build Coastguard Worker
10569*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub && ctx->sub->sub_ctx_id == sub_ctx_id)
10570*bbecb9d1SAndroid Build Coastguard Worker return ctx->sub;
10571*bbecb9d1SAndroid Build Coastguard Worker
10572*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(sub, &ctx->sub_ctxs, head) {
10573*bbecb9d1SAndroid Build Coastguard Worker if (sub->sub_ctx_id == sub_ctx_id)
10574*bbecb9d1SAndroid Build Coastguard Worker return sub;
10575*bbecb9d1SAndroid Build Coastguard Worker }
10576*bbecb9d1SAndroid Build Coastguard Worker
10577*bbecb9d1SAndroid Build Coastguard Worker return NULL;
10578*bbecb9d1SAndroid Build Coastguard Worker }
10579*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_switch_context_with_sub(struct vrend_context * ctx,int sub_ctx_id)10580*bbecb9d1SAndroid Build Coastguard Worker static bool vrend_hw_switch_context_with_sub(struct vrend_context *ctx, int sub_ctx_id)
10581*bbecb9d1SAndroid Build Coastguard Worker {
10582*bbecb9d1SAndroid Build Coastguard Worker if (!ctx)
10583*bbecb9d1SAndroid Build Coastguard Worker return false;
10584*bbecb9d1SAndroid Build Coastguard Worker
10585*bbecb9d1SAndroid Build Coastguard Worker if (ctx == vrend_state.current_ctx && sub_ctx_id == ctx->sub->sub_ctx_id &&
10586*bbecb9d1SAndroid Build Coastguard Worker ctx->ctx_switch_pending == false) {
10587*bbecb9d1SAndroid Build Coastguard Worker return true;
10588*bbecb9d1SAndroid Build Coastguard Worker }
10589*bbecb9d1SAndroid Build Coastguard Worker
10590*bbecb9d1SAndroid Build Coastguard Worker if (ctx->ctx_id != 0 && ctx->in_error)
10591*bbecb9d1SAndroid Build Coastguard Worker return false;
10592*bbecb9d1SAndroid Build Coastguard Worker
10593*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub = vrend_renderer_find_sub_ctx(ctx, sub_ctx_id);
10594*bbecb9d1SAndroid Build Coastguard Worker if (!sub)
10595*bbecb9d1SAndroid Build Coastguard Worker return false;
10596*bbecb9d1SAndroid Build Coastguard Worker
10597*bbecb9d1SAndroid Build Coastguard Worker /* force the gl context switch to occur */
10598*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub != sub) {
10599*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_hw_ctx = NULL;
10600*bbecb9d1SAndroid Build Coastguard Worker ctx->sub = sub;
10601*bbecb9d1SAndroid Build Coastguard Worker }
10602*bbecb9d1SAndroid Build Coastguard Worker
10603*bbecb9d1SAndroid Build Coastguard Worker ctx->ctx_switch_pending = true;
10604*bbecb9d1SAndroid Build Coastguard Worker vrend_finish_context_switch(ctx);
10605*bbecb9d1SAndroid Build Coastguard Worker
10606*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_ctx = ctx;
10607*bbecb9d1SAndroid Build Coastguard Worker return true;
10608*bbecb9d1SAndroid Build Coastguard Worker }
10609*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_check_queries(void)10610*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_check_queries(void)
10611*bbecb9d1SAndroid Build Coastguard Worker {
10612*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *query, *stor;
10613*bbecb9d1SAndroid Build Coastguard Worker
10614*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(query, stor, &vrend_state.waiting_query_list, waiting_queries) {
10615*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_hw_switch_context_with_sub(query->ctx, query->sub_ctx_id)) {
10616*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("failed to switch to context (%d) with sub (%d) for query %u\n",
10617*bbecb9d1SAndroid Build Coastguard Worker query->ctx->ctx_id, query->sub_ctx_id, query->id);
10618*bbecb9d1SAndroid Build Coastguard Worker }
10619*bbecb9d1SAndroid Build Coastguard Worker else if (!vrend_check_query(query)) {
10620*bbecb9d1SAndroid Build Coastguard Worker continue;
10621*bbecb9d1SAndroid Build Coastguard Worker }
10622*bbecb9d1SAndroid Build Coastguard Worker
10623*bbecb9d1SAndroid Build Coastguard Worker list_delinit(&query->waiting_queries);
10624*bbecb9d1SAndroid Build Coastguard Worker }
10625*bbecb9d1SAndroid Build Coastguard Worker
10626*bbecb9d1SAndroid Build Coastguard Worker atomic_store(&vrend_state.has_waiting_queries,
10627*bbecb9d1SAndroid Build Coastguard Worker !LIST_IS_EMPTY(&vrend_state.waiting_query_list));
10628*bbecb9d1SAndroid Build Coastguard Worker }
10629*bbecb9d1SAndroid Build Coastguard Worker
vrend_hw_switch_context(struct vrend_context * ctx,bool now)10630*bbecb9d1SAndroid Build Coastguard Worker bool vrend_hw_switch_context(struct vrend_context *ctx, bool now)
10631*bbecb9d1SAndroid Build Coastguard Worker {
10632*bbecb9d1SAndroid Build Coastguard Worker if (!ctx)
10633*bbecb9d1SAndroid Build Coastguard Worker return false;
10634*bbecb9d1SAndroid Build Coastguard Worker
10635*bbecb9d1SAndroid Build Coastguard Worker if (ctx == vrend_state.current_ctx && ctx->ctx_switch_pending == false)
10636*bbecb9d1SAndroid Build Coastguard Worker return true;
10637*bbecb9d1SAndroid Build Coastguard Worker
10638*bbecb9d1SAndroid Build Coastguard Worker if (ctx->ctx_id != 0 && ctx->in_error) {
10639*bbecb9d1SAndroid Build Coastguard Worker return false;
10640*bbecb9d1SAndroid Build Coastguard Worker }
10641*bbecb9d1SAndroid Build Coastguard Worker
10642*bbecb9d1SAndroid Build Coastguard Worker ctx->ctx_switch_pending = true;
10643*bbecb9d1SAndroid Build Coastguard Worker if (now == true) {
10644*bbecb9d1SAndroid Build Coastguard Worker vrend_finish_context_switch(ctx);
10645*bbecb9d1SAndroid Build Coastguard Worker }
10646*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_ctx = ctx;
10647*bbecb9d1SAndroid Build Coastguard Worker return true;
10648*bbecb9d1SAndroid Build Coastguard Worker }
10649*bbecb9d1SAndroid Build Coastguard Worker
vrend_finish_context_switch(struct vrend_context * ctx)10650*bbecb9d1SAndroid Build Coastguard Worker static void vrend_finish_context_switch(struct vrend_context *ctx)
10651*bbecb9d1SAndroid Build Coastguard Worker {
10652*bbecb9d1SAndroid Build Coastguard Worker if (ctx->ctx_switch_pending == false)
10653*bbecb9d1SAndroid Build Coastguard Worker return;
10654*bbecb9d1SAndroid Build Coastguard Worker ctx->ctx_switch_pending = false;
10655*bbecb9d1SAndroid Build Coastguard Worker
10656*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.current_hw_ctx == ctx)
10657*bbecb9d1SAndroid Build Coastguard Worker return;
10658*bbecb9d1SAndroid Build Coastguard Worker
10659*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_hw_ctx = ctx;
10660*bbecb9d1SAndroid Build Coastguard Worker
10661*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(ctx->sub->gl_context);
10662*bbecb9d1SAndroid Build Coastguard Worker }
10663*bbecb9d1SAndroid Build Coastguard Worker
10664*bbecb9d1SAndroid Build Coastguard Worker void
vrend_renderer_object_destroy(struct vrend_context * ctx,uint32_t handle)10665*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_object_destroy(struct vrend_context *ctx, uint32_t handle)
10666*bbecb9d1SAndroid Build Coastguard Worker {
10667*bbecb9d1SAndroid Build Coastguard Worker vrend_object_remove(ctx->sub->object_hash, handle, 0);
10668*bbecb9d1SAndroid Build Coastguard Worker }
10669*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_object_insert(struct vrend_context * ctx,void * data,uint32_t handle,enum virgl_object_type type)10670*bbecb9d1SAndroid Build Coastguard Worker uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data,
10671*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle, enum virgl_object_type type)
10672*bbecb9d1SAndroid Build Coastguard Worker {
10673*bbecb9d1SAndroid Build Coastguard Worker return vrend_object_insert(ctx->sub->object_hash, data, handle, type);
10674*bbecb9d1SAndroid Build Coastguard Worker }
10675*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_query(struct vrend_context * ctx,uint32_t handle,uint32_t query_type,uint32_t query_index,uint32_t res_handle,UNUSED uint32_t offset)10676*bbecb9d1SAndroid Build Coastguard Worker int vrend_create_query(struct vrend_context *ctx, uint32_t handle,
10677*bbecb9d1SAndroid Build Coastguard Worker uint32_t query_type, uint32_t query_index,
10678*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle, UNUSED uint32_t offset)
10679*bbecb9d1SAndroid Build Coastguard Worker {
10680*bbecb9d1SAndroid Build Coastguard Worker bool fake_samples_passed = false;
10681*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
10682*bbecb9d1SAndroid Build Coastguard Worker if (!res || !has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) {
10683*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
10684*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
10685*bbecb9d1SAndroid Build Coastguard Worker }
10686*bbecb9d1SAndroid Build Coastguard Worker
10687*bbecb9d1SAndroid Build Coastguard Worker /* If we don't have ARB_occlusion_query, at least try to fake GL_SAMPLES_PASSED
10688*bbecb9d1SAndroid Build Coastguard Worker * by using GL_ANY_SAMPLES_PASSED (i.e. EXT_occlusion_query_boolean) */
10689*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_occlusion_query) && query_type == PIPE_QUERY_OCCLUSION_COUNTER) {
10690*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_query, ctx, "GL_SAMPLES_PASSED not supported will try GL_ANY_SAMPLES_PASSED\n");
10691*bbecb9d1SAndroid Build Coastguard Worker query_type = PIPE_QUERY_OCCLUSION_PREDICATE;
10692*bbecb9d1SAndroid Build Coastguard Worker fake_samples_passed = true;
10693*bbecb9d1SAndroid Build Coastguard Worker }
10694*bbecb9d1SAndroid Build Coastguard Worker
10695*bbecb9d1SAndroid Build Coastguard Worker if (query_type == PIPE_QUERY_OCCLUSION_PREDICATE &&
10696*bbecb9d1SAndroid Build Coastguard Worker !has_feature(feat_occlusion_query_boolean)) {
10697*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_GL_ANY_SAMPLES_PASSED, res_handle);
10698*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
10699*bbecb9d1SAndroid Build Coastguard Worker }
10700*bbecb9d1SAndroid Build Coastguard Worker
10701*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *q = CALLOC_STRUCT(vrend_query);
10702*bbecb9d1SAndroid Build Coastguard Worker if (!q)
10703*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
10704*bbecb9d1SAndroid Build Coastguard Worker
10705*bbecb9d1SAndroid Build Coastguard Worker int err = 0;
10706*bbecb9d1SAndroid Build Coastguard Worker
10707*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&q->waiting_queries);
10708*bbecb9d1SAndroid Build Coastguard Worker q->type = query_type;
10709*bbecb9d1SAndroid Build Coastguard Worker q->index = query_index;
10710*bbecb9d1SAndroid Build Coastguard Worker q->ctx = ctx;
10711*bbecb9d1SAndroid Build Coastguard Worker q->sub_ctx_id = ctx->sub->sub_ctx_id;
10712*bbecb9d1SAndroid Build Coastguard Worker q->fake_samples_passed = fake_samples_passed;
10713*bbecb9d1SAndroid Build Coastguard Worker
10714*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&q->res, res);
10715*bbecb9d1SAndroid Build Coastguard Worker
10716*bbecb9d1SAndroid Build Coastguard Worker switch (q->type) {
10717*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_OCCLUSION_COUNTER:
10718*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_SAMPLES_PASSED_ARB;
10719*bbecb9d1SAndroid Build Coastguard Worker break;
10720*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_OCCLUSION_PREDICATE:
10721*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_occlusion_query_boolean))
10722*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_ANY_SAMPLES_PASSED;
10723*bbecb9d1SAndroid Build Coastguard Worker else
10724*bbecb9d1SAndroid Build Coastguard Worker err = EINVAL;
10725*bbecb9d1SAndroid Build Coastguard Worker break;
10726*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TIMESTAMP:
10727*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_timer_query))
10728*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_TIMESTAMP;
10729*bbecb9d1SAndroid Build Coastguard Worker else
10730*bbecb9d1SAndroid Build Coastguard Worker err = EINVAL;
10731*bbecb9d1SAndroid Build Coastguard Worker break;
10732*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TIME_ELAPSED:
10733*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_timer_query))
10734*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_TIME_ELAPSED;
10735*bbecb9d1SAndroid Build Coastguard Worker else
10736*bbecb9d1SAndroid Build Coastguard Worker err = EINVAL;
10737*bbecb9d1SAndroid Build Coastguard Worker break;
10738*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_PRIMITIVES_GENERATED:
10739*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_PRIMITIVES_GENERATED;
10740*bbecb9d1SAndroid Build Coastguard Worker break;
10741*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_PRIMITIVES_EMITTED:
10742*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
10743*bbecb9d1SAndroid Build Coastguard Worker break;
10744*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
10745*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_ANY_SAMPLES_PASSED_CONSERVATIVE;
10746*bbecb9d1SAndroid Build Coastguard Worker break;
10747*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
10748*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback_overflow_query))
10749*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB;
10750*bbecb9d1SAndroid Build Coastguard Worker else
10751*bbecb9d1SAndroid Build Coastguard Worker err = EINVAL;
10752*bbecb9d1SAndroid Build Coastguard Worker break;
10753*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE:
10754*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback_overflow_query))
10755*bbecb9d1SAndroid Build Coastguard Worker q->gltype = GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB;
10756*bbecb9d1SAndroid Build Coastguard Worker else
10757*bbecb9d1SAndroid Build Coastguard Worker err = EINVAL;
10758*bbecb9d1SAndroid Build Coastguard Worker break;
10759*bbecb9d1SAndroid Build Coastguard Worker default:
10760*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("unknown query object received %d\n", q->type);
10761*bbecb9d1SAndroid Build Coastguard Worker break;
10762*bbecb9d1SAndroid Build Coastguard Worker }
10763*bbecb9d1SAndroid Build Coastguard Worker
10764*bbecb9d1SAndroid Build Coastguard Worker if (!err) {
10765*bbecb9d1SAndroid Build Coastguard Worker glGenQueries(1, &q->id);
10766*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_renderer_object_insert(ctx, q, handle, VIRGL_OBJECT_QUERY)) {
10767*bbecb9d1SAndroid Build Coastguard Worker glDeleteQueries(1, &q->id);
10768*bbecb9d1SAndroid Build Coastguard Worker err = ENOMEM;
10769*bbecb9d1SAndroid Build Coastguard Worker }
10770*bbecb9d1SAndroid Build Coastguard Worker }
10771*bbecb9d1SAndroid Build Coastguard Worker
10772*bbecb9d1SAndroid Build Coastguard Worker if (err)
10773*bbecb9d1SAndroid Build Coastguard Worker FREE(q);
10774*bbecb9d1SAndroid Build Coastguard Worker
10775*bbecb9d1SAndroid Build Coastguard Worker return err;
10776*bbecb9d1SAndroid Build Coastguard Worker }
10777*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_query(struct vrend_query * query)10778*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_query(struct vrend_query *query)
10779*bbecb9d1SAndroid Build Coastguard Worker {
10780*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&query->res, NULL);
10781*bbecb9d1SAndroid Build Coastguard Worker list_del(&query->waiting_queries);
10782*bbecb9d1SAndroid Build Coastguard Worker glDeleteQueries(1, &query->id);
10783*bbecb9d1SAndroid Build Coastguard Worker free(query);
10784*bbecb9d1SAndroid Build Coastguard Worker }
10785*bbecb9d1SAndroid Build Coastguard Worker
vrend_destroy_query_object(void * obj_ptr)10786*bbecb9d1SAndroid Build Coastguard Worker static void vrend_destroy_query_object(void *obj_ptr)
10787*bbecb9d1SAndroid Build Coastguard Worker {
10788*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *query = obj_ptr;
10789*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_query(query);
10790*bbecb9d1SAndroid Build Coastguard Worker }
10791*bbecb9d1SAndroid Build Coastguard Worker
vrend_begin_query(struct vrend_context * ctx,uint32_t handle)10792*bbecb9d1SAndroid Build Coastguard Worker int vrend_begin_query(struct vrend_context *ctx, uint32_t handle)
10793*bbecb9d1SAndroid Build Coastguard Worker {
10794*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *q;
10795*bbecb9d1SAndroid Build Coastguard Worker
10796*bbecb9d1SAndroid Build Coastguard Worker q = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_QUERY);
10797*bbecb9d1SAndroid Build Coastguard Worker if (!q)
10798*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
10799*bbecb9d1SAndroid Build Coastguard Worker
10800*bbecb9d1SAndroid Build Coastguard Worker if (q->index > 0 && !has_feature(feat_transform_feedback3))
10801*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
10802*bbecb9d1SAndroid Build Coastguard Worker
10803*bbecb9d1SAndroid Build Coastguard Worker list_delinit(&q->waiting_queries);
10804*bbecb9d1SAndroid Build Coastguard Worker
10805*bbecb9d1SAndroid Build Coastguard Worker if (q->gltype == GL_TIMESTAMP)
10806*bbecb9d1SAndroid Build Coastguard Worker return 0;
10807*bbecb9d1SAndroid Build Coastguard Worker
10808*bbecb9d1SAndroid Build Coastguard Worker if (q->index > 0)
10809*bbecb9d1SAndroid Build Coastguard Worker glBeginQueryIndexed(q->gltype, q->index, q->id);
10810*bbecb9d1SAndroid Build Coastguard Worker else
10811*bbecb9d1SAndroid Build Coastguard Worker glBeginQuery(q->gltype, q->id);
10812*bbecb9d1SAndroid Build Coastguard Worker return 0;
10813*bbecb9d1SAndroid Build Coastguard Worker }
10814*bbecb9d1SAndroid Build Coastguard Worker
vrend_end_query(struct vrend_context * ctx,uint32_t handle)10815*bbecb9d1SAndroid Build Coastguard Worker int vrend_end_query(struct vrend_context *ctx, uint32_t handle)
10816*bbecb9d1SAndroid Build Coastguard Worker {
10817*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *q;
10818*bbecb9d1SAndroid Build Coastguard Worker q = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_QUERY);
10819*bbecb9d1SAndroid Build Coastguard Worker if (!q)
10820*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
10821*bbecb9d1SAndroid Build Coastguard Worker
10822*bbecb9d1SAndroid Build Coastguard Worker if (q->index > 0 && !has_feature(feat_transform_feedback3))
10823*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
10824*bbecb9d1SAndroid Build Coastguard Worker
10825*bbecb9d1SAndroid Build Coastguard Worker if (vrend_is_timer_query(q->gltype)) {
10826*bbecb9d1SAndroid Build Coastguard Worker if (q->gltype == GL_TIMESTAMP && !has_feature(feat_timer_query)) {
10827*bbecb9d1SAndroid Build Coastguard Worker report_gles_warn(ctx, GLES_WARN_TIMESTAMP);
10828*bbecb9d1SAndroid Build Coastguard Worker } else if (q->gltype == GL_TIMESTAMP) {
10829*bbecb9d1SAndroid Build Coastguard Worker glQueryCounter(q->id, q->gltype);
10830*bbecb9d1SAndroid Build Coastguard Worker } else {
10831*bbecb9d1SAndroid Build Coastguard Worker /* remove from active query list for this context */
10832*bbecb9d1SAndroid Build Coastguard Worker glEndQuery(q->gltype);
10833*bbecb9d1SAndroid Build Coastguard Worker }
10834*bbecb9d1SAndroid Build Coastguard Worker return 0;
10835*bbecb9d1SAndroid Build Coastguard Worker }
10836*bbecb9d1SAndroid Build Coastguard Worker
10837*bbecb9d1SAndroid Build Coastguard Worker if (q->index > 0)
10838*bbecb9d1SAndroid Build Coastguard Worker glEndQueryIndexed(q->gltype, q->index);
10839*bbecb9d1SAndroid Build Coastguard Worker else
10840*bbecb9d1SAndroid Build Coastguard Worker glEndQuery(q->gltype);
10841*bbecb9d1SAndroid Build Coastguard Worker return 0;
10842*bbecb9d1SAndroid Build Coastguard Worker }
10843*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_query_result(struct vrend_context * ctx,uint32_t handle,UNUSED uint32_t wait)10844*bbecb9d1SAndroid Build Coastguard Worker void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle,
10845*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t wait)
10846*bbecb9d1SAndroid Build Coastguard Worker {
10847*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *q;
10848*bbecb9d1SAndroid Build Coastguard Worker bool ret;
10849*bbecb9d1SAndroid Build Coastguard Worker
10850*bbecb9d1SAndroid Build Coastguard Worker q = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_QUERY);
10851*bbecb9d1SAndroid Build Coastguard Worker if (!q)
10852*bbecb9d1SAndroid Build Coastguard Worker return;
10853*bbecb9d1SAndroid Build Coastguard Worker
10854*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_check_query(q);
10855*bbecb9d1SAndroid Build Coastguard Worker if (ret) {
10856*bbecb9d1SAndroid Build Coastguard Worker list_delinit(&q->waiting_queries);
10857*bbecb9d1SAndroid Build Coastguard Worker } else if (LIST_IS_EMPTY(&q->waiting_queries)) {
10858*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&q->waiting_queries, &vrend_state.waiting_query_list);
10859*bbecb9d1SAndroid Build Coastguard Worker }
10860*bbecb9d1SAndroid Build Coastguard Worker
10861*bbecb9d1SAndroid Build Coastguard Worker atomic_store(&vrend_state.has_waiting_queries,
10862*bbecb9d1SAndroid Build Coastguard Worker !LIST_IS_EMPTY(&vrend_state.waiting_query_list));
10863*bbecb9d1SAndroid Build Coastguard Worker }
10864*bbecb9d1SAndroid Build Coastguard Worker
10865*bbecb9d1SAndroid Build Coastguard Worker #define COPY_QUERY_RESULT_TO_BUFFER(resid, offset, pvalue, size, multiplier) \
10866*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_QUERY_BUFFER, resid); \
10867*bbecb9d1SAndroid Build Coastguard Worker value *= multiplier; \
10868*bbecb9d1SAndroid Build Coastguard Worker void* buf = glMapBufferRange(GL_QUERY_BUFFER, offset, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT); \
10869*bbecb9d1SAndroid Build Coastguard Worker if (buf) memcpy(buf, &value, size); \
10870*bbecb9d1SAndroid Build Coastguard Worker glUnmapBuffer(GL_QUERY_BUFFER);
10871*bbecb9d1SAndroid Build Coastguard Worker
buffer_offset(intptr_t i)10872*bbecb9d1SAndroid Build Coastguard Worker static inline void *buffer_offset(intptr_t i)
10873*bbecb9d1SAndroid Build Coastguard Worker {
10874*bbecb9d1SAndroid Build Coastguard Worker return (void *)i;
10875*bbecb9d1SAndroid Build Coastguard Worker }
10876*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_query_result_qbo(struct vrend_context * ctx,uint32_t handle,uint32_t qbo_handle,uint32_t wait,uint32_t result_type,uint32_t offset,int32_t index)10877*bbecb9d1SAndroid Build Coastguard Worker void vrend_get_query_result_qbo(struct vrend_context *ctx, uint32_t handle,
10878*bbecb9d1SAndroid Build Coastguard Worker uint32_t qbo_handle,
10879*bbecb9d1SAndroid Build Coastguard Worker uint32_t wait, uint32_t result_type, uint32_t offset,
10880*bbecb9d1SAndroid Build Coastguard Worker int32_t index)
10881*bbecb9d1SAndroid Build Coastguard Worker {
10882*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *q;
10883*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
10884*bbecb9d1SAndroid Build Coastguard Worker
10885*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_qbo))
10886*bbecb9d1SAndroid Build Coastguard Worker return;
10887*bbecb9d1SAndroid Build Coastguard Worker
10888*bbecb9d1SAndroid Build Coastguard Worker q = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_QUERY);
10889*bbecb9d1SAndroid Build Coastguard Worker if (!q)
10890*bbecb9d1SAndroid Build Coastguard Worker return;
10891*bbecb9d1SAndroid Build Coastguard Worker
10892*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, qbo_handle);
10893*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
10894*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, qbo_handle);
10895*bbecb9d1SAndroid Build Coastguard Worker return;
10896*bbecb9d1SAndroid Build Coastguard Worker }
10897*bbecb9d1SAndroid Build Coastguard Worker
10898*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_query, ctx, "Get query result from Query:%d\n", q->id);
10899*bbecb9d1SAndroid Build Coastguard Worker
10900*bbecb9d1SAndroid Build Coastguard Worker GLenum qtype;
10901*bbecb9d1SAndroid Build Coastguard Worker
10902*bbecb9d1SAndroid Build Coastguard Worker if (index == -1)
10903*bbecb9d1SAndroid Build Coastguard Worker qtype = GL_QUERY_RESULT_AVAILABLE;
10904*bbecb9d1SAndroid Build Coastguard Worker else
10905*bbecb9d1SAndroid Build Coastguard Worker qtype = wait ? GL_QUERY_RESULT : GL_QUERY_RESULT_NO_WAIT;
10906*bbecb9d1SAndroid Build Coastguard Worker
10907*bbecb9d1SAndroid Build Coastguard Worker if (!q->fake_samples_passed) {
10908*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_QUERY_BUFFER, res->id);
10909*bbecb9d1SAndroid Build Coastguard Worker switch ((enum pipe_query_value_type)result_type) {
10910*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_I32:
10911*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectiv(q->id, qtype, buffer_offset(offset));
10912*bbecb9d1SAndroid Build Coastguard Worker break;
10913*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_U32:
10914*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectuiv(q->id, qtype, buffer_offset(offset));
10915*bbecb9d1SAndroid Build Coastguard Worker break;
10916*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_I64:
10917*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjecti64v(q->id, qtype, buffer_offset(offset));
10918*bbecb9d1SAndroid Build Coastguard Worker break;
10919*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_U64:
10920*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectui64v(q->id, qtype, buffer_offset(offset));
10921*bbecb9d1SAndroid Build Coastguard Worker break;
10922*bbecb9d1SAndroid Build Coastguard Worker }
10923*bbecb9d1SAndroid Build Coastguard Worker } else {
10924*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_query, ctx, "Was emulating GL_PIXELS_PASSED by GL_ANY_PIXELS_PASSED, artifically upscaling the result\n");
10925*bbecb9d1SAndroid Build Coastguard Worker /* The application expects a sample count but we have only a boolean
10926*bbecb9d1SAndroid Build Coastguard Worker * so we blow the result up by 1/10 of the screen space to make sure the
10927*bbecb9d1SAndroid Build Coastguard Worker * app doesn't think only one sample passed. */
10928*bbecb9d1SAndroid Build Coastguard Worker vrend_update_oq_samples_multiplier(ctx);
10929*bbecb9d1SAndroid Build Coastguard Worker switch ((enum pipe_query_value_type)result_type) {
10930*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_I32: {
10931*bbecb9d1SAndroid Build Coastguard Worker GLint value;
10932*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectiv(q->id, qtype, &value);
10933*bbecb9d1SAndroid Build Coastguard Worker COPY_QUERY_RESULT_TO_BUFFER(q->id, offset, value, 4, ctx->sub->fake_occlusion_query_samples_passed_multiplier);
10934*bbecb9d1SAndroid Build Coastguard Worker break;
10935*bbecb9d1SAndroid Build Coastguard Worker }
10936*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_U32: {
10937*bbecb9d1SAndroid Build Coastguard Worker GLuint value;
10938*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectuiv(q->id, qtype, &value);
10939*bbecb9d1SAndroid Build Coastguard Worker COPY_QUERY_RESULT_TO_BUFFER(q->id, offset, value, 4, ctx->sub->fake_occlusion_query_samples_passed_multiplier);
10940*bbecb9d1SAndroid Build Coastguard Worker break;
10941*bbecb9d1SAndroid Build Coastguard Worker }
10942*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_I64: {
10943*bbecb9d1SAndroid Build Coastguard Worker GLint64 value;
10944*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjecti64v(q->id, qtype, &value);
10945*bbecb9d1SAndroid Build Coastguard Worker COPY_QUERY_RESULT_TO_BUFFER(q->id, offset, value, 8, ctx->sub->fake_occlusion_query_samples_passed_multiplier);
10946*bbecb9d1SAndroid Build Coastguard Worker break;
10947*bbecb9d1SAndroid Build Coastguard Worker }
10948*bbecb9d1SAndroid Build Coastguard Worker case PIPE_QUERY_TYPE_U64: {
10949*bbecb9d1SAndroid Build Coastguard Worker GLuint64 value;
10950*bbecb9d1SAndroid Build Coastguard Worker glGetQueryObjectui64v(q->id, qtype, &value);
10951*bbecb9d1SAndroid Build Coastguard Worker COPY_QUERY_RESULT_TO_BUFFER(q->id, offset, value, 8, ctx->sub->fake_occlusion_query_samples_passed_multiplier);
10952*bbecb9d1SAndroid Build Coastguard Worker break;
10953*bbecb9d1SAndroid Build Coastguard Worker }
10954*bbecb9d1SAndroid Build Coastguard Worker }
10955*bbecb9d1SAndroid Build Coastguard Worker
10956*bbecb9d1SAndroid Build Coastguard Worker
10957*bbecb9d1SAndroid Build Coastguard Worker }
10958*bbecb9d1SAndroid Build Coastguard Worker
10959*bbecb9d1SAndroid Build Coastguard Worker glBindBuffer(GL_QUERY_BUFFER, 0);
10960*bbecb9d1SAndroid Build Coastguard Worker }
10961*bbecb9d1SAndroid Build Coastguard Worker
vrend_pause_render_condition(struct vrend_context * ctx,bool pause)10962*bbecb9d1SAndroid Build Coastguard Worker static void vrend_pause_render_condition(struct vrend_context *ctx, bool pause)
10963*bbecb9d1SAndroid Build Coastguard Worker {
10964*bbecb9d1SAndroid Build Coastguard Worker if (pause) {
10965*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->cond_render_q_id) {
10966*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gl_conditional_render))
10967*bbecb9d1SAndroid Build Coastguard Worker glEndConditionalRender();
10968*bbecb9d1SAndroid Build Coastguard Worker else if (has_feature(feat_nv_conditional_render))
10969*bbecb9d1SAndroid Build Coastguard Worker glEndConditionalRenderNV();
10970*bbecb9d1SAndroid Build Coastguard Worker }
10971*bbecb9d1SAndroid Build Coastguard Worker } else {
10972*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub->cond_render_q_id) {
10973*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gl_conditional_render))
10974*bbecb9d1SAndroid Build Coastguard Worker glBeginConditionalRender(ctx->sub->cond_render_q_id,
10975*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->cond_render_gl_mode);
10976*bbecb9d1SAndroid Build Coastguard Worker else if (has_feature(feat_nv_conditional_render))
10977*bbecb9d1SAndroid Build Coastguard Worker glBeginConditionalRenderNV(ctx->sub->cond_render_q_id,
10978*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->cond_render_gl_mode);
10979*bbecb9d1SAndroid Build Coastguard Worker }
10980*bbecb9d1SAndroid Build Coastguard Worker }
10981*bbecb9d1SAndroid Build Coastguard Worker }
10982*bbecb9d1SAndroid Build Coastguard Worker
vrend_render_condition(struct vrend_context * ctx,uint32_t handle,bool condition,uint mode)10983*bbecb9d1SAndroid Build Coastguard Worker void vrend_render_condition(struct vrend_context *ctx,
10984*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
10985*bbecb9d1SAndroid Build Coastguard Worker bool condition,
10986*bbecb9d1SAndroid Build Coastguard Worker uint mode)
10987*bbecb9d1SAndroid Build Coastguard Worker {
10988*bbecb9d1SAndroid Build Coastguard Worker struct vrend_query *q;
10989*bbecb9d1SAndroid Build Coastguard Worker GLenum glmode = 0;
10990*bbecb9d1SAndroid Build Coastguard Worker
10991*bbecb9d1SAndroid Build Coastguard Worker if (handle == 0) {
10992*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gl_conditional_render))
10993*bbecb9d1SAndroid Build Coastguard Worker glEndConditionalRender();
10994*bbecb9d1SAndroid Build Coastguard Worker else if (has_feature(feat_nv_conditional_render))
10995*bbecb9d1SAndroid Build Coastguard Worker glEndConditionalRenderNV();
10996*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->cond_render_q_id = 0;
10997*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->cond_render_gl_mode = 0;
10998*bbecb9d1SAndroid Build Coastguard Worker return;
10999*bbecb9d1SAndroid Build Coastguard Worker }
11000*bbecb9d1SAndroid Build Coastguard Worker
11001*bbecb9d1SAndroid Build Coastguard Worker q = vrend_object_lookup(ctx->sub->object_hash, handle, VIRGL_OBJECT_QUERY);
11002*bbecb9d1SAndroid Build Coastguard Worker if (!q)
11003*bbecb9d1SAndroid Build Coastguard Worker return;
11004*bbecb9d1SAndroid Build Coastguard Worker
11005*bbecb9d1SAndroid Build Coastguard Worker if (condition && !has_feature(feat_conditional_render_inverted))
11006*bbecb9d1SAndroid Build Coastguard Worker return;
11007*bbecb9d1SAndroid Build Coastguard Worker switch (mode) {
11008*bbecb9d1SAndroid Build Coastguard Worker case PIPE_RENDER_COND_WAIT:
11009*bbecb9d1SAndroid Build Coastguard Worker glmode = condition ? GL_QUERY_WAIT_INVERTED : GL_QUERY_WAIT;
11010*bbecb9d1SAndroid Build Coastguard Worker break;
11011*bbecb9d1SAndroid Build Coastguard Worker case PIPE_RENDER_COND_NO_WAIT:
11012*bbecb9d1SAndroid Build Coastguard Worker glmode = condition ? GL_QUERY_NO_WAIT_INVERTED : GL_QUERY_NO_WAIT;
11013*bbecb9d1SAndroid Build Coastguard Worker break;
11014*bbecb9d1SAndroid Build Coastguard Worker case PIPE_RENDER_COND_BY_REGION_WAIT:
11015*bbecb9d1SAndroid Build Coastguard Worker glmode = condition ? GL_QUERY_BY_REGION_WAIT_INVERTED : GL_QUERY_BY_REGION_WAIT;
11016*bbecb9d1SAndroid Build Coastguard Worker break;
11017*bbecb9d1SAndroid Build Coastguard Worker case PIPE_RENDER_COND_BY_REGION_NO_WAIT:
11018*bbecb9d1SAndroid Build Coastguard Worker glmode = condition ? GL_QUERY_BY_REGION_NO_WAIT_INVERTED : GL_QUERY_BY_REGION_NO_WAIT;
11019*bbecb9d1SAndroid Build Coastguard Worker break;
11020*bbecb9d1SAndroid Build Coastguard Worker default:
11021*bbecb9d1SAndroid Build Coastguard Worker vrend_printf( "unhandled condition %x\n", mode);
11022*bbecb9d1SAndroid Build Coastguard Worker }
11023*bbecb9d1SAndroid Build Coastguard Worker
11024*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->cond_render_q_id = q->id;
11025*bbecb9d1SAndroid Build Coastguard Worker ctx->sub->cond_render_gl_mode = glmode;
11026*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_gl_conditional_render))
11027*bbecb9d1SAndroid Build Coastguard Worker glBeginConditionalRender(q->id, glmode);
11028*bbecb9d1SAndroid Build Coastguard Worker else if (has_feature(feat_nv_conditional_render))
11029*bbecb9d1SAndroid Build Coastguard Worker glBeginConditionalRenderNV(q->id, glmode);
11030*bbecb9d1SAndroid Build Coastguard Worker }
11031*bbecb9d1SAndroid Build Coastguard Worker
vrend_create_so_target(struct vrend_context * ctx,uint32_t handle,uint32_t res_handle,uint32_t buffer_offset,uint32_t buffer_size)11032*bbecb9d1SAndroid Build Coastguard Worker int vrend_create_so_target(struct vrend_context *ctx,
11033*bbecb9d1SAndroid Build Coastguard Worker uint32_t handle,
11034*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_handle,
11035*bbecb9d1SAndroid Build Coastguard Worker uint32_t buffer_offset,
11036*bbecb9d1SAndroid Build Coastguard Worker uint32_t buffer_size)
11037*bbecb9d1SAndroid Build Coastguard Worker {
11038*bbecb9d1SAndroid Build Coastguard Worker struct vrend_so_target *target;
11039*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
11040*bbecb9d1SAndroid Build Coastguard Worker int ret_handle;
11041*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
11042*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
11043*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
11044*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
11045*bbecb9d1SAndroid Build Coastguard Worker }
11046*bbecb9d1SAndroid Build Coastguard Worker
11047*bbecb9d1SAndroid Build Coastguard Worker target = CALLOC_STRUCT(vrend_so_target);
11048*bbecb9d1SAndroid Build Coastguard Worker if (!target)
11049*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
11050*bbecb9d1SAndroid Build Coastguard Worker
11051*bbecb9d1SAndroid Build Coastguard Worker pipe_reference_init(&target->reference, 1);
11052*bbecb9d1SAndroid Build Coastguard Worker target->res_handle = res_handle;
11053*bbecb9d1SAndroid Build Coastguard Worker target->buffer_offset = buffer_offset;
11054*bbecb9d1SAndroid Build Coastguard Worker target->buffer_size = buffer_size;
11055*bbecb9d1SAndroid Build Coastguard Worker target->sub_ctx = ctx->sub;
11056*bbecb9d1SAndroid Build Coastguard Worker vrend_resource_reference(&target->buffer, res);
11057*bbecb9d1SAndroid Build Coastguard Worker
11058*bbecb9d1SAndroid Build Coastguard Worker ret_handle = vrend_renderer_object_insert(ctx, target, handle,
11059*bbecb9d1SAndroid Build Coastguard Worker VIRGL_OBJECT_STREAMOUT_TARGET);
11060*bbecb9d1SAndroid Build Coastguard Worker if (ret_handle == 0) {
11061*bbecb9d1SAndroid Build Coastguard Worker FREE(target);
11062*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
11063*bbecb9d1SAndroid Build Coastguard Worker }
11064*bbecb9d1SAndroid Build Coastguard Worker return 0;
11065*bbecb9d1SAndroid Build Coastguard Worker }
11066*bbecb9d1SAndroid Build Coastguard Worker
vrender_get_glsl_version(void)11067*bbecb9d1SAndroid Build Coastguard Worker static int vrender_get_glsl_version(void)
11068*bbecb9d1SAndroid Build Coastguard Worker {
11069*bbecb9d1SAndroid Build Coastguard Worker int major_local = 0, minor_local = 0;
11070*bbecb9d1SAndroid Build Coastguard Worker const GLubyte *version_str;
11071*bbecb9d1SAndroid Build Coastguard Worker ASSERTED int c;
11072*bbecb9d1SAndroid Build Coastguard Worker
11073*bbecb9d1SAndroid Build Coastguard Worker version_str = glGetString(GL_SHADING_LANGUAGE_VERSION);
11074*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
11075*bbecb9d1SAndroid Build Coastguard Worker c = sscanf((const char *)version_str, "%*s %*s %*s %*s %i.%i",
11076*bbecb9d1SAndroid Build Coastguard Worker &major_local, &minor_local);
11077*bbecb9d1SAndroid Build Coastguard Worker } else {
11078*bbecb9d1SAndroid Build Coastguard Worker c = sscanf((const char *)version_str, "%i.%i",
11079*bbecb9d1SAndroid Build Coastguard Worker &major_local, &minor_local);
11080*bbecb9d1SAndroid Build Coastguard Worker }
11081*bbecb9d1SAndroid Build Coastguard Worker assert(c == 2);
11082*bbecb9d1SAndroid Build Coastguard Worker
11083*bbecb9d1SAndroid Build Coastguard Worker return (major_local * 100) + minor_local;
11084*bbecb9d1SAndroid Build Coastguard Worker }
11085*bbecb9d1SAndroid Build Coastguard Worker
vrend_fill_caps_glsl_version(int gl_ver,int gles_ver,union virgl_caps * caps)11086*bbecb9d1SAndroid Build Coastguard Worker static void vrend_fill_caps_glsl_version(int gl_ver, int gles_ver,
11087*bbecb9d1SAndroid Build Coastguard Worker union virgl_caps *caps)
11088*bbecb9d1SAndroid Build Coastguard Worker {
11089*bbecb9d1SAndroid Build Coastguard Worker if (gles_ver > 0) {
11090*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 120;
11091*bbecb9d1SAndroid Build Coastguard Worker
11092*bbecb9d1SAndroid Build Coastguard Worker if (gles_ver >= 31)
11093*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 310;
11094*bbecb9d1SAndroid Build Coastguard Worker else if (gles_ver >= 30)
11095*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 130;
11096*bbecb9d1SAndroid Build Coastguard Worker }
11097*bbecb9d1SAndroid Build Coastguard Worker
11098*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver > 0) {
11099*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 130;
11100*bbecb9d1SAndroid Build Coastguard Worker
11101*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver == 31)
11102*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 140;
11103*bbecb9d1SAndroid Build Coastguard Worker else if (gl_ver == 32)
11104*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 150;
11105*bbecb9d1SAndroid Build Coastguard Worker else if (gl_ver >= 33)
11106*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 10 * gl_ver;
11107*bbecb9d1SAndroid Build Coastguard Worker }
11108*bbecb9d1SAndroid Build Coastguard Worker
11109*bbecb9d1SAndroid Build Coastguard Worker if (caps->v1.glsl_level < 400) {
11110*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_tessellation) &&
11111*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_geometry_shader) &&
11112*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_gpu_shader5)) {
11113*bbecb9d1SAndroid Build Coastguard Worker /* This is probably a lie, but Gallium enables
11114*bbecb9d1SAndroid Build Coastguard Worker * OES_geometry_shader and ARB_gpu_shader5
11115*bbecb9d1SAndroid Build Coastguard Worker * based on this value, apart from that it doesn't
11116*bbecb9d1SAndroid Build Coastguard Worker * seem to be a crucial value */
11117*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 400;
11118*bbecb9d1SAndroid Build Coastguard Worker
11119*bbecb9d1SAndroid Build Coastguard Worker /* Let's lie a bit more */
11120*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_separate_shader_objects)) {
11121*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 410;
11122*bbecb9d1SAndroid Build Coastguard Worker
11123*bbecb9d1SAndroid Build Coastguard Worker /* Compute shaders require GLSL 4.30 unless the shader explicitely
11124*bbecb9d1SAndroid Build Coastguard Worker * specifies GL_ARB_compute_shader as required. However, on OpenGL ES
11125*bbecb9d1SAndroid Build Coastguard Worker * they are already supported with version 3.10, so if we already
11126*bbecb9d1SAndroid Build Coastguard Worker * advertise a feature level of 410, just lie a bit more to make
11127*bbecb9d1SAndroid Build Coastguard Worker * compute shaders available to GL programs that don't specify the
11128*bbecb9d1SAndroid Build Coastguard Worker * extension within the shaders. */
11129*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_compute_shader))
11130*bbecb9d1SAndroid Build Coastguard Worker caps->v1.glsl_level = 430;
11131*bbecb9d1SAndroid Build Coastguard Worker }
11132*bbecb9d1SAndroid Build Coastguard Worker }
11133*bbecb9d1SAndroid Build Coastguard Worker }
11134*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("GLSL feature level %d\n", caps->v1.glsl_level);
11135*bbecb9d1SAndroid Build Coastguard Worker }
11136*bbecb9d1SAndroid Build Coastguard Worker
set_format_bit(struct virgl_supported_format_mask * mask,enum virgl_formats fmt)11137*bbecb9d1SAndroid Build Coastguard Worker static void set_format_bit(struct virgl_supported_format_mask *mask, enum virgl_formats fmt)
11138*bbecb9d1SAndroid Build Coastguard Worker {
11139*bbecb9d1SAndroid Build Coastguard Worker assert(fmt < VIRGL_FORMAT_MAX);
11140*bbecb9d1SAndroid Build Coastguard Worker unsigned val = (unsigned)fmt;
11141*bbecb9d1SAndroid Build Coastguard Worker unsigned idx = val / 32;
11142*bbecb9d1SAndroid Build Coastguard Worker unsigned bit = val % 32;
11143*bbecb9d1SAndroid Build Coastguard Worker assert(idx < ARRAY_SIZE(mask->bitmask));
11144*bbecb9d1SAndroid Build Coastguard Worker mask->bitmask[idx] |= 1u << bit;
11145*bbecb9d1SAndroid Build Coastguard Worker }
11146*bbecb9d1SAndroid Build Coastguard Worker
11147*bbecb9d1SAndroid Build Coastguard Worker /*
11148*bbecb9d1SAndroid Build Coastguard Worker * Does all of the common caps setting,
11149*bbecb9d1SAndroid Build Coastguard Worker * if it dedects a early out returns true.
11150*bbecb9d1SAndroid Build Coastguard Worker */
vrend_renderer_fill_caps_v1(int gl_ver,int gles_ver,union virgl_caps * caps)11151*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_fill_caps_v1(int gl_ver, int gles_ver, union virgl_caps *caps)
11152*bbecb9d1SAndroid Build Coastguard Worker {
11153*bbecb9d1SAndroid Build Coastguard Worker int i;
11154*bbecb9d1SAndroid Build Coastguard Worker GLint max;
11155*bbecb9d1SAndroid Build Coastguard Worker
11156*bbecb9d1SAndroid Build Coastguard Worker /*
11157*bbecb9d1SAndroid Build Coastguard Worker * We can't fully support this feature on GLES,
11158*bbecb9d1SAndroid Build Coastguard Worker * but it is needed for OpenGL 2.1 so lie.
11159*bbecb9d1SAndroid Build Coastguard Worker */
11160*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.occlusion_query = 1;
11161*bbecb9d1SAndroid Build Coastguard Worker
11162*bbecb9d1SAndroid Build Coastguard Worker /* Set supported prims here as we now know what shaders we support. */
11163*bbecb9d1SAndroid Build Coastguard Worker caps->v1.prim_mask = (1 << PIPE_PRIM_POINTS) | (1 << PIPE_PRIM_LINES) |
11164*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_LINE_STRIP) | (1 << PIPE_PRIM_LINE_LOOP) |
11165*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_TRIANGLES) | (1 << PIPE_PRIM_TRIANGLE_STRIP) |
11166*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_TRIANGLE_FAN);
11167*bbecb9d1SAndroid Build Coastguard Worker
11168*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver > 0 && !vrend_state.use_core_profile) {
11169*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.poly_stipple = 1;
11170*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.color_clamping = 1;
11171*bbecb9d1SAndroid Build Coastguard Worker caps->v1.prim_mask |= (1 << PIPE_PRIM_QUADS) |
11172*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_QUAD_STRIP) |
11173*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_POLYGON);
11174*bbecb9d1SAndroid Build Coastguard Worker }
11175*bbecb9d1SAndroid Build Coastguard Worker
11176*bbecb9d1SAndroid Build Coastguard Worker if (caps->v1.glsl_level >= 150) {
11177*bbecb9d1SAndroid Build Coastguard Worker caps->v1.prim_mask |= (1 << PIPE_PRIM_LINES_ADJACENCY) |
11178*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_LINE_STRIP_ADJACENCY) |
11179*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_TRIANGLES_ADJACENCY) |
11180*bbecb9d1SAndroid Build Coastguard Worker (1 << PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
11181*bbecb9d1SAndroid Build Coastguard Worker }
11182*bbecb9d1SAndroid Build Coastguard Worker if (caps->v1.glsl_level >= 400 || has_feature(feat_tessellation))
11183*bbecb9d1SAndroid Build Coastguard Worker caps->v1.prim_mask |= (1 << PIPE_PRIM_PATCHES);
11184*bbecb9d1SAndroid Build Coastguard Worker
11185*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_ARB_vertex_type_10f_11f_11f_rev"))
11186*bbecb9d1SAndroid Build Coastguard Worker set_format_bit(&caps->v1.vertexbuffer, VIRGL_FORMAT_R11G11B10_FLOAT);
11187*bbecb9d1SAndroid Build Coastguard Worker
11188*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_nv_conditional_render) ||
11189*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_gl_conditional_render))
11190*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.conditional_render = 1;
11191*bbecb9d1SAndroid Build Coastguard Worker
11192*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_indep_blend))
11193*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.indep_blend_enable = 1;
11194*bbecb9d1SAndroid Build Coastguard Worker
11195*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_draw_instance))
11196*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.instanceid = 1;
11197*bbecb9d1SAndroid Build Coastguard Worker
11198*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_ubo)) {
11199*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &max);
11200*bbecb9d1SAndroid Build Coastguard Worker /* GL_MAX_VERTEX_UNIFORM_BLOCKS is omitting the ordinary uniform block, add it
11201*bbecb9d1SAndroid Build Coastguard Worker * also reduce by 1 as we might generate a VirglBlock helper uniform block */
11202*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_uniform_blocks = max + 1 - 1;
11203*bbecb9d1SAndroid Build Coastguard Worker }
11204*bbecb9d1SAndroid Build Coastguard Worker
11205*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_depth_clamp))
11206*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.depth_clip_disable = 1;
11207*bbecb9d1SAndroid Build Coastguard Worker
11208*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver >= 32) {
11209*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.fragment_coord_conventions = 1;
11210*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.seamless_cube_map = 1;
11211*bbecb9d1SAndroid Build Coastguard Worker } else {
11212*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_ARB_fragment_coord_conventions"))
11213*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.fragment_coord_conventions = 1;
11214*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_ARB_seamless_cube_map") || gles_ver >= 30)
11215*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.seamless_cube_map = 1;
11216*bbecb9d1SAndroid Build Coastguard Worker }
11217*bbecb9d1SAndroid Build Coastguard Worker
11218*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_AMD_seamless_cube_map_per_texture")) {
11219*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.seamless_cube_map_per_texture = 1;
11220*bbecb9d1SAndroid Build Coastguard Worker }
11221*bbecb9d1SAndroid Build Coastguard Worker
11222*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_multisample))
11223*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.texture_multisample = 1;
11224*bbecb9d1SAndroid Build Coastguard Worker
11225*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_tessellation))
11226*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.has_tessellation_shaders = 1;
11227*bbecb9d1SAndroid Build Coastguard Worker
11228*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_sample_shading))
11229*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.has_sample_shading = 1;
11230*bbecb9d1SAndroid Build Coastguard Worker
11231*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_indirect_draw))
11232*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.has_indirect_draw = 1;
11233*bbecb9d1SAndroid Build Coastguard Worker
11234*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_indep_blend_func))
11235*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.indep_blend_func = 1;
11236*bbecb9d1SAndroid Build Coastguard Worker
11237*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_cube_map_array))
11238*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.cube_map_array = 1;
11239*bbecb9d1SAndroid Build Coastguard Worker
11240*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_query_lod))
11241*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.texture_query_lod = 1;
11242*bbecb9d1SAndroid Build Coastguard Worker
11243*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver >= 40) {
11244*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.has_fp64 = 1;
11245*bbecb9d1SAndroid Build Coastguard Worker } else {
11246*bbecb9d1SAndroid Build Coastguard Worker /* need gpu shader 5 for bitfield insert */
11247*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_ARB_gpu_shader_fp64") &&
11248*bbecb9d1SAndroid Build Coastguard Worker epoxy_has_gl_extension("GL_ARB_gpu_shader5"))
11249*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.has_fp64 = 1;
11250*bbecb9d1SAndroid Build Coastguard Worker }
11251*bbecb9d1SAndroid Build Coastguard Worker
11252*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_base_instance))
11253*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.start_instance = 1;
11254*bbecb9d1SAndroid Build Coastguard Worker
11255*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_ARB_shader_stencil_export")) {
11256*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.shader_stencil_export = 1;
11257*bbecb9d1SAndroid Build Coastguard Worker }
11258*bbecb9d1SAndroid Build Coastguard Worker
11259*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_conditional_render_inverted))
11260*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.conditional_render_inverted = 1;
11261*bbecb9d1SAndroid Build Coastguard Worker
11262*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver >= 45) {
11263*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.has_cull = 1;
11264*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.derivative_control = 1;
11265*bbecb9d1SAndroid Build Coastguard Worker } else {
11266*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_cull_distance))
11267*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.has_cull = 1;
11268*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_ARB_derivative_control"))
11269*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.derivative_control = 1;
11270*bbecb9d1SAndroid Build Coastguard Worker }
11271*bbecb9d1SAndroid Build Coastguard Worker
11272*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_polygon_offset_clamp))
11273*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.polygon_offset_clamp = 1;
11274*bbecb9d1SAndroid Build Coastguard Worker
11275*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback_overflow_query))
11276*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.transform_feedback_overflow_query = 1;
11277*bbecb9d1SAndroid Build Coastguard Worker
11278*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_EXT_texture_mirror_clamp") ||
11279*bbecb9d1SAndroid Build Coastguard Worker epoxy_has_gl_extension("GL_ARB_texture_mirror_clamp_to_edge") ||
11280*bbecb9d1SAndroid Build Coastguard Worker epoxy_has_gl_extension("GL_EXT_texture_mirror_clamp_to_edge")) {
11281*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.mirror_clamp = true;
11282*bbecb9d1SAndroid Build Coastguard Worker }
11283*bbecb9d1SAndroid Build Coastguard Worker
11284*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_array)) {
11285*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max);
11286*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_texture_array_layers = max;
11287*bbecb9d1SAndroid Build Coastguard Worker }
11288*bbecb9d1SAndroid Build Coastguard Worker
11289*bbecb9d1SAndroid Build Coastguard Worker /* we need tf3 so we can do gallium skip buffers */
11290*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback)) {
11291*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback2))
11292*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.streamout_pause_resume = 1;
11293*bbecb9d1SAndroid Build Coastguard Worker
11294*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback3)) {
11295*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max);
11296*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_streamout_buffers = max;
11297*bbecb9d1SAndroid Build Coastguard Worker } else if (gles_ver > 0) {
11298*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max);
11299*bbecb9d1SAndroid Build Coastguard Worker /* As with the earlier version of transform feedback this min 4. */
11300*bbecb9d1SAndroid Build Coastguard Worker if (max >= 4) {
11301*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_streamout_buffers = 4;
11302*bbecb9d1SAndroid Build Coastguard Worker }
11303*bbecb9d1SAndroid Build Coastguard Worker } else
11304*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_streamout_buffers = 4;
11305*bbecb9d1SAndroid Build Coastguard Worker }
11306*bbecb9d1SAndroid Build Coastguard Worker
11307*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_dual_src_blend)) {
11308*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max);
11309*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_dual_source_render_targets = max;
11310*bbecb9d1SAndroid Build Coastguard Worker }
11311*bbecb9d1SAndroid Build Coastguard Worker
11312*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_or_gles_ext_texture_buffer)) {
11313*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max);
11314*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_buffer_size = caps->v1.max_tbo_size = max;
11315*bbecb9d1SAndroid Build Coastguard Worker }
11316*bbecb9d1SAndroid Build Coastguard Worker
11317*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_gather)) {
11318*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver > 0) {
11319*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB, &max);
11320*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_texture_gather_components = max;
11321*bbecb9d1SAndroid Build Coastguard Worker } else {
11322*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_texture_gather_components = 4;
11323*bbecb9d1SAndroid Build Coastguard Worker }
11324*bbecb9d1SAndroid Build Coastguard Worker }
11325*bbecb9d1SAndroid Build Coastguard Worker
11326*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_viewport_array)) {
11327*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VIEWPORTS, &max);
11328*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_viewports = max;
11329*bbecb9d1SAndroid Build Coastguard Worker } else {
11330*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_viewports = 1;
11331*bbecb9d1SAndroid Build Coastguard Worker }
11332*bbecb9d1SAndroid Build Coastguard Worker
11333*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_timer_query)) {
11334*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.timer_query = 1;
11335*bbecb9d1SAndroid Build Coastguard Worker }
11336*bbecb9d1SAndroid Build Coastguard Worker
11337*bbecb9d1SAndroid Build Coastguard Worker /* Common limits for all backends. */
11338*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_render_targets = vrend_state.max_draw_buffers;
11339*bbecb9d1SAndroid Build Coastguard Worker
11340*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_SAMPLES, &max);
11341*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_samples = max;
11342*bbecb9d1SAndroid Build Coastguard Worker
11343*bbecb9d1SAndroid Build Coastguard Worker /* All of the formats are common. */
11344*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < VIRGL_FORMAT_MAX; i++) {
11345*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats fmt = (enum virgl_formats)i;
11346*bbecb9d1SAndroid Build Coastguard Worker if (tex_conv_table[i].internalformat != 0 || fmt == VIRGL_FORMAT_YV12 ||
11347*bbecb9d1SAndroid Build Coastguard Worker fmt == VIRGL_FORMAT_NV12) {
11348*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_can_sample(fmt)) {
11349*bbecb9d1SAndroid Build Coastguard Worker set_format_bit(&caps->v1.sampler, fmt);
11350*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_can_render(fmt))
11351*bbecb9d1SAndroid Build Coastguard Worker set_format_bit(&caps->v1.render, fmt);
11352*bbecb9d1SAndroid Build Coastguard Worker }
11353*bbecb9d1SAndroid Build Coastguard Worker }
11354*bbecb9d1SAndroid Build Coastguard Worker }
11355*bbecb9d1SAndroid Build Coastguard Worker
11356*bbecb9d1SAndroid Build Coastguard Worker /* These are filled in by the init code, so are common. */
11357*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_nv_prim_restart) ||
11358*bbecb9d1SAndroid Build Coastguard Worker has_feature(feat_gl_prim_restart)) {
11359*bbecb9d1SAndroid Build Coastguard Worker caps->v1.bset.primitive_restart = 1;
11360*bbecb9d1SAndroid Build Coastguard Worker }
11361*bbecb9d1SAndroid Build Coastguard Worker }
11362*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_fill_caps_v2(int gl_ver,int gles_ver,union virgl_caps * caps)11363*bbecb9d1SAndroid Build Coastguard Worker static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_caps *caps)
11364*bbecb9d1SAndroid Build Coastguard Worker {
11365*bbecb9d1SAndroid Build Coastguard Worker GLint max;
11366*bbecb9d1SAndroid Build Coastguard Worker GLfloat range[2];
11367*bbecb9d1SAndroid Build Coastguard Worker uint32_t video_memory;
11368*bbecb9d1SAndroid Build Coastguard Worker const char *renderer = (const char *)glGetString(GL_RENDERER);
11369*bbecb9d1SAndroid Build Coastguard Worker
11370*bbecb9d1SAndroid Build Coastguard Worker /* Count this up when you add a feature flag that is used to set a CAP in
11371*bbecb9d1SAndroid Build Coastguard Worker * the guest that was set unconditionally before. Then check that flag and
11372*bbecb9d1SAndroid Build Coastguard Worker * this value to avoid regressions when a guest with a new mesa version is
11373*bbecb9d1SAndroid Build Coastguard Worker * run on an old virgl host. Use it also to indicate non-cap fixes on the
11374*bbecb9d1SAndroid Build Coastguard Worker * host that help enable features in the guest. */
11375*bbecb9d1SAndroid Build Coastguard Worker caps->v2.host_feature_check_version = 15;
11376*bbecb9d1SAndroid Build Coastguard Worker
11377*bbecb9d1SAndroid Build Coastguard Worker /* Forward host GL_RENDERER to the guest. */
11378*bbecb9d1SAndroid Build Coastguard Worker strncpy(caps->v2.renderer, renderer, sizeof(caps->v2.renderer) - 1);
11379*bbecb9d1SAndroid Build Coastguard Worker
11380*bbecb9d1SAndroid Build Coastguard Worker /* glamor reject llvmpipe, and since the renderer string is
11381*bbecb9d1SAndroid Build Coastguard Worker * composed of "virgl" and this renderer string we have to
11382*bbecb9d1SAndroid Build Coastguard Worker * hide the "llvmpipe" part */
11383*bbecb9d1SAndroid Build Coastguard Worker char *llvmpipe_string = strstr(caps->v2.renderer, "llvmpipe");
11384*bbecb9d1SAndroid Build Coastguard Worker if (llvmpipe_string)
11385*bbecb9d1SAndroid Build Coastguard Worker memcpy(llvmpipe_string, "LLVMPIPE", 8);
11386*bbecb9d1SAndroid Build Coastguard Worker
11387*bbecb9d1SAndroid Build Coastguard Worker glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, range);
11388*bbecb9d1SAndroid Build Coastguard Worker caps->v2.min_aliased_point_size = range[0];
11389*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_aliased_point_size = range[1];
11390*bbecb9d1SAndroid Build Coastguard Worker
11391*bbecb9d1SAndroid Build Coastguard Worker glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
11392*bbecb9d1SAndroid Build Coastguard Worker caps->v2.min_aliased_line_width = range[0];
11393*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_aliased_line_width = range[1];
11394*bbecb9d1SAndroid Build Coastguard Worker
11395*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver > 0) {
11396*bbecb9d1SAndroid Build Coastguard Worker glGetFloatv(GL_SMOOTH_POINT_SIZE_RANGE, range);
11397*bbecb9d1SAndroid Build Coastguard Worker caps->v2.min_smooth_point_size = range[0];
11398*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_smooth_point_size = range[1];
11399*bbecb9d1SAndroid Build Coastguard Worker
11400*bbecb9d1SAndroid Build Coastguard Worker glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range);
11401*bbecb9d1SAndroid Build Coastguard Worker caps->v2.min_smooth_line_width = range[0];
11402*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_smooth_line_width = range[1];
11403*bbecb9d1SAndroid Build Coastguard Worker }
11404*bbecb9d1SAndroid Build Coastguard Worker
11405*bbecb9d1SAndroid Build Coastguard Worker glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->v2.max_texture_lod_bias);
11406*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, (GLint*)&caps->v2.max_vertex_attribs);
11407*bbecb9d1SAndroid Build Coastguard Worker
11408*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver >= 32 || (vrend_state.use_gles && gl_ver >= 30))
11409*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &max);
11410*bbecb9d1SAndroid Build Coastguard Worker else
11411*bbecb9d1SAndroid Build Coastguard Worker max = 64; // minimum required value
11412*bbecb9d1SAndroid Build Coastguard Worker
11413*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_vertex_outputs = max / 4;
11414*bbecb9d1SAndroid Build Coastguard Worker
11415*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->v2.min_texel_offset);
11416*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->v2.max_texel_offset);
11417*bbecb9d1SAndroid Build Coastguard Worker
11418*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, (GLint*)&caps->v2.uniform_buffer_offset_alignment);
11419*bbecb9d1SAndroid Build Coastguard Worker
11420*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&caps->v2.max_texture_2d_size);
11421*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&caps->v2.max_texture_3d_size);
11422*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&caps->v2.max_texture_cube_size);
11423*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_2d_size = caps->v2.max_texture_2d_size;
11424*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_3d_size = caps->v2.max_texture_3d_size;
11425*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_cube_size = caps->v2.max_texture_cube_size;
11426*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_features, NULL, "Texture limits: 2D:%u 3D:%u Cube:%u\n",
11427*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_2d_size, vrend_state.max_texture_3d_size,
11428*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_texture_cube_size);
11429*bbecb9d1SAndroid Build Coastguard Worker
11430*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_geometry_shader)) {
11431*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, (GLint*)&caps->v2.max_geom_output_vertices);
11432*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, (GLint*)&caps->v2.max_geom_total_output_components);
11433*bbecb9d1SAndroid Build Coastguard Worker }
11434*bbecb9d1SAndroid Build Coastguard Worker
11435*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_tessellation)) {
11436*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TESS_PATCH_COMPONENTS, &max);
11437*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_shader_patch_varyings = max / 4;
11438*bbecb9d1SAndroid Build Coastguard Worker } else
11439*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_shader_patch_varyings = 0;
11440*bbecb9d1SAndroid Build Coastguard Worker
11441*bbecb9d1SAndroid Build Coastguard Worker vrend_state.max_shader_patch_varyings = caps->v2.max_shader_patch_varyings;
11442*bbecb9d1SAndroid Build Coastguard Worker
11443*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_gather)) {
11444*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, &caps->v2.min_texture_gather_offset);
11445*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, &caps->v2.max_texture_gather_offset);
11446*bbecb9d1SAndroid Build Coastguard Worker }
11447*bbecb9d1SAndroid Build Coastguard Worker
11448*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_buffer_range)) {
11449*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, (GLint*)&caps->v2.texture_buffer_offset_alignment);
11450*bbecb9d1SAndroid Build Coastguard Worker }
11451*bbecb9d1SAndroid Build Coastguard Worker
11452*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_ssbo)) {
11453*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, (GLint*)&caps->v2.shader_buffer_offset_alignment);
11454*bbecb9d1SAndroid Build Coastguard Worker
11455*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max);
11456*bbecb9d1SAndroid Build Coastguard Worker if (max > PIPE_MAX_SHADER_BUFFERS)
11457*bbecb9d1SAndroid Build Coastguard Worker max = PIPE_MAX_SHADER_BUFFERS;
11458*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_shader_buffer_other_stages = max;
11459*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &max);
11460*bbecb9d1SAndroid Build Coastguard Worker if (max > PIPE_MAX_SHADER_BUFFERS)
11461*bbecb9d1SAndroid Build Coastguard Worker max = PIPE_MAX_SHADER_BUFFERS;
11462*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_shader_buffer_frag_compute = max;
11463*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS,
11464*bbecb9d1SAndroid Build Coastguard Worker (GLint*)&caps->v2.max_combined_shader_buffers);
11465*bbecb9d1SAndroid Build Coastguard Worker }
11466*bbecb9d1SAndroid Build Coastguard Worker
11467*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_images)) {
11468*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &max);
11469*bbecb9d1SAndroid Build Coastguard Worker if (max > PIPE_MAX_SHADER_IMAGES)
11470*bbecb9d1SAndroid Build Coastguard Worker max = PIPE_MAX_SHADER_IMAGES;
11471*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_shader_image_other_stages = max;
11472*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &max);
11473*bbecb9d1SAndroid Build Coastguard Worker if (max > PIPE_MAX_SHADER_IMAGES)
11474*bbecb9d1SAndroid Build Coastguard Worker max = PIPE_MAX_SHADER_IMAGES;
11475*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_shader_image_frag_compute = max;
11476*bbecb9d1SAndroid Build Coastguard Worker
11477*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver > 0) /* Seems GLES doesn't support multisample images */
11478*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_IMAGE_SAMPLES, (GLint*)&caps->v2.max_image_samples);
11479*bbecb9d1SAndroid Build Coastguard Worker }
11480*bbecb9d1SAndroid Build Coastguard Worker
11481*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_storage_multisample))
11482*bbecb9d1SAndroid Build Coastguard Worker caps->v1.max_samples = vrend_renderer_query_multisample_caps(caps->v1.max_samples, &caps->v2);
11483*bbecb9d1SAndroid Build Coastguard Worker
11484*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TGSI_INVARIANT | VIRGL_CAP_SET_MIN_SAMPLES |
11485*bbecb9d1SAndroid Build Coastguard Worker VIRGL_CAP_TGSI_PRECISE | VIRGL_CAP_APP_TWEAK_SUPPORT;
11486*bbecb9d1SAndroid Build Coastguard Worker
11487*bbecb9d1SAndroid Build Coastguard Worker /* If attribute isn't supported, assume 2048 which is the minimum allowed
11488*bbecb9d1SAndroid Build Coastguard Worker by the specification. */
11489*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver >= 44 || gles_ver >= 31)
11490*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, (GLint*)&caps->v2.max_vertex_attrib_stride);
11491*bbecb9d1SAndroid Build Coastguard Worker else
11492*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_vertex_attrib_stride = 2048;
11493*bbecb9d1SAndroid Build Coastguard Worker
11494*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_compute_shader) && (vrend_state.use_gles || gl_ver >= 33)) {
11495*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, (GLint*)&caps->v2.max_compute_work_group_invocations);
11496*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, (GLint*)&caps->v2.max_compute_shared_memory_size);
11497*bbecb9d1SAndroid Build Coastguard Worker glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, (GLint*)&caps->v2.max_compute_grid_size[0]);
11498*bbecb9d1SAndroid Build Coastguard Worker glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, (GLint*)&caps->v2.max_compute_grid_size[1]);
11499*bbecb9d1SAndroid Build Coastguard Worker glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, (GLint*)&caps->v2.max_compute_grid_size[2]);
11500*bbecb9d1SAndroid Build Coastguard Worker glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, (GLint*)&caps->v2.max_compute_block_size[0]);
11501*bbecb9d1SAndroid Build Coastguard Worker glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, (GLint*)&caps->v2.max_compute_block_size[1]);
11502*bbecb9d1SAndroid Build Coastguard Worker glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, (GLint*)&caps->v2.max_compute_block_size[2]);
11503*bbecb9d1SAndroid Build Coastguard Worker
11504*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_COMPUTE_SHADER;
11505*bbecb9d1SAndroid Build Coastguard Worker }
11506*bbecb9d1SAndroid Build Coastguard Worker
11507*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_atomic_counters)) {
11508*bbecb9d1SAndroid Build Coastguard Worker
11509*bbecb9d1SAndroid Build Coastguard Worker /* On GLES hosts we want atomics to be lowered to SSBOs */
11510*bbecb9d1SAndroid Build Coastguard Worker if (gl_ver > 0) {
11511*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS,
11512*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counters + PIPE_SHADER_VERTEX));
11513*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS,
11514*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counters + PIPE_SHADER_FRAGMENT));
11515*bbecb9d1SAndroid Build Coastguard Worker
11516*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_geometry_shader)) {
11517*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTERS,
11518*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counters + PIPE_SHADER_GEOMETRY));
11519*bbecb9d1SAndroid Build Coastguard Worker }
11520*bbecb9d1SAndroid Build Coastguard Worker
11521*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_tessellation)) {
11522*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS,
11523*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counters + PIPE_SHADER_TESS_CTRL));
11524*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS,
11525*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counters + PIPE_SHADER_TESS_EVAL));
11526*bbecb9d1SAndroid Build Coastguard Worker }
11527*bbecb9d1SAndroid Build Coastguard Worker
11528*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_compute_shader)) {
11529*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTERS,
11530*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counters + PIPE_SHADER_COMPUTE));
11531*bbecb9d1SAndroid Build Coastguard Worker }
11532*bbecb9d1SAndroid Build Coastguard Worker
11533*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTERS,
11534*bbecb9d1SAndroid Build Coastguard Worker (GLint*)&caps->v2.max_combined_atomic_counters);
11535*bbecb9d1SAndroid Build Coastguard Worker }
11536*bbecb9d1SAndroid Build Coastguard Worker
11537*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS,
11538*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counter_buffers + PIPE_SHADER_VERTEX));
11539*bbecb9d1SAndroid Build Coastguard Worker
11540*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS,
11541*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counter_buffers + PIPE_SHADER_FRAGMENT));
11542*bbecb9d1SAndroid Build Coastguard Worker
11543*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_geometry_shader))
11544*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS,
11545*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counter_buffers + PIPE_SHADER_GEOMETRY));
11546*bbecb9d1SAndroid Build Coastguard Worker
11547*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_tessellation)) {
11548*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS,
11549*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counter_buffers + PIPE_SHADER_TESS_CTRL));
11550*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS,
11551*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counter_buffers + PIPE_SHADER_TESS_EVAL));
11552*bbecb9d1SAndroid Build Coastguard Worker }
11553*bbecb9d1SAndroid Build Coastguard Worker
11554*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_compute_shader)) {
11555*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS,
11556*bbecb9d1SAndroid Build Coastguard Worker (GLint*)(caps->v2.max_atomic_counter_buffers + PIPE_SHADER_COMPUTE));
11557*bbecb9d1SAndroid Build Coastguard Worker }
11558*bbecb9d1SAndroid Build Coastguard Worker
11559*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS,
11560*bbecb9d1SAndroid Build Coastguard Worker (GLint*)&caps->v2.max_combined_atomic_counter_buffers);
11561*bbecb9d1SAndroid Build Coastguard Worker }
11562*bbecb9d1SAndroid Build Coastguard Worker
11563*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_fb_no_attach))
11564*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_FB_NO_ATTACH;
11565*bbecb9d1SAndroid Build Coastguard Worker
11566*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_view))
11567*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TEXTURE_VIEW;
11568*bbecb9d1SAndroid Build Coastguard Worker
11569*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_txqs))
11570*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TXQS;
11571*bbecb9d1SAndroid Build Coastguard Worker
11572*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_barrier))
11573*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_MEMORY_BARRIER;
11574*bbecb9d1SAndroid Build Coastguard Worker
11575*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_copy_image))
11576*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_COPY_IMAGE;
11577*bbecb9d1SAndroid Build Coastguard Worker
11578*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_robust_buffer_access))
11579*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_ROBUST_BUFFER_ACCESS;
11580*bbecb9d1SAndroid Build Coastguard Worker
11581*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_framebuffer_fetch))
11582*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TGSI_FBFETCH;
11583*bbecb9d1SAndroid Build Coastguard Worker
11584*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_shader_clock))
11585*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_SHADER_CLOCK;
11586*bbecb9d1SAndroid Build Coastguard Worker
11587*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_barrier))
11588*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TEXTURE_BARRIER;
11589*bbecb9d1SAndroid Build Coastguard Worker
11590*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TGSI_COMPONENTS;
11591*bbecb9d1SAndroid Build Coastguard Worker
11592*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_srgb_write_control))
11593*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_SRGB_WRITE_CONTROL;
11594*bbecb9d1SAndroid Build Coastguard Worker
11595*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_transform_feedback3))
11596*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TRANSFORM_FEEDBACK3;
11597*bbecb9d1SAndroid Build Coastguard Worker /* Enable feature use just now otherwise we just get a lot noise because
11598*bbecb9d1SAndroid Build Coastguard Worker * of the caps setting */
11599*bbecb9d1SAndroid Build Coastguard Worker if (vrend_debug(NULL, dbg_features))
11600*bbecb9d1SAndroid Build Coastguard Worker vrend_debug_add_flag(dbg_feature_use);
11601*bbecb9d1SAndroid Build Coastguard Worker
11602*bbecb9d1SAndroid Build Coastguard Worker /* always enable, only indicates that the CMD is supported */
11603*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_GUEST_MAY_INIT_LOG;
11604*bbecb9d1SAndroid Build Coastguard Worker
11605*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_qbo))
11606*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_QBO;
11607*bbecb9d1SAndroid Build Coastguard Worker
11608*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_TRANSFER;
11609*bbecb9d1SAndroid Build Coastguard Worker
11610*bbecb9d1SAndroid Build Coastguard Worker if (vrend_check_framebuffer_mixed_color_attachements())
11611*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_FBO_MIXED_COLOR_FORMATS;
11612*bbecb9d1SAndroid Build Coastguard Worker
11613*bbecb9d1SAndroid Build Coastguard Worker /* We want to expose ARB_gpu_shader_fp64 when running on top of ES */
11614*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
11615*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_HOST_IS_GLES;
11616*bbecb9d1SAndroid Build Coastguard Worker }
11617*bbecb9d1SAndroid Build Coastguard Worker
11618*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_indirect_draw))
11619*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_BIND_COMMAND_ARGS;
11620*bbecb9d1SAndroid Build Coastguard Worker
11621*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_multi_draw_indirect))
11622*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_MULTI_DRAW_INDIRECT;
11623*bbecb9d1SAndroid Build Coastguard Worker
11624*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_indirect_params))
11625*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_INDIRECT_PARAMS;
11626*bbecb9d1SAndroid Build Coastguard Worker
11627*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < VIRGL_FORMAT_MAX; i++) {
11628*bbecb9d1SAndroid Build Coastguard Worker enum virgl_formats fmt = (enum virgl_formats)i;
11629*bbecb9d1SAndroid Build Coastguard Worker if (tex_conv_table[i].internalformat != 0) {
11630*bbecb9d1SAndroid Build Coastguard Worker const char *readback_str = "";
11631*bbecb9d1SAndroid Build Coastguard Worker const char *multisample_str = "";
11632*bbecb9d1SAndroid Build Coastguard Worker bool log_texture_feature = false;
11633*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_can_readback(fmt)) {
11634*bbecb9d1SAndroid Build Coastguard Worker log_texture_feature = true;
11635*bbecb9d1SAndroid Build Coastguard Worker readback_str = "readback";
11636*bbecb9d1SAndroid Build Coastguard Worker set_format_bit(&caps->v2.supported_readback_formats, fmt);
11637*bbecb9d1SAndroid Build Coastguard Worker }
11638*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_can_multisample(fmt)) {
11639*bbecb9d1SAndroid Build Coastguard Worker log_texture_feature = true;
11640*bbecb9d1SAndroid Build Coastguard Worker multisample_str = "multisample";
11641*bbecb9d1SAndroid Build Coastguard Worker set_format_bit(&caps->v2.supported_multisample_formats, fmt);
11642*bbecb9d1SAndroid Build Coastguard Worker }
11643*bbecb9d1SAndroid Build Coastguard Worker if (log_texture_feature)
11644*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_features, NULL, "%s: Supports %s %s\n",
11645*bbecb9d1SAndroid Build Coastguard Worker util_format_name(fmt), readback_str, multisample_str);
11646*bbecb9d1SAndroid Build Coastguard Worker }
11647*bbecb9d1SAndroid Build Coastguard Worker
11648*bbecb9d1SAndroid Build Coastguard Worker if (vrend_format_can_scanout(fmt))
11649*bbecb9d1SAndroid Build Coastguard Worker set_format_bit(&caps->v2.scanout, fmt);
11650*bbecb9d1SAndroid Build Coastguard Worker }
11651*bbecb9d1SAndroid Build Coastguard Worker
11652*bbecb9d1SAndroid Build Coastguard Worker /* Needed for framebuffer_no_attachment */
11653*bbecb9d1SAndroid Build Coastguard Worker set_format_bit(&caps->v2.supported_multisample_formats, VIRGL_FORMAT_NONE);
11654*bbecb9d1SAndroid Build Coastguard Worker
11655*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_clear_texture))
11656*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_CLEAR_TEXTURE;
11657*bbecb9d1SAndroid Build Coastguard Worker
11658*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_clip_control))
11659*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_CLIP_HALFZ;
11660*bbecb9d1SAndroid Build Coastguard Worker
11661*bbecb9d1SAndroid Build Coastguard Worker if (epoxy_has_gl_extension("GL_KHR_texture_compression_astc_sliced_3d"))
11662*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_3D_ASTC;
11663*bbecb9d1SAndroid Build Coastguard Worker
11664*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_INDIRECT_INPUT_ADDR;
11665*bbecb9d1SAndroid Build Coastguard Worker
11666*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_COPY_TRANSFER;
11667*bbecb9d1SAndroid Build Coastguard Worker
11668*bbecb9d1SAndroid Build Coastguard Worker
11669*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_buffer_storage) && !vrend_state.use_external_blob) {
11670*bbecb9d1SAndroid Build Coastguard Worker const char *vendor = (const char *)glGetString(GL_VENDOR);
11671*bbecb9d1SAndroid Build Coastguard Worker bool is_mesa = ((strstr(renderer, "Mesa") != NULL) || (strstr(renderer, "DRM") != NULL) ||
11672*bbecb9d1SAndroid Build Coastguard Worker (strstr(renderer, "llvmpipe") != NULL));
11673*bbecb9d1SAndroid Build Coastguard Worker /*
11674*bbecb9d1SAndroid Build Coastguard Worker * Intel GPUs (aside from Atom, which doesn't expose GL4.5) are cache-coherent.
11675*bbecb9d1SAndroid Build Coastguard Worker * Mesa AMDGPUs use write-combine mappings for coherent/persistent memory (see
11676*bbecb9d1SAndroid Build Coastguard Worker * RADEON_FLAG_GTT_WC in si_buffer.c/r600_buffer_common.c). For Nvidia, we can guess and
11677*bbecb9d1SAndroid Build Coastguard Worker * check. Long term, maybe a GL extension or using VK could replace these heuristics.
11678*bbecb9d1SAndroid Build Coastguard Worker *
11679*bbecb9d1SAndroid Build Coastguard Worker * Note Intel VMX ignores the caching type returned from virglrenderer, while AMD SVM and
11680*bbecb9d1SAndroid Build Coastguard Worker * ARM honor it.
11681*bbecb9d1SAndroid Build Coastguard Worker */
11682*bbecb9d1SAndroid Build Coastguard Worker if (is_mesa) {
11683*bbecb9d1SAndroid Build Coastguard Worker if (strstr(vendor, "Intel") != NULL)
11684*bbecb9d1SAndroid Build Coastguard Worker vrend_state.inferred_gl_caching_type = VIRGL_RENDERER_MAP_CACHE_CACHED;
11685*bbecb9d1SAndroid Build Coastguard Worker else if (strstr(vendor, "AMD") != NULL)
11686*bbecb9d1SAndroid Build Coastguard Worker vrend_state.inferred_gl_caching_type = VIRGL_RENDERER_MAP_CACHE_WC;
11687*bbecb9d1SAndroid Build Coastguard Worker else if (strstr(vendor, "Mesa") != NULL)
11688*bbecb9d1SAndroid Build Coastguard Worker vrend_state.inferred_gl_caching_type = VIRGL_RENDERER_MAP_CACHE_CACHED;
11689*bbecb9d1SAndroid Build Coastguard Worker } else {
11690*bbecb9d1SAndroid Build Coastguard Worker /* This is an educated guess since things don't explode with VMX + Nvidia. */
11691*bbecb9d1SAndroid Build Coastguard Worker if (strstr(renderer, "Quadro K2200") != NULL)
11692*bbecb9d1SAndroid Build Coastguard Worker vrend_state.inferred_gl_caching_type = VIRGL_RENDERER_MAP_CACHE_CACHED;
11693*bbecb9d1SAndroid Build Coastguard Worker }
11694*bbecb9d1SAndroid Build Coastguard Worker
11695*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.inferred_gl_caching_type)
11696*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_ARB_BUFFER_STORAGE;
11697*bbecb9d1SAndroid Build Coastguard Worker }
11698*bbecb9d1SAndroid Build Coastguard Worker
11699*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
11700*bbecb9d1SAndroid Build Coastguard Worker if (gbm) {
11701*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_memory_object) && has_feature(feat_memory_object_fd)) {
11702*bbecb9d1SAndroid Build Coastguard Worker if ((!strcmp(gbm_device_get_backend_name(gbm->device), "i915") ||
11703*bbecb9d1SAndroid Build Coastguard Worker !strcmp(gbm_device_get_backend_name(gbm->device), "amdgpu")) &&
11704*bbecb9d1SAndroid Build Coastguard Worker !vrend_winsys_different_gpu())
11705*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits |= VIRGL_CAP_ARB_BUFFER_STORAGE;
11706*bbecb9d1SAndroid Build Coastguard Worker }
11707*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_SCANOUT_USES_GBM;
11708*bbecb9d1SAndroid Build Coastguard Worker }
11709*bbecb9d1SAndroid Build Coastguard Worker #endif
11710*bbecb9d1SAndroid Build Coastguard Worker
11711*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_blend_equation_advanced))
11712*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_BLEND_EQUATION;
11713*bbecb9d1SAndroid Build Coastguard Worker
11714*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
11715*bbecb9d1SAndroid Build Coastguard Worker if (egl)
11716*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_UNTYPED_RESOURCE;
11717*bbecb9d1SAndroid Build Coastguard Worker #endif
11718*bbecb9d1SAndroid Build Coastguard Worker
11719*bbecb9d1SAndroid Build Coastguard Worker video_memory = vrend_renderer_get_video_memory();
11720*bbecb9d1SAndroid Build Coastguard Worker if (video_memory) {
11721*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_VIDEO_MEMORY;
11722*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_video_memory = video_memory;
11723*bbecb9d1SAndroid Build Coastguard Worker }
11724*bbecb9d1SAndroid Build Coastguard Worker
11725*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_ati_meminfo) || has_feature(feat_nvx_gpu_memory_info)) {
11726*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_MEMINFO;
11727*bbecb9d1SAndroid Build Coastguard Worker }
11728*bbecb9d1SAndroid Build Coastguard Worker
11729*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_khr_debug))
11730*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_STRING_MARKER;
11731*bbecb9d1SAndroid Build Coastguard Worker
11732*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_implicit_msaa))
11733*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_IMPLICIT_MSAA;
11734*bbecb9d1SAndroid Build Coastguard Worker
11735*bbecb9d1SAndroid Build Coastguard Worker if (vrend_winsys_different_gpu())
11736*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_DIFFERENT_GPU;
11737*bbecb9d1SAndroid Build Coastguard Worker
11738*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_texture_shadow_lod))
11739*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_TEXTURE_SHADOW_LOD;
11740*bbecb9d1SAndroid Build Coastguard Worker
11741*bbecb9d1SAndroid Build Coastguard Worker // we use capability bits (not a version of protocol), because
11742*bbecb9d1SAndroid Build Coastguard Worker // we disable this on client side if virglrenderer is used under
11743*bbecb9d1SAndroid Build Coastguard Worker // vtest. vtest can't support this, because size of resource
11744*bbecb9d1SAndroid Build Coastguard Worker // is used to create shmem. On drm path, we can use this, because
11745*bbecb9d1SAndroid Build Coastguard Worker // size of drm resource (bo) is not passed to virglrenderer and
11746*bbecb9d1SAndroid Build Coastguard Worker // we can pass "1" as size on drm path, but not on vtest.
11747*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_COPY_TRANSFER_BOTH_DIRECTIONS;
11748*bbecb9d1SAndroid Build Coastguard Worker
11749*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_anisotropic_filter)) {
11750*bbecb9d1SAndroid Build Coastguard Worker float max_aniso;
11751*bbecb9d1SAndroid Build Coastguard Worker glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &max_aniso);
11752*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_anisotropy = MIN2(max_aniso, 16.0);
11753*bbecb9d1SAndroid Build Coastguard Worker }
11754*bbecb9d1SAndroid Build Coastguard Worker
11755*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max);
11756*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_texture_image_units = MIN2(max, PIPE_MAX_SHADER_SAMPLER_VIEWS);
11757*bbecb9d1SAndroid Build Coastguard Worker
11758*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_ubo)) {
11759*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max);
11760*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_uniform_block_size = max;
11761*bbecb9d1SAndroid Build Coastguard Worker }
11762*bbecb9d1SAndroid Build Coastguard Worker
11763*bbecb9d1SAndroid Build Coastguard Worker /* Propagate the max of Uniform Components */
11764*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max);
11765*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_const_buffer_size[PIPE_SHADER_VERTEX] = max * 4;
11766*bbecb9d1SAndroid Build Coastguard Worker
11767*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max);
11768*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_const_buffer_size[PIPE_SHADER_FRAGMENT] = max * 4;
11769*bbecb9d1SAndroid Build Coastguard Worker
11770*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_geometry_shader)) {
11771*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, &max);
11772*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_const_buffer_size[PIPE_SHADER_GEOMETRY] = max * 4;
11773*bbecb9d1SAndroid Build Coastguard Worker }
11774*bbecb9d1SAndroid Build Coastguard Worker
11775*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_tessellation)) {
11776*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, &max);
11777*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_const_buffer_size[PIPE_SHADER_TESS_CTRL] = max * 4;
11778*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, &max);
11779*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_const_buffer_size[PIPE_SHADER_TESS_EVAL] = max * 4;
11780*bbecb9d1SAndroid Build Coastguard Worker }
11781*bbecb9d1SAndroid Build Coastguard Worker
11782*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_compute_shader)) {
11783*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_COMPONENTS, &max);
11784*bbecb9d1SAndroid Build Coastguard Worker caps->v2.max_const_buffer_size[PIPE_SHADER_COMPUTE] = max * 4;
11785*bbecb9d1SAndroid Build Coastguard Worker }
11786*bbecb9d1SAndroid Build Coastguard Worker
11787*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_separate_shader_objects))
11788*bbecb9d1SAndroid Build Coastguard Worker caps->v2.capability_bits_v2 |= VIRGL_CAP_V2_SSO;
11789*bbecb9d1SAndroid Build Coastguard Worker
11790*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
11791*bbecb9d1SAndroid Build Coastguard Worker vrend_video_fill_caps(caps);
11792*bbecb9d1SAndroid Build Coastguard Worker #else
11793*bbecb9d1SAndroid Build Coastguard Worker caps->v2.num_video_caps = 0;
11794*bbecb9d1SAndroid Build Coastguard Worker #endif
11795*bbecb9d1SAndroid Build Coastguard Worker }
11796*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_fill_caps(uint32_t set,uint32_t version,union virgl_caps * caps)11797*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
11798*bbecb9d1SAndroid Build Coastguard Worker union virgl_caps *caps)
11799*bbecb9d1SAndroid Build Coastguard Worker {
11800*bbecb9d1SAndroid Build Coastguard Worker int gl_ver, gles_ver;
11801*bbecb9d1SAndroid Build Coastguard Worker GLenum err;
11802*bbecb9d1SAndroid Build Coastguard Worker bool fill_capset2 = false;
11803*bbecb9d1SAndroid Build Coastguard Worker
11804*bbecb9d1SAndroid Build Coastguard Worker if (!caps)
11805*bbecb9d1SAndroid Build Coastguard Worker return;
11806*bbecb9d1SAndroid Build Coastguard Worker
11807*bbecb9d1SAndroid Build Coastguard Worker switch (set) {
11808*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_RENDERER_CAPSET_VIRGL:
11809*bbecb9d1SAndroid Build Coastguard Worker if (version > VREND_CAPSET_VIRGL_MAX_VERSION)
11810*bbecb9d1SAndroid Build Coastguard Worker return;
11811*bbecb9d1SAndroid Build Coastguard Worker memset(caps, 0, sizeof(struct virgl_caps_v1));
11812*bbecb9d1SAndroid Build Coastguard Worker caps->max_version = VREND_CAPSET_VIRGL_MAX_VERSION;
11813*bbecb9d1SAndroid Build Coastguard Worker break;
11814*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_RENDERER_CAPSET_VIRGL2:
11815*bbecb9d1SAndroid Build Coastguard Worker if (version > VREND_CAPSET_VIRGL2_MAX_VERSION)
11816*bbecb9d1SAndroid Build Coastguard Worker return;
11817*bbecb9d1SAndroid Build Coastguard Worker memset(caps, 0, sizeof(*caps));
11818*bbecb9d1SAndroid Build Coastguard Worker caps->max_version = VREND_CAPSET_VIRGL2_MAX_VERSION;
11819*bbecb9d1SAndroid Build Coastguard Worker fill_capset2 = true;
11820*bbecb9d1SAndroid Build Coastguard Worker break;
11821*bbecb9d1SAndroid Build Coastguard Worker default:
11822*bbecb9d1SAndroid Build Coastguard Worker return;
11823*bbecb9d1SAndroid Build Coastguard Worker }
11824*bbecb9d1SAndroid Build Coastguard Worker
11825*bbecb9d1SAndroid Build Coastguard Worker /* We don't want to deal with stale error states that the caller might not
11826*bbecb9d1SAndroid Build Coastguard Worker * have cleaned up propperly, so read the error state until we are okay.
11827*bbecb9d1SAndroid Build Coastguard Worker */
11828*bbecb9d1SAndroid Build Coastguard Worker while ((err = glGetError()) != GL_NO_ERROR)
11829*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: Entering with stale GL error: %d\n", __func__, err);
11830*bbecb9d1SAndroid Build Coastguard Worker
11831*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles) {
11832*bbecb9d1SAndroid Build Coastguard Worker gles_ver = epoxy_gl_version();
11833*bbecb9d1SAndroid Build Coastguard Worker gl_ver = 0;
11834*bbecb9d1SAndroid Build Coastguard Worker } else {
11835*bbecb9d1SAndroid Build Coastguard Worker gles_ver = 0;
11836*bbecb9d1SAndroid Build Coastguard Worker gl_ver = epoxy_gl_version();
11837*bbecb9d1SAndroid Build Coastguard Worker }
11838*bbecb9d1SAndroid Build Coastguard Worker
11839*bbecb9d1SAndroid Build Coastguard Worker vrend_fill_caps_glsl_version(gl_ver, gles_ver, caps);
11840*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_features, NULL, "GLSL support level: %d", caps->v1.glsl_level);
11841*bbecb9d1SAndroid Build Coastguard Worker
11842*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_fill_caps_v1(gl_ver, gles_ver, caps);
11843*bbecb9d1SAndroid Build Coastguard Worker
11844*bbecb9d1SAndroid Build Coastguard Worker if (!fill_capset2)
11845*bbecb9d1SAndroid Build Coastguard Worker return;
11846*bbecb9d1SAndroid Build Coastguard Worker
11847*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_fill_caps_v2(gl_ver, gles_ver, caps);
11848*bbecb9d1SAndroid Build Coastguard Worker }
11849*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_get_timestamp(void)11850*bbecb9d1SAndroid Build Coastguard Worker GLint64 vrend_renderer_get_timestamp(void)
11851*bbecb9d1SAndroid Build Coastguard Worker {
11852*bbecb9d1SAndroid Build Coastguard Worker GLint64 v;
11853*bbecb9d1SAndroid Build Coastguard Worker glGetInteger64v(GL_TIMESTAMP, &v);
11854*bbecb9d1SAndroid Build Coastguard Worker return v;
11855*bbecb9d1SAndroid Build Coastguard Worker }
11856*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_get_cursor_contents(struct pipe_resource * pres,uint32_t * width,uint32_t * height)11857*bbecb9d1SAndroid Build Coastguard Worker void *vrend_renderer_get_cursor_contents(struct pipe_resource *pres,
11858*bbecb9d1SAndroid Build Coastguard Worker uint32_t *width,
11859*bbecb9d1SAndroid Build Coastguard Worker uint32_t *height)
11860*bbecb9d1SAndroid Build Coastguard Worker {
11861*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
11862*bbecb9d1SAndroid Build Coastguard Worker GLenum format, type;
11863*bbecb9d1SAndroid Build Coastguard Worker int blsize;
11864*bbecb9d1SAndroid Build Coastguard Worker char *data, *data2;
11865*bbecb9d1SAndroid Build Coastguard Worker int size;
11866*bbecb9d1SAndroid Build Coastguard Worker uint h;
11867*bbecb9d1SAndroid Build Coastguard Worker
11868*bbecb9d1SAndroid Build Coastguard Worker if (res->base.width0 > 128 || res->base.height0 > 128)
11869*bbecb9d1SAndroid Build Coastguard Worker return NULL;
11870*bbecb9d1SAndroid Build Coastguard Worker
11871*bbecb9d1SAndroid Build Coastguard Worker if (res->target != GL_TEXTURE_2D)
11872*bbecb9d1SAndroid Build Coastguard Worker return NULL;
11873*bbecb9d1SAndroid Build Coastguard Worker
11874*bbecb9d1SAndroid Build Coastguard Worker if (!width || !height)
11875*bbecb9d1SAndroid Build Coastguard Worker return NULL;
11876*bbecb9d1SAndroid Build Coastguard Worker
11877*bbecb9d1SAndroid Build Coastguard Worker *width = res->base.width0;
11878*bbecb9d1SAndroid Build Coastguard Worker *height = res->base.height0;
11879*bbecb9d1SAndroid Build Coastguard Worker
11880*bbecb9d1SAndroid Build Coastguard Worker format = tex_conv_table[res->base.format].glformat;
11881*bbecb9d1SAndroid Build Coastguard Worker type = tex_conv_table[res->base.format].gltype;
11882*bbecb9d1SAndroid Build Coastguard Worker blsize = util_format_get_blocksize(res->base.format);
11883*bbecb9d1SAndroid Build Coastguard Worker size = util_format_get_nblocks(res->base.format, res->base.width0, res->base.height0) * blsize;
11884*bbecb9d1SAndroid Build Coastguard Worker data = malloc(size);
11885*bbecb9d1SAndroid Build Coastguard Worker data2 = malloc(size);
11886*bbecb9d1SAndroid Build Coastguard Worker
11887*bbecb9d1SAndroid Build Coastguard Worker if (!data || !data2) {
11888*bbecb9d1SAndroid Build Coastguard Worker free(data);
11889*bbecb9d1SAndroid Build Coastguard Worker free(data2);
11890*bbecb9d1SAndroid Build Coastguard Worker return NULL;
11891*bbecb9d1SAndroid Build Coastguard Worker }
11892*bbecb9d1SAndroid Build Coastguard Worker
11893*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_arb_robustness)) {
11894*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(res->target, res->id);
11895*bbecb9d1SAndroid Build Coastguard Worker glGetnTexImageARB(res->target, 0, format, type, size, data);
11896*bbecb9d1SAndroid Build Coastguard Worker } else if (vrend_state.use_gles) {
11897*bbecb9d1SAndroid Build Coastguard Worker do_readpixels(res, 0, 0, 0, 0, 0, *width, *height, format, type, size, data);
11898*bbecb9d1SAndroid Build Coastguard Worker } else {
11899*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(res->target, res->id);
11900*bbecb9d1SAndroid Build Coastguard Worker glGetTexImage(res->target, 0, format, type, data);
11901*bbecb9d1SAndroid Build Coastguard Worker }
11902*bbecb9d1SAndroid Build Coastguard Worker
11903*bbecb9d1SAndroid Build Coastguard Worker for (h = 0; h < res->base.height0; h++) {
11904*bbecb9d1SAndroid Build Coastguard Worker uint32_t doff = (res->base.height0 - h - 1) * res->base.width0 * blsize;
11905*bbecb9d1SAndroid Build Coastguard Worker uint32_t soff = h * res->base.width0 * blsize;
11906*bbecb9d1SAndroid Build Coastguard Worker
11907*bbecb9d1SAndroid Build Coastguard Worker memcpy(data2 + doff, data + soff, res->base.width0 * blsize);
11908*bbecb9d1SAndroid Build Coastguard Worker }
11909*bbecb9d1SAndroid Build Coastguard Worker free(data);
11910*bbecb9d1SAndroid Build Coastguard Worker glBindTexture(res->target, 0);
11911*bbecb9d1SAndroid Build Coastguard Worker return data2;
11912*bbecb9d1SAndroid Build Coastguard Worker }
11913*bbecb9d1SAndroid Build Coastguard Worker
11914*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_force_ctx_0(void)11915*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_force_ctx_0(void)
11916*bbecb9d1SAndroid Build Coastguard Worker {
11917*bbecb9d1SAndroid Build Coastguard Worker TRACE_FUNC();
11918*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_ctx = NULL;
11919*bbecb9d1SAndroid Build Coastguard Worker vrend_state.current_hw_ctx = NULL;
11920*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_switch_context(vrend_state.ctx0, true);
11921*bbecb9d1SAndroid Build Coastguard Worker }
11922*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_get_rect(struct pipe_resource * pres,const struct iovec * iov,unsigned int num_iovs,uint32_t offset,int x,int y,int width,int height)11923*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_get_rect(struct pipe_resource *pres,
11924*bbecb9d1SAndroid Build Coastguard Worker const struct iovec *iov, unsigned int num_iovs,
11925*bbecb9d1SAndroid Build Coastguard Worker uint32_t offset,
11926*bbecb9d1SAndroid Build Coastguard Worker int x, int y, int width, int height)
11927*bbecb9d1SAndroid Build Coastguard Worker {
11928*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
11929*bbecb9d1SAndroid Build Coastguard Worker struct vrend_transfer_info transfer_info;
11930*bbecb9d1SAndroid Build Coastguard Worker struct pipe_box box;
11931*bbecb9d1SAndroid Build Coastguard Worker int elsize;
11932*bbecb9d1SAndroid Build Coastguard Worker
11933*bbecb9d1SAndroid Build Coastguard Worker memset(&transfer_info, 0, sizeof(transfer_info));
11934*bbecb9d1SAndroid Build Coastguard Worker
11935*bbecb9d1SAndroid Build Coastguard Worker elsize = util_format_get_blocksize(res->base.format);
11936*bbecb9d1SAndroid Build Coastguard Worker box.x = x;
11937*bbecb9d1SAndroid Build Coastguard Worker box.y = y;
11938*bbecb9d1SAndroid Build Coastguard Worker box.z = 0;
11939*bbecb9d1SAndroid Build Coastguard Worker box.width = width;
11940*bbecb9d1SAndroid Build Coastguard Worker box.height = height;
11941*bbecb9d1SAndroid Build Coastguard Worker box.depth = 1;
11942*bbecb9d1SAndroid Build Coastguard Worker
11943*bbecb9d1SAndroid Build Coastguard Worker transfer_info.box = &box;
11944*bbecb9d1SAndroid Build Coastguard Worker
11945*bbecb9d1SAndroid Build Coastguard Worker transfer_info.stride = util_format_get_nblocksx(res->base.format, res->base.width0) * elsize;
11946*bbecb9d1SAndroid Build Coastguard Worker transfer_info.offset = offset;
11947*bbecb9d1SAndroid Build Coastguard Worker transfer_info.iovec = iov;
11948*bbecb9d1SAndroid Build Coastguard Worker transfer_info.iovec_cnt = num_iovs;
11949*bbecb9d1SAndroid Build Coastguard Worker
11950*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_transfer_pipe(pres, &transfer_info,
11951*bbecb9d1SAndroid Build Coastguard Worker VIRGL_TRANSFER_FROM_HOST);
11952*bbecb9d1SAndroid Build Coastguard Worker }
11953*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_attach_res_ctx(struct vrend_context * ctx,struct virgl_resource * res)11954*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_attach_res_ctx(struct vrend_context *ctx,
11955*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *res)
11956*bbecb9d1SAndroid Build Coastguard Worker {
11957*bbecb9d1SAndroid Build Coastguard Worker if (!res->pipe_resource) {
11958*bbecb9d1SAndroid Build Coastguard Worker /* move the last untyped resource from cache to list */
11959*bbecb9d1SAndroid Build Coastguard Worker if (unlikely(ctx->untyped_resource_cache)) {
11960*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *last = ctx->untyped_resource_cache;
11961*bbecb9d1SAndroid Build Coastguard Worker struct vrend_untyped_resource *wrapper = malloc(sizeof(*wrapper));
11962*bbecb9d1SAndroid Build Coastguard Worker if (wrapper) {
11963*bbecb9d1SAndroid Build Coastguard Worker wrapper->resource = last;
11964*bbecb9d1SAndroid Build Coastguard Worker list_add(&wrapper->head, &ctx->untyped_resources);
11965*bbecb9d1SAndroid Build Coastguard Worker } else {
11966*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("dropping attached resource %d due to OOM\n", last->res_id);
11967*bbecb9d1SAndroid Build Coastguard Worker }
11968*bbecb9d1SAndroid Build Coastguard Worker }
11969*bbecb9d1SAndroid Build Coastguard Worker
11970*bbecb9d1SAndroid Build Coastguard Worker ctx->untyped_resource_cache = res;
11971*bbecb9d1SAndroid Build Coastguard Worker /* defer to vrend_renderer_pipe_resource_set_type */
11972*bbecb9d1SAndroid Build Coastguard Worker return;
11973*bbecb9d1SAndroid Build Coastguard Worker }
11974*bbecb9d1SAndroid Build Coastguard Worker
11975*bbecb9d1SAndroid Build Coastguard Worker vrend_ctx_resource_insert(ctx->res_hash,
11976*bbecb9d1SAndroid Build Coastguard Worker res->res_id,
11977*bbecb9d1SAndroid Build Coastguard Worker (struct vrend_resource *)res->pipe_resource);
11978*bbecb9d1SAndroid Build Coastguard Worker }
11979*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_detach_res_ctx(struct vrend_context * ctx,struct virgl_resource * res)11980*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_detach_res_ctx(struct vrend_context *ctx,
11981*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *res)
11982*bbecb9d1SAndroid Build Coastguard Worker {
11983*bbecb9d1SAndroid Build Coastguard Worker if (!res->pipe_resource) {
11984*bbecb9d1SAndroid Build Coastguard Worker if (ctx->untyped_resource_cache == res) {
11985*bbecb9d1SAndroid Build Coastguard Worker ctx->untyped_resource_cache = NULL;
11986*bbecb9d1SAndroid Build Coastguard Worker } else {
11987*bbecb9d1SAndroid Build Coastguard Worker struct vrend_untyped_resource *iter;
11988*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(iter, &ctx->untyped_resources, head) {
11989*bbecb9d1SAndroid Build Coastguard Worker if (iter->resource == res) {
11990*bbecb9d1SAndroid Build Coastguard Worker list_del(&iter->head);
11991*bbecb9d1SAndroid Build Coastguard Worker free(iter);
11992*bbecb9d1SAndroid Build Coastguard Worker break;
11993*bbecb9d1SAndroid Build Coastguard Worker }
11994*bbecb9d1SAndroid Build Coastguard Worker }
11995*bbecb9d1SAndroid Build Coastguard Worker }
11996*bbecb9d1SAndroid Build Coastguard Worker
11997*bbecb9d1SAndroid Build Coastguard Worker return;
11998*bbecb9d1SAndroid Build Coastguard Worker }
11999*bbecb9d1SAndroid Build Coastguard Worker
12000*bbecb9d1SAndroid Build Coastguard Worker vrend_ctx_resource_remove(ctx->res_hash, res->res_id);
12001*bbecb9d1SAndroid Build Coastguard Worker }
12002*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_ctx_res_lookup(struct vrend_context * ctx,int res_handle)12003*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *vrend_renderer_ctx_res_lookup(struct vrend_context *ctx, int res_handle)
12004*bbecb9d1SAndroid Build Coastguard Worker {
12005*bbecb9d1SAndroid Build Coastguard Worker return vrend_ctx_resource_lookup(ctx->res_hash, res_handle);
12006*bbecb9d1SAndroid Build Coastguard Worker }
12007*bbecb9d1SAndroid Build Coastguard Worker
vrend_context_set_debug_flags(struct vrend_context * ctx,const char * flagstring)12008*bbecb9d1SAndroid Build Coastguard Worker void vrend_context_set_debug_flags(struct vrend_context *ctx, const char *flagstring)
12009*bbecb9d1SAndroid Build Coastguard Worker {
12010*bbecb9d1SAndroid Build Coastguard Worker if (vrend_debug_can_override()) {
12011*bbecb9d1SAndroid Build Coastguard Worker ctx->debug_flags |= vrend_get_debug_flags(flagstring);
12012*bbecb9d1SAndroid Build Coastguard Worker if (ctx->debug_flags & dbg_features)
12013*bbecb9d1SAndroid Build Coastguard Worker vrend_debug_add_flag(dbg_feature_use);
12014*bbecb9d1SAndroid Build Coastguard Worker }
12015*bbecb9d1SAndroid Build Coastguard Worker }
12016*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_resource_get_info(struct pipe_resource * pres,struct vrend_renderer_resource_info * info)12017*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_resource_get_info(struct pipe_resource *pres,
12018*bbecb9d1SAndroid Build Coastguard Worker struct vrend_renderer_resource_info *info)
12019*bbecb9d1SAndroid Build Coastguard Worker {
12020*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
12021*bbecb9d1SAndroid Build Coastguard Worker int elsize;
12022*bbecb9d1SAndroid Build Coastguard Worker
12023*bbecb9d1SAndroid Build Coastguard Worker elsize = util_format_get_blocksize(res->base.format);
12024*bbecb9d1SAndroid Build Coastguard Worker
12025*bbecb9d1SAndroid Build Coastguard Worker info->tex_id = res->id;
12026*bbecb9d1SAndroid Build Coastguard Worker info->width = res->base.width0;
12027*bbecb9d1SAndroid Build Coastguard Worker info->height = res->base.height0;
12028*bbecb9d1SAndroid Build Coastguard Worker info->depth = res->base.depth0;
12029*bbecb9d1SAndroid Build Coastguard Worker info->format = res->base.format;
12030*bbecb9d1SAndroid Build Coastguard Worker info->flags = res->y_0_top ? VIRGL_RESOURCE_Y_0_TOP : 0;
12031*bbecb9d1SAndroid Build Coastguard Worker info->stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, 0)) * elsize;
12032*bbecb9d1SAndroid Build Coastguard Worker }
12033*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_get_cap_set(uint32_t cap_set,uint32_t * max_ver,uint32_t * max_size)12034*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
12035*bbecb9d1SAndroid Build Coastguard Worker uint32_t *max_size)
12036*bbecb9d1SAndroid Build Coastguard Worker {
12037*bbecb9d1SAndroid Build Coastguard Worker switch (cap_set) {
12038*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_RENDERER_CAPSET_VIRGL:
12039*bbecb9d1SAndroid Build Coastguard Worker *max_ver = VREND_CAPSET_VIRGL_MAX_VERSION;
12040*bbecb9d1SAndroid Build Coastguard Worker *max_size = sizeof(struct virgl_caps_v1);
12041*bbecb9d1SAndroid Build Coastguard Worker break;
12042*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_RENDERER_CAPSET_VIRGL2:
12043*bbecb9d1SAndroid Build Coastguard Worker *max_ver = VREND_CAPSET_VIRGL2_MAX_VERSION;
12044*bbecb9d1SAndroid Build Coastguard Worker *max_size = sizeof(struct virgl_caps_v2);
12045*bbecb9d1SAndroid Build Coastguard Worker break;
12046*bbecb9d1SAndroid Build Coastguard Worker default:
12047*bbecb9d1SAndroid Build Coastguard Worker *max_ver = 0;
12048*bbecb9d1SAndroid Build Coastguard Worker *max_size = 0;
12049*bbecb9d1SAndroid Build Coastguard Worker break;
12050*bbecb9d1SAndroid Build Coastguard Worker }
12051*bbecb9d1SAndroid Build Coastguard Worker }
12052*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_create_sub_ctx(struct vrend_context * ctx,int sub_ctx_id)12053*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id)
12054*bbecb9d1SAndroid Build Coastguard Worker {
12055*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub;
12056*bbecb9d1SAndroid Build Coastguard Worker struct virgl_gl_ctx_param ctx_params;
12057*bbecb9d1SAndroid Build Coastguard Worker GLuint i;
12058*bbecb9d1SAndroid Build Coastguard Worker
12059*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(sub, &ctx->sub_ctxs, head) {
12060*bbecb9d1SAndroid Build Coastguard Worker if (sub->sub_ctx_id == sub_ctx_id) {
12061*bbecb9d1SAndroid Build Coastguard Worker return;
12062*bbecb9d1SAndroid Build Coastguard Worker }
12063*bbecb9d1SAndroid Build Coastguard Worker }
12064*bbecb9d1SAndroid Build Coastguard Worker
12065*bbecb9d1SAndroid Build Coastguard Worker sub = CALLOC_STRUCT(vrend_sub_context);
12066*bbecb9d1SAndroid Build Coastguard Worker if (!sub)
12067*bbecb9d1SAndroid Build Coastguard Worker return;
12068*bbecb9d1SAndroid Build Coastguard Worker
12069*bbecb9d1SAndroid Build Coastguard Worker ctx_params.shared = (ctx->ctx_id == 0 && sub_ctx_id == 0) ? false : true;
12070*bbecb9d1SAndroid Build Coastguard Worker ctx_params.major_ver = vrend_state.gl_major_ver;
12071*bbecb9d1SAndroid Build Coastguard Worker ctx_params.minor_ver = vrend_state.gl_minor_ver;
12072*bbecb9d1SAndroid Build Coastguard Worker sub->gl_context = vrend_clicbs->create_gl_context(0, &ctx_params);
12073*bbecb9d1SAndroid Build Coastguard Worker sub->parent = ctx;
12074*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(sub->gl_context);
12075*bbecb9d1SAndroid Build Coastguard Worker
12076*bbecb9d1SAndroid Build Coastguard Worker /* enable if vrend_renderer_init function has done it as well */
12077*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_debug_cb)) {
12078*bbecb9d1SAndroid Build Coastguard Worker glDebugMessageCallback(vrend_debug_cb, NULL);
12079*bbecb9d1SAndroid Build Coastguard Worker glEnable(GL_DEBUG_OUTPUT);
12080*bbecb9d1SAndroid Build Coastguard Worker glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
12081*bbecb9d1SAndroid Build Coastguard Worker }
12082*bbecb9d1SAndroid Build Coastguard Worker
12083*bbecb9d1SAndroid Build Coastguard Worker sub->sub_ctx_id = sub_ctx_id;
12084*bbecb9d1SAndroid Build Coastguard Worker
12085*bbecb9d1SAndroid Build Coastguard Worker /* initialize the depth far_val to 1 */
12086*bbecb9d1SAndroid Build Coastguard Worker for (i = 0; i < PIPE_MAX_VIEWPORTS; i++) {
12087*bbecb9d1SAndroid Build Coastguard Worker sub->vps[i].far_val = 1.0;
12088*bbecb9d1SAndroid Build Coastguard Worker }
12089*bbecb9d1SAndroid Build Coastguard Worker
12090*bbecb9d1SAndroid Build Coastguard Worker /* Default is enabled, so set the initial hardware state accordingly */
12091*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
12092*bbecb9d1SAndroid Build Coastguard Worker sub->hw_blend_state.rt[i].colormask = 0xf;
12093*bbecb9d1SAndroid Build Coastguard Worker }
12094*bbecb9d1SAndroid Build Coastguard Worker
12095*bbecb9d1SAndroid Build Coastguard Worker if (!has_feature(feat_gles31_vertex_attrib_binding)) {
12096*bbecb9d1SAndroid Build Coastguard Worker glGenVertexArrays(1, &sub->vaoid);
12097*bbecb9d1SAndroid Build Coastguard Worker glBindVertexArray(sub->vaoid);
12098*bbecb9d1SAndroid Build Coastguard Worker }
12099*bbecb9d1SAndroid Build Coastguard Worker
12100*bbecb9d1SAndroid Build Coastguard Worker glGenFramebuffers(1, &sub->fb_id);
12101*bbecb9d1SAndroid Build Coastguard Worker glBindFramebuffer(GL_FRAMEBUFFER, sub->fb_id);
12102*bbecb9d1SAndroid Build Coastguard Worker glGenFramebuffers(2, sub->blit_fb_ids);
12103*bbecb9d1SAndroid Build Coastguard Worker
12104*bbecb9d1SAndroid Build Coastguard Worker for (int i = 0; i < VREND_PROGRAM_NQUEUES; ++i)
12105*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&sub->gl_programs[i]);
12106*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&sub->cs_programs);
12107*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&sub->streamout_list);
12108*bbecb9d1SAndroid Build Coastguard Worker
12109*bbecb9d1SAndroid Build Coastguard Worker sub->object_hash = vrend_object_init_ctx_table();
12110*bbecb9d1SAndroid Build Coastguard Worker
12111*bbecb9d1SAndroid Build Coastguard Worker sub->sysvalue_data.winsys_adjust_y = 1.f;
12112*bbecb9d1SAndroid Build Coastguard Worker sub->sysvalue_data_cookie = 1;
12113*bbecb9d1SAndroid Build Coastguard Worker
12114*bbecb9d1SAndroid Build Coastguard Worker ctx->sub = sub;
12115*bbecb9d1SAndroid Build Coastguard Worker list_add(&sub->head, &ctx->sub_ctxs);
12116*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx_id == 0)
12117*bbecb9d1SAndroid Build Coastguard Worker ctx->sub0 = sub;
12118*bbecb9d1SAndroid Build Coastguard Worker
12119*bbecb9d1SAndroid Build Coastguard Worker vrend_set_tweak_from_env(&ctx->sub->tweaks);
12120*bbecb9d1SAndroid Build Coastguard Worker }
12121*bbecb9d1SAndroid Build Coastguard Worker
vrend_context_has_debug_flag(const struct vrend_context * ctx,enum virgl_debug_flags flag)12122*bbecb9d1SAndroid Build Coastguard Worker unsigned vrend_context_has_debug_flag(const struct vrend_context *ctx, enum virgl_debug_flags flag)
12123*bbecb9d1SAndroid Build Coastguard Worker {
12124*bbecb9d1SAndroid Build Coastguard Worker return ctx && (ctx->debug_flags & flag);
12125*bbecb9d1SAndroid Build Coastguard Worker }
12126*bbecb9d1SAndroid Build Coastguard Worker
vrend_print_context_name(const struct vrend_context * ctx)12127*bbecb9d1SAndroid Build Coastguard Worker void vrend_print_context_name(const struct vrend_context *ctx)
12128*bbecb9d1SAndroid Build Coastguard Worker {
12129*bbecb9d1SAndroid Build Coastguard Worker if (ctx)
12130*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: ", ctx->debug_name);
12131*bbecb9d1SAndroid Build Coastguard Worker else
12132*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("HOST: ");
12133*bbecb9d1SAndroid Build Coastguard Worker }
12134*bbecb9d1SAndroid Build Coastguard Worker
12135*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_destroy_sub_ctx(struct vrend_context * ctx,int sub_ctx_id)12136*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_destroy_sub_ctx(struct vrend_context *ctx, int sub_ctx_id)
12137*bbecb9d1SAndroid Build Coastguard Worker {
12138*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub, *tofree = NULL;
12139*bbecb9d1SAndroid Build Coastguard Worker
12140*bbecb9d1SAndroid Build Coastguard Worker /* never destroy sub context id 0 */
12141*bbecb9d1SAndroid Build Coastguard Worker if (sub_ctx_id == 0)
12142*bbecb9d1SAndroid Build Coastguard Worker return;
12143*bbecb9d1SAndroid Build Coastguard Worker
12144*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(sub, &ctx->sub_ctxs, head) {
12145*bbecb9d1SAndroid Build Coastguard Worker if (sub->sub_ctx_id == sub_ctx_id) {
12146*bbecb9d1SAndroid Build Coastguard Worker tofree = sub;
12147*bbecb9d1SAndroid Build Coastguard Worker }
12148*bbecb9d1SAndroid Build Coastguard Worker }
12149*bbecb9d1SAndroid Build Coastguard Worker
12150*bbecb9d1SAndroid Build Coastguard Worker if (tofree) {
12151*bbecb9d1SAndroid Build Coastguard Worker if (ctx->sub == tofree) {
12152*bbecb9d1SAndroid Build Coastguard Worker ctx->sub = ctx->sub0;
12153*bbecb9d1SAndroid Build Coastguard Worker }
12154*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_sub_context(tofree);
12155*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(ctx->sub->gl_context);
12156*bbecb9d1SAndroid Build Coastguard Worker }
12157*bbecb9d1SAndroid Build Coastguard Worker }
12158*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_set_sub_ctx(struct vrend_context * ctx,int sub_ctx_id)12159*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_set_sub_ctx(struct vrend_context *ctx, int sub_ctx_id)
12160*bbecb9d1SAndroid Build Coastguard Worker {
12161*bbecb9d1SAndroid Build Coastguard Worker struct vrend_sub_context *sub = vrend_renderer_find_sub_ctx(ctx, sub_ctx_id);
12162*bbecb9d1SAndroid Build Coastguard Worker if (sub && ctx->sub != sub) {
12163*bbecb9d1SAndroid Build Coastguard Worker ctx->sub = sub;
12164*bbecb9d1SAndroid Build Coastguard Worker vrend_clicbs->make_current(sub->gl_context);
12165*bbecb9d1SAndroid Build Coastguard Worker }
12166*bbecb9d1SAndroid Build Coastguard Worker }
12167*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_prepare_reset(void)12168*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_prepare_reset(void)
12169*bbecb9d1SAndroid Build Coastguard Worker {
12170*bbecb9d1SAndroid Build Coastguard Worker /* make sure user contexts are no longer accessed */
12171*bbecb9d1SAndroid Build Coastguard Worker vrend_free_sync_thread();
12172*bbecb9d1SAndroid Build Coastguard Worker vrend_hw_switch_context(vrend_state.ctx0, true);
12173*bbecb9d1SAndroid Build Coastguard Worker }
12174*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_reset(void)12175*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_reset(void)
12176*bbecb9d1SAndroid Build Coastguard Worker {
12177*bbecb9d1SAndroid Build Coastguard Worker vrend_free_fences();
12178*bbecb9d1SAndroid Build Coastguard Worker vrend_blitter_fini();
12179*bbecb9d1SAndroid Build Coastguard Worker
12180*bbecb9d1SAndroid Build Coastguard Worker vrend_destroy_context(vrend_state.ctx0);
12181*bbecb9d1SAndroid Build Coastguard Worker
12182*bbecb9d1SAndroid Build Coastguard Worker vrend_state.ctx0 = vrend_create_context(0, strlen("HOST"), "HOST");
12183*bbecb9d1SAndroid Build Coastguard Worker /* TODO respawn sync thread */
12184*bbecb9d1SAndroid Build Coastguard Worker }
12185*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_get_poll_fd(void)12186*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_get_poll_fd(void)
12187*bbecb9d1SAndroid Build Coastguard Worker {
12188*bbecb9d1SAndroid Build Coastguard Worker int fd = vrend_state.eventfd;
12189*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_async_fence_cb && fd < 0)
12190*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("failed to duplicate eventfd: error=%d\n", errno);
12191*bbecb9d1SAndroid Build Coastguard Worker return fd;
12192*bbecb9d1SAndroid Build Coastguard Worker }
12193*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_export_query(struct pipe_resource * pres,struct virgl_renderer_export_query * export_query)12194*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_export_query(struct pipe_resource *pres,
12195*bbecb9d1SAndroid Build Coastguard Worker struct virgl_renderer_export_query *export_query)
12196*bbecb9d1SAndroid Build Coastguard Worker {
12197*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
12198*bbecb9d1SAndroid Build Coastguard Worker
12199*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_MINIGBM_ALLOCATION
12200*bbecb9d1SAndroid Build Coastguard Worker if (res->gbm_bo)
12201*bbecb9d1SAndroid Build Coastguard Worker return virgl_gbm_export_query(res->gbm_bo, export_query);
12202*bbecb9d1SAndroid Build Coastguard Worker #else
12203*bbecb9d1SAndroid Build Coastguard Worker (void)res;
12204*bbecb9d1SAndroid Build Coastguard Worker #endif
12205*bbecb9d1SAndroid Build Coastguard Worker
12206*bbecb9d1SAndroid Build Coastguard Worker /*
12207*bbecb9d1SAndroid Build Coastguard Worker * Implementations that support eglExportDMABUFImageMESA can also export certain resources.
12208*bbecb9d1SAndroid Build Coastguard Worker * This is omitted currently since virgl_renderer_get_fd_for_texture supports that use case.
12209*bbecb9d1SAndroid Build Coastguard Worker */
12210*bbecb9d1SAndroid Build Coastguard Worker export_query->out_num_fds = 0;
12211*bbecb9d1SAndroid Build Coastguard Worker export_query->out_fourcc = 0;
12212*bbecb9d1SAndroid Build Coastguard Worker export_query->out_modifier = DRM_FORMAT_MOD_INVALID;
12213*bbecb9d1SAndroid Build Coastguard Worker if (export_query->in_export_fds)
12214*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
12215*bbecb9d1SAndroid Build Coastguard Worker
12216*bbecb9d1SAndroid Build Coastguard Worker return 0;
12217*bbecb9d1SAndroid Build Coastguard Worker }
12218*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_pipe_resource_create(struct vrend_context * ctx,uint32_t blob_id,const struct vrend_renderer_resource_create_args * args)12219*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_pipe_resource_create(struct vrend_context *ctx, uint32_t blob_id,
12220*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_renderer_resource_create_args *args)
12221*bbecb9d1SAndroid Build Coastguard Worker {
12222*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
12223*bbecb9d1SAndroid Build Coastguard Worker res = (struct vrend_resource *)vrend_renderer_resource_create(args, NULL);
12224*bbecb9d1SAndroid Build Coastguard Worker if (!res)
12225*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
12226*bbecb9d1SAndroid Build Coastguard Worker
12227*bbecb9d1SAndroid Build Coastguard Worker res->blob_id = blob_id;
12228*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&res->head, &ctx->vrend_resources);
12229*bbecb9d1SAndroid Build Coastguard Worker return 0;
12230*bbecb9d1SAndroid Build Coastguard Worker }
12231*bbecb9d1SAndroid Build Coastguard Worker
vrend_get_blob_pipe(struct vrend_context * ctx,uint64_t blob_id)12232*bbecb9d1SAndroid Build Coastguard Worker struct pipe_resource *vrend_get_blob_pipe(struct vrend_context *ctx, uint64_t blob_id)
12233*bbecb9d1SAndroid Build Coastguard Worker {
12234*bbecb9d1SAndroid Build Coastguard Worker uint32_t id = (uint32_t)blob_id;
12235*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res, *stor;
12236*bbecb9d1SAndroid Build Coastguard Worker
12237*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE(res, stor, &ctx->vrend_resources, head) {
12238*bbecb9d1SAndroid Build Coastguard Worker if (res->blob_id != id)
12239*bbecb9d1SAndroid Build Coastguard Worker continue;
12240*bbecb9d1SAndroid Build Coastguard Worker
12241*bbecb9d1SAndroid Build Coastguard Worker list_del(&res->head);
12242*bbecb9d1SAndroid Build Coastguard Worker /* Set the blob id to zero, since it won't be used anymore */
12243*bbecb9d1SAndroid Build Coastguard Worker res->blob_id = 0;
12244*bbecb9d1SAndroid Build Coastguard Worker return &res->base;
12245*bbecb9d1SAndroid Build Coastguard Worker }
12246*bbecb9d1SAndroid Build Coastguard Worker
12247*bbecb9d1SAndroid Build Coastguard Worker return NULL;
12248*bbecb9d1SAndroid Build Coastguard Worker }
12249*bbecb9d1SAndroid Build Coastguard Worker
12250*bbecb9d1SAndroid Build Coastguard Worker int
vrend_renderer_pipe_resource_set_type(struct vrend_context * ctx,uint32_t res_id,const struct vrend_renderer_resource_set_type_args * args)12251*bbecb9d1SAndroid Build Coastguard Worker vrend_renderer_pipe_resource_set_type(struct vrend_context *ctx,
12252*bbecb9d1SAndroid Build Coastguard Worker uint32_t res_id,
12253*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_renderer_resource_set_type_args *args)
12254*bbecb9d1SAndroid Build Coastguard Worker {
12255*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *res = NULL;
12256*bbecb9d1SAndroid Build Coastguard Worker
12257*bbecb9d1SAndroid Build Coastguard Worker /* look up the untyped resource */
12258*bbecb9d1SAndroid Build Coastguard Worker if (ctx->untyped_resource_cache &&
12259*bbecb9d1SAndroid Build Coastguard Worker ctx->untyped_resource_cache->res_id == res_id) {
12260*bbecb9d1SAndroid Build Coastguard Worker res = ctx->untyped_resource_cache;
12261*bbecb9d1SAndroid Build Coastguard Worker ctx->untyped_resource_cache = NULL;
12262*bbecb9d1SAndroid Build Coastguard Worker } else {
12263*bbecb9d1SAndroid Build Coastguard Worker /* cache miss */
12264*bbecb9d1SAndroid Build Coastguard Worker struct vrend_untyped_resource *iter;
12265*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(iter, &ctx->untyped_resources, head) {
12266*bbecb9d1SAndroid Build Coastguard Worker if (iter->resource->res_id == res_id) {
12267*bbecb9d1SAndroid Build Coastguard Worker res = iter->resource;
12268*bbecb9d1SAndroid Build Coastguard Worker list_del(&iter->head);
12269*bbecb9d1SAndroid Build Coastguard Worker free(iter);
12270*bbecb9d1SAndroid Build Coastguard Worker break;
12271*bbecb9d1SAndroid Build Coastguard Worker }
12272*bbecb9d1SAndroid Build Coastguard Worker }
12273*bbecb9d1SAndroid Build Coastguard Worker }
12274*bbecb9d1SAndroid Build Coastguard Worker
12275*bbecb9d1SAndroid Build Coastguard Worker /* either a bad res_id or the resource is already typed */
12276*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
12277*bbecb9d1SAndroid Build Coastguard Worker if (vrend_renderer_ctx_res_lookup(ctx, res_id))
12278*bbecb9d1SAndroid Build Coastguard Worker return 0;
12279*bbecb9d1SAndroid Build Coastguard Worker
12280*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_id);
12281*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
12282*bbecb9d1SAndroid Build Coastguard Worker }
12283*bbecb9d1SAndroid Build Coastguard Worker
12284*bbecb9d1SAndroid Build Coastguard Worker /* resource is still untyped */
12285*bbecb9d1SAndroid Build Coastguard Worker if (!res->pipe_resource) {
12286*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
12287*bbecb9d1SAndroid Build Coastguard Worker const struct vrend_renderer_resource_create_args create_args = {
12288*bbecb9d1SAndroid Build Coastguard Worker .target = PIPE_TEXTURE_2D,
12289*bbecb9d1SAndroid Build Coastguard Worker .format = args->format,
12290*bbecb9d1SAndroid Build Coastguard Worker .bind = args->bind,
12291*bbecb9d1SAndroid Build Coastguard Worker .width = args->width,
12292*bbecb9d1SAndroid Build Coastguard Worker .height = args->height,
12293*bbecb9d1SAndroid Build Coastguard Worker .depth = 1,
12294*bbecb9d1SAndroid Build Coastguard Worker .array_size = 1,
12295*bbecb9d1SAndroid Build Coastguard Worker .last_level = 0,
12296*bbecb9d1SAndroid Build Coastguard Worker .nr_samples = 0,
12297*bbecb9d1SAndroid Build Coastguard Worker .flags = 0,
12298*bbecb9d1SAndroid Build Coastguard Worker };
12299*bbecb9d1SAndroid Build Coastguard Worker int plane_fds[VIRGL_GBM_MAX_PLANES];
12300*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *gr;
12301*bbecb9d1SAndroid Build Coastguard Worker uint32_t virgl_format;
12302*bbecb9d1SAndroid Build Coastguard Worker uint32_t drm_format;
12303*bbecb9d1SAndroid Build Coastguard Worker int ret;
12304*bbecb9d1SAndroid Build Coastguard Worker
12305*bbecb9d1SAndroid Build Coastguard Worker if (res->fd_type != VIRGL_RESOURCE_FD_DMABUF)
12306*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
12307*bbecb9d1SAndroid Build Coastguard Worker
12308*bbecb9d1SAndroid Build Coastguard Worker for (uint32_t i = 0; i < args->plane_count; i++)
12309*bbecb9d1SAndroid Build Coastguard Worker plane_fds[i] = res->fd;
12310*bbecb9d1SAndroid Build Coastguard Worker
12311*bbecb9d1SAndroid Build Coastguard Worker gr = vrend_resource_create(&create_args);
12312*bbecb9d1SAndroid Build Coastguard Worker if (!gr)
12313*bbecb9d1SAndroid Build Coastguard Worker return ENOMEM;
12314*bbecb9d1SAndroid Build Coastguard Worker
12315*bbecb9d1SAndroid Build Coastguard Worker virgl_format = gr->base.format;
12316*bbecb9d1SAndroid Build Coastguard Worker drm_format = 0;
12317*bbecb9d1SAndroid Build Coastguard Worker if (virgl_gbm_convert_format(&virgl_format, &drm_format)) {
12318*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: unsupported format %d\n", __func__, virgl_format);
12319*bbecb9d1SAndroid Build Coastguard Worker FREE(gr);
12320*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
12321*bbecb9d1SAndroid Build Coastguard Worker }
12322*bbecb9d1SAndroid Build Coastguard Worker
12323*bbecb9d1SAndroid Build Coastguard Worker gr->egl_image = virgl_egl_image_from_dmabuf(egl,
12324*bbecb9d1SAndroid Build Coastguard Worker args->width,
12325*bbecb9d1SAndroid Build Coastguard Worker args->height,
12326*bbecb9d1SAndroid Build Coastguard Worker drm_format,
12327*bbecb9d1SAndroid Build Coastguard Worker args->modifier,
12328*bbecb9d1SAndroid Build Coastguard Worker args->plane_count,
12329*bbecb9d1SAndroid Build Coastguard Worker plane_fds,
12330*bbecb9d1SAndroid Build Coastguard Worker args->plane_strides,
12331*bbecb9d1SAndroid Build Coastguard Worker args->plane_offsets);
12332*bbecb9d1SAndroid Build Coastguard Worker if (!gr->egl_image) {
12333*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: failed to create egl image\n", __func__);
12334*bbecb9d1SAndroid Build Coastguard Worker FREE(gr);
12335*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
12336*bbecb9d1SAndroid Build Coastguard Worker }
12337*bbecb9d1SAndroid Build Coastguard Worker
12338*bbecb9d1SAndroid Build Coastguard Worker gr->storage_bits |= VREND_STORAGE_EGL_IMAGE;
12339*bbecb9d1SAndroid Build Coastguard Worker
12340*bbecb9d1SAndroid Build Coastguard Worker ret = vrend_resource_alloc_texture(gr, virgl_format, gr->egl_image);
12341*bbecb9d1SAndroid Build Coastguard Worker if (ret) {
12342*bbecb9d1SAndroid Build Coastguard Worker virgl_egl_image_destroy(egl, gr->egl_image);
12343*bbecb9d1SAndroid Build Coastguard Worker FREE(gr);
12344*bbecb9d1SAndroid Build Coastguard Worker return ret;
12345*bbecb9d1SAndroid Build Coastguard Worker }
12346*bbecb9d1SAndroid Build Coastguard Worker
12347*bbecb9d1SAndroid Build Coastguard Worker /* "promote" the fd to pipe_resource */
12348*bbecb9d1SAndroid Build Coastguard Worker close(res->fd);
12349*bbecb9d1SAndroid Build Coastguard Worker res->fd = -1;
12350*bbecb9d1SAndroid Build Coastguard Worker res->fd_type = VIRGL_RESOURCE_FD_INVALID;
12351*bbecb9d1SAndroid Build Coastguard Worker res->pipe_resource = &gr->base;
12352*bbecb9d1SAndroid Build Coastguard Worker #else /* HAVE_EPOXY_EGL_H */
12353*bbecb9d1SAndroid Build Coastguard Worker (void)args;
12354*bbecb9d1SAndroid Build Coastguard Worker vrend_printf("%s: no EGL support \n", __func__);
12355*bbecb9d1SAndroid Build Coastguard Worker return EINVAL;
12356*bbecb9d1SAndroid Build Coastguard Worker #endif /* HAVE_EPOXY_EGL_H */
12357*bbecb9d1SAndroid Build Coastguard Worker }
12358*bbecb9d1SAndroid Build Coastguard Worker
12359*bbecb9d1SAndroid Build Coastguard Worker vrend_ctx_resource_insert(ctx->res_hash,
12360*bbecb9d1SAndroid Build Coastguard Worker res->res_id,
12361*bbecb9d1SAndroid Build Coastguard Worker (struct vrend_resource *)res->pipe_resource);
12362*bbecb9d1SAndroid Build Coastguard Worker
12363*bbecb9d1SAndroid Build Coastguard Worker return 0;
12364*bbecb9d1SAndroid Build Coastguard Worker }
12365*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_resource_get_map_info(struct pipe_resource * pres)12366*bbecb9d1SAndroid Build Coastguard Worker uint32_t vrend_renderer_resource_get_map_info(struct pipe_resource *pres)
12367*bbecb9d1SAndroid Build Coastguard Worker {
12368*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
12369*bbecb9d1SAndroid Build Coastguard Worker return res->map_info;
12370*bbecb9d1SAndroid Build Coastguard Worker }
12371*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_resource_map(struct pipe_resource * pres,void ** map,uint64_t * out_size)12372*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_resource_map(struct pipe_resource *pres, void **map, uint64_t *out_size)
12373*bbecb9d1SAndroid Build Coastguard Worker {
12374*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
12375*bbecb9d1SAndroid Build Coastguard Worker if (!has_bits(res->storage_bits, VREND_STORAGE_GL_BUFFER | VREND_STORAGE_GL_IMMUTABLE))
12376*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
12377*bbecb9d1SAndroid Build Coastguard Worker
12378*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, res->id);
12379*bbecb9d1SAndroid Build Coastguard Worker *map = glMapBufferRange(res->target, 0, res->size, res->buffer_storage_flags);
12380*bbecb9d1SAndroid Build Coastguard Worker if (!*map)
12381*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
12382*bbecb9d1SAndroid Build Coastguard Worker
12383*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, 0);
12384*bbecb9d1SAndroid Build Coastguard Worker *out_size = res->size;
12385*bbecb9d1SAndroid Build Coastguard Worker return 0;
12386*bbecb9d1SAndroid Build Coastguard Worker }
12387*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_resource_unmap(struct pipe_resource * pres)12388*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_resource_unmap(struct pipe_resource *pres)
12389*bbecb9d1SAndroid Build Coastguard Worker {
12390*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res = (struct vrend_resource *)pres;
12391*bbecb9d1SAndroid Build Coastguard Worker if (!has_bits(res->storage_bits, VREND_STORAGE_GL_BUFFER | VREND_STORAGE_GL_IMMUTABLE))
12392*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
12393*bbecb9d1SAndroid Build Coastguard Worker
12394*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, res->id);
12395*bbecb9d1SAndroid Build Coastguard Worker glUnmapBuffer(res->target);
12396*bbecb9d1SAndroid Build Coastguard Worker glBindBufferARB(res->target, 0);
12397*bbecb9d1SAndroid Build Coastguard Worker return 0;
12398*bbecb9d1SAndroid Build Coastguard Worker }
12399*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_create_ctx0_fence(uint32_t fence_id)12400*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_create_ctx0_fence(uint32_t fence_id)
12401*bbecb9d1SAndroid Build Coastguard Worker {
12402*bbecb9d1SAndroid Build Coastguard Worker return vrend_renderer_create_fence(vrend_state.ctx0,
12403*bbecb9d1SAndroid Build Coastguard Worker VIRGL_RENDERER_FENCE_FLAG_MERGEABLE, fence_id);
12404*bbecb9d1SAndroid Build Coastguard Worker }
12405*bbecb9d1SAndroid Build Coastguard Worker
12406*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
find_ctx0_fence_locked(struct list_head * fence_list,uint64_t fence_id,bool * seen_first,struct vrend_fence ** fence)12407*bbecb9d1SAndroid Build Coastguard Worker static bool find_ctx0_fence_locked(struct list_head *fence_list,
12408*bbecb9d1SAndroid Build Coastguard Worker uint64_t fence_id,
12409*bbecb9d1SAndroid Build Coastguard Worker bool *seen_first,
12410*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence **fence)
12411*bbecb9d1SAndroid Build Coastguard Worker {
12412*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *iter;
12413*bbecb9d1SAndroid Build Coastguard Worker
12414*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY(iter, fence_list, fences) {
12415*bbecb9d1SAndroid Build Coastguard Worker /* only consider ctx0 fences */
12416*bbecb9d1SAndroid Build Coastguard Worker if (iter->ctx != vrend_state.ctx0)
12417*bbecb9d1SAndroid Build Coastguard Worker continue;
12418*bbecb9d1SAndroid Build Coastguard Worker
12419*bbecb9d1SAndroid Build Coastguard Worker if (iter->fence_id == fence_id) {
12420*bbecb9d1SAndroid Build Coastguard Worker *fence = iter;
12421*bbecb9d1SAndroid Build Coastguard Worker return true;
12422*bbecb9d1SAndroid Build Coastguard Worker }
12423*bbecb9d1SAndroid Build Coastguard Worker
12424*bbecb9d1SAndroid Build Coastguard Worker if (!*seen_first) {
12425*bbecb9d1SAndroid Build Coastguard Worker if (fence_id < iter->fence_id)
12426*bbecb9d1SAndroid Build Coastguard Worker return true;
12427*bbecb9d1SAndroid Build Coastguard Worker *seen_first = true;
12428*bbecb9d1SAndroid Build Coastguard Worker }
12429*bbecb9d1SAndroid Build Coastguard Worker }
12430*bbecb9d1SAndroid Build Coastguard Worker
12431*bbecb9d1SAndroid Build Coastguard Worker return false;
12432*bbecb9d1SAndroid Build Coastguard Worker }
12433*bbecb9d1SAndroid Build Coastguard Worker #endif
12434*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_export_ctx0_fence(uint32_t fence_id,int * out_fd)12435*bbecb9d1SAndroid Build Coastguard Worker int vrend_renderer_export_ctx0_fence(uint32_t fence_id, int* out_fd) {
12436*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EPOXY_EGL_H
12437*bbecb9d1SAndroid Build Coastguard Worker if (!vrend_state.use_egl_fence) {
12438*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
12439*bbecb9d1SAndroid Build Coastguard Worker }
12440*bbecb9d1SAndroid Build Coastguard Worker
12441*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.sync_thread)
12442*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&vrend_state.fence_mutex);
12443*bbecb9d1SAndroid Build Coastguard Worker
12444*bbecb9d1SAndroid Build Coastguard Worker bool seen_first = false;
12445*bbecb9d1SAndroid Build Coastguard Worker struct vrend_fence *fence = NULL;
12446*bbecb9d1SAndroid Build Coastguard Worker bool found = find_ctx0_fence_locked(&vrend_state.fence_list,
12447*bbecb9d1SAndroid Build Coastguard Worker fence_id,
12448*bbecb9d1SAndroid Build Coastguard Worker &seen_first,
12449*bbecb9d1SAndroid Build Coastguard Worker &fence);
12450*bbecb9d1SAndroid Build Coastguard Worker if (!found) {
12451*bbecb9d1SAndroid Build Coastguard Worker found = find_ctx0_fence_locked(&vrend_state.fence_wait_list,
12452*bbecb9d1SAndroid Build Coastguard Worker fence_id,
12453*bbecb9d1SAndroid Build Coastguard Worker &seen_first,
12454*bbecb9d1SAndroid Build Coastguard Worker &fence);
12455*bbecb9d1SAndroid Build Coastguard Worker /* consider signaled when no active ctx0 fence at all */
12456*bbecb9d1SAndroid Build Coastguard Worker if (!found && !seen_first)
12457*bbecb9d1SAndroid Build Coastguard Worker found = true;
12458*bbecb9d1SAndroid Build Coastguard Worker }
12459*bbecb9d1SAndroid Build Coastguard Worker
12460*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.sync_thread)
12461*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&vrend_state.fence_mutex);
12462*bbecb9d1SAndroid Build Coastguard Worker
12463*bbecb9d1SAndroid Build Coastguard Worker if (found) {
12464*bbecb9d1SAndroid Build Coastguard Worker if (fence)
12465*bbecb9d1SAndroid Build Coastguard Worker return virgl_egl_export_fence(egl, fence->eglsyncobj, out_fd) ? 0 : -EINVAL;
12466*bbecb9d1SAndroid Build Coastguard Worker else
12467*bbecb9d1SAndroid Build Coastguard Worker return virgl_egl_export_signaled_fence(egl, out_fd) ? 0 : -EINVAL;
12468*bbecb9d1SAndroid Build Coastguard Worker }
12469*bbecb9d1SAndroid Build Coastguard Worker #else
12470*bbecb9d1SAndroid Build Coastguard Worker (void)fence_id;
12471*bbecb9d1SAndroid Build Coastguard Worker (void)out_fd;
12472*bbecb9d1SAndroid Build Coastguard Worker #endif
12473*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
12474*bbecb9d1SAndroid Build Coastguard Worker }
12475*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_get_meminfo(struct vrend_context * ctx,uint32_t res_handle)12476*bbecb9d1SAndroid Build Coastguard Worker void vrend_renderer_get_meminfo(struct vrend_context *ctx, uint32_t res_handle)
12477*bbecb9d1SAndroid Build Coastguard Worker {
12478*bbecb9d1SAndroid Build Coastguard Worker struct vrend_resource *res;
12479*bbecb9d1SAndroid Build Coastguard Worker struct virgl_memory_info *info;
12480*bbecb9d1SAndroid Build Coastguard Worker
12481*bbecb9d1SAndroid Build Coastguard Worker res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
12482*bbecb9d1SAndroid Build Coastguard Worker if (!res) {
12483*bbecb9d1SAndroid Build Coastguard Worker vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
12484*bbecb9d1SAndroid Build Coastguard Worker return;
12485*bbecb9d1SAndroid Build Coastguard Worker }
12486*bbecb9d1SAndroid Build Coastguard Worker
12487*bbecb9d1SAndroid Build Coastguard Worker info = (struct virgl_memory_info *)res->iov->iov_base;
12488*bbecb9d1SAndroid Build Coastguard Worker
12489*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_nvx_gpu_memory_info)) {
12490*bbecb9d1SAndroid Build Coastguard Worker GLint i;
12491*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &i);
12492*bbecb9d1SAndroid Build Coastguard Worker info->total_device_memory = i;
12493*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &i);
12494*bbecb9d1SAndroid Build Coastguard Worker info->total_staging_memory = i - info->total_device_memory;
12495*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX, &i);
12496*bbecb9d1SAndroid Build Coastguard Worker info->nr_device_memory_evictions = i;
12497*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX, &i);
12498*bbecb9d1SAndroid Build Coastguard Worker info->device_memory_evicted = i;
12499*bbecb9d1SAndroid Build Coastguard Worker }
12500*bbecb9d1SAndroid Build Coastguard Worker
12501*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_ati_meminfo)) {
12502*bbecb9d1SAndroid Build Coastguard Worker GLint i[4];
12503*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, i);
12504*bbecb9d1SAndroid Build Coastguard Worker info->avail_device_memory = i[0];
12505*bbecb9d1SAndroid Build Coastguard Worker info->avail_staging_memory = i[2];
12506*bbecb9d1SAndroid Build Coastguard Worker }
12507*bbecb9d1SAndroid Build Coastguard Worker }
12508*bbecb9d1SAndroid Build Coastguard Worker
vrend_renderer_get_video_memory(void)12509*bbecb9d1SAndroid Build Coastguard Worker static uint32_t vrend_renderer_get_video_memory(void)
12510*bbecb9d1SAndroid Build Coastguard Worker {
12511*bbecb9d1SAndroid Build Coastguard Worker GLint video_memory = vrend_winsys_query_video_memory();
12512*bbecb9d1SAndroid Build Coastguard Worker
12513*bbecb9d1SAndroid Build Coastguard Worker if (!video_memory && has_feature(feat_nvx_gpu_memory_info))
12514*bbecb9d1SAndroid Build Coastguard Worker glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &video_memory);
12515*bbecb9d1SAndroid Build Coastguard Worker
12516*bbecb9d1SAndroid Build Coastguard Worker return video_memory;
12517*bbecb9d1SAndroid Build Coastguard Worker }
12518*bbecb9d1SAndroid Build Coastguard Worker
vrend_context_emit_string_marker(struct vrend_context * ctx,GLsizei length,const char * message)12519*bbecb9d1SAndroid Build Coastguard Worker void vrend_context_emit_string_marker(struct vrend_context *ctx, GLsizei length, const char * message)
12520*bbecb9d1SAndroid Build Coastguard Worker {
12521*bbecb9d1SAndroid Build Coastguard Worker VREND_DEBUG(dbg_khr, ctx, "MARKER: '%.*s'\n", length, message);
12522*bbecb9d1SAndroid Build Coastguard Worker
12523*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_TRACING
12524*bbecb9d1SAndroid Build Coastguard Worker char buf[256];
12525*bbecb9d1SAndroid Build Coastguard Worker if (length > 6 && !strncmp(message, "BEGIN:", 6)) {
12526*bbecb9d1SAndroid Build Coastguard Worker snprintf(buf, 256, "%.*s", length - 6, &message[6]);
12527*bbecb9d1SAndroid Build Coastguard Worker TRACE_SCOPE_BEGIN(buf);
12528*bbecb9d1SAndroid Build Coastguard Worker } else if (length > 4 && !strncmp(message, "END:", 4)) {
12529*bbecb9d1SAndroid Build Coastguard Worker snprintf(buf, 256, "%.*s", length - 4, &message[4]);
12530*bbecb9d1SAndroid Build Coastguard Worker const char *scope = buf;
12531*bbecb9d1SAndroid Build Coastguard Worker TRACE_SCOPE_END(scope);
12532*bbecb9d1SAndroid Build Coastguard Worker }
12533*bbecb9d1SAndroid Build Coastguard Worker #endif
12534*bbecb9d1SAndroid Build Coastguard Worker
12535*bbecb9d1SAndroid Build Coastguard Worker if (has_feature(feat_khr_debug)) {
12536*bbecb9d1SAndroid Build Coastguard Worker if (vrend_state.use_gles)
12537*bbecb9d1SAndroid Build Coastguard Worker glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION_KHR,
12538*bbecb9d1SAndroid Build Coastguard Worker GL_DEBUG_TYPE_MARKER_KHR,
12539*bbecb9d1SAndroid Build Coastguard Worker 0, GL_DEBUG_SEVERITY_NOTIFICATION,
12540*bbecb9d1SAndroid Build Coastguard Worker length, message);
12541*bbecb9d1SAndroid Build Coastguard Worker else
12542*bbecb9d1SAndroid Build Coastguard Worker glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION,
12543*bbecb9d1SAndroid Build Coastguard Worker GL_DEBUG_TYPE_MARKER,
12544*bbecb9d1SAndroid Build Coastguard Worker 0, GL_DEBUG_SEVERITY_NOTIFICATION_KHR,
12545*bbecb9d1SAndroid Build Coastguard Worker length, message);
12546*bbecb9d1SAndroid Build Coastguard Worker }
12547*bbecb9d1SAndroid Build Coastguard Worker }
12548*bbecb9d1SAndroid Build Coastguard Worker
12549*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VIDEO
vrend_context_get_video_ctx(struct vrend_context * ctx)12550*bbecb9d1SAndroid Build Coastguard Worker struct vrend_video_context *vrend_context_get_video_ctx(struct vrend_context *ctx)
12551*bbecb9d1SAndroid Build Coastguard Worker {
12552*bbecb9d1SAndroid Build Coastguard Worker return ctx->video;
12553*bbecb9d1SAndroid Build Coastguard Worker }
12554*bbecb9d1SAndroid Build Coastguard Worker #endif
12555*bbecb9d1SAndroid Build Coastguard Worker
12556