vrend: Add handling for swizzled BGRA formats

v2: - Clear stale error state before testing emulation formats
    - correct typos (Gurchetan)

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Gert Wollny 6 years ago
parent 4749e8791b
commit 0977e48e24
  1. 4
      src/virgl_hw.h
  2. 81
      src/vrend_renderer.c
  3. 3
      src/vrend_renderer.h

@ -261,6 +261,7 @@ enum virgl_formats {
#define VIRGL_CAP_COPY_TRANSFER (1 << 26)
#define VIRGL_CAP_CLIP_HALFZ (1 << 27)
#define VIRGL_CAP_APP_TWEAK_SUPPORT (1 << 28)
#define VIRGL_CAP_BGRA_SRGB_IS_EMULATED (1 << 29)
/* virgl bind flags - these are compatible with mesa 10.5 gallium.
* but are fixed, no other should be passed to virgl either.
@ -285,6 +286,8 @@ enum virgl_formats {
#define VIRGL_BIND_STAGING (1 << 19)
#define VIRGL_BIND_SHARED (1 << 20)
#define VIRGL_BIND_PREFER_EMULATED_BGRA (1 << 21)
struct virgl_caps_bool_set1 {
unsigned indep_blend_enable:1;
unsigned indep_blend_func:1;
@ -419,6 +422,7 @@ enum virgl_ctx_errors {
VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT,
VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER,
VIRGL_ERROR_CTX_GLES_HAVE_TES_BUT_MISS_TCS,
VIRGL_ERROR_GL_ANY_SAMPLES_PASSED,
};
#define VIRGL_RESOURCE_Y_0_TOP (1 << 0)

@ -279,6 +279,8 @@ struct global_renderer_state {
/* Needed on GLES to inject a TCS */
float tess_factors[6];
bool bgra_srgb_emulation_loaded;
};
static struct global_renderer_state vrend_state;
@ -988,12 +990,44 @@ vrend_insert_format_swizzle(int override_format, struct vrend_format_table *entr
tex_conv_table[override_format].swizzle[i] = swizzle[i];
}
static inline enum virgl_formats
vrend_format_replace_emulated(uint32_t bind, enum pipe_format format)
{
enum virgl_formats retval = (enum virgl_formats)format;
if (vrend_state.use_gles && (bind & VIRGL_BIND_PREFER_EMULATED_BGRA)) {
VREND_DEBUG(dbg_tweak, vrend_state.current_ctx, "Check tweak for format %s", util_format_name(format));
if (!vrend_state.bgra_srgb_emulation_loaded) {
GLint err = glGetError();
if (err != GL_NO_ERROR)
vrend_printf("Warning: stale error state when calling %s\n", __func__);
VREND_DEBUG_NOCTX(dbg_tweak, vrend_state.current_ctx, " ... add swizzled formats\n");
vrend_build_emulated_format_list_gles();
vrend_check_texture_storage(tex_conv_table);
vrend_state.bgra_srgb_emulation_loaded = true;
}
if (format == PIPE_FORMAT_B8G8R8A8_UNORM)
retval = VIRGL_FORMAT_B8G8R8A8_UNORM_EMULATED;
else if (format == PIPE_FORMAT_B8G8R8X8_UNORM)
retval = VIRGL_FORMAT_B8G8R8X8_UNORM_EMULATED;
VREND_DEBUG_NOCTX(dbg_tweak, vrend_state.current_ctx,
"%s\n", (retval != (enum virgl_formats)format ? "... replace" : ""));
}
return retval;
}
const struct vrend_format_table *
vrend_get_format_table_entry(enum virgl_formats format)
{
return &tex_conv_table[format];
}
const struct vrend_format_table *vrend_get_format_table_entry_with_emulation(uint32_t bind, enum virgl_formats format)
{
return vrend_get_format_table_entry(vrend_format_replace_emulated(bind, format));
}
static bool vrend_is_timer_query(GLenum gltype)
{
return gltype == GL_TIMESTAMP ||
@ -1644,13 +1678,15 @@ int vrend_create_surface(struct vrend_context *ctx,
surf->res_handle = res_handle;
surf->format = format;
format = vrend_format_replace_emulated(res->base.bind, format);
surf->val0 = val0;
surf->val1 = val1;
surf->id = res->id;
if (has_feature(feat_texture_view) &&
res->storage != VREND_RESOURCE_STORAGE_BUFFER &&
(tex_conv_table[res->base.format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE)) {
(tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE)) {
/* We don't need texture views for buffer objects.
* Otherwise we only need a texture view if the
* a) formats differ between the surface and base texture
@ -1662,17 +1698,18 @@ int vrend_create_surface(struct vrend_context *ctx,
int first_layer = surf->val1 & 0xffff;
int last_layer = (surf->val1 >> 16) & 0xffff;
VREND_DEBUG(dbg_tex, ctx, "Create texture view from %s for %s\n",
VREND_DEBUG(dbg_tex, ctx, "Create texture view from %s for %s (emulated:%d)\n",
util_format_name(res->base.format),
util_format_name(surf->format));
util_format_name(surf->format),
surf->format != format);
if ((first_layer != last_layer &&
(first_layer != 0 || (last_layer != (int)util_max_layer(&res->base, surf->val0)))) ||
surf->format != res->base.format) {
GLenum internalformat = tex_conv_table[surf->format].internalformat;
GLenum target = res->target;
glGenTextures(1, &surf->id);
GLenum internalformat = tex_conv_table[format].internalformat;
glGenTextures(1, &surf->id);
if (vrend_state.use_gles) {
if (target == GL_TEXTURE_RECTANGLE_NV ||
target == GL_TEXTURE_1D)
@ -5619,6 +5656,7 @@ int vrend_renderer_init(struct vrend_if_cbs *cbs, uint32_t flags)
glDisable(GL_DEBUG_OUTPUT);
}
vrend_state.bgra_srgb_emulation_loaded = false;
vrend_build_format_list_common();
if (vrend_state.use_gles) {
@ -5996,6 +6034,7 @@ vrend_renderer_resource_copy_args(struct vrend_renderer_resource_create_args *ar
assert(args);
gr->handle = args->handle;
gr->base.bind = args->bind;
gr->base.width0 = args->width;
gr->base.height0 = args->height;
gr->base.depth0 = args->depth;
@ -6017,8 +6056,9 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
if (pr->width0 == 0)
return EINVAL;
enum virgl_formats format = vrend_format_replace_emulated(gr->base.bind, gr->base.format);
bool format_can_texture_storage = has_feature(feat_texture_storage) &&
(tex_conv_table[pr->format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE);
(tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE);
gr->target = tgsitargettogltarget(pr->target, pr->nr_samples);
gr->storage = VREND_RESOURCE_STORAGE_TEXTURE;
@ -6044,9 +6084,9 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,
debug_texture(__func__, gr);
internalformat = tex_conv_table[pr->format].internalformat;
glformat = tex_conv_table[pr->format].glformat;
gltype = tex_conv_table[pr->format].gltype;
internalformat = tex_conv_table[format].internalformat;
glformat = tex_conv_table[format].glformat;
gltype = tex_conv_table[format].gltype;
if (internalformat == 0) {
vrend_printf("unknown format is %d\n", pr->format);
@ -6921,8 +6961,9 @@ static int vrend_transfer_send_readpixels(struct vrend_resource *res,
glUseProgram(0);
format = tex_conv_table[res->base.format].glformat;
type = tex_conv_table[res->base.format].gltype;
enum virgl_formats fmt = vrend_format_replace_emulated(res->base.bind, res->base.format);
format = tex_conv_table[fmt].glformat;
type = tex_conv_table[fmt].gltype;
/* if we are asked to invert and reading from a front then don't */
actually_invert = res->y_0_top;
@ -7781,15 +7822,21 @@ static GLuint vrend_make_view(struct vrend_resource *res, enum pipe_format forma
{
GLuint view_id;
glGenTextures(1, &view_id);
GLenum fmt = tex_conv_table[format].internalformat;
enum virgl_formats src_fmt = vrend_format_replace_emulated(res->base.bind, res->base.format);
enum virgl_formats dst_fmt = vrend_format_replace_emulated(res->base.bind, format);
GLenum fmt = tex_conv_table[dst_fmt].internalformat;
/* If the format doesn't support TextureStorage it is not immutable, so no TextureView*/
if (!(tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE))
if (!(tex_conv_table[src_fmt].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE))
return res->id;
VREND_DEBUG(dbg_blit, NULL, "Create texture view from %s for %s\n",
VREND_DEBUG(dbg_blit, NULL, "Create texture view from %s%s as %s%s\n",
util_format_name(res->base.format),
util_format_name(format));
(enum virgl_formats)res->base.format != src_fmt ? "(emulated)" : "",
util_format_name(format),
(enum virgl_formats)format != dst_fmt ? "(emulated)" : "");
unsigned layers_factor = 1;
if (res->target == GL_TEXTURE_CUBE_MAP || res->target == GL_TEXTURE_CUBE_MAP_ARRAY)
@ -9145,8 +9192,10 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c
caps->v2.capability_bits |= VIRGL_CAP_FBO_MIXED_COLOR_FORMATS;
/* We want to expose ARB_gpu_shader_fp64 when running on top of ES */
if (vrend_state.use_gles)
if (vrend_state.use_gles) {
caps->v2.capability_bits |= VIRGL_CAP_FAKE_FP64;
caps->v2.capability_bits |= VIRGL_CAP_BGRA_SRGB_IS_EMULATED;
}
if (has_feature(feat_indirect_draw))
caps->v2.capability_bits |= VIRGL_CAP_BIND_COMMAND_ARGS;

@ -132,6 +132,8 @@ bool vrend_check_framebuffer_mixed_color_attachements(void);
void vrend_insert_format_swizzle(int override_format, struct vrend_format_table *entry,
uint32_t bindings, uint8_t swizzle[4], uint32_t flags);
const struct vrend_format_table *vrend_get_format_table_entry(enum virgl_formats format);
const struct vrend_format_table *vrend_get_format_table_entry_with_emulation(uint32_t bind, enum virgl_formats format);
int vrend_create_shader(struct vrend_context *ctx,
uint32_t handle,
const struct pipe_stream_output_info *stream_output,
@ -370,6 +372,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_build_emulated_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,

Loading…
Cancel
Save