[PATCH 3/5] wined3d: Introduce resource-type specific format flags.

Stefan Dösinger stefan at codeweavers.com
Wed Apr 22 04:30:17 CDT 2015


WINED3D_GL_RES_TYPE_TEX_2D will be separated into 2d, rect and
renderbuffer with a separate patch. I'll treat onscreen buffers like
renderbuffers until we find a situation where format abilities differ.

Some flags don't depend on the GL capabilities, like
WINED3DFMT_FLAG_BLOCKs. In places where no obvious resource type is
available, like wined3d_format_calculate_pitch, I read the capabilities
of 2D textures. Alternatively I could split the flags field into a
single static field and WINED3D_GL_RES_TYPE_COUNT GL dependent fields.
The blit_supported functions will need an additional gl type parameter
to handle renderbuffers properly, but that's the topic for a different
patch.
---
 dlls/wined3d/buffer.c          |   5 +-
 dlls/wined3d/context.c         |   7 ++-
 dlls/wined3d/directx.c         |  25 +++++----
 dlls/wined3d/resource.c        |   5 +-
 dlls/wined3d/surface.c         |  23 ++++----
 dlls/wined3d/texture.c         |  19 ++++---
 dlls/wined3d/utils.c           | 119 +++++++++++++++++++++++------------------
 dlls/wined3d/volume.c          |   4 +-
 dlls/wined3d/wined3d_private.h |   8 +--
 9 files changed, 124 insertions(+), 91 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index f2a22b0..857bae6 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1145,9 +1145,8 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
         return WINED3DERR_INVALIDCALL;
     }
 
