Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- Looking again at the mipmap generation checks, I think I don't need the stuff I was adding in "wined3d: Refuse to create textures with mipmap generation when unsupported." at all.
dlls/wined3d/directx.c | 8 ++------ dlls/wined3d/texture.c | 16 +++++++++++++--- dlls/wined3d/utils.c | 18 ++++++++++++++++++ dlls/wined3d/wined3d_private.h | 1 + 4 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c8f42fe253a..924cc72e773 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -5296,7 +5296,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad const struct wined3d_gl_info *gl_info = &adapter->gl_info; const struct wined3d_format *adapter_format, *format; enum wined3d_gl_resource_type gl_type, gl_type_end; - BOOL mipmap_autogen_supported; + BOOL mipmap_autogen_supported = TRUE; DWORD format_flags = 0; DWORD allowed_usage;
@@ -5410,7 +5410,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; }
- mipmap_autogen_supported = gl_info->supported[SGIS_GENERATE_MIPMAP]; for (; gl_type <= gl_type_end; ++gl_type) { if ((format->flags[gl_type] & format_flags) != format_flags) @@ -5440,11 +5439,8 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; }
- if ((format->flags[gl_type] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) - != (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) - { + if (!(format->flags[gl_type] & WINED3DFMT_FLAG_GEN_MIPMAP)) mipmap_autogen_supported = FALSE; - } }
if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_autogen_supported) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 750101fac66..740afeace80 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -386,8 +386,18 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc 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)) + static const enum wined3d_gl_resource_type gl_type_from_res_type[] = + { + WINED3D_GL_RES_TYPE_BUFFER, + WINED3D_GL_RES_TYPE_BUFFER, + WINED3D_GL_RES_TYPE_TEX_2D, + WINED3D_GL_RES_TYPE_TEX_3D, + }; + enum wined3d_gl_resource_type gl_type; + + assert(desc->resource_type < ARRAY_SIZE(gl_type_from_res_type)); + gl_type = gl_type_from_res_type[desc->resource_type]; + if (!(format->flags[gl_type] & WINED3DFMT_FLAG_GEN_MIPMAP)) WARN("Format doesn't support mipmaps generation, " "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n"); else @@ -2685,7 +2695,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct texture->resource.map_binding = WINED3D_LOCATION_BUFFER; }
- /* Generate all the surfaces. */ + /* Generate all the sub resources. */ for (i = 0; i < texture->level_count; ++i) { struct wined3d_texture_sub_resource *sub_resource; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 6f7740deda0..960909f35b4 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -3595,6 +3595,23 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) return TRUE; }
+static void init_format_gen_mipmap_info(struct wined3d_gl_info *gl_info) +{ + unsigned int i, j; + + if (!gl_info->supported[SGIS_GENERATE_MIPMAP] && !gl_info->fbo_ops.glGenerateMipmap) + return; + + for (i = 0; i < gl_info->format_count; ++i) + { + struct wined3d_format *format = &gl_info->formats[i]; + + for (j = 0; j < ARRAY_SIZE(format->flags); ++j) + if (!(~format->flags[j] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))) + format->flags[j] |= WINED3DFMT_FLAG_GEN_MIPMAP; + } +} + BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx) { static const struct wined3d_color red = {1.0f, 0.0f, 0.0f, 1.0f}; @@ -3783,6 +3800,7 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wi init_format_fbo_compat_info(ctx); init_format_filter_info(gl_info, adapter->driver_info.vendor); if (!init_typeless_formats(gl_info)) goto fail; + init_format_gen_mipmap_info(gl_info); init_format_depth_bias_scale(ctx, &adapter->d3d_info);
return TRUE; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f1f75301d6d..8201536a5de 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4205,6 +4205,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_TEXTURE 0x00080000 #define WINED3DFMT_FLAG_BLOCKS_NO_VERIFY 0x00100000 #define WINED3DFMT_FLAG_INTEGER 0x00200000 +#define WINED3DFMT_FLAG_GEN_MIPMAP 0x00400000
struct wined3d_rational {
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Rebase.
dlls/d3d9/d3d9_private.h | 25 ++++- dlls/d3d9/device.c | 75 +++++++++++++ dlls/d3d9/surface.c | 4 + dlls/d3d9/tests/device.c | 5 +- dlls/d3d9/texture.c | 270 ++++++++++++++++++++++++++++++++++++----------- 5 files changed, 313 insertions(+), 66 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 24b793eff17..b7504c2b357 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -40,8 +40,16 @@ #include "d3d9.h" #include "wine/wined3d.h"
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 +#define D3D9_MAX_TEXTURE_UNITS 20 +#define D3D9_MAX_SIMULTANEOUS_RENDERTARGETS 4 + #define D3DPRESENTFLAGS_MASK 0x00000fffu
+#define D3D9_TEXTURE_MIPMAP_DIRTY 0x1 + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + extern const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops DECLSPEC_HIDDEN;
HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN; @@ -93,6 +101,9 @@ struct d3d9_device UINT index_buffer_size; UINT index_buffer_pos;
+ struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS]; + struct d3d9_surface *render_targets[D3D9_MAX_SIMULTANEOUS_RENDERTARGETS]; + LONG device_state; BOOL in_destruction; BOOL in_scene; @@ -199,6 +210,10 @@ struct d3d9_texture struct wined3d_texture *wined3d_texture; IDirect3DDevice9Ex *parent_device; struct list rtv_list; + DWORD usage; + BOOL flags; + struct wined3d_shader_resource_view *wined3d_srv; + D3DTEXTUREFILTERTYPE autogen_filter_type; };
HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device, @@ -208,6 +223,8 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device, UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN; struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface) DECLSPEC_HIDDEN; +void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture) DECLSPEC_HIDDEN; +void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture) DECLSPEC_HIDDEN;
struct d3d9_stateblock { @@ -248,9 +265,6 @@ HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device *device, const DWORD *byte_code) DECLSPEC_HIDDEN; struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface) DECLSPEC_HIDDEN;
-#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 -#define D3D9_MAX_SIMULTANEOUS_RENDERTARGETS 4 - struct d3d9_pixelshader { IDirect3DPixelShader9 IDirect3DPixelShader9_iface; @@ -316,4 +330,9 @@ static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool) } }
+static inline DWORD wined3dusage_from_d3dusage(unsigned int usage) +{ + return usage & WINED3DUSAGE_MASK & ~WINED3DUSAGE_AUTOGENMIPMAP; +} + #endif /* __WINE_D3D9_PRIVATE_H */ diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 3bd23b6b293..03249ee5bf0 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -815,6 +815,8 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, BOOL extended = device->d3d_parent->extended; struct wined3d_swapchain_desc swapchain_desc; struct wined3d_display_mode wined3d_mode; + struct wined3d_rendertarget_view *rtv; + unsigned int i; HRESULT hr;
if (!extended && device->device_state == D3D9_DEVICE_STATE_LOST) @@ -876,6 +878,15 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
device->device_state = D3D9_DEVICE_STATE_OK; } + + if (!device->d3d_parent->extended) + for (i = 0; i < ARRAY_SIZE(device->textures); ++i) + device->textures[i] = NULL; + + rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0); + device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i) + device->render_targets[i] = NULL; } else if (!extended) { @@ -1425,6 +1436,9 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface, wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0, dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture), src->sub_resource_idx, &src_box); + if (SUCCEEDED(hr) && dst->texture) + d3d9_texture_flag_auto_gen_mipmap(dst->texture); + wined3d_mutex_unlock();
if (FAILED(hr)) @@ -1448,6 +1462,8 @@ static HRESULT WINAPI d3d9_device_UpdateTexture(IDirect3DDevice9Ex *iface, wined3d_mutex_lock(); hr = wined3d_device_update_texture(device->wined3d_device, src_impl->wined3d_texture, dst_impl->wined3d_texture); + if (SUCCEEDED(hr)) + d3d9_texture_flag_auto_gen_mipmap(dst_impl); wined3d_mutex_unlock();
return hr; @@ -1566,6 +1582,8 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect src->wined3d_texture, src->sub_resource_idx, src_rect, 0, NULL, filter); if (hr == WINEDDERR_INVALIDRECT) hr = D3DERR_INVALIDCALL; + if (SUCCEEDED(hr) && dst->texture) + d3d9_texture_flag_auto_gen_mipmap(dst->texture);
done: wined3d_mutex_unlock(); @@ -1622,6 +1640,8 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0); d3d9_surface_release_rendertarget_view(surface_impl, rtv); + if (SUCCEEDED(hr) && surface_impl->texture) + d3d9_texture_flag_auto_gen_mipmap(surface_impl->texture);
wined3d_mutex_unlock();
@@ -1704,6 +1724,8 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL; hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE); d3d9_surface_release_rendertarget_view(surface_impl, rtv); + if (SUCCEEDED(hr)) + device->render_targets[idx] = surface_impl; wined3d_mutex_unlock();
return hr; @@ -1824,6 +1846,19 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_EndScene(IDirect3DDevice9Ex return hr; }
+static void d3d9_rts_flag_auto_gen_mipmap(struct d3d9_device *device) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(device->render_targets); ++i) + { + struct d3d9_surface *surface = device->render_targets[i]; + + if (surface && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); + } +} + static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil) { @@ -1848,6 +1883,8 @@ static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_co
wined3d_mutex_lock(); hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock();
return hr; @@ -2243,6 +2280,13 @@ static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD st wined3d_mutex_lock(); hr = wined3d_device_set_texture(device->wined3d_device, stage, texture_impl ? texture_impl->wined3d_texture : NULL); + if (SUCCEEDED(hr)) + { + unsigned int i = stage >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage; + + if (stage < ARRAY_SIZE(device->textures)) + device->textures[i] = texture_impl; + } wined3d_mutex_unlock();
return hr; @@ -2483,6 +2527,16 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface) return ret; }
+/* wined3d critical section must be taken by the caller. */ +static void d3d9_generate_auto_mipmaps(struct d3d9_device *device) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(device->textures); ++i) + if (device->textures[i]) + d3d9_texture_gen_auto_mipmap(device->textures[i]); +} + static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count) { @@ -2499,9 +2553,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, WARN("Called without a valid vertex declaration set.\n"); return D3DERR_INVALIDCALL; } + d3d9_generate_auto_mipmaps(device); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count_from_primitive_count(primitive_type, primitive_count)); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock();
return hr; @@ -2526,10 +2583,13 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface WARN("Called without a valid vertex declaration set.\n"); return D3DERR_INVALIDCALL; } + d3d9_generate_auto_mipmaps(device); wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, vertex_count_from_primitive_count(primitive_type, primitive_count)); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock();
return hr; @@ -2628,9 +2688,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, if (FAILED(hr)) goto done;
+ d3d9_generate_auto_mipmaps(device); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count); wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device);
done: wined3d_mutex_unlock(); @@ -2758,6 +2821,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa if (FAILED(hr)) goto done;
+ d3d9_generate_auto_mipmaps(device); wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, wined3dformat_from_d3dformat(index_format), 0); wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx); @@ -2769,6 +2833,9 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
+ if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); + done: wined3d_mutex_unlock(); return hr; @@ -4147,6 +4214,14 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine return E_OUTOFMEMORY; }
+ /* We could also simply ignore the initial rendertarget since it's known + * not to be a texture (we currently use these only for automatic mipmap + * generation). */ + wined3d_mutex_lock(); + device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent( + wined3d_device_get_rendertarget_view(device->wined3d_device, 0)); + wined3d_mutex_unlock(); + IDirect3D9Ex_AddRef(&parent->IDirect3D9Ex_iface); device->d3d_parent = parent;
diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index fae6ca66ff4..813f89cc283 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -270,6 +270,8 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface)
wined3d_mutex_lock(); hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + if (SUCCEEDED(hr) && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); wined3d_mutex_unlock();
if (hr == WINEDDERR_NOTLOCKED) @@ -307,6 +309,8 @@ static HRESULT WINAPI d3d9_surface_ReleaseDC(IDirect3DSurface9 *iface, HDC dc)
wined3d_mutex_lock(); hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); + if (SUCCEEDED(hr) && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); wined3d_mutex_unlock();
return hr; diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 7c7017d528a..4b6d60efed5 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -7124,10 +7124,9 @@ static void test_mipmap_gen(void) ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture); - ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/, - "Got unexpected filter_type %#x.\n", filter_type); + ok(filter_type == D3DTEXF_LINEAR, "Got unexpected filter_type %#x.\n", filter_type); hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC); ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture); diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c index 6b7a30cdc1d..4549ea16191 100644 --- a/dlls/d3d9/texture.c +++ b/dlls/d3d9/texture.c @@ -38,6 +38,62 @@ static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVo return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); }
+static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent) +{ + struct d3d9_texture *texture = parent; + + texture->wined3d_srv = NULL; +} + +static const struct wined3d_parent_ops d3d9_srv_wined3d_parent_ops = +{ + srv_wined3d_object_destroyed, +}; + +/* wined3d critical section must be taken by the caller. */ +static struct wined3d_shader_resource_view *d3d9_texture_acquire_shader_resource_view(struct d3d9_texture *texture) +{ + struct wined3d_sub_resource_desc sr_desc; + struct wined3d_view_desc desc; + HRESULT hr; + + if (texture->wined3d_srv) + return texture->wined3d_srv; + + wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, 0, &sr_desc); + desc.format_id = sr_desc.format; + desc.flags = 0; + desc.u.texture.level_idx = 0; + desc.u.texture.level_count = wined3d_texture_get_level_count(texture->wined3d_texture); + desc.u.texture.layer_idx = 0; + desc.u.texture.layer_count = sr_desc.usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1; + if (FAILED(hr = wined3d_shader_resource_view_create(&desc, + wined3d_texture_get_resource(texture->wined3d_texture), texture, + &d3d9_srv_wined3d_parent_ops, &texture->wined3d_srv))) + { + ERR("Failed to create shader resource view, hr %#x.\n", hr); + return NULL; + } + + return texture->wined3d_srv; +} + +/* wined3d critical section must be taken by the caller. */ +void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture) +{ + if (!(texture->flags & D3D9_TEXTURE_MIPMAP_DIRTY)) + return; + d3d9_texture_acquire_shader_resource_view(texture); + wined3d_shader_resource_view_generate_mipmaps(texture->wined3d_srv); + texture->flags &= ~D3D9_TEXTURE_MIPMAP_DIRTY; +} + +void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture) +{ + if (texture->usage & D3DUSAGE_AUTOGENMIPMAP) + texture->flags |= D3D9_TEXTURE_MIPMAP_DIRTY; +} + static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); @@ -95,6 +151,8 @@ static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface) struct d3d9_surface *surface;
wined3d_mutex_lock(); + if (texture->wined3d_srv) + wined3d_shader_resource_view_decref(texture->wined3d_srv); LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) { wined3d_rendertarget_view_decref(surface->wined3d_rtv); @@ -235,6 +293,9 @@ static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
TRACE("iface %p.\n", iface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP) + return 1; + wined3d_mutex_lock(); ret = wined3d_texture_get_level_count(texture->wined3d_texture); wined3d_mutex_unlock(); @@ -245,35 +306,44 @@ static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface) static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - HRESULT hr;
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
- wined3d_mutex_lock(); - hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, - (enum wined3d_texture_filter_type)filter_type); - wined3d_mutex_unlock(); + if (filter_type == D3DTEXF_NONE) + { + WARN("Invalid filter type D3DTEXF_NONE specified.\n"); + return D3DERR_INVALIDCALL; + } + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n"); + else if (filter_type != D3DTEXF_LINEAR) + FIXME("Unsupported filter type %u.\n", filter_type);
- return hr; + texture->autogen_filter_type = filter_type; + return D3D_OK; }
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - D3DTEXTUREFILTERTYPE ret;
TRACE("iface %p.\n", iface);
- wined3d_mutex_lock(); - ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); - wined3d_mutex_unlock(); + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
- return ret; + return texture->autogen_filter_type; }
static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface) { + struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + d3d9_texture_gen_auto_mipmap(texture); + wined3d_mutex_unlock(); }
static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) @@ -284,12 +354,18 @@ static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UIN
TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = texture->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->MultiSampleType = wined3d_desc.multisample_type; desc->MultiSampleQuality = wined3d_desc.multisample_quality; @@ -309,6 +385,12 @@ static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) { @@ -333,6 +415,12 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface, TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n", iface, level, locked_rect, rect, flags);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; @@ -351,6 +439,12 @@ static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT
TRACE("iface %p, level %u.\n", iface, level);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; @@ -473,6 +567,8 @@ static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface) TRACE("Releasing child %p.\n", texture->wined3d_texture);
wined3d_mutex_lock(); + if (texture->wined3d_srv) + wined3d_shader_resource_view_decref(texture->wined3d_srv); LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) { wined3d_rendertarget_view_decref(surface->wined3d_rtv); @@ -613,6 +709,9 @@ static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface
TRACE("iface %p.\n", iface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP) + return 1; + wined3d_mutex_lock(); ret = wined3d_texture_get_level_count(texture->wined3d_texture); wined3d_mutex_unlock(); @@ -624,35 +723,44 @@ static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTextur D3DTEXTUREFILTERTYPE filter_type) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - HRESULT hr;
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
- wined3d_mutex_lock(); - hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, - (enum wined3d_texture_filter_type)filter_type); - wined3d_mutex_unlock(); + if (filter_type == D3DTEXF_NONE) + { + WARN("Invalid filter type D3DTEXF_NONE specified.\n"); + return D3DERR_INVALIDCALL; + } + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n"); + else if (filter_type != D3DTEXF_LINEAR) + FIXME("Unsupported filter type %u.\n", filter_type);
- return hr; + texture->autogen_filter_type = filter_type; + return D3D_OK; }
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - D3DTEXTUREFILTERTYPE ret;
TRACE("iface %p.\n", iface);
- wined3d_mutex_lock(); - ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); - wined3d_mutex_unlock(); + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
- return ret; + return texture->autogen_filter_type; }
static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface) { + struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + d3d9_texture_gen_auto_mipmap(texture); + wined3d_mutex_unlock(); }
static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) @@ -664,6 +772,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac
TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); level_count = wined3d_texture_get_level_count(texture->wined3d_texture); if (level >= level_count) @@ -676,7 +790,7 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = texture->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->MultiSampleType = wined3d_desc.multisample_type; desc->MultiSampleQuality = wined3d_desc.multisample_quality; @@ -698,6 +812,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9
TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); level_count = wined3d_texture_get_level_count(texture->wined3d_texture); if (level >= level_count) @@ -732,6 +852,12 @@ static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface, TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n", iface, face, level, locked_rect, rect, flags);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) @@ -753,6 +879,12 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) @@ -1014,31 +1146,16 @@ static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type) { - struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - HRESULT hr; - TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
- wined3d_mutex_lock(); - hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, - (enum wined3d_texture_filter_type)filter_type); - wined3d_mutex_unlock(); - - return hr; + return D3DERR_INVALIDCALL; }
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface) { - struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - D3DTEXTUREFILTERTYPE filter_type; - TRACE("iface %p.\n", iface);
- wined3d_mutex_lock(); - filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); - wined3d_mutex_unlock(); - - return filter_type; + return D3DTEXF_NONE; }
static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface) @@ -1059,7 +1176,7 @@ static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *ifac { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_VOLUME; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = texture->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Width = wined3d_desc.width; desc->Height = wined3d_desc.height; @@ -1213,12 +1330,13 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); + texture->usage = usage;
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; - desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; @@ -1234,13 +1352,28 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, if (is_gdi_compat_wined3dformat(desc.format)) flags |= WINED3D_TEXTURE_CREATE_GET_DC;
- if (!levels) + if (usage & D3DUSAGE_AUTOGENMIPMAP) + { + if (pool == D3DPOOL_SYSTEMMEM) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } + if (levels && levels != 1) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels); + return D3DERR_INVALIDCALL; + } + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + texture->autogen_filter_type = D3DTEXF_LINEAR; + levels = 0; + } + else { - if (usage & D3DUSAGE_AUTOGENMIPMAP) - levels = 1; - else - levels = wined3d_log2i(max(width, height)) + 1; + texture->autogen_filter_type = D3DTEXF_NONE; } + if (!levels) + levels = wined3d_log2i(max(width, height)) + 1;
wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags, @@ -1268,12 +1401,13 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); + texture->usage = usage;
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; - desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; @@ -1289,13 +1423,28 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic if (is_gdi_compat_wined3dformat(desc.format)) flags |= WINED3D_TEXTURE_CREATE_GET_DC;
- if (!levels) + if (usage & D3DUSAGE_AUTOGENMIPMAP) { - if (usage & D3DUSAGE_AUTOGENMIPMAP) - levels = 1; - else - levels = wined3d_log2i(edge_length) + 1; + if (pool == D3DPOOL_SYSTEMMEM) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } + if (levels && levels != 1) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels); + return D3DERR_INVALIDCALL; + } + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + texture->autogen_filter_type = D3DTEXF_LINEAR; + levels = 0; } + else + { + texture->autogen_filter_type = D3DTEXF_NONE; + } + if (!levels) + levels = wined3d_log2i(edge_length) + 1;
wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags, @@ -1322,12 +1471,13 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); + texture->usage = usage;
desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; - desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; @@ -1337,13 +1487,13 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev desc.depth = depth; desc.size = 0;
- if (!levels) + if (usage & D3DUSAGE_AUTOGENMIPMAP) { - if (usage & D3DUSAGE_AUTOGENMIPMAP) - levels = 1; - else - levels = wined3d_log2i(max(max(width, height), depth)) + 1; + WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; } + if (!levels) + levels = wined3d_log2i(max(max(width, height), depth)) + 1;
wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
On 13 February 2018 at 03:30, Matteo Bruni mbruni@codeweavers.com wrote:
@@ -95,6 +151,8 @@ static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface) struct d3d9_surface *surface;
wined3d_mutex_lock();
if (texture->wined3d_srv)
wined3d_shader_resource_view_decref(texture->wined3d_srv);
Shouldn't this happen for volume textures as well?
2018-02-14 14:57 GMT+01:00 Henri Verbeet hverbeet@gmail.com:
On 13 February 2018 at 03:30, Matteo Bruni mbruni@codeweavers.com wrote:
@@ -95,6 +151,8 @@ static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface) struct d3d9_surface *surface;
wined3d_mutex_lock();
if (texture->wined3d_srv)
wined3d_shader_resource_view_decref(texture->wined3d_srv);
Shouldn't this happen for volume textures as well?
wined3d_srv should never be set for volume textures but sure, I could add the release there too, to be safe WRT future changes.
On 14 February 2018 at 19:22, Matteo Bruni matteo.mystral@gmail.com wrote:
wined3d_srv should never be set for volume textures but sure, I could add the release there too, to be safe WRT future changes.
Oh right, mipmap generation is not supported on 3D textures in d3d9. The patch is probably fine as it is then, although it may still make sense to introduce some kind of d3d9_texture_cleanup() to make sure cleanup is consistent.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Rebase, update for the new patch 1/5.
dlls/wined3d/directx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 924cc72e773..d48b1d3d142 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -5296,7 +5296,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad const struct wined3d_gl_info *gl_info = &adapter->gl_info; const struct wined3d_format *adapter_format, *format; enum wined3d_gl_resource_type gl_type, gl_type_end; - BOOL mipmap_autogen_supported = TRUE; + BOOL mipmap_gen_supported = TRUE; DWORD format_flags = 0; DWORD allowed_usage;
@@ -5440,10 +5440,10 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad }
if (!(format->flags[gl_type] & WINED3DFMT_FLAG_GEN_MIPMAP)) - mipmap_autogen_supported = FALSE; + mipmap_gen_supported = FALSE; }
- if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_autogen_supported) + if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_gen_supported) { TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n"); return WINED3DOK_NOAUTOGEN; @@ -5618,7 +5618,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED | WINED3DCAPS2_FULLSCREENGAMMA | WINED3DCAPS2_DYNAMICTEXTURES; - if (gl_info->supported[SGIS_GENERATE_MIPMAP]) + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
caps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Rebase, update for the new patch 1/5.
dlls/d3d11/device.c | 2 +- dlls/d3d9/d3d9_private.h | 2 +- dlls/wined3d/directx.c | 13 ++++----- dlls/wined3d/resource.c | 1 - dlls/wined3d/texture.c | 62 ------------------------------------------ dlls/wined3d/utils.c | 4 +-- dlls/wined3d/wined3d.spec | 2 -- dlls/wined3d/wined3d_gl.h | 2 -- dlls/wined3d/wined3d_private.h | 1 - include/wine/wined3d.h | 13 ++++----- 10 files changed, 14 insertions(+), 88 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index f65c9947cb1..25308c29801 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -3250,7 +3250,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CheckFormatSupport(ID3D11Device *i { hr = wined3d_check_device_format(wined3d, params.adapter_idx, params.device_type, WINED3DFMT_UNKNOWN, flag_mapping[i].usage, flag_mapping[i].rtype, wined3d_format); - if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DOK_NOAUTOGEN) + if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DOK_NOMIPGEN) continue; if (hr != WINED3D_OK) { diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index b7504c2b357..2e081fd7eb4 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -332,7 +332,7 @@ static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool)
static inline DWORD wined3dusage_from_d3dusage(unsigned int usage) { - return usage & WINED3DUSAGE_MASK & ~WINED3DUSAGE_AUTOGENMIPMAP; + return usage & WINED3DUSAGE_MASK; }
#endif /* __WINE_D3D9_PRIVATE_H */ diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index d48b1d3d142..3ddc075d204 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -270,9 +270,6 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 }, {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION }, {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 }, - - /* SGI */ - {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP }, };
static const struct wined3d_extension_map wgl_extension_map[] = @@ -5338,12 +5335,12 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad gl_type = gl_type_end = WINED3D_GL_RES_TYPE_RB; break; } - allowed_usage |= WINED3DUSAGE_AUTOGENMIPMAP - | WINED3DUSAGE_DYNAMIC + allowed_usage |= WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_SOFTWAREPROCESSING | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER + | WINED3DUSAGE_QUERY_GENMIPMAP | WINED3DUSAGE_QUERY_LEGACYBUMPMAP | WINED3DUSAGE_QUERY_SRGBREAD | WINED3DUSAGE_QUERY_SRGBWRITE @@ -5443,10 +5440,10 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad mipmap_gen_supported = FALSE; }
- if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_gen_supported) + if ((usage & WINED3DUSAGE_QUERY_GENMIPMAP) && !mipmap_gen_supported) { TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n"); - return WINED3DOK_NOAUTOGEN; + return WINED3DOK_NOMIPGEN; }
return WINED3D_OK; @@ -5619,7 +5616,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DCAPS2_FULLSCREENGAMMA | WINED3DCAPS2_DYNAMICTEXTURES; if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) - caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP; + caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP;
caps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | WINED3DCAPS3_COPY_TO_VIDMEM | diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index e3188883205..1f555c36a67 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -34,7 +34,6 @@ static void resource_check_usage(DWORD usage) | WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC - | WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_STATICDECL | WINED3DUSAGE_OVERLAY | WINED3DUSAGE_SCRATCH diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 740afeace80..b04a0a7090b 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -375,7 +375,6 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
texture->layer_count = layer_count; texture->level_count = level_count; - texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE; texture->lod = 0; texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) @@ -739,12 +738,6 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
context_bind_texture(context, target, gl_tex->name);
- if (texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)"); - } - /* For a new texture we have to set the texture levels after binding the * texture. Beware that texture rectangles do not support mipmapping, but * set the maxmiplevel if we're relying on the partial @@ -1188,29 +1181,6 @@ DWORD CDECL wined3d_texture_get_level_count(const struct wined3d_texture *textur return texture->level_count; }
-HRESULT CDECL wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture, - enum wined3d_texture_filter_type filter_type) -{ - FIXME("texture %p, filter_type %s stub!\n", texture, debug_d3dtexturefiltertype(filter_type)); - - if (!(texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) - { - WARN("Texture doesn't have AUTOGENMIPMAP usage.\n"); - return WINED3DERR_INVALIDCALL; - } - - texture->filter_type = filter_type; - - return WINED3D_OK; -} - -enum wined3d_texture_filter_type CDECL wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture) -{ - TRACE("texture %p.\n", texture); - - return texture->filter_type; -} - HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture, DWORD flags, const struct wined3d_color_key *color_key) { @@ -2170,22 +2140,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height); }
- /* Calculate levels for mip mapping. */ - if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (level_count != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - } - if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, flags, device, parent, parent_ops, &texture_resource_ops))) { @@ -2624,22 +2578,6 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct return WINED3DERR_INVALIDCALL; }
- /* Calculate levels for mip mapping. */ - if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (level_count != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - } - if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access) || desc->usage & WINED3DUSAGE_SCRATCH)) { diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 960909f35b4..401b978be82 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -3599,7 +3599,7 @@ static void init_format_gen_mipmap_info(struct wined3d_gl_info *gl_info) { unsigned int i, j;
- if (!gl_info->supported[SGIS_GENERATE_MIPMAP] && !gl_info->fbo_ops.glGenerateMipmap) + if (!gl_info->fbo_ops.glGenerateMipmap) return;
for (i = 0; i < gl_info->format_count; ++i) @@ -4179,7 +4179,6 @@ const char *debug_d3dusage(DWORD usage) WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES); WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES); WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC); - WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP); WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICTED_CONTENT); WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER); WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE); @@ -4203,6 +4202,7 @@ const char *debug_d3dusagequery(DWORD usagequery) buf[0] = '\0'; #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; } WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER); + WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_GENMIPMAP); WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP); WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING); WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 035746d86aa..d2b6bef3634 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -294,7 +294,6 @@ @ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr) @ cdecl wined3d_texture_decref(ptr) @ cdecl wined3d_texture_from_resource(ptr) -@ cdecl wined3d_texture_get_autogen_filter_type(ptr) @ cdecl wined3d_texture_get_dc(ptr long ptr) @ cdecl wined3d_texture_get_level_count(ptr) @ cdecl wined3d_texture_get_lod(ptr) @@ -306,7 +305,6 @@ @ cdecl wined3d_texture_get_sub_resource_parent(ptr long) @ cdecl wined3d_texture_incref(ptr) @ cdecl wined3d_texture_release_dc(ptr long ptr) -@ cdecl wined3d_texture_set_autogen_filter_type(ptr long) @ cdecl wined3d_texture_set_color_key(ptr long ptr) @ cdecl wined3d_texture_set_lod(ptr long) @ cdecl wined3d_texture_set_overlay_position(ptr long long long) diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index a3dee243595..cc6f8880256 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -199,8 +199,6 @@ enum wined3d_gl_extension NV_VERTEX_PROGRAM2, NV_VERTEX_PROGRAM2_OPTION, NV_VERTEX_PROGRAM3, - /* SGI */ - SGIS_GENERATE_MIPMAP, /* WGL extensions */ WGL_ARB_PIXEL_FORMAT, WGL_EXT_SWAP_CONTROL, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8201536a5de..c2565379e54 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3116,7 +3116,6 @@ struct wined3d_texture unsigned int sysmem_count; float pow2_matrix[16]; UINT lod; - enum wined3d_texture_filter_type filter_type; DWORD sampler; DWORD flags; GLenum target; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index ed7445ea5a3..78540f4a8cc 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -36,7 +36,7 @@
#define _FACWINED3D 0x876 #define MAKE_WINED3DSTATUS(code) MAKE_HRESULT(0, _FACWINED3D, code) -#define WINED3DOK_NOAUTOGEN MAKE_WINED3DSTATUS(2159) +#define WINED3DOK_NOMIPGEN MAKE_WINED3DSTATUS(2159)
#define MAKE_WINED3DHRESULT(code) MAKE_HRESULT(1, _FACWINED3D, code) #define WINED3DERR_CONFLICTINGRENDERSTATE MAKE_WINED3DHRESULT(2081) @@ -884,13 +884,12 @@ enum wined3d_shader_byte_code_format #define WINED3DUSAGE_RTPATCHES 0x00000080 #define WINED3DUSAGE_NPATCHES 0x00000100 #define WINED3DUSAGE_DYNAMIC 0x00000200 -#define WINED3DUSAGE_AUTOGENMIPMAP 0x00000400 #define WINED3DUSAGE_RESTRICTED_CONTENT 0x00000800 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER 0x00001000 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE 0x00002000 #define WINED3DUSAGE_DMAP 0x00004000 #define WINED3DUSAGE_TEXTAPI 0x10000000 -#define WINED3DUSAGE_MASK 0x10007fff +#define WINED3DUSAGE_MASK 0x10007bff
#define WINED3DUSAGE_SCRATCH 0x00200000 #define WINED3DUSAGE_PRIVATE 0x00400000 @@ -900,6 +899,7 @@ enum wined3d_shader_byte_code_format #define WINED3DUSAGE_STATICDECL 0x04000000 #define WINED3DUSAGE_OVERLAY 0x08000000
+#define WINED3DUSAGE_QUERY_GENMIPMAP 0x00000400 #define WINED3DUSAGE_QUERY_LEGACYBUMPMAP 0x00008000 #define WINED3DUSAGE_QUERY_FILTER 0x00020000 #define WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING 0x00080000 @@ -907,7 +907,7 @@ enum wined3d_shader_byte_code_format #define WINED3DUSAGE_QUERY_SRGBWRITE 0x00040000 #define WINED3DUSAGE_QUERY_VERTEXTEXTURE 0x00100000 #define WINED3DUSAGE_QUERY_WRAPANDMIP 0x00200000 -#define WINED3DUSAGE_QUERY_MASK 0x003f8000 +#define WINED3DUSAGE_QUERY_MASK 0x003f8400
#define WINED3D_MAP_READONLY 0x0010 #define WINED3D_MAP_NOSYSLOCK 0x0800 @@ -1163,7 +1163,7 @@ enum wined3d_shader_byte_code_format #define WINED3DCAPS2_RESERVED 0x02000000 #define WINED3DCAPS2_CANMANAGERESOURCE 0x10000000 #define WINED3DCAPS2_DYNAMICTEXTURES 0x20000000 -#define WINED3DCAPS2_CANAUTOGENMIPMAP 0x40000000 +#define WINED3DCAPS2_CANGENMIPMAP 0x40000000
#define WINED3DPRASTERCAPS_DITHER 0x00000001 #define WINED3DPRASTERCAPS_ROP2 0x00000002 @@ -2674,7 +2674,6 @@ HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const stru void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource); ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture); -enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture); HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc); DWORD __cdecl wined3d_texture_get_level_count(const struct wined3d_texture *texture); DWORD __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture); @@ -2689,8 +2688,6 @@ HRESULT __cdecl wined3d_texture_get_sub_resource_desc(const struct wined3d_textu void * __cdecl wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx); ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture); HRESULT __cdecl wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc); -HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture, - enum wined3d_texture_filter_type filter_type); HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture, DWORD flags, const struct wined3d_color_key *color_key); DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3d9/tests/device.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 4b6d60efed5..0ffc1aeb972 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -7065,12 +7065,12 @@ static void test_mipmap_gen(void) IDirect3DTexture9 *texture; IDirect3DSurface9 *surface; IDirect3DDevice9 *device; + unsigned int i, count; D3DSURFACE_DESC desc; D3DLOCKED_RECT lr; IDirect3D9 *d3d; BOOL renderable; ULONG refcount; - unsigned int i; DWORD levels; HWND window; HRESULT hr; @@ -7170,8 +7170,74 @@ static void test_mipmap_gen(void) ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); levels = IDirect3DTexture9_GetLevelCount(texture); ok(levels == 1, "Got unexpected levels %u.\n", levels); + hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + ok(desc.Usage == D3DUSAGE_AUTOGENMIPMAP, "Got unexpected usage %#x.\n", desc.Usage); IDirect3DTexture9_Release(texture);
+ hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP, + D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, 0); + ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(formats); ++i) + { + hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, + D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, formats[i]); + if (SUCCEEDED(hr)) + { + /* i.e. there is no difference between the D3D_OK and the + * D3DOK_NOAUTOGEN cases. */ + hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP, + formats[i], D3DPOOL_DEFAULT, &texture, 0); + ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); + count = IDirect3DTexture9_GetLevelCount(texture); + ok(count == 1, "Unexpected level count %u.\n", count); + hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + ok(desc.Usage == D3DUSAGE_AUTOGENMIPMAP, "Got unexpected usage %#x.\n", desc.Usage); + filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture); + ok(filter_type == D3DTEXF_LINEAR, "Got unexpected filter_type %#x.\n", filter_type); + hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture); + ok(filter_type == D3DTEXF_ANISOTROPIC, "Got unexpected filter_type %#x.\n", filter_type); + IDirect3DTexture9_Release(texture); + } + } + + hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_WRAPANDMIP, D3DRTYPE_TEXTURE, D3DFMT_D16); + if (hr == D3D_OK) + { + hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, + D3DFMT_D16, D3DPOOL_DEFAULT, &texture, 0); + ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); + count = IDirect3DTexture9_GetLevelCount(texture); + ok(count == 7, "Unexpected level count %u.\n", count); + IDirect3DTexture9_Release(texture); + + hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, + D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_D16); + ok(hr == D3DOK_NOAUTOGEN, "Unexpected hr %#x.\n", hr); + hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP, + D3DFMT_D16, D3DPOOL_DEFAULT, &texture, 0); + ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr); + count = IDirect3DTexture9_GetLevelCount(texture); + ok(count == 1, "Unexpected level count %u.\n", count); + hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc); + ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); + ok(desc.Usage == D3DUSAGE_AUTOGENMIPMAP, "Got unexpected usage %#x.\n", desc.Usage); + IDirect3DTexture9_Release(texture); + } + else + { + skip("Mipmapping not supported for D3DFMT_D16, skipping test.\n"); + } + + hr = IDirect3DDevice9_CreateVolumeTexture(device, 64, 64, 64, 0, D3DUSAGE_AUTOGENMIPMAP, + D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, (IDirect3DVolumeTexture9 **)&texture, 0); + ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr); + refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); IDirect3D9_Release(d3d);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Just use texture->resource.format_flags.
dlls/wined3d/directx.c | 8 ++------ dlls/wined3d/texture.c | 5 ++--- dlls/wined3d/utils.c | 18 ++++++++++++++++++ dlls/wined3d/wined3d_private.h | 1 + 4 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index c8f42fe253a..924cc72e773 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -5296,7 +5296,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad const struct wined3d_gl_info *gl_info = &adapter->gl_info; const struct wined3d_format *adapter_format, *format; enum wined3d_gl_resource_type gl_type, gl_type_end; - BOOL mipmap_autogen_supported; + BOOL mipmap_autogen_supported = TRUE; DWORD format_flags = 0; DWORD allowed_usage;
@@ -5410,7 +5410,6 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; }
- mipmap_autogen_supported = gl_info->supported[SGIS_GENERATE_MIPMAP]; for (; gl_type <= gl_type_end; ++gl_type) { if ((format->flags[gl_type] & format_flags) != format_flags) @@ -5440,11 +5439,8 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; }
- if ((format->flags[gl_type] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) - != (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) - { + if (!(format->flags[gl_type] & WINED3DFMT_FLAG_GEN_MIPMAP)) mipmap_autogen_supported = FALSE; - } }
if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_autogen_supported) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 750101fac66..5d198619c98 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -386,8 +386,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc 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)) + if (!(texture->resource.format_flags & WINED3DFMT_FLAG_GEN_MIPMAP)) WARN("Format doesn't support mipmaps generation, " "ignoring WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS flag.\n"); else @@ -2685,7 +2684,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct texture->resource.map_binding = WINED3D_LOCATION_BUFFER; }
- /* Generate all the surfaces. */ + /* Generate all the sub resources. */ for (i = 0; i < texture->level_count; ++i) { struct wined3d_texture_sub_resource *sub_resource; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 6f7740deda0..960909f35b4 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -3595,6 +3595,23 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info) return TRUE; }
+static void init_format_gen_mipmap_info(struct wined3d_gl_info *gl_info) +{ + unsigned int i, j; + + if (!gl_info->supported[SGIS_GENERATE_MIPMAP] && !gl_info->fbo_ops.glGenerateMipmap) + return; + + for (i = 0; i < gl_info->format_count; ++i) + { + struct wined3d_format *format = &gl_info->formats[i]; + + for (j = 0; j < ARRAY_SIZE(format->flags); ++j) + if (!(~format->flags[j] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING))) + format->flags[j] |= WINED3DFMT_FLAG_GEN_MIPMAP; + } +} + BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx) { static const struct wined3d_color red = {1.0f, 0.0f, 0.0f, 1.0f}; @@ -3783,6 +3800,7 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wi init_format_fbo_compat_info(ctx); init_format_filter_info(gl_info, adapter->driver_info.vendor); if (!init_typeless_formats(gl_info)) goto fail; + init_format_gen_mipmap_info(gl_info); init_format_depth_bias_scale(ctx, &adapter->d3d_info);
return TRUE; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f1f75301d6d..8201536a5de 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4205,6 +4205,7 @@ extern enum wined3d_format_id pixelformat_for_depth(DWORD depth) DECLSPEC_HIDDEN #define WINED3DFMT_FLAG_TEXTURE 0x00080000 #define WINED3DFMT_FLAG_BLOCKS_NO_VERIFY 0x00100000 #define WINED3DFMT_FLAG_INTEGER 0x00200000 +#define WINED3DFMT_FLAG_GEN_MIPMAP 0x00400000
struct wined3d_rational {
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com