[PATCH 3/6] wined3d: Add support for separate sRGB formats.

Józef Kucia jkucia at codeweavers.com
Wed Feb 3 18:17:52 CST 2016


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/dxgi/factory.c            |  2 +-
 dlls/wined3d/context.c         |  2 +-
 dlls/wined3d/directx.c         |  5 ++-
 dlls/wined3d/texture.c         |  5 +--
 dlls/wined3d/utils.c           | 88 +++++++++++++++++++++++++++++++++++++++---
 dlls/wined3d/wined3d_private.h | 26 ++++++++-----
 include/wine/wined3d.h         |  1 +
 7 files changed, 108 insertions(+), 21 deletions(-)

diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c
index 5da45f3..683f75f 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -312,7 +312,7 @@ static HRESULT dxgi_factory_init(struct dxgi_factory *factory, BOOL extended)
     wined3d_private_store_init(&factory->private_store);
 
     wined3d_mutex_lock();
-    factory->wined3d = wined3d_create(0);
+    factory->wined3d = wined3d_create(WINED3D_SEPARATE_SRGB_FORMATS);
     if (!factory->wined3d)
     {
         wined3d_mutex_unlock();
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 490c20f..66c9a5d 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -214,7 +214,7 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
             case WINED3D_LOCATION_TEXTURE_SRGB:
                 srgb = location == WINED3D_LOCATION_TEXTURE_SRGB;
                 gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
-                        surface->texture_target, surface_get_texture_name(surface, gl_info, srgb),
+                        surface->texture_target, surface_get_texture_name(surface, context, srgb),
                         surface->texture_level);
                 checkGLcall("glFramebufferTexture2D()");
                 break;
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index c7b63f1..2b46aa2 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -5822,7 +5822,7 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc
     }
 }
 
-static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
+static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, struct wined3d *wined3d, UINT ordinal)
 {
     static const DWORD supported_gl_versions[] =
     {
@@ -5836,6 +5836,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
 
     TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
 
+    adapter->wined3d = wined3d;
     adapter->ordinal = ordinal;
 
 /* Dynamically load all GL core functions */
@@ -5993,7 +5994,7 @@ HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags)
         return WINED3D_OK;
     }
 
