Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- While writing more tests for the mipmap generation stuff I stumbled upon a couple of missing checks in our implementation. I decided to add those checks rather than changing the tests...
dlls/d3d11/tests/d3d11.c | 15 +++++++++++++++ dlls/d3d11/view.c | 5 +++++ 2 files changed, 20 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 2447cd771c..f636a85db2 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -18433,6 +18433,21 @@ static void test_buffer_srv(void) cb = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER, sizeof(cb_size), NULL); ID3D11DeviceContext_PSSetConstantBuffers(context, 0, 1, &cb);
+ buffer_desc.ByteWidth = 256; + buffer_desc.Usage = D3D11_USAGE_DEFAULT; + buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + buffer_desc.CPUAccessFlags = 0; + buffer_desc.MiscFlags = 0; + hr = ID3D11Device_CreateBuffer(device, &buffer_desc, NULL, &buffer); + ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr); + srv_desc.Format = DXGI_FORMAT_R8_UNORM; + srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + U(srv_desc).Buffer.FirstElement = 0; + U(srv_desc).Buffer.NumElements = 0; + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)buffer, &srv_desc, &srv); + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + ID3D11Buffer_Release(buffer); + ps = NULL; srv = NULL; buffer = NULL; diff --git a/dlls/d3d11/view.c b/dlls/d3d11/view.c index f747c4bfde..034a4940b0 100644 --- a/dlls/d3d11/view.c +++ b/dlls/d3d11/view.c @@ -616,6 +616,11 @@ static HRESULT normalize_srv_desc(D3D11_SHADER_RESOURCE_VIEW_DESC *desc, ID3D11R WARN("Incompatible dimensions %#x, %#x.\n", dimension, desc->ViewDimension); return E_INVALIDARG; } + if (!desc->u.Buffer.u2.NumElements) + { + WARN("Zero sized buffer view.\n"); + return E_INVALIDARG; + } return S_OK; }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/view.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 62f087b23a..f75dd00000 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -128,6 +128,13 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_ struct wined3d_texture *texture = texture_from_resource(resource); unsigned int depth_or_layer_count;
+ if (resource->format->id != format->id && !wined3d_format_is_typeless(resource->format)) + { + WARN("Trying to create incompatible view for non typeless format %s.\n", + debug_d3dformat(format->id)); + return NULL; + } + if (mip_slice && resource->type == WINED3D_RTYPE_TEXTURE_3D) depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); else
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Allow views with the sRGB variant.
dlls/wined3d/utils.c | 14 ++++++++++++++ dlls/wined3d/view.c | 8 ++++++++ dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 24 insertions(+)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 5eda92acf1..f73968546f 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -3815,6 +3815,20 @@ UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT ali return slice_pitch * depth; }
+BOOL wined3d_formats_are_srgb_variants(enum wined3d_format_id format1, enum wined3d_format_id format2) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) + { + if (format1 == format_srgb_info[i].srgb_format_id) + return format2 == format_srgb_info[i].base_format_id; + if (format1 == format_srgb_info[i].base_format_id) + return format2 == format_srgb_info[i].srgb_format_id; + } + return FALSE; +} + /***************************************************************************** * Trace formatting of useful values */ diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 62f087b23a..b35b66bfeb 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -128,6 +128,14 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_ struct wined3d_texture *texture = texture_from_resource(resource); unsigned int depth_or_layer_count;
+ if (resource->format->id != format->id && !wined3d_format_is_typeless(resource->format) + && !wined3d_formats_are_srgb_variants(resource->format->id, format->id)) + { + WARN("Trying to create incompatible view for non typeless format %s.\n", + debug_d3dformat(format->id)); + return NULL; + } + if (mip_slice && resource->type == WINED3D_RTYPE_TEXTURE_3D) depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); else diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3a9ac2e181..bd4a2102f2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4251,6 +4251,8 @@ BOOL wined3d_format_is_depth_view(enum wined3d_format_id resource_format_id, enum wined3d_format_id view_format_id) DECLSPEC_HIDDEN; const struct wined3d_color_key_conversion * wined3d_format_get_color_key_conversion( const struct wined3d_texture *texture, BOOL need_alpha_ck) DECLSPEC_HIDDEN; +BOOL wined3d_formats_are_srgb_variants(enum wined3d_format_id format1, + enum wined3d_format_id format2) DECLSPEC_HIDDEN;
BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) DECLSPEC_HIDDEN;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3d11/tests/d3d11.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index f636a85db2..906761dd33 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -3274,6 +3274,7 @@ static void test_create_shader_resource_view(void)
#define FMT_UNKNOWN DXGI_FORMAT_UNKNOWN #define RGBA8_UNORM DXGI_FORMAT_R8G8B8A8_UNORM +#define RGBA8_UINT DXGI_FORMAT_R8G8B8A8_UINT #define RGBA8_TL DXGI_FORMAT_R8G8B8A8_TYPELESS #define DIM_UNKNOWN D3D11_SRV_DIMENSION_UNKNOWN #define TEX_1D D3D11_SRV_DIMENSION_TEXTURE1D @@ -3344,6 +3345,8 @@ static void test_create_shader_resource_view(void) {{ 1, 13, RGBA8_UNORM}, {0}, {RGBA8_UNORM, CUBE_ARRAY, 0, 1, 0, 2}}, {{ 1, 14, RGBA8_UNORM}, {0}, {RGBA8_UNORM, CUBE_ARRAY, 0, 1, 0, 2}}, {{ 1, 18, RGBA8_UNORM}, {0}, {RGBA8_UNORM, CUBE_ARRAY, 0, 1, 0, 3}}, + {{ 1, 1, RGBA8_UINT}, {0}, {RGBA8_UINT, TEX_2D, 0, 1, 0, 1}}, + {{ 1, 1, RGBA8_TL}, {RGBA8_UINT, TEX_2D, 0, ~0u}, {RGBA8_UINT, TEX_2D, 0, 1, 0, 1}}, }; static const struct { @@ -3394,6 +3397,8 @@ static void test_create_shader_resource_view(void) {{TEX_2D, 1, 7, RGBA8_UNORM}, {RGBA8_UNORM, CUBE_ARRAY, 0, 1, 2, ~0u}}, {{TEX_2D, 1, 7, RGBA8_UNORM}, {RGBA8_UNORM, CUBE_ARRAY, 0, 1, 0, 2}}, {{TEX_2D, 1, 9, RGBA8_UNORM}, {RGBA8_UNORM, CUBE_ARRAY, 0, 1, 0, 2}}, + {{TEX_2D, 1, 1, RGBA8_UNORM}, {RGBA8_UINT, TEX_2D, 0, 1}}, + {{TEX_2D, 1, 1, RGBA8_UINT}, {RGBA8_UNORM, TEX_2D, 0, 1}}, {{TEX_3D, 1, 1, RGBA8_UNORM}, {RGBA8_UNORM, TEX_1D, 0, 1}}, {{TEX_3D, 1, 1, RGBA8_UNORM}, {RGBA8_UNORM, TEX_1D_ARRAY, 0, 1, 0, 1}}, {{TEX_3D, 1, 1, RGBA8_UNORM}, {RGBA8_UNORM, TEX_2D, 0, 1}},
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Make use of the new flag in wined3d_texture_generate_mipmaps(). Don't set the flag if the format is not renderable or filterable.
This still keeps the separate usage flag for automatic mipmap generation for the time being. That will be removed entirely later on, when the whole handling of AUTOGENMIPMAP textures will move to d3d9 on top of manual mipmap generation.
dlls/wined3d/texture.c | 16 +++++++++++++++- dlls/wined3d/wined3d_private.h | 1 + include/wine/wined3d.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index ef8545d003..7a8e1fb7d1 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -384,6 +384,15 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc texture->flags |= WINED3D_TEXTURE_GET_DC; if (flags & WINED3D_TEXTURE_CREATE_DISCARD) texture->flags |= WINED3D_TEXTURE_DISCARD; + if (flags & WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS) + { + if (~format->flags[WINED3D_GL_RES_TYPE_TEX_2D] + & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) + WARN("Format doesn't support mipmaps generation, " + "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n"); + else + texture->flags |= WINED3D_TEXTURE_GENERATE_MIPMAPS; + }
return WINED3D_OK; } @@ -1573,8 +1582,13 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture, unsigned
void CDECL wined3d_texture_generate_mipmaps(struct wined3d_texture *texture) { - /* TODO: Implement filters using GL_SGI_generate_mipmaps. */ FIXME("texture %p stub!\n", texture); + + if (!(texture->flags & WINED3D_TEXTURE_GENERATE_MIPMAPS)) + { + WARN("Texture without the WINED3D_TEXTURE_GENERATE_MIPMAPS flag, ignoring.\n"); + return; + } }
static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3a9ac2e181..16afd346fb 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3074,6 +3074,7 @@ struct wined3d_texture_ops #define WINED3D_TEXTURE_DC_IN_USE 0x00001000 #define WINED3D_TEXTURE_DISCARD 0x00002000 #define WINED3D_TEXTURE_GET_DC 0x00004000 +#define WINED3D_TEXTURE_GENERATE_MIPMAPS 0x00008000
#define WINED3D_TEXTURE_ASYNC_COLOR_KEY 0x00000001
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index f35d9806e3..a0ac7ba02f 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1538,6 +1538,7 @@ enum wined3d_shader_byte_code_format #define WINED3D_TEXTURE_CREATE_DISCARD 0x00000002 #define WINED3D_TEXTURE_CREATE_GET_DC_LENIENT 0x00000004 #define WINED3D_TEXTURE_CREATE_GET_DC 0x00000008 +#define WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS 0x00000010
#define WINED3D_APPEND_ALIGNED_ELEMENT 0xffffffff
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3d11/texture.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/dlls/d3d11/texture.c b/dlls/d3d11/texture.c index ef2c9a29fe..12186dcf37 100644 --- a/dlls/d3d11/texture.c +++ b/dlls/d3d11/texture.c @@ -472,6 +472,14 @@ static BOOL validate_texture2d_desc(const D3D11_TEXTURE2D_DESC *desc) return FALSE; }
+ if (desc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS + && (~desc->BindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE))) + { + WARN("D3D11_RESOURCE_MISC_GENERATE_MIPS used without D3D11_BIND_RENDER_TARGET and " + "D3D11_BIND_SHADER_RESOURCE.\n"); + return FALSE; + } + return TRUE; }