diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_drawpixels.c | 10 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.c | 96 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_manager.c | 47 |
5 files changed, 130 insertions, 26 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c index 95b706cb9..1f833d282 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/mesalib/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -94,7 +94,7 @@ create_color_map_texture(struct gl_context *ctx) const uint texSize = 256; /* simple, and usually perfect */ /* find an RGBA texture format */ - format = st_choose_format(pipe->screen, GL_RGBA, + format = st_choose_format(pipe->screen, GL_RGBA, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); /* create texture for color map/table */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 965fbcd1d..c730975df 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -989,8 +989,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, /* can we write to stencil if not fallback */ if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) goto stencil_fallback; - + tex_format = st_choose_format(st->pipe->screen, base_format(format), + GL_NONE, GL_NONE, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); if (tex_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED) @@ -1399,13 +1400,14 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, /* srcFormat can't be used as a texture format */ if (type == GL_DEPTH) { texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, - st->internal_target, sample_count, - PIPE_BIND_DEPTH_STENCIL); + st->internal_target, GL_NONE, GL_NONE, + sample_count, PIPE_BIND_DEPTH_STENCIL); assert(texFormat != PIPE_FORMAT_NONE); } else { /* default color format */ - texFormat = st_choose_format(screen, GL_RGBA, st->internal_target, + texFormat = st_choose_format(screen, GL_RGBA, + st->internal_target, GL_NONE, GL_NONE, sample_count, PIPE_BIND_SAMPLER_VIEW); assert(texFormat != PIPE_FORMAT_NONE); } diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 263613b2c..8118df37d 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -1124,6 +1124,87 @@ find_supported_format(struct pipe_screen *screen, return PIPE_FORMAT_NONE; } +struct exact_format_mapping +{ + GLenum format; + GLenum type; + enum pipe_format pformat; +}; + +static const struct exact_format_mapping rgba8888_tbl[] = +{ + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8R8G8B8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8A8_UNORM }, + { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8A8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_A8B8G8R8_UNORM }, + { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8A8_UNORM }, + { 0, 0, 0 } +}; + +static const struct exact_format_mapping rgbx8888_tbl[] = +{ + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8B8G8R8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_X8B8G8R8_UNORM }, + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8R8G8B8_UNORM }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8X8_UNORM }, + { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8X8_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_X8B8G8R8_UNORM }, + { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8X8_UNORM }, + { 0, 0, 0 } +}; + +static const struct exact_format_mapping rgba1010102_tbl[] = +{ + { GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_B10G10R10A2_UNORM }, + { GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_R10G10B10A2_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT_10_10_10_2, PIPE_FORMAT_R10G10B10A2_UNORM }, + { GL_ABGR_EXT, GL_UNSIGNED_INT, PIPE_FORMAT_R10G10B10A2_UNORM }, + { 0, 0, 0 } +}; + +/** + * If there is an exact pipe_format match for {internalFormat, format, type} + * return that, otherwise return PIPE_FORMAT_NONE so we can do fuzzy matching. + */ +static enum pipe_format +find_exact_format(GLint internalFormat, GLenum format, GLenum type) +{ + uint i; + const struct exact_format_mapping* tbl; + + if (format == GL_NONE || type == GL_NONE) + return PIPE_FORMAT_NONE; + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_RGBA8: + tbl = rgba8888_tbl; + break; + case 3: + case GL_RGB: + case GL_RGB8: + tbl = rgbx8888_tbl; + break; + case GL_RGB10_A2: + tbl = rgba1010102_tbl; + break; + default: + return PIPE_FORMAT_NONE; + } + + for (i = 0; tbl[i].format; i++) + if (tbl[i].format == format && tbl[i].type == type) + return tbl[i].pformat; + + return PIPE_FORMAT_NONE; +} /** * Given an OpenGL internalFormat value for a texture or surface, return @@ -1140,11 +1221,13 @@ find_supported_format(struct pipe_screen *screen, */ enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, + GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, unsigned bindings) { GET_CURRENT_CONTEXT(ctx); /* XXX this should be a function parameter */ int i, j; + enum pipe_format pf; /* can't render to compressed formats at this time */ if (_mesa_is_compressed_format(ctx, internalFormat) @@ -1152,6 +1235,13 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, return PIPE_FORMAT_NONE; } + /* search for exact matches */ + pf = find_exact_format(internalFormat, format, type); + if (pf != PIPE_FORMAT_NONE && + screen->is_format_supported(screen, pf, + target, sample_count, bindings)) + return pf; + /* search table for internalFormat */ for (i = 0; i < Elements(format_map); i++) { const struct format_mapping *mapping = &format_map[i]; @@ -1183,7 +1273,7 @@ st_choose_renderbuffer_format(struct pipe_screen *screen, usage = PIPE_BIND_DEPTH_STENCIL; else usage = PIPE_BIND_RENDER_TARGET; - return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, + return st_choose_format(screen, internalFormat, GL_NONE, GL_NONE, PIPE_TEXTURE_2D, sample_count, usage); } @@ -1210,12 +1300,12 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat, bindings |= PIPE_BIND_RENDER_TARGET; } - pFormat = st_choose_format(screen, internalFormat, + pFormat = st_choose_format(screen, internalFormat, format, type, PIPE_TEXTURE_2D, 0, bindings); if (pFormat == PIPE_FORMAT_NONE) { /* try choosing format again, this time without render target bindings */ - pFormat = st_choose_format(screen, internalFormat, + pFormat = st_choose_format(screen, internalFormat, format, type, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); } diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h index 0fb570f6e..7bda785af 100644 --- a/mesalib/src/mesa/state_tracker/st_format.h +++ b/mesalib/src/mesa/state_tracker/st_format.h @@ -52,6 +52,7 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat); extern enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, + GLenum format, GLenum type, enum pipe_texture_target target, unsigned sample_count, unsigned tex_usage); diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 46be55318..c95514cbe 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -716,38 +716,49 @@ st_api_get_current(struct st_api *stapi) return (st) ? &st->iface : NULL; } +static struct st_framebuffer * +st_framebuffer_reuse_or_create(struct gl_framebuffer *fb, + struct st_framebuffer_iface *stfbi) +{ + struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL; + + if (cur && cur->iface == stfbi) { + /* reuse the current stfb */ + st_framebuffer_reference(&stfb, cur); + } + else { + /* create a new one */ + stfb = st_framebuffer_create(stfbi); + } + + return stfb; +} + static boolean st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, struct st_framebuffer_iface *stdrawi, struct st_framebuffer_iface *streadi) { struct st_context *st = (struct st_context *) stctxi; - struct st_framebuffer *stdraw, *stread, *stfb; + struct st_framebuffer *stdraw, *stread; boolean ret; _glapi_check_multithread(); if (st) { - /* reuse/create the draw fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer); - if (stfb && stfb->iface == stdrawi) { - stdraw = NULL; - st_framebuffer_reference(&stdraw, stfb); + /* reuse or create the draw fb */ + stdraw = st_framebuffer_reuse_or_create(st->ctx->WinSysDrawBuffer, + stdrawi); + if (streadi != stdrawi) { + /* do the same for the read fb */ + stread = st_framebuffer_reuse_or_create(st->ctx->WinSysReadBuffer, + streadi); } else { - stdraw = st_framebuffer_create(stdrawi); - } - - /* reuse/create the read fb */ - stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer); - if (!stfb || stfb->iface != streadi) - stfb = stdraw; - if (stfb && stfb->iface == streadi) { stread = NULL; - st_framebuffer_reference(&stread, stfb); - } - else { - stread = st_framebuffer_create(streadi); + /* reuse the draw fb for the read fb */ + if (stdraw) + st_framebuffer_reference(&stread, stdraw); } if (stdraw && stread) { |