summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker/st_manager.c
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2014-03-03 12:44:43 +0800
committerChia-I Wu <[email protected]>2014-03-06 10:59:25 +0800
commit4c68c6dcffe6c738d563eb0e0650bb865a5457b2 (patch)
tree184258c93e8ff7d80ed182e54b41cd306efd1c63 /src/mesa/state_tracker/st_manager.c
parent6d23ca1621cf2c68b0bab02374061ec026cb6ef3 (diff)
st/mesa: make winsys fbo sRGB-capable when supported
The texture formats of winsys fbo are always linear becase the st manager (st/dri for example) could not know the colorspace used. But it does not mean that we cannot make the fbo sRGB-capable. By - setting rb->Visual.sRGBCapable to GL_TRUE when the pipe driver supports the format in sRGB colorspace, - giving rb an sRGB internal format, and - updating code to check rb->Format instead of strb->texture->format, we should be good. Fixed bug 75226 for at least llvmpipe and ilo, with no piglit regression. v2: do not set rb->Visual.sRGBCapable for GLES contexts to avoid surprises Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75226 Reviewed-by: Brian Paul <[email protected]> Tested-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker/st_manager.c')
-rw-r--r--src/mesa/state_tracker/st_manager.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index 6a776a8a236..68cb5dee693 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -302,6 +302,8 @@ st_framebuffer_add_renderbuffer(struct st_framebuffer *stfb,
break;
default:
format = stfb->iface->visual->color_format;
+ if (stfb->Base.Visual.sRGBCapable)
+ format = util_format_srgb(format);
sw = FALSE;
break;
}
@@ -400,7 +402,8 @@ st_visual_to_context_mode(const struct st_visual *visual,
* Create a framebuffer from a manager interface.
*/
static struct st_framebuffer *
-st_framebuffer_create(struct st_framebuffer_iface *stfbi)
+st_framebuffer_create(struct st_context *st,
+ struct st_framebuffer_iface *stfbi)
{
struct st_framebuffer *stfb;
struct gl_config mode;
@@ -414,6 +417,37 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi)
return NULL;
st_visual_to_context_mode(stfbi->visual, &mode);
+
+ /*
+ * For desktop GL, sRGB framebuffer write is controlled by both the
+ * capability of the framebuffer and GL_FRAMEBUFFER_SRGB. We should
+ * advertise the capability when the pipe driver supports it so that
+ * applications can enable sRGB write when they want to.
+ *
+ * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB. When
+ * the attribute is GLX_TRUE, it tells the st manager to pick a color
+ * format such that util_format_srgb(visual->color_format) can be supported
+ * by the pipe driver. We still need to advertise the capability here.
+ *
+ * For GLES, however, sRGB framebuffer write is controlled only by the
+ * capability of the framebuffer. There is GL_EXT_sRGB_write_control to
+ * give applications the control back, but sRGB write is still enabled by
+ * default. To avoid unexpected results, we should not advertise the
+ * capability. This could change when we add support for
+ * EGL_KHR_gl_colorspace.
+ */
+ if (_mesa_is_desktop_gl(st->ctx)) {
+ struct pipe_screen *screen = st->pipe->screen;
+ const enum pipe_format srgb_format =
+ util_format_srgb(stfbi->visual->color_format);
+
+ if (srgb_format != PIPE_FORMAT_NONE &&
+ screen->is_format_supported(screen, srgb_format,
+ PIPE_TEXTURE_2D, stfbi->visual->samples,
+ PIPE_BIND_RENDER_TARGET))
+ mode.sRGBCapable = GL_TRUE;
+ }
+
_mesa_initialize_window_framebuffer(&stfb->Base, &mode);
stfb->iface = stfbi;
@@ -677,7 +711,8 @@ st_api_get_current(struct st_api *stapi)
}
static struct st_framebuffer *
-st_framebuffer_reuse_or_create(struct gl_framebuffer *fb,
+st_framebuffer_reuse_or_create(struct st_context *st,
+ struct gl_framebuffer *fb,
struct st_framebuffer_iface *stfbi)
{
struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL;
@@ -690,7 +725,7 @@ st_framebuffer_reuse_or_create(struct gl_framebuffer *fb,
}
else {
/* create a new one */
- stfb = st_framebuffer_create(stfbi);
+ stfb = st_framebuffer_create(st, stfbi);
}
return stfb;
@@ -709,12 +744,12 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
if (st) {
/* reuse or create the draw fb */
- stdraw = st_framebuffer_reuse_or_create(st->ctx->WinSysDrawBuffer,
- stdrawi);
+ stdraw = st_framebuffer_reuse_or_create(st,
+ st->ctx->WinSysDrawBuffer, stdrawi);
if (streadi != stdrawi) {
/* do the same for the read fb */
- stread = st_framebuffer_reuse_or_create(st->ctx->WinSysReadBuffer,
- streadi);
+ stread = st_framebuffer_reuse_or_create(st,
+ st->ctx->WinSysReadBuffer, streadi);
}
else {
stread = NULL;