formats: Add emulated versions of some BGRA formats

On GLES B8G8R8A8_SRGB is not available and B8G8R8A8_UNORM can not be
created as immutable. In order to have versions of these formats that
can be created immutable on GLES provide the formats R8G8B8A8_SRGB and
_UNORM with swizzling to BGRA that can then be used instead of the BGRA
formats. Since this may break things these swizzled versions will later
be only enabled when the guest requests them.

v2: Check the base swizzled BGRA format only on GL
v3: Correct type in method name (Gurchetan)
v4: Add PREFER_EMULATED_BRGA to according format binding flags (Gurchetan)
v5: Add comment about formats nou to be used in the guest (Gurchetan)

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Gert Wollny 5 years ago
parent 267d486889
commit 4749e8791b
  1. 7
      src/virgl_hw.h
  2. 97
      src/vrend_formats.c
  3. 2
      src/vrend_renderer.c

@ -222,7 +222,12 @@ enum virgl_formats {
VIRGL_FORMAT_A4B4G4R4_UNORM = 311, VIRGL_FORMAT_A4B4G4R4_UNORM = 311,
VIRGL_FORMAT_R8_SRGB = 312, VIRGL_FORMAT_R8_SRGB = 312,
VIRGL_FORMAT_MAX, VIRGL_FORMAT_MAX /* = PIPE_FORMAT_COUNT */,
/* Below formats must not be used in the guest. */
VIRGL_FORMAT_B8G8R8X8_UNORM_EMULATED,
VIRGL_FORMAT_B8G8R8A8_UNORM_EMULATED,
VIRGL_FORMAT_MAX_EXTENDED
}; };
/* These are used by the capability_bits field in virgl_caps_v2. */ /* These are used by the capability_bits field in virgl_caps_v2. */

