[virglrenderer-devel] [PATCH 4/5] vrend: Rework caps for running on GLES hosts v3
Jakob Bornecrantz
jakob at collabora.com
Tue Mar 20 17:39:29 UTC 2018
v2: Update base on comments from ML.
v3: Add version 2 setting as well.
Signed-off-by: Jakob Bornecrantz <jakob at collabora.com>
---
src/vrend_renderer.c | 296 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 226 insertions(+), 70 deletions(-)
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 5df3f68..628df61 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -6443,32 +6443,233 @@ static void vrender_get_glsl_version(int *glsl_version)
*glsl_version = version;
}
-void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
- union virgl_caps *caps)
+/*
+ * Does all of the common caps setting,
+ * if it dedects a early out returns true.
+ */
+bool vrend_renderer_fill_caps_common(uint32_t set, uint32_t version,
+ union virgl_caps *caps)
{
- int i;
+ int i, gl_ver;
GLint max;
- GLfloat range[2];
- int gl_ver = epoxy_gl_version();
- bool fill_capset2 = false;
- if (!caps)
- return;
+
+ if (!caps) {
+ return true;
+ }
if (set > 2) {
caps->max_version = 0;
- return;
+ return true;
}
if (set == 1) {
memset(caps, 0, sizeof(struct virgl_caps_v1));
caps->max_version = 1;
} else if (set == 2) {
- fill_capset2 = true;
memset(caps, 0, sizeof(*caps));
caps->max_version = 2;
}
+ gl_ver = epoxy_gl_version();
+
+ /*
+ * We can't fully support this feature on GLES,
+ * but it is needed for OpenGL 2.1 so lie.
+ */
caps->v1.bset.occlusion_query = 1;
+
+
+ /* Some checks looks at v1.glsl_level so set it here. */
+ if (vrend_state.use_gles) {
+ caps->v1.glsl_level = 120;
+ } else if (vrend_state.use_core_profile) {
+ if (gl_ver == 31)
+ caps->v1.glsl_level = 140;
+ else if (gl_ver == 32)
+ caps->v1.glsl_level = 150;
+ else if (gl_ver >= 33)
+ caps->v1.glsl_level = 330;
+ } else {
+ caps->v1.glsl_level = 130;
+ }
+
+
+ /* Set supported prims here as we now know what shaders we support. */
+ caps->v1.prim_mask = (1 << PIPE_PRIM_POINTS) | (1 << PIPE_PRIM_LINES) | (1 << PIPE_PRIM_LINE_STRIP) | (1 << PIPE_PRIM_LINE_LOOP) | (1 << PIPE_PRIM_TRIANGLES) | (1 << PIPE_PRIM_TRIANGLE_STRIP) | (1 << PIPE_PRIM_TRIANGLE_FAN);
+
+ if (vrend_state.use_gles == false &&
+ vrend_state.use_core_profile == false) {
+ caps->v1.prim_mask |= (1 << PIPE_PRIM_QUADS) | (1 << PIPE_PRIM_QUAD_STRIP) | (1 << PIPE_PRIM_POLYGON);
+ }
+
+ if (!vrend_state.use_gles && caps->v1.glsl_level >= 150) {
+ caps->v1.prim_mask |= (1 << PIPE_PRIM_LINES_ADJACENCY) |
+ (1 << PIPE_PRIM_LINE_STRIP_ADJACENCY) |
+ (1 << PIPE_PRIM_TRIANGLES_ADJACENCY) |
+ (1 << PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
+ }
+
+
+ /* Common limits for all backends. */
+ glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max);
+ caps->v1.max_render_targets = max;
+
+ glGetIntegerv(GL_MAX_SAMPLES, &max);
+ caps->v1.max_samples = max;
+
+
+ /* All of the formats are common. */
+ for (i = 0; i < VIRGL_FORMAT_MAX; i++) {
+ uint32_t offset = i / 32;
+ uint32_t index = i % 32;
+
+ if (tex_conv_table[i].internalformat != 0) {
+ if (vrend_format_can_sample(i)) {
+ caps->v1.sampler.bitmask[offset] |= (1 << index);
+ if (vrend_format_can_render(i))
+ caps->v1.render.bitmask[offset] |= (1 << index);
+ }
+ }
+ }
+
+ if (!vrend_state.use_gles &&
+ epoxy_has_gl_extension("GL_ARB_vertex_type_10f_11f_11f_rev")) {
+ int val = VIRGL_FORMAT_R11G11B10_FLOAT;
+ uint32_t offset = val / 32;
+ uint32_t index = val % 32;
+
+ caps->v1.vertexbuffer.bitmask[offset] |= (1 << index);
+ }
+
+
+ /* These are filled in by the init code, so are common. */
+ if (vrend_state.have_nv_prim_restart ||
+ vrend_state.have_gl_prim_restart) {
+ caps->v1.bset.primitive_restart = 1;
+ }
+
+ return false;
+}
+
+void vrend_renderer_fill_caps_gles(uint32_t set, uint32_t version,
+ union virgl_caps *caps)
+{
+ GLint max;
+ GLfloat range[2];
+ bool fill_capset2 = false;
+
+ if (set == 2) {
+ fill_capset2 = true;
+ }
+
+ caps->v1.bset.indep_blend_enable = 0;
+ caps->v1.bset.conditional_render = 0;
+
+ caps->v1.bset.poly_stipple = 0;
+ caps->v1.bset.color_clamping = 0;
+
+ caps->v1.bset.instanceid = 0;
+
+ caps->v1.bset.primitive_restart = 0;
+
+ caps->v1.bset.fragment_coord_conventions = 0;
+ caps->v1.bset.depth_clip_disable = 0;
+ caps->v1.bset.seamless_cube_map = 0;
+
+ caps->v1.bset.seamless_cube_map_per_texture = 0;
+
+ caps->v1.bset.texture_multisample = 0;
+
+ caps->v1.bset.mirror_clamp = 0;
+ caps->v1.bset.indep_blend_func = 0;
+ caps->v1.bset.cube_map_array = 0;
+ caps->v1.bset.texture_query_lod = 0;
+ caps->v1.bset.has_indirect_draw = 0;
+ caps->v1.bset.has_sample_shading = 0;
+
+ caps->v1.bset.start_instance = 0;
+
+ caps->v1.bset.shader_stencil_export = 0;
+
+ caps->v1.bset.streamout_pause_resume = 0;
+
+ caps->v1.max_dual_source_render_targets = 0;
+
+ caps->v1.max_dual_source_render_targets = 0;
+
+ caps->v1.max_tbo_size = 0;
+
+ caps->v1.max_texture_gather_components = 0;
+
+ caps->v1.max_viewports = 1;
+
+ if (!fill_capset2) {
+ return;
+ }
+
+ glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, range);
+ caps->v2.min_aliased_point_size = range[0];
+ caps->v2.max_aliased_point_size = range[1];
+
+ /* Not available on GLES */
+ caps->v2.min_smooth_point_size = 0.0f;
+ caps->v2.max_smooth_point_size = 0.0f;
+
+ glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
+ caps->v2.min_aliased_line_width = range[0];
+ caps->v2.max_aliased_line_width = range[1];
+
+ /* Not available on GLES */
+ caps->v2.min_smooth_line_width = 0.0f;
+ caps->v2.max_smooth_line_width = 0.0f;
+
+ glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &caps->v2.max_texture_lod_bias);
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps->v2.max_vertex_attribs);
+ glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &max);
+ caps->v2.max_vertex_outputs = max / 4;
+
+ /* Not available on GLES */
+ caps->v2.max_geom_output_vertices = 0;
+ caps->v2.max_geom_total_output_components = 0;
+ caps->v2.max_shader_patch_varyings = 0;
+
+ /* Not available on GLES */
+ caps->v2.min_texture_gather_offset = 0;
+ caps->v2.max_texture_gather_offset = 0;
+
+ glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &caps->v2.min_texel_offset);
+ glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &caps->v2.max_texel_offset);
+
+ glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &caps->v2.uniform_buffer_offset_alignment);
+
+ /* Not available on GLES */
+ caps->v2.texture_buffer_offset_alignment = 0;
+}
+
+void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
+ union virgl_caps *caps)
+{
+ int i;
+ GLint max;
+ GLfloat range[2];
+ int gl_ver = epoxy_gl_version();
+ bool fill_capset2 = false;
+
+ /* Returns true if we should early out. */
+ if (vrend_renderer_fill_caps_common(set, version, caps)) {
+ return;
+ }
+
+ /* GLES has it's own path */
+ if (vrend_state.use_gles) {
+ vrend_renderer_fill_caps_gles(set, version, caps);
+ return;
+ }
+
+ if (set == 2) {
+ fill_capset2 = true;
+ }
+
if (gl_ver >= 30) {
caps->v1.bset.indep_blend_enable = 1;
caps->v1.bset.conditional_render = 1;
@@ -6486,6 +6687,7 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
caps->v1.bset.poly_stipple = 1;
caps->v1.bset.color_clamping = 1;
}
+
if (gl_ver >= 31) {
caps->v1.bset.instanceid = 1;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &max);
@@ -6496,9 +6698,6 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
caps->v1.bset.instanceid = 1;
}
- if (vrend_state.have_nv_prim_restart || vrend_state.have_gl_prim_restart)
- caps->v1.bset.primitive_restart = 1;
-
if (gl_ver >= 32) {
caps->v1.bset.fragment_coord_conventions = 1;
caps->v1.bset.depth_clip_disable = 1;
@@ -6510,13 +6709,14 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
caps->v1.bset.seamless_cube_map = 1;
}
- if (epoxy_has_gl_extension("GL_AMD_seamless_cube_map_per_texture"))
+ if (epoxy_has_gl_extension("GL_AMD_seamless_cube_map_per_texture")) {
caps->v1.bset.seamless_cube_map_per_texture = 1;
+ }
if (epoxy_has_gl_extension("GL_ARB_texture_multisample")) {
- /* disable multisample until developed */
caps->v1.bset.texture_multisample = 1;
}
+
if (gl_ver >= 40) {
caps->v1.bset.indep_blend_func = 1;
caps->v1.bset.cube_map_array = 1;
@@ -6538,26 +6738,17 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
if (gl_ver >= 42) {
caps->v1.bset.start_instance = 1;
- } else {
- if (epoxy_has_gl_extension("GL_ARB_base_instance"))
- caps->v1.bset.start_instance = 1;
+ } else if (epoxy_has_gl_extension("GL_ARB_base_instance")) {
+ caps->v1.bset.start_instance = 1;
}
- if (epoxy_has_gl_extension("GL_ARB_shader_stencil_export"))
- caps->v1.bset.shader_stencil_export = 1;
- /* we only support up to GLSL 1.40 features now */
- caps->v1.glsl_level = 130;
- if (vrend_state.use_core_profile) {
- if (gl_ver == 31)
- caps->v1.glsl_level = 140;
- else if (gl_ver == 32)
- caps->v1.glsl_level = 150;
- else if (gl_ver >= 33)
- caps->v1.glsl_level = 330;
+ if (epoxy_has_gl_extension("GL_ARB_shader_stencil_export")) {
+ caps->v1.bset.shader_stencil_export = 1;
}
- if (epoxy_has_gl_extension("GL_EXT_texture_mirror_clamp"))
+ if (epoxy_has_gl_extension("GL_EXT_texture_mirror_clamp")) {
caps->v1.bset.mirror_clamp = true;
+ }
if (epoxy_has_gl_extension("GL_EXT_texture_array")) {
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max);
@@ -6572,19 +6763,14 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
if (epoxy_has_gl_extension("GL_ARB_transform_feedback3")) {
glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max);
caps->v1.max_streamout_buffers = max;
- } else if (epoxy_has_gl_extension("GL_EXT_transform_feedback"))
+ } else if (epoxy_has_gl_extension("GL_EXT_transform_feedback")) {
caps->v1.max_streamout_buffers = 4;
+ }
+
if (epoxy_has_gl_extension("GL_ARB_blend_func_extended")) {
glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max);
caps->v1.max_dual_source_render_targets = max;
- } else
- caps->v1.max_dual_source_render_targets = 0;
-
- glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max);
- caps->v1.max_render_targets = max;
-
- glGetIntegerv(GL_MAX_SAMPLES, &max);
- caps->v1.max_samples = max;
+ }
if (epoxy_has_gl_extension("GL_ARB_texture_buffer_object")) {
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max);
@@ -6599,40 +6785,10 @@ void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
if (epoxy_has_gl_extension("GL_ARB_viewport_array")) {
glGetIntegerv(GL_MAX_VIEWPORTS, &max);
caps->v1.max_viewports = max;
- } else
+ } else {
caps->v1.max_viewports = 1;
-
- caps->v1.prim_mask = (1 << PIPE_PRIM_POINTS) | (1 << PIPE_PRIM_LINES) | (1 << PIPE_PRIM_LINE_STRIP) | (1 << PIPE_PRIM_LINE_LOOP) | (1 << PIPE_PRIM_TRIANGLES) | (1 << PIPE_PRIM_TRIANGLE_STRIP) | (1 << PIPE_PRIM_TRIANGLE_FAN);
- if (vrend_state.use_core_profile == false) {
- caps->v1.prim_mask |= (1 << PIPE_PRIM_QUADS) | (1 << PIPE_PRIM_QUAD_STRIP) | (1 << PIPE_PRIM_POLYGON);
- }
- if (caps->v1.glsl_level >= 150)
- caps->v1.prim_mask |= (1 << PIPE_PRIM_LINES_ADJACENCY) |
- (1 << PIPE_PRIM_LINE_STRIP_ADJACENCY) |
- (1 << PIPE_PRIM_TRIANGLES_ADJACENCY) |
- (1 << PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
-
-
- if (epoxy_has_gl_extension("GL_ARB_vertex_type_10f_11f_11f_rev")) {
- int val = VIRGL_FORMAT_R11G11B10_FLOAT;
- uint32_t offset = val / 32;
- uint32_t index = val % 32;
-
- caps->v1.vertexbuffer.bitmask[offset] |= (1 << index);
}
- for (i = 0; i < VIRGL_FORMAT_MAX; i++) {
- uint32_t offset = i / 32;
- uint32_t index = i % 32;
-
- if (tex_conv_table[i].internalformat != 0) {
- if (vrend_format_can_sample(i)) {
- caps->v1.sampler.bitmask[offset] |= (1 << index);
- if (vrend_format_can_render(i))
- caps->v1.render.bitmask[offset] |= (1 << index);
- }
- }
- }
if (!fill_capset2)
return;
--
2.14.1
More information about the virglrenderer-devel
mailing list