-    hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format,
-            WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size,
-            parent, parent_ops, &buffer_resource_ops);
+    hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, WINED3D_GL_RES_TYPE_BUFFER, format,
+            WINED3D_MULTISAMPLE_NONE, 0, usage, pool, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops);
     if (FAILED(hr))
     {
         WARN("Failed to initialize resource, hr %#x\n", hr);
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 0334d1c..8dbfcb1 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -2195,8 +2195,11 @@ static BOOL match_depth_stencil_format(const struct wined3d_format *existing,
 {
     BYTE existing_depth, existing_stencil, required_depth, required_stencil;
 
-    if (existing == required) return TRUE;
-    if ((existing->flags & WINED3DFMT_FLAG_FLOAT) != (required->flags & WINED3DFMT_FLAG_FLOAT)) return FALSE;
+    if (existing == required)
+        return TRUE;
+    if ((existing->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
+            != (required->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT))
+        return FALSE;
 
     getDepthStencilBits(existing, &existing_depth, &existing_stencil);
     getDepthStencilBits(required, &required_depth, &required_stencil);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 01048fd..917edf9 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -4096,7 +4096,8 @@ static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_in
     BYTE redSize, greenSize, blueSize, alphaSize, colorBits;
 
     /* Float formats need FBOs. If FBOs are used this function isn't called */
-    if (format->flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
+    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
+        return FALSE;
 
     if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
         if (!getColorBits(format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
@@ -4137,7 +4138,8 @@ static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_in
     }
 
     /* Float formats need FBOs. If FBOs are used this function isn't called */
-    if (format->flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
+    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
+        return FALSE;
 
     if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT))
         lockable = TRUE;
@@ -4177,8 +4179,8 @@ HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d,
     ds_format = wined3d_get_format(&adapter->gl_info, depth_stencil_format_id);
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
-        if ((rt_format->flags & WINED3DFMT_FLAG_RENDERTARGET)
-                && (ds_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
+        if ((rt_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET)
+                && (ds_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
         {
             TRACE("Formats match.\n");
             return WINED3D_OK;
@@ -4269,7 +4271,8 @@ static BOOL CheckDepthStencilCapability(const struct wined3d_adapter *adapter,
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
     {
         /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
-        if (ds_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE;
+        if (ds_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+            return TRUE;
     }
     else
     {
@@ -4293,7 +4296,8 @@ static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter,
         const struct wined3d_format *adapter_format, const struct wined3d_format *check_format)
 {
     /* Filter out non-RT formats */
-    if (!(check_format->flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
+    if (!(check_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET))
+        return FALSE;
     if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
     {
         BYTE AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
@@ -4372,7 +4376,7 @@ static BOOL CheckSurfaceCapability(const struct wined3d_adapter *adapter,
 
     /* All formats that are supported for textures are supported for surfaces
      * as well. */
-    if (check_format->flags & WINED3DFMT_FLAG_TEXTURE)
+    if (check_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE)
         return TRUE;
     /* All depth stencil formats are supported on surfaces */
     if (CheckDepthStencilCapability(adapter, adapter_format, check_format)) return TRUE;
@@ -4455,7 +4459,8 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
             break;
 
         case WINED3D_RTYPE_TEXTURE:
-            if ((usage & WINED3DUSAGE_DEPTHSTENCIL) && (format->flags & WINED3DFMT_FLAG_SHADOW)
+            if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
+                    && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SHADOW)
                     && !gl_info->supported[ARB_SHADOW])
             {
                 TRACE("[FAILED] - No shadow sampler support.\n");
@@ -4543,10 +4548,10 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad
     if (usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
         format_flags |= WINED3DFMT_FLAG_BUMPMAP;
 
-    if ((format->flags & format_flags) != format_flags)
+    if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & format_flags) != format_flags)
     {
         TRACE("Requested format flags %#x, but format %s only has %#x.\n",
-                format_flags, debug_d3dformat(check_format_id), format->flags);
+                format_flags, debug_d3dformat(check_format_id), format->flags[WINED3D_GL_RES_TYPE_TEX_2D]);
         return WINED3DERR_NOTAVAILABLE;
     }
 
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index efdb2a8..2bc1cc1 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -72,7 +72,7 @@ static void resource_check_usage(DWORD usage)
 }
 
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
-        enum wined3d_resource_type type, const struct wined3d_format *format,
+        enum wined3d_resource_type type, enum wined3d_gl_resource_type gl_type, const struct wined3d_format *format,
         enum wined3d_multisample_type multisample_type, UINT multisample_quality,
         DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
         void *parent, const struct wined3d_parent_ops *parent_ops,
@@ -85,8 +85,9 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
     resource->ref = 1;
     resource->device = device;
     resource->type = type;
+    resource->gl_type = gl_type;
     resource->format = format;
-    resource->format_flags = format->flags;
+    resource->format_flags = format->flags[gl_type];
     resource->multisample_type = multisample_type;
     resource->multisample_quality = multisample_quality;
     resource->usage = usage;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index e21b9ca..6b5f771 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -989,16 +989,18 @@ static BOOL fbo_blit_supported(const struct wined3d_gl_info *gl_info, enum wined
     switch (blit_op)
     {
         case WINED3D_BLIT_OP_COLOR_BLIT:
-            if (!((src_format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (src_usage & WINED3DUSAGE_RENDERTARGET)))
+            if (!((src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+                    || (src_usage & WINED3DUSAGE_RENDERTARGET)))
                 return FALSE;
-            if (!((dst_format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
+            if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+                    || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
                 return FALSE;
             break;
 
         case WINED3D_BLIT_OP_DEPTH_BLIT:
-            if (!(src_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
+            if (!(src_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
                 return FALSE;
-            if (!(dst_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
+            if (!(dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
                 return FALSE;
             break;
 
@@ -1430,7 +1432,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
         surface->container->flags |= WINED3D_TEXTURE_PIN_SYSMEM;
     }
 
-    if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE)
     {
         update_h *= format->height_scale.numerator;
         update_h /= format->height_scale.denominator;
@@ -1442,7 +1444,7 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
         checkGLcall("glBindBuffer");
     }
 
-    if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
+    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
     {
         UINT row_length = wined3d_format_calculate_size(format, 1, update_w, 1, 1);
         UINT row_count = (update_h + format->block_height - 1) / format->block_height;
@@ -4316,7 +4318,8 @@ static BOOL ffp_blit_supported(const struct wined3d_gl_info *gl_info,
         case WINED3D_BLIT_OP_COLOR_FILL:
             if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
             {
-                if (!((dst_format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE) || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
+                if (!((dst_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+                        || (dst_usage & WINED3DUSAGE_RENDERTARGET)))
                     return FALSE;
             }
             else if (!(dst_usage & WINED3DUSAGE_RENDERTARGET))
@@ -5457,9 +5460,9 @@ static HRESULT surface_init(struct wined3d_surface *surface, struct wined3d_text
     else
         surface->surface_ops = &surface_ops;
 
-    if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, format,
-            desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height, 1,
-            resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops)))
+    if (FAILED(hr = resource_init(&surface->resource, device, WINED3D_RTYPE_SURFACE, container->resource.gl_type,
+            format, desc->multisample_type, multisample_quality, desc->usage, desc->pool, desc->width, desc->height,
+            1, resource_size, NULL, &wined3d_null_parent_ops, &surface_resource_ops)))
     {
         WARN("Failed to initialize resource, returning %#x.\n", hr);
         return hr;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index de92e0e..19a1fb8 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -29,8 +29,8 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struct wined3d_texture_ops *texture_ops,
         UINT layer_count, UINT level_count, const struct wined3d_resource_desc *desc, DWORD surface_flags,
-        struct wined3d_device *device, void *parent, const struct wined3d_parent_ops *parent_ops,
-        const struct wined3d_resource_ops *resource_ops)
+        enum wined3d_gl_resource_type gl_type, struct wined3d_device *device, void *parent,
+        const struct wined3d_parent_ops *parent_ops, const struct wined3d_resource_ops *resource_ops)
 {
     const struct wined3d_format *format = wined3d_get_format(&device->adapter->gl_info, desc->format);
     HRESULT hr;
@@ -43,7 +43,8 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
             debug_d3dusage(desc->usage), debug_d3dpool(desc->pool), desc->width, desc->height, desc->depth,
             surface_flags, device, parent, parent_ops, resource_ops);
 
-    if ((format->flags & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY)) == WINED3DFMT_FLAG_BLOCKS)
+    if ((format->flags[gl_type] & (WINED3DFMT_FLAG_BLOCKS | WINED3DFMT_FLAG_BLOCKS_NO_VERIFY))
+            == WINED3DFMT_FLAG_BLOCKS)
     {
         UINT width_mask = format->block_width - 1;
         UINT height_mask = format->block_height - 1;
@@ -51,15 +52,17 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
             return WINED3DERR_INVALIDCALL;
     }
 
-    if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
+    if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, gl_type, format,
             desc->multisample_type, desc->multisample_quality, desc->usage, desc->pool,
             desc->width, desc->height, desc->depth, 0, parent, parent_ops, resource_ops)))
     {
         static unsigned int once;
 
+        /* Always check 2D textures here, we don't want to write this ERR when the app tried
+         * to create a compressed volume texture but s3tc support is otherwise available. */
         if ((desc->format == WINED3DFMT_DXT1 || desc->format == WINED3DFMT_DXT2 || desc->format == WINED3DFMT_DXT3
                 || desc->format == WINED3DFMT_DXT4 || desc->format == WINED3DFMT_DXT5)
-                && !(format->flags & WINED3DFMT_FLAG_TEXTURE) && !once++)
+                && !(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE) && !once++)
             ERR_(winediag)("The application tried to create a DXTn texture, but the driver does not support them.\n");
 
         WARN("Failed to initialize resource, returning %#x\n", hr);
@@ -1027,7 +1030,7 @@ static HRESULT cubetexture_init(struct wined3d_texture *texture, const struct wi
     }
 
     if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 6, levels, desc,
-            surface_flags, device, parent, parent_ops, &texture_resource_ops)))
+            surface_flags, WINED3D_GL_RES_TYPE_TEX_CUBE, device, parent, parent_ops, &texture_resource_ops)))
     {
         WARN("Failed to initialize texture, returning %#x\n", hr);
         return hr;
@@ -1145,7 +1148,7 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
     }
 
     if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, 1, levels, desc,
-            surface_flags, device, parent, parent_ops, &texture_resource_ops)))
+            surface_flags, WINED3D_GL_RES_TYPE_TEX_2D, device, parent, parent_ops, &texture_resource_ops)))
     {
         WARN("Failed to initialize texture, returning %#x.\n", hr);
         return hr;
@@ -1384,7 +1387,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct
     }
 
     if (FAILED(hr = wined3d_texture_init(texture, &texture3d_ops, 1, levels, desc,
-            0, device, parent, parent_ops, &texture_resource_ops)))
+            0, WINED3D_GL_RES_TYPE_TEX_3D, device, parent, parent_ops, &texture_resource_ops)))
     {
         WARN("Failed to initialize texture, returning %#x.\n", hr);
         return hr;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 5596375..412f599 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1307,6 +1307,22 @@ static inline int getFmtIdx(enum wined3d_format_id format_id)
     return -1;
 }
 
+static void format_set_flag(struct wined3d_format *format, unsigned int flag)
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(format->flags) / sizeof(*format->flags); ++i)
+        format->flags[i] |= flag;
+}
+
+static void format_clear_flag(struct wined3d_format *format, unsigned int flag)
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(format->flags) / sizeof(*format->flags); ++i)
+        format->flags[i] &= ~flag;
+}
+
 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
 {
     UINT format_count = sizeof(formats) / sizeof(*formats);
@@ -1351,7 +1367,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
             return FALSE;
         }
 
-        gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
+        format_set_flag(&gl_info->formats[fmt_idx], format_base_flags[i].flags);
     }
 
     return TRUE;
@@ -1377,9 +1393,9 @@ static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
         format->block_width = format_block_info[i].block_width;
         format->block_height = format_block_info[i].block_height;
         format->block_byte_count = format_block_info[i].block_byte_count;
-        format->flags |= WINED3DFMT_FLAG_BLOCKS;
+        format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_BLOCKS);
         if (!format_block_info[i].verify)
-            format->flags |= WINED3DFMT_FLAG_BLOCKS_NO_VERIFY;
+            format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_BLOCKS_NO_VERIFY);
     }
 
     return TRUE;
@@ -1414,18 +1430,18 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
     if (status == GL_FRAMEBUFFER_COMPLETE)
     {
         TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
-        format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
+        format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE);
         format->rtInternal = format->glInternal;
     }
     else
     {
         if (!format->rtInternal)
         {
-            if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
+            if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET)
             {
                 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
                         " and no fallback specified.\n", debug_d3dformat(format->id));
-                format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+                format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET);
             }
             else
             {
@@ -1461,12 +1477,13 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
             {
                 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
                         debug_d3dformat(format->id));
-                format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+                format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET);
             }
         }
     }
 
