vrend: Enable ARB_texture_storage on GLES

glTexStorage*D is more restrictive in supporting texture formats, especially
on GLES. Specifically, it doesn't support BGRA textures that are needed to get
any useful display, but it is needed to get immutable textures that are required
for glTextureView.
Check which formats are supported and use glTexStorage*D for these, otherwise
fall back to use glTexImage*D.

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
macos/master
Gert Wollny 6 years ago committed by Dave Airlie
parent da81b0c93d
commit c91500a14c
  1. 20
      src/vrend_formats.c
  2. 17
      src/vrend_renderer.c
  3. 3
      src/vrend_renderer.h

@ -444,6 +444,26 @@ void vrend_build_format_list_gles(void)
add_formats(gles_z32_format); add_formats(gles_z32_format);
} }
/* glTexStorage may not support all that is supported by glTexImage,
* so add a flag to indicate when it can be used.
*/
void vrend_check_texture_storage(struct vrend_format_table *table)
{
int i;
GLuint tex_id;
for (i = 0; i < VIRGL_FORMAT_MAX; i++) {
if (table[i].internalformat != 0) {
glGenTextures(1, &tex_id);
glBindTexture(GL_TEXTURE_2D, tex_id);
glTexStorage2D(GL_TEXTURE_2D, 1, table[i].internalformat, 32, 32);
if (glGetError() == GL_NO_ERROR)
table[i].bindings |= VIRGL_BIND_CAN_TEXTURE_STORAGE;
glDeleteTextures(1, &tex_id);
}
}
}
unsigned vrend_renderer_query_multisample_caps(unsigned max_samples, struct virgl_caps_v2 *caps) unsigned vrend_renderer_query_multisample_caps(unsigned max_samples, struct virgl_caps_v2 *caps)
{ {
GLuint tex; GLuint tex;

@ -191,7 +191,7 @@ static const struct {
[feat_texture_buffer_range] = { 43, UNAVAIL, { "GL_ARB_texture_buffer_range" } }, [feat_texture_buffer_range] = { 43, UNAVAIL, { "GL_ARB_texture_buffer_range" } },
[feat_texture_multisample] = { 32, 30, { "GL_ARB_texture_multisample" } }, [feat_texture_multisample] = { 32, 30, { "GL_ARB_texture_multisample" } },
[feat_texture_srgb_decode] = { UNAVAIL, UNAVAIL, { "GL_EXT_texture_sRGB_decode" } }, [feat_texture_srgb_decode] = { UNAVAIL, UNAVAIL, { "GL_EXT_texture_sRGB_decode" } },
[feat_texture_storage] = { 42, UNAVAIL, { "GL_ARB_texture_storage" } }, [feat_texture_storage] = { 42, 30, { "GL_ARB_texture_storage" } },
[feat_texture_view] = { 43, UNAVAIL, { "GL_ARB_texture_view" } }, [feat_texture_view] = { 43, UNAVAIL, { "GL_ARB_texture_view" } },
[feat_transform_feedback] = { 30, 30, { "GL_EXT_transform_feedback" } }, [feat_transform_feedback] = { 30, 30, { "GL_EXT_transform_feedback" } },
[feat_transform_feedback2] = { 40, 30, { "GL_ARB_transform_feedback2" } }, [feat_transform_feedback2] = { 40, 30, { "GL_ARB_transform_feedback2" } },
@ -5149,6 +5149,8 @@ int vrend_renderer_init(struct vrend_if_cbs *cbs, uint32_t flags)
vrend_build_format_list_gl(); vrend_build_format_list_gl();
} }
vrend_check_texture_storage(tex_conv_table);
/* disable for format testing */ /* disable for format testing */
if (has_feature(feat_debug_cb)) { if (has_feature(feat_debug_cb)) {
glDisable(GL_DEBUG_OUTPUT); glDisable(GL_DEBUG_OUTPUT);
@ -5498,6 +5500,9 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
struct pipe_resource *pr = &gr->base; struct pipe_resource *pr = &gr->base;
assert(pr->width0 > 0); assert(pr->width0 > 0);
bool format_can_texture_storage = has_feature(feat_texture_storage) &&
(tex_conv_table[pr->format].bindings & VIRGL_BIND_CAN_TEXTURE_STORAGE);
gr->target = tgsitargettogltarget(pr->target, pr->nr_samples); gr->target = tgsitargettogltarget(pr->target, pr->nr_samples);
/* ugly workaround for texture rectangle missing on GLES */ /* ugly workaround for texture rectangle missing on GLES */
@ -5564,7 +5569,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
} }
} else if (gr->target == GL_TEXTURE_CUBE_MAP) { } else if (gr->target == GL_TEXTURE_CUBE_MAP) {
int i; int i;
if (has_feature(feat_texture_storage)) if (format_can_texture_storage)
glTexStorage2D(GL_TEXTURE_CUBE_MAP, pr->last_level + 1, internalformat, pr->width0, pr->height0); glTexStorage2D(GL_TEXTURE_CUBE_MAP, pr->last_level + 1, internalformat, pr->width0, pr->height0);
else { else {
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
@ -5581,7 +5586,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
} else if (gr->target == GL_TEXTURE_3D || } else if (gr->target == GL_TEXTURE_3D ||
gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_2D_ARRAY ||
gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) { gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) {
if (has_feature(feat_texture_storage)) { if (format_can_texture_storage) {
unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ? unsigned depth_param = (gr->target == GL_TEXTURE_2D_ARRAY || gr->target == GL_TEXTURE_CUBE_MAP_ARRAY) ?
pr->array_size : pr->depth0; pr->array_size : pr->depth0;
glTexStorage3D(gr->target, pr->last_level + 1, internalformat, pr->width0, pr->height0, depth_param); glTexStorage3D(gr->target, pr->last_level + 1, internalformat, pr->width0, pr->height0, depth_param);
@ -5598,7 +5603,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
} else if (gr->target == GL_TEXTURE_1D && vrend_state.use_gles) { } else if (gr->target == GL_TEXTURE_1D && vrend_state.use_gles) {
report_gles_missing_func(NULL, "glTexImage1D"); report_gles_missing_func(NULL, "glTexImage1D");
} else if (gr->target == GL_TEXTURE_1D) { } else if (gr->target == GL_TEXTURE_1D) {
if (has_feature(feat_texture_storage)) { if (format_can_texture_storage) {
glTexStorage1D(gr->target, pr->last_level + 1, internalformat, pr->width0); glTexStorage1D(gr->target, pr->last_level + 1, internalformat, pr->width0);
} else { } else {
for (level = 0; level <= pr->last_level; level++) { for (level = 0; level <= pr->last_level; level++) {
@ -5608,7 +5613,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
} }
} }
} else { } else {
if (has_feature(feat_texture_storage)) if (format_can_texture_storage)
glTexStorage2D(gr->target, pr->last_level + 1, internalformat, pr->width0, glTexStorage2D(gr->target, pr->last_level + 1, internalformat, pr->width0,
gr->target == GL_TEXTURE_1D_ARRAY ? pr->array_size : pr->height0); gr->target == GL_TEXTURE_1D_ARRAY ? pr->array_size : pr->height0);
else { else {
@ -5622,7 +5627,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
} }
} }
if (!has_feature(feat_texture_storage)) { if (!format_can_texture_storage) {
glTexParameteri(gr->target, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(gr->target, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(gr->target, GL_TEXTURE_MAX_LEVEL, pr->last_level); glTexParameteri(gr->target, GL_TEXTURE_MAX_LEVEL, pr->last_level);
} }

@ -71,6 +71,8 @@ struct vrend_resource {
}; };
#define VIRGL_BIND_NEED_SWIZZLE (1 << 28) #define VIRGL_BIND_NEED_SWIZZLE (1 << 28)
#define VIRGL_BIND_CAN_TEXTURE_STORAGE (1 << 29)
struct vrend_format_table { struct vrend_format_table {
enum virgl_formats format; enum virgl_formats format;
@ -330,6 +332,7 @@ GLint64 vrend_renderer_get_timestamp(void);
void vrend_build_format_list_common(void); void vrend_build_format_list_common(void);
void vrend_build_format_list_gl(void); void vrend_build_format_list_gl(void);
void vrend_build_format_list_gles(void); void vrend_build_format_list_gles(void);
void vrend_check_texture_storage(struct vrend_format_table *table);
int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov, int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov,
int num_iovs); int num_iovs);

Loading…
Cancel
Save