[virglrenderer-devel] [PATCH] vrend: Enable ARB_texture_storage on GLES
Gert Wollny
gert.wollny at collabora.com
Wed Jul 25 11:14:02 UTC 2018
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 glTexStorage*D 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 at collabora.com>
---
src/vrend_formats.c | 20 ++++++++++++++++++++
src/vrend_renderer.c | 17 +++++++++++------
src/vrend_renderer.h | 3 +++
3 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/src/vrend_formats.c b/src/vrend_formats.c
index 4647c43..b9f85a0 100644
--- a/src/vrend_formats.c
+++ b/src/vrend_formats.c
@@ -444,6 +444,26 @@ void vrend_build_format_list_gles(void)
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)
{
GLuint tex;
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index b56092f..2c58e1a 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -172,7 +172,7 @@ static const struct {
[feat_texture_array] = { 30, 30, { "GL_EXT_texture_array" } },
[feat_texture_buffer_range] = { 43, UNAVAIL, { "GL_ARB_texture_buffer_range" } },
[feat_texture_multisample] = { 32, 30, { "GL_ARB_texture_multisample" } },
- [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_transform_feedback] = { 30, 30, { "GL_EXT_transform_feedback" } },
[feat_transform_feedback2] = { 40, 30, { "GL_ARB_transform_feedback2" } },
@@ -4762,6 +4762,8 @@ int vrend_renderer_init(struct vrend_if_cbs *cbs, uint32_t flags)
vrend_build_format_list_gl();
}
+ vrend_check_texture_storage(tex_conv_table);
+
/* disable for format testing */
if (has_feature(feat_debug_cb)) {
glDisable(GL_DEBUG_OUTPUT);
@@ -5109,6 +5111,9 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
struct pipe_resource *pr = &gr->base;
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);
/* ugly workaround for texture rectangle missing on GLES */
@@ -5175,7 +5180,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
}
} else if (gr->target == GL_TEXTURE_CUBE_MAP) {
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);
else {
for (i = 0; i < 6; i++) {
@@ -5192,7 +5197,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
} else if (gr->target == GL_TEXTURE_3D ||
gr->target == GL_TEXTURE_2D_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) ?
pr->array_size : pr->depth0;
glTexStorage3D(gr->target, pr->last_level + 1, internalformat, pr->width0, pr->height0, depth_param);
@@ -5209,7 +5214,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
} else if (gr->target == GL_TEXTURE_1D && vrend_state.use_gles) {
report_gles_missing_func(NULL, "glTexImage1D");
} 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);
} else {
for (level = 0; level <= pr->last_level; level++) {
@@ -5219,7 +5224,7 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
}
}
} else {
- if (has_feature(feat_texture_storage))
+ if (format_can_texture_storage)
glTexStorage2D(gr->target, pr->last_level + 1, internalformat, pr->width0,
gr->target == GL_TEXTURE_1D_ARRAY ? pr->array_size : pr->height0);
else {
@@ -5233,7 +5238,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_MAX_LEVEL, pr->last_level);
}
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index 8f1192e..36a0d3d 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -71,6 +71,8 @@ struct vrend_resource {
};
#define VIRGL_BIND_NEED_SWIZZLE (1 << 28)
+#define VIRGL_BIND_CAN_TEXTURE_STORAGE (1 << 29)
+
struct vrend_format_table {
enum virgl_formats format;
@@ -314,6 +316,7 @@ GLint64 vrend_renderer_get_timestamp(void);
void vrend_build_format_list_common(void);
void vrend_build_format_list_gl(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 num_iovs);
--
2.16.4
More information about the virglrenderer-devel
mailing list