-    if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
+    if (status == GL_FRAMEBUFFER_COMPLETE
+            && ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
             || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
             && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
             && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA
@@ -1495,7 +1512,7 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
         {
             while (gl_info->gl_ops.gl.p_glGetError());
             TRACE("Format doesn't support post-pixelshader blending.\n");
-            format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+            format_clear_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
         }
         else
         {
@@ -1549,13 +1566,13 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
             {
                 TRACE("Format doesn't support post-pixelshader blending.\n");
                 TRACE("Color output: %#x\n", color);
-                format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+                format_clear_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
             }
             else
             {
                 TRACE("Format supports post-pixelshader blending.\n");
                 TRACE("Color output: %#x\n", color);
-                format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
+                format_set_flag(format, WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING);
             }
         }
 
@@ -1581,7 +1598,7 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
         if (status == GL_FRAMEBUFFER_COMPLETE)
         {
             TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
-            format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+            format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB);
         }
         else
         {
@@ -1589,7 +1606,7 @@ static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined
         }
     }
     else if (status == GL_FRAMEBUFFER_COMPLETE)
-        format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+        format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB);
 
     gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
 }
@@ -1603,12 +1620,12 @@ static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_fo
     if (value == GL_FULL_SUPPORT)
     {
         TRACE("Format %s supports %s.\n", debug_d3dformat(format->id), string);
-        format->flags |= flag;
+        format_set_flag(format, flag);
     }
     else
     {
         TRACE("Format %s doesn't support %s.\n", debug_d3dformat(format->id), string);
-        format->flags &= ~flag;
+        format_clear_flag(format, flag);
     }
 }
 