-    if (!wined3d_adapter_init(&wined3d->adapters[0], 0))
+    if (!wined3d_adapter_init(&wined3d->adapters[0], wined3d, 0))
     {
         WARN("Failed to initialize adapter.\n");
         return E_FAIL;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index ee2d17e..bb13099 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -153,7 +153,7 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
 
     TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
 
-    if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+    if (!should_use_separate_srgb_gl_texture(context))
         srgb = FALSE;
 
     /* sRGB mode cache for preload() calls outside drawprim. */
@@ -439,14 +439,13 @@ void wined3d_texture_load(struct wined3d_texture *texture,
         struct wined3d_context *context, BOOL srgb)
 {
     UINT sub_count = texture->level_count * texture->layer_count;
-    const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_d3d_info *d3d_info = context->d3d_info;
     DWORD flag;
     UINT i;
 
     TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
 
-    if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+    if (!should_use_separate_srgb_gl_texture(context))
         srgb = FALSE;
 
     if (srgb)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 1904dd1..718aa18 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -58,8 +58,11 @@ static const struct wined3d_format_channels formats[] =
     {WINED3DFMT_DXT4,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_DXT5,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_BC1_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
+    {WINED3DFMT_BC1_UNORM_SRGB,             0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_BC2_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
+    {WINED3DFMT_BC2_UNORM_SRGB,             0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_BC3_UNORM,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
+    {WINED3DFMT_BC3_UNORM_SRGB,             0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_MULTI2_ARGB8,               0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_G8R8_G8B8,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_R8G8_B8G8,                  0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
@@ -1344,6 +1347,21 @@ static const struct wined3d_format_texture_info format_texture_info[] =
             ARB_FRAMEBUFFER_OBJECT,     NULL},
 };
 
+struct wined3d_format_srgb_info
+{
+    enum wined3d_format_id id;
+    enum wined3d_format_id base_format_id;
+    GLint glGammaInternal;
+};
+
+static const struct wined3d_format_srgb_info format_separate_srgb_info[] =
+{
+    {WINED3DFMT_BC1_UNORM_SRGB,      WINED3DFMT_BC1_UNORM,      GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT},
+    {WINED3DFMT_BC2_UNORM_SRGB,      WINED3DFMT_BC2_UNORM,      GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT},
+    {WINED3DFMT_BC3_UNORM_SRGB,      WINED3DFMT_BC3_UNORM,      GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT},
+    {WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_UNORM, GL_SRGB8_ALPHA8},
+};
+
 static inline int getFmtIdx(enum wined3d_format_id format_id)
 {
     /* First check if the format is at the position of its value.
@@ -2172,7 +2190,7 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
 
 static void query_internal_format(struct wined3d_adapter *adapter,
         struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info,
-        struct wined3d_gl_info *gl_info)
+        struct wined3d_gl_info *gl_info, BOOL srgb_format)
 {
     GLint count, multisample_types[MAX_MULTISAMPLE_TYPES];
     struct fragment_caps fragment_caps;
@@ -2192,7 +2210,7 @@ static void query_internal_format(struct wined3d_adapter *adapter,
         query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
                 WINED3DFMT_FLAG_FILTERING, "filtering");
 
-        if (format->glGammaInternal != format->glInternal)
+        if (srgb_format || format->glGammaInternal != format->glInternal)
         {
             query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
                     WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
@@ -2219,7 +2237,7 @@ static void query_internal_format(struct wined3d_adapter *adapter,
         else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
             format_clear_flag(format, WINED3DFMT_FLAG_VTF);
 
-        if (format->glGammaInternal != format->glInternal)
+        if (srgb_format || format->glGammaInternal != format->glInternal)
         {
             /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
             if (!gl_info->supported[EXT_TEXTURE_SRGB])
@@ -2237,7 +2255,7 @@ static void query_internal_format(struct wined3d_adapter *adapter,
             format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE);
 
         if (!gl_info->supported[ARB_DEPTH_TEXTURE]
-                && texture_info->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+                && !!texture_info && texture_info->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
         {
             format->flags[WINED3D_GL_RES_TYPE_TEX_1D] &= ~WINED3DFMT_FLAG_TEXTURE;
             format->flags[WINED3D_GL_RES_TYPE_TEX_2D] &= ~WINED3DFMT_FLAG_TEXTURE;
@@ -2330,7 +2348,14 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
         format->flags[WINED3D_GL_RES_TYPE_RB] |= format_texture_info[i].flags;
         format->flags[WINED3D_GL_RES_TYPE_RB] &= ~WINED3DFMT_FLAG_TEXTURE;
 
-        query_internal_format(adapter, format, &format_texture_info[i], gl_info);
+        if (format->glGammaInternal != format->glInternal
+                && adapter->wined3d->flags & WINED3D_SEPARATE_SRGB_FORMATS)
+        {
+            format->glGammaInternal = format->glInternal;
+            format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
+        }
+
+        query_internal_format(adapter, format, &format_texture_info[i], gl_info, FALSE);
 
         /* Texture conversion stuff */
         format->convert = format_texture_info[i].convert;
@@ -2340,6 +2365,58 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
     return TRUE;
 }
 
+static BOOL init_separate_srgb_formats(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
+{
+    unsigned int i;
+
+    if (!gl_info->supported[EXT_TEXTURE_SRGB] || !(adapter->wined3d->flags & WINED3D_SEPARATE_SRGB_FORMATS))
+        return TRUE;
+
+    for (i = 0; i < sizeof(format_separate_srgb_info) / sizeof(*format_separate_srgb_info); ++i)
+    {
+        struct wined3d_format *format, *base_format;
+        int fmt_idx = getFmtIdx(format_separate_srgb_info[i].id);
+        int base_format_fmt_idx = getFmtIdx(format_separate_srgb_info[i].base_format_id);
+
+        if (fmt_idx == -1)
+        {
+            ERR("Format %s (%#x) not found.\n",
+                    debug_d3dformat(format_separate_srgb_info[i].id),
+                    format_separate_srgb_info[i].id);
+            return FALSE;
+        }
+        if (base_format_fmt_idx == -1)
+        {
+            ERR("Base format %s (%#x) not found.\n",
+                    debug_d3dformat(format_separate_srgb_info[i].base_format_id),
+                    format_separate_srgb_info[i].base_format_id);
+            return FALSE;
+        }
+
+        format = &gl_info->formats[fmt_idx];
+        base_format = &gl_info->formats[base_format_fmt_idx];
+
+        *format = *base_format;
+        format->id = format_separate_srgb_info[i].id;
+
+        if (!base_format->glInternal && !base_format->glGammaInternal)
+        {
+            TRACE("Base format %s (%#x) for %s (%#x) is not supported.\n",
+                    debug_d3dformat(base_format->id), base_format->id,
+                    debug_d3dformat(format->id), format->id);
+            continue;
+        }
+
+        format->glInternal = format_separate_srgb_info[i].glGammaInternal;
+        format->glGammaInternal = format_separate_srgb_info[i].glGammaInternal;
+
+        format_set_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
+        query_internal_format(adapter, format, NULL, gl_info, TRUE);
+    }
+
+    return TRUE;
+}
+
 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
 {
     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
@@ -2798,6 +2875,7 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wi
 
     if (!init_format_block_info(gl_info)) goto fail;
     if (!init_format_texture_info(adapter, gl_info)) goto fail;
+    if (!init_separate_srgb_formats(adapter, gl_info)) goto fail;
     if (!init_format_vertex_info(gl_info)) goto fail;
 
     apply_format_fixups(adapter, gl_info);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 84a6dc1..27b0558 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1880,14 +1880,16 @@ struct wined3d_d3d_info
 /* The adapter structure */
 struct wined3d_adapter
 {
+    struct wined3d *wined3d;
+
     UINT ordinal;
     POINT monitor_position;
     enum wined3d_format_id screen_format;
 
-    struct wined3d_gl_info  gl_info;
+    struct wined3d_gl_info gl_info;
     struct wined3d_d3d_info d3d_info;
     struct wined3d_driver_info driver_info;
-    WCHAR                   DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
+    WCHAR DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
     unsigned int cfg_count;
     struct wined3d_pixel_format *cfgs;
     UINT64 vram_bytes;
@@ -2526,13 +2528,6 @@ static inline struct wined3d_surface *surface_from_resource(struct wined3d_resou
     return CONTAINING_RECORD(resource, struct wined3d_surface, resource);
 }
 
-static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface,
-        const struct wined3d_gl_info *gl_info, BOOL srgb)
-{
-    return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
-            ? surface->container->texture_srgb.name : surface->container->texture_rgb.name;
-}
-
 HRESULT wined3d_surface_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
         struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
         const WINEDDBLTFX *blt_fx, enum wined3d_texture_filter_type filter) DECLSPEC_HIDDEN;
@@ -3370,6 +3365,19 @@ static inline void context_apply_state(struct wined3d_context *context,
     state_table[rep].apply(context, state, rep);
 }
 
+static inline BOOL should_use_separate_srgb_gl_texture(const struct wined3d_context *context)
+{
+    return !context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
+            && !(context->swapchain->device->wined3d->flags & WINED3D_SEPARATE_SRGB_FORMATS);
+}
+
+static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface,
+        const struct wined3d_context *context, BOOL srgb)
+{
+    return srgb && should_use_separate_srgb_gl_texture(context)
+            ? surface->container->texture_srgb.name : surface->container->texture_rgb.name;
+}
+
 /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
 #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
 
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index f29f4ff..0c36027 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1230,6 +1230,7 @@ enum wined3d_display_rotation
 #define WINED3D_HANDLE_RESTORE                                  0x00000040
 #define WINED3D_PIXEL_CENTER_INTEGER                            0x00000080
 #define WINED3D_LEGACY_FFP_LIGHTING                             0x00000100
+#define WINED3D_SEPARATE_SRGB_FORMATS                           0x00000200
 
 #define WINED3D_RESZ_CODE                                       0x7fa05000
 
-- 
2.4.10




More information about the wine-patches mailing list