@ -32,6 +32,9 @@
#define RRR1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ONE } #define RRR1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ONE }
#define RGB1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ONE } #define RGB1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ONE }
#define BGR1_SWIZZLE { PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ONE }
#define BGRA_SWIZZLE { PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ALPHA }
#ifdef __GNUC__ #ifdef __GNUC__
/* The warning missing-field-initializers is misleading: If at least one field /* The warning missing-field-initializers is misleading: If at least one field
* is initialized, then the un-initialized fields will be filled with zero. * is initialized, then the un-initialized fields will be filled with zero.
@ -50,9 +53,6 @@
/* fill the format table */ /* fill the format table */
static struct vrend_format_table base_rgba_formats[] = static struct vrend_format_table base_rgba_formats[] =
{ {
{ VIRGL_FORMAT_B8G8R8X8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
{ VIRGL_FORMAT_B8G8R8A8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
{ VIRGL_FORMAT_R8G8B8X8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, { VIRGL_FORMAT_R8G8B8X8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
{ VIRGL_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE }, { VIRGL_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
@ -280,11 +280,25 @@ static struct vrend_format_table bptc_formats[] = {
{ VIRGL_FORMAT_BPTC_RGB_UFLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE }, { VIRGL_FORMAT_BPTC_RGB_UFLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
}; };
static struct vrend_format_table gl_bgra_formats[] = {
{ VIRGL_FORMAT_B8G8R8X8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
{ VIRGL_FORMAT_B8G8R8A8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
};
static struct vrend_format_table gles_bgra_formats[] = { static struct vrend_format_table gles_bgra_formats[] = {
{ VIRGL_FORMAT_B8G8R8X8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, RGB1_SWIZZLE }, { VIRGL_FORMAT_B8G8R8X8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
{ VIRGL_FORMAT_B8G8R8A8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE }, { VIRGL_FORMAT_B8G8R8A8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE },
}; };
static struct vrend_format_table gles_bgra_formats_emulation[] = {
{ VIRGL_FORMAT_B8G8R8X8_UNORM_EMULATED, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, BGR1_SWIZZLE },
{ VIRGL_FORMAT_B8G8R8A8_UNORM_EMULATED, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, BGRA_SWIZZLE },
{ VIRGL_FORMAT_B8G8R8X8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, BGR1_SWIZZLE },
{ VIRGL_FORMAT_B8G8R8A8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, BGRA_SWIZZLE },
};
static struct vrend_format_table gles_z32_format[] = { static struct vrend_format_table gles_z32_format[] = {
{ VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE }, { VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE },
}; };
@ -378,33 +392,35 @@ static void vrend_add_formats(struct vrend_format_table *table, int num_entries)
/* we can't probe compressed formats, as we'd need valid payloads to /* we can't probe compressed formats, as we'd need valid payloads to
* glCompressedTexImage2D. Let's just check for extensions instead. * glCompressedTexImage2D. Let's just check for extensions instead.
*/ */
const struct util_format_description *desc = util_format_description(table[i].format); if (table[i].format < VIRGL_FORMAT_MAX) {
switch (desc->layout) { const struct util_format_description *desc = util_format_description(table[i].format);
case UTIL_FORMAT_LAYOUT_S3TC: switch (desc->layout) {
if (epoxy_has_gl_extension("GL_S3_s3tc") || case UTIL_FORMAT_LAYOUT_S3TC:
epoxy_has_gl_extension("GL_EXT_texture_compression_s3tc")) if (epoxy_has_gl_extension("GL_S3_s3tc") ||
vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags); epoxy_has_gl_extension("GL_EXT_texture_compression_s3tc"))
continue; vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags);
continue;
case UTIL_FORMAT_LAYOUT_RGTC:
if (epoxy_has_gl_extension("GL_ARB_texture_compression_rgtc") || case UTIL_FORMAT_LAYOUT_RGTC:
epoxy_has_gl_extension("GL_EXT_texture_compression_rgtc") ) if (epoxy_has_gl_extension("GL_ARB_texture_compression_rgtc") ||
vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags); epoxy_has_gl_extension("GL_EXT_texture_compression_rgtc") )
continue; vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags);
continue;
case UTIL_FORMAT_LAYOUT_ETC:
if (epoxy_has_gl_extension("GL_OES_compressed_ETC1_RGB8_texture")) case UTIL_FORMAT_LAYOUT_ETC:
vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags); if (epoxy_has_gl_extension("GL_OES_compressed_ETC1_RGB8_texture"))
continue; vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags);
continue;
case UTIL_FORMAT_LAYOUT_BPTC:
if (epoxy_has_gl_extension("GL_ARB_texture_compression_bptc") || case UTIL_FORMAT_LAYOUT_BPTC:
epoxy_has_gl_extension("GL_EXT_texture_compression_bptc")) if (epoxy_has_gl_extension("GL_ARB_texture_compression_bptc") ||
vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags); epoxy_has_gl_extension("GL_EXT_texture_compression_bptc"))
continue; vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags);
continue;
default:
;/* do logic below */ default:
;/* do logic below */
}
} }
/* The error state should be clear here */ /* The error state should be clear here */
@ -441,7 +457,7 @@ static void vrend_add_formats(struct vrend_format_table *table, int num_entries)
continue; continue;
} }
if (util_format_is_depth_or_stencil(table[i].format)) { if (table[i].format < VIRGL_FORMAT_MAX && util_format_is_depth_or_stencil(table[i].format)) {
GLenum attachment; GLenum attachment;
if (table[i].format == VIRGL_FORMAT_Z24X8_UNORM || table[i].format == VIRGL_FORMAT_Z32_UNORM || table[i].format == VIRGL_FORMAT_Z16_UNORM || table[i].format == VIRGL_FORMAT_Z32_FLOAT) if (table[i].format == VIRGL_FORMAT_Z24X8_UNORM || table[i].format == VIRGL_FORMAT_Z32_UNORM || table[i].format == VIRGL_FORMAT_Z16_UNORM || table[i].format == VIRGL_FORMAT_Z32_FLOAT)
@ -472,6 +488,14 @@ static void vrend_add_formats(struct vrend_format_table *table, int num_entries)
flags |= VIRGL_TEXTURE_CAN_READBACK; flags |= VIRGL_TEXTURE_CAN_READBACK;
} }
if (i == VIRGL_FORMAT_B8G8R8A8_UNORM_EMULATED) {
table[VIRGL_FORMAT_B8G8R8A8_UNORM].flags |= VIRGL_TEXTURE_CAN_READBACK;
binding |= VIRGL_BIND_PREFER_EMULATED_BGRA;
} else if (i == VIRGL_FORMAT_B8G8R8X8_UNORM_EMULATED) {
table[VIRGL_FORMAT_B8G8R8X8_UNORM].flags |= VIRGL_TEXTURE_CAN_READBACK;
binding |= VIRGL_BIND_PREFER_EMULATED_BGRA;
}
glDeleteTextures(1, &tex_id); glDeleteTextures(1, &tex_id);
glDeleteFramebuffers(1, &fb_id); glDeleteFramebuffers(1, &fb_id);
@ -533,6 +557,7 @@ void vrend_build_format_list_gl(void)
* transfer operations. So we only register support for it in GL. * transfer operations. So we only register support for it in GL.
*/ */
add_formats(gl_base_rgba_formats); add_formats(gl_base_rgba_formats);
add_formats(gl_bgra_formats);
add_formats(gl_srgb_formats); add_formats(gl_srgb_formats);
} }
@ -553,6 +578,11 @@ void vrend_build_format_list_gles(void)
add_formats(gles_bit10_formats); add_formats(gles_bit10_formats);
} }
void vrend_build_emulated_format_list_gles(void)
{
add_formats(gles_bgra_formats_emulation);
}
/* glTexStorage may not support all that is supported by glTexImage, /* glTexStorage may not support all that is supported by glTexImage,
* so add a flag to indicate when it can be used. * so add a flag to indicate when it can be used.
*/ */
@ -560,9 +590,10 @@ void vrend_check_texture_storage(struct vrend_format_table *table)
{ {
int i; int i;
GLuint tex_id; GLuint tex_id;
for (i = 0; i < VIRGL_FORMAT_MAX; i++) { for (i = 0; i < VIRGL_FORMAT_MAX_EXTENDED; i++) {
if (table[i].internalformat != 0) { if (table[i].internalformat != 0 &&
!(table[i].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE)) {
glGenTextures(1, &tex_id); glGenTextures(1, &tex_id);
glBindTexture(GL_TEXTURE_2D, tex_id); glBindTexture(GL_TEXTURE_2D, tex_id);
glTexStorage2D(GL_TEXTURE_2D, 1, table[i].internalformat, 32, 32); glTexStorage2D(GL_TEXTURE_2D, 1, table[i].internalformat, 32, 32);

@ -646,7 +646,7 @@ static GLenum tgsitargettogltarget(const enum pipe_texture_target target, int nr
void vrend_update_stencil_state(struct vrend_context *ctx); void vrend_update_stencil_state(struct vrend_context *ctx);
static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX]; static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX_EXTENDED];
static inline bool vrend_format_can_sample(enum virgl_formats format) static inline bool vrend_format_can_sample(enum virgl_formats format)
{ {

Loading…
Cancel
Save