@@ -1627,7 +1644,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
 
             if (!format->glInternal)
                 continue;
-            if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+            if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
                 continue;
 
             gl_info->gl_ops.ext.p_glGetInternalformativ(GL_TEXTURE_2D, format->glInternal,
@@ -1635,7 +1652,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
             if (value == GL_FULL_SUPPORT)
             {
                 TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
-                format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
+                format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE);
                 format->rtInternal = format->glInternal;
 
                 query_format_flag(gl_info, format, format->glInternal, GL_FRAMEBUFFER_BLEND,
@@ -1645,11 +1662,11 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
             {
                 if (!format->rtInternal)
                 {
-                    if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
+                    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET)
                     {
                         WARN("Format %s with rendertarget flag is not supported as FBO color attachment"
                                 " and no fallback specified.\n", debug_d3dformat(format->id));
-                        format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+                        format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET);
                     }
                     else
                         TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
@@ -1668,7 +1685,7 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
                     {
                         WARN("Format %s rtInternal format is not supported as FBO color attachment.\n",
                                 debug_d3dformat(format->id));
-                        format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
+                        format_clear_flag(format, WINED3DFMT_FLAG_RENDERTARGET);
                     }
                 }
             }
@@ -1680,15 +1697,15 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
                 if (value == GL_FULL_SUPPORT)
                 {
                     TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
-                    format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+                    format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB);
                 }
                 else
                 {
                     WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
                 }
             }
-            else if (format->flags & WINED3DFMT_FLAG_FBO_ATTACHABLE)
-                format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
+            else if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FBO_ATTACHABLE)
+                format_set_flag(format, WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB);
         }
         return;
     }
@@ -1707,14 +1724,14 @@ static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
 
         if (!format->glInternal) continue;
 
-        if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
+        if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
         {
             TRACE("Skipping format %s because it's a depth/stencil format.\n",
                     debug_d3dformat(format->id));
             continue;
         }
 
-        if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
+        if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_COMPRESSED)
         {
             TRACE("Skipping format %s because it's a compressed format.\n",
                     debug_d3dformat(format->id));
@@ -1767,7 +1784,7 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
         /* ARB_texture_rg defines floating point formats, but only if
          * ARB_texture_float is also supported. */
         if (!gl_info->supported[ARB_TEXTURE_FLOAT]
-                && (format->flags & WINED3DFMT_FLAG_FLOAT))
+                && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT))
             continue;
 
         format->glInternal = format_texture_info[i].gl_internal;
@@ -1776,7 +1793,7 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
         format->glFormat = format_texture_info[i].gl_format;
         format->glType = format_texture_info[i].gl_type;
         format->color_fixup = COLOR_FIXUP_IDENTITY;
-        format->flags |= format_texture_info[i].flags;
+        format_set_flag(format, format_texture_info[i].flags);
         format->height_scale.numerator = 1;
         format->height_scale.denominator = 1;
 
@@ -1796,9 +1813,9 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
                     query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_WRITE,
                             WINED3DFMT_FLAG_SRGB_WRITE, "sRGB write");
                 else
-                    format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
+                    format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE);
 
-                if (!(format->flags & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
+                if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE)))
                     format->glGammaInternal = format->glInternal;
                 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
                     format->glInternal = format->glGammaInternal;
@@ -1807,12 +1824,12 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
         else
         {
             if (!gl_info->limits.vertex_samplers)
-                format->flags &= ~WINED3DFMT_FLAG_VTF;
+                format_clear_flag(format, WINED3DFMT_FLAG_VTF);
 
             if (!(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
-                format->flags |= WINED3DFMT_FLAG_FILTERING;
+                format_set_flag(format, WINED3DFMT_FLAG_FILTERING);
             else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
-                format->flags &= ~WINED3DFMT_FLAG_VTF;
+                format_clear_flag(format, WINED3DFMT_FLAG_VTF);
 
             if (format->glGammaInternal != format->glInternal)
             {
@@ -1820,7 +1837,7 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
                 if (!gl_info->supported[EXT_TEXTURE_SRGB])
                 {
                     format->glGammaInternal = format->glInternal;
-                    format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
+                    format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
                 }
                 else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
                 {
@@ -1828,8 +1845,8 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
                 }
             }
 
-            if ((format->flags & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
-                format->flags &= ~WINED3DFMT_FLAG_SRGB_WRITE;
+            if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SRGB_WRITE) && !srgb_write)
+                format_clear_flag(format, WINED3DFMT_FLAG_SRGB_WRITE);
         }
 
         /* Texture conversion stuff */
@@ -1991,7 +2008,7 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3
             for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
             {
                 fmt_idx = getFmtIdx(fmts16[i]);
-                gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
+                format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_FILTERING);
             }
         }
         return;
@@ -2007,7 +2024,7 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3
         if(filtered)
         {
             TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
-            format->flags |= WINED3DFMT_FLAG_FILTERING;
+            format_set_flag(format, WINED3DFMT_FLAG_FILTERING);
         }
         else
         {
@@ -2107,13 +2124,13 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
     }
 
     idx = getFmtIdx(WINED3DFMT_YV12);
-    gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
+    format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
     gl_info->formats[idx].height_scale.numerator = 3;
     gl_info->formats[idx].height_scale.denominator = 2;
     gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
 
     idx = getFmtIdx(WINED3DFMT_NV12);
-    gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
+    format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
     gl_info->formats[idx].height_scale.numerator = 3;
     gl_info->formats[idx].height_scale.denominator = 2;
     gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
@@ -2144,19 +2161,19 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
     if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
     {
         idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
-        gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+        format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
 
         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
-        gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+        format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
 
         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
-        gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+        format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
     }
 
     if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
     {
         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_UNORM);
-        gl_info->formats[idx].flags &= ~WINED3DFMT_FLAG_TEXTURE;
+        format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
     }
 
     /* ATI instancing hack: Although ATI cards do not support Shader Model
@@ -2175,7 +2192,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
     if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
     {
         idx = getFmtIdx(WINED3DFMT_INST);
-        gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
+        format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
     }
 
     /* Depth bound test. To query if the card supports it CheckDeviceFormat()
@@ -2187,7 +2204,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
     if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
     {
         idx = getFmtIdx(WINED3DFMT_NVDB);
-        gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE;
+        format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
     }
 
     /* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
@@ -2196,19 +2213,19 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
     if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
     {
         idx = getFmtIdx(WINED3DFMT_RESZ);
-        gl_info->formats[idx].flags |= WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET;
+        format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET);
     }
 
     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
     {
         struct wined3d_format *format = &gl_info->formats[i];
 
-        if (!(format->flags & WINED3DFMT_FLAG_TEXTURE))
+        if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE))
             continue;
 
         if (!adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
                 || !adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
-            format->flags &= ~WINED3DFMT_FLAG_TEXTURE;
+            format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
     }
 }
 
@@ -2297,7 +2314,7 @@ UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT wi
 {
     /* For block based formats, pitch means the amount of bytes to the next
      * row of blocks rather than the next row of pixels. */
-    if (format->flags & WINED3DFMT_FLAG_BLOCKS)
+    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS)
         return format->block_byte_count * ((width + format->block_width - 1) / format->block_width);
 
     return format->byte_count * width;
@@ -2313,7 +2330,7 @@ UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT ali
     {
         size = 0;
     }
-    else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
+    else if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS)
     {
         UINT row_count = (height + format->block_height - 1) / format->block_height;
         size = row_count * ((pitch + alignment - 1) & ~(alignment - 1));
@@ -2323,7 +2340,7 @@ UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT ali
         size = height * ((pitch + alignment - 1) & ~(alignment - 1));
     }
 
-    if (format->flags & WINED3DFMT_FLAG_HEIGHT_SCALE)
+    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE)
     {
         /* The D3D format requirements make sure that the resulting format is an integer again */
         size *= format->height_scale.numerator;
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index b83ff26..a231081 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -764,8 +764,8 @@ static HRESULT volume_init(struct wined3d_volume *volume, struct wined3d_texture
 
     size = wined3d_format_calculate_size(format, device->surface_alignment, desc->width, desc->height, desc->depth);
 
-    if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, format,
-            WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth,
+    if (FAILED(hr = resource_init(&volume->resource, device, WINED3D_RTYPE_VOLUME, container->resource.gl_type,
+            format, WINED3D_MULTISAMPLE_NONE, 0, desc->usage, desc->pool, desc->width, desc->height, desc->depth,
             size, NULL, &wined3d_null_parent_ops, &volume_resource_ops)))
     {
         WARN("Failed to initialize resource, returning %#x.\n", hr);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index dd2a85a..5fb39218 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -780,7 +780,8 @@ enum wined3d_gl_resource_type
     WINED3D_GL_RES_TYPE_TEX_3D          = 2,
     WINED3D_GL_RES_TYPE_TEX_CUBE        = 3,
     WINED3D_GL_RES_TYPE_TEX_RECT        = 4,
-    WINED3D_GL_RES_TYPE_COUNT           = 5,
+    WINED3D_GL_RES_TYPE_BUFFER          = 5,
+    WINED3D_GL_RES_TYPE_COUNT           = 6,
 };
 
 enum vertexprocessing_mode {
@@ -2107,6 +2108,7 @@ struct wined3d_resource
     LONG map_count;
     struct wined3d_device *device;
     enum wined3d_resource_type type;
+    enum wined3d_gl_resource_type gl_type;
     const struct wined3d_format *format;
     unsigned int format_flags;
     enum wined3d_multisample_type multisample_type;
@@ -2141,7 +2143,7 @@ static inline ULONG wined3d_resource_decref(struct wined3d_resource *resource)
 
 void resource_cleanup(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
-        enum wined3d_resource_type type, const struct wined3d_format *format,
+        enum wined3d_resource_type type, enum wined3d_gl_resource_type gl_type, const struct wined3d_format *format,
         enum wined3d_multisample_type multisample_type, UINT multisample_quality,
         DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
         void *parent, const struct wined3d_parent_ops *parent_ops,
@@ -3172,7 +3174,7 @@ struct wined3d_format
     GLint glFormat;
     GLint glType;
     UINT  conv_byte_count;
-    unsigned int flags;
+    unsigned int flags[WINED3D_GL_RES_TYPE_COUNT];
     struct wined3d_rational height_scale;
     struct color_fixup_desc color_fixup;
     void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
-- 
2.3.4




More information about the wine-patches mailing list