d3d9: Handle D3DUSAGE_AUTOGENMIPMAP textures entirely in d3d9.
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
478c8b0eb1
commit
3d6eb8cf1d
@ -40,8 +40,16 @@
|
|||||||
#include "d3d9.h"
|
#include "d3d9.h"
|
||||||
#include "wine/wined3d.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 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;
|
extern const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) 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_size;
|
||||||
UINT index_buffer_pos;
|
UINT index_buffer_pos;
|
||||||
|
|
||||||
|
struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS];
|
||||||
|
struct d3d9_surface *render_targets[D3D9_MAX_SIMULTANEOUS_RENDERTARGETS];
|
||||||
|
|
||||||
LONG device_state;
|
LONG device_state;
|
||||||
BOOL in_destruction;
|
BOOL in_destruction;
|
||||||
BOOL in_scene;
|
BOOL in_scene;
|
||||||
@ -199,6 +210,10 @@ struct d3d9_texture
|
|||||||
struct wined3d_texture *wined3d_texture;
|
struct wined3d_texture *wined3d_texture;
|
||||||
IDirect3DDevice9Ex *parent_device;
|
IDirect3DDevice9Ex *parent_device;
|
||||||
struct list rtv_list;
|
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,
|
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,
|
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;
|
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;
|
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
|
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_device *device, const DWORD *byte_code) DECLSPEC_HIDDEN;
|
||||||
struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface) 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
|
struct d3d9_pixelshader
|
||||||
{
|
{
|
||||||
IDirect3DPixelShader9 IDirect3DPixelShader9_iface;
|
IDirect3DPixelShader9 IDirect3DPixelShader9_iface;
|
||||||
@ -318,4 +332,9 @@ static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool, unsigned int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline DWORD wined3dusage_from_d3dusage(unsigned int usage)
|
||||||
|
{
|
||||||
|
return usage & WINED3DUSAGE_MASK & ~WINED3DUSAGE_AUTOGENMIPMAP;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __WINE_D3D9_PRIVATE_H */
|
#endif /* __WINE_D3D9_PRIVATE_H */
|
||||||
|
@ -815,6 +815,8 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
|
|||||||
BOOL extended = device->d3d_parent->extended;
|
BOOL extended = device->d3d_parent->extended;
|
||||||
struct wined3d_swapchain_desc swapchain_desc;
|
struct wined3d_swapchain_desc swapchain_desc;
|
||||||
struct wined3d_display_mode wined3d_mode;
|
struct wined3d_display_mode wined3d_mode;
|
||||||
|
struct wined3d_rendertarget_view *rtv;
|
||||||
|
unsigned int i;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!extended && device->device_state == D3D9_DEVICE_STATE_LOST)
|
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;
|
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)
|
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,
|
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),
|
dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture),
|
||||||
src->sub_resource_idx, &src_box);
|
src->sub_resource_idx, &src_box);
|
||||||
|
if (SUCCEEDED(hr) && dst->texture)
|
||||||
|
d3d9_texture_flag_auto_gen_mipmap(dst->texture);
|
||||||
|
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
@ -1448,6 +1462,8 @@ static HRESULT WINAPI d3d9_device_UpdateTexture(IDirect3DDevice9Ex *iface,
|
|||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_device_update_texture(device->wined3d_device,
|
hr = wined3d_device_update_texture(device->wined3d_device,
|
||||||
src_impl->wined3d_texture, dst_impl->wined3d_texture);
|
src_impl->wined3d_texture, dst_impl->wined3d_texture);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
d3d9_texture_flag_auto_gen_mipmap(dst_impl);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return hr;
|
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);
|
src->wined3d_texture, src->sub_resource_idx, src_rect, 0, NULL, filter);
|
||||||
if (hr == WINEDDERR_INVALIDRECT)
|
if (hr == WINEDDERR_INVALIDRECT)
|
||||||
hr = D3DERR_INVALIDCALL;
|
hr = D3DERR_INVALIDCALL;
|
||||||
|
if (SUCCEEDED(hr) && dst->texture)
|
||||||
|
d3d9_texture_flag_auto_gen_mipmap(dst->texture);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
@ -1622,6 +1640,8 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface,
|
|||||||
hr = wined3d_device_clear_rendertarget_view(device->wined3d_device,
|
hr = wined3d_device_clear_rendertarget_view(device->wined3d_device,
|
||||||
rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0);
|
rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0);
|
||||||
d3d9_surface_release_rendertarget_view(surface_impl, rtv);
|
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();
|
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;
|
rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL;
|
||||||
hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE);
|
hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE);
|
||||||
d3d9_surface_release_rendertarget_view(surface_impl, rtv);
|
d3d9_surface_release_rendertarget_view(surface_impl, rtv);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
device->render_targets[idx] = surface_impl;
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
@ -1824,6 +1846,19 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_EndScene(IDirect3DDevice9Ex
|
|||||||
return hr;
|
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,
|
static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count,
|
||||||
const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil)
|
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();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil);
|
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();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
@ -2243,6 +2280,13 @@ static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD st
|
|||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_device_set_texture(device->wined3d_device, stage,
|
hr = wined3d_device_set_texture(device->wined3d_device, stage,
|
||||||
texture_impl ? texture_impl->wined3d_texture : NULL);
|
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();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
@ -2483,6 +2527,16 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface)
|
|||||||
return ret;
|
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,
|
static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface,
|
||||||
D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count)
|
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");
|
WARN("Called without a valid vertex declaration set.\n");
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
d3d9_generate_auto_mipmaps(device);
|
||||||
wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
|
wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
|
||||||
hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
|
hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex,
|
||||||
vertex_count_from_primitive_count(primitive_type, primitive_count));
|
vertex_count_from_primitive_count(primitive_type, primitive_count));
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
d3d9_rts_flag_auto_gen_mipmap(device);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
@ -2526,10 +2583,13 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface
|
|||||||
WARN("Called without a valid vertex declaration set.\n");
|
WARN("Called without a valid vertex declaration set.\n");
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
d3d9_generate_auto_mipmaps(device);
|
||||||
wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
|
wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx);
|
||||||
wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
|
wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
|
||||||
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
|
hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx,
|
||||||
vertex_count_from_primitive_count(primitive_type, primitive_count));
|
vertex_count_from_primitive_count(primitive_type, primitive_count));
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
d3d9_rts_flag_auto_gen_mipmap(device);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
@ -2628,9 +2688,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
|
|||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
d3d9_generate_auto_mipmaps(device);
|
||||||
wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
|
wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0);
|
||||||
hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count);
|
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);
|
wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
d3d9_rts_flag_auto_gen_mipmap(device);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
@ -2758,6 +2821,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa
|
|||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
d3d9_generate_auto_mipmaps(device);
|
||||||
wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer,
|
wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer,
|
||||||
wined3dformat_from_d3dformat(index_format), 0);
|
wined3dformat_from_d3dformat(index_format), 0);
|
||||||
wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx);
|
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_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0);
|
||||||
wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
|
wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
d3d9_rts_flag_auto_gen_mipmap(device);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
return hr;
|
return hr;
|
||||||
@ -4147,6 +4214,14 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine
|
|||||||
return E_OUTOFMEMORY;
|
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);
|
IDirect3D9Ex_AddRef(&parent->IDirect3D9Ex_iface);
|
||||||
device->d3d_parent = parent;
|
device->d3d_parent = parent;
|
||||||
|
|
||||||
|
@ -270,6 +270,8 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface)
|
|||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx);
|
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();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
if (hr == WINEDDERR_NOTLOCKED)
|
if (hr == WINEDDERR_NOTLOCKED)
|
||||||
@ -307,6 +309,8 @@ static HRESULT WINAPI d3d9_surface_ReleaseDC(IDirect3DSurface9 *iface, HDC dc)
|
|||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, dc);
|
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();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
@ -7124,10 +7124,9 @@ static void test_mipmap_gen(void)
|
|||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
|
filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
|
||||||
ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/,
|
ok(filter_type == D3DTEXF_LINEAR, "Got unexpected filter_type %#x.\n", filter_type);
|
||||||
"Got unexpected filter_type %#x.\n", filter_type);
|
|
||||||
hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE);
|
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);
|
hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC);
|
||||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
|
filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture);
|
||||||
|
@ -38,6 +38,62 @@ static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVo
|
|||||||
return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
|
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)
|
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);
|
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;
|
struct d3d9_surface *surface;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
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)
|
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
|
||||||
{
|
{
|
||||||
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
|
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);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
|
if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
|
||||||
|
return 1;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
ret = wined3d_texture_get_level_count(texture->wined3d_texture);
|
ret = wined3d_texture_get_level_count(texture->wined3d_texture);
|
||||||
wined3d_mutex_unlock();
|
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)
|
static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
|
||||||
{
|
{
|
||||||
struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
|
struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
|
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
if (filter_type == D3DTEXF_NONE)
|
||||||
hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
|
{
|
||||||
(enum wined3d_texture_filter_type)filter_type);
|
WARN("Invalid filter type D3DTEXF_NONE specified.\n");
|
||||||
wined3d_mutex_unlock();
|
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)
|
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
|
||||||
{
|
{
|
||||||
struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
|
struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
|
||||||
D3DTEXTUREFILTERTYPE ret;
|
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
|
||||||
ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
|
WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
|
||||||
wined3d_mutex_unlock();
|
|
||||||
|
|
||||||
return ret;
|
return texture->autogen_filter_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
|
static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
|
||||||
{
|
{
|
||||||
|
struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", 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)
|
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);
|
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();
|
wined3d_mutex_lock();
|
||||||
if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
|
if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
|
||||||
{
|
{
|
||||||
desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
|
desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
|
||||||
desc->Type = D3DRTYPE_SURFACE;
|
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->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
|
||||||
desc->MultiSampleType = wined3d_desc.multisample_type;
|
desc->MultiSampleType = wined3d_desc.multisample_type;
|
||||||
desc->MultiSampleQuality = wined3d_desc.multisample_quality;
|
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);
|
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();
|
wined3d_mutex_lock();
|
||||||
if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
|
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",
|
TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
|
||||||
iface, level, locked_rect, rect, flags);
|
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();
|
wined3d_mutex_lock();
|
||||||
if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
|
if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
|
||||||
hr = D3DERR_INVALIDCALL;
|
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);
|
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();
|
wined3d_mutex_lock();
|
||||||
if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
|
if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
|
||||||
hr = D3DERR_INVALIDCALL;
|
hr = D3DERR_INVALIDCALL;
|
||||||
@ -473,6 +567,8 @@ static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
|
|||||||
TRACE("Releasing child %p.\n", texture->wined3d_texture);
|
TRACE("Releasing child %p.\n", texture->wined3d_texture);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
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)
|
LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
|
||||||
{
|
{
|
||||||
wined3d_rendertarget_view_decref(surface->wined3d_rtv);
|
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);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
|
if (texture->usage & D3DUSAGE_AUTOGENMIPMAP)
|
||||||
|
return 1;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
ret = wined3d_texture_get_level_count(texture->wined3d_texture);
|
ret = wined3d_texture_get_level_count(texture->wined3d_texture);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
@ -624,35 +723,44 @@ static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTextur
|
|||||||
D3DTEXTUREFILTERTYPE filter_type)
|
D3DTEXTUREFILTERTYPE filter_type)
|
||||||
{
|
{
|
||||||
struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
|
struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
|
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
if (filter_type == D3DTEXF_NONE)
|
||||||
hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
|
{
|
||||||
(enum wined3d_texture_filter_type)filter_type);
|
WARN("Invalid filter type D3DTEXF_NONE specified.\n");
|
||||||
wined3d_mutex_unlock();
|
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)
|
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
|
||||||
{
|
{
|
||||||
struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
|
struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
|
||||||
D3DTEXTUREFILTERTYPE ret;
|
|
||||||
|
|
||||||
TRACE("iface %p.\n", iface);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP))
|
||||||
ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
|
WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
|
||||||
wined3d_mutex_unlock();
|
|
||||||
|
|
||||||
return ret;
|
return texture->autogen_filter_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
|
static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
|
||||||
{
|
{
|
||||||
|
struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
|
||||||
|
|
||||||
TRACE("iface %p.\n", 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)
|
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);
|
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();
|
wined3d_mutex_lock();
|
||||||
level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
|
level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
|
||||||
if (level >= level_count)
|
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->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
|
||||||
desc->Type = D3DRTYPE_SURFACE;
|
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->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
|
||||||
desc->MultiSampleType = wined3d_desc.multisample_type;
|
desc->MultiSampleType = wined3d_desc.multisample_type;
|
||||||
desc->MultiSampleQuality = wined3d_desc.multisample_quality;
|
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);
|
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();
|
wined3d_mutex_lock();
|
||||||
level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
|
level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
|
||||||
if (level >= level_count)
|
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",
|
TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
|
||||||
iface, face, level, locked_rect, rect, flags);
|
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();
|
wined3d_mutex_lock();
|
||||||
sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
|
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)))
|
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);
|
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();
|
wined3d_mutex_lock();
|
||||||
sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
|
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)))
|
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,
|
static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
|
||||||
D3DTEXTUREFILTERTYPE filter_type)
|
D3DTEXTUREFILTERTYPE filter_type)
|
||||||
{
|
{
|
||||||
struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
|
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
return D3DERR_INVALIDCALL;
|
||||||
hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
|
|
||||||
(enum wined3d_texture_filter_type)filter_type);
|
|
||||||
wined3d_mutex_unlock();
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
|
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);
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
return D3DTEXF_NONE;
|
||||||
filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
|
|
||||||
wined3d_mutex_unlock();
|
|
||||||
|
|
||||||
return filter_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
|
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->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
|
||||||
desc->Type = D3DRTYPE_VOLUME;
|
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->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage);
|
||||||
desc->Width = wined3d_desc.width;
|
desc->Width = wined3d_desc.width;
|
||||||
desc->Height = wined3d_desc.height;
|
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;
|
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
|
||||||
d3d9_resource_init(&texture->resource);
|
d3d9_resource_init(&texture->resource);
|
||||||
list_init(&texture->rtv_list);
|
list_init(&texture->rtv_list);
|
||||||
|
texture->usage = usage;
|
||||||
|
|
||||||
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
||||||
desc.format = wined3dformat_from_d3dformat(format);
|
desc.format = wined3dformat_from_d3dformat(format);
|
||||||
desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
|
desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
|
||||||
desc.multisample_quality = 0;
|
desc.multisample_quality = 0;
|
||||||
desc.usage = usage & WINED3DUSAGE_MASK;
|
desc.usage = wined3dusage_from_d3dusage(usage);
|
||||||
desc.usage |= WINED3DUSAGE_TEXTURE;
|
desc.usage |= WINED3DUSAGE_TEXTURE;
|
||||||
if (pool == D3DPOOL_SCRATCH)
|
if (pool == D3DPOOL_SCRATCH)
|
||||||
desc.usage |= WINED3DUSAGE_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))
|
if (is_gdi_compat_wined3dformat(desc.format))
|
||||||
flags |= WINED3D_TEXTURE_CREATE_GET_DC;
|
flags |= WINED3D_TEXTURE_CREATE_GET_DC;
|
||||||
|
|
||||||
if (!levels)
|
|
||||||
{
|
|
||||||
if (usage & D3DUSAGE_AUTOGENMIPMAP)
|
if (usage & D3DUSAGE_AUTOGENMIPMAP)
|
||||||
levels = 1;
|
{
|
||||||
else
|
if (pool == D3DPOOL_SYSTEMMEM)
|
||||||
levels = wined3d_log2i(max(width, height)) + 1;
|
{
|
||||||
|
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(max(width, height)) + 1;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
|
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;
|
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
|
||||||
d3d9_resource_init(&texture->resource);
|
d3d9_resource_init(&texture->resource);
|
||||||
list_init(&texture->rtv_list);
|
list_init(&texture->rtv_list);
|
||||||
|
texture->usage = usage;
|
||||||
|
|
||||||
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
|
||||||
desc.format = wined3dformat_from_d3dformat(format);
|
desc.format = wined3dformat_from_d3dformat(format);
|
||||||
desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
|
desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
|
||||||
desc.multisample_quality = 0;
|
desc.multisample_quality = 0;
|
||||||
desc.usage = usage & WINED3DUSAGE_MASK;
|
desc.usage = wined3dusage_from_d3dusage(usage);
|
||||||
desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
|
desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
|
||||||
if (pool == D3DPOOL_SCRATCH)
|
if (pool == D3DPOOL_SCRATCH)
|
||||||
desc.usage |= WINED3DUSAGE_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))
|
if (is_gdi_compat_wined3dformat(desc.format))
|
||||||
flags |= WINED3D_TEXTURE_CREATE_GET_DC;
|
flags |= WINED3D_TEXTURE_CREATE_GET_DC;
|
||||||
|
|
||||||
if (!levels)
|
|
||||||
{
|
|
||||||
if (usage & D3DUSAGE_AUTOGENMIPMAP)
|
if (usage & D3DUSAGE_AUTOGENMIPMAP)
|
||||||
levels = 1;
|
{
|
||||||
else
|
if (pool == D3DPOOL_SYSTEMMEM)
|
||||||
levels = wined3d_log2i(edge_length) + 1;
|
{
|
||||||
|
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();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
|
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;
|
texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
|
||||||
d3d9_resource_init(&texture->resource);
|
d3d9_resource_init(&texture->resource);
|
||||||
list_init(&texture->rtv_list);
|
list_init(&texture->rtv_list);
|
||||||
|
texture->usage = usage;
|
||||||
|
|
||||||
desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
|
desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
|
||||||
desc.format = wined3dformat_from_d3dformat(format);
|
desc.format = wined3dformat_from_d3dformat(format);
|
||||||
desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
|
desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
|
||||||
desc.multisample_quality = 0;
|
desc.multisample_quality = 0;
|
||||||
desc.usage = usage & WINED3DUSAGE_MASK;
|
desc.usage = wined3dusage_from_d3dusage(usage);
|
||||||
desc.usage |= WINED3DUSAGE_TEXTURE;
|
desc.usage |= WINED3DUSAGE_TEXTURE;
|
||||||
if (pool == D3DPOOL_SCRATCH)
|
if (pool == D3DPOOL_SCRATCH)
|
||||||
desc.usage |= WINED3DUSAGE_SCRATCH;
|
desc.usage |= WINED3DUSAGE_SCRATCH;
|
||||||
@ -1337,13 +1487,13 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev
|
|||||||
desc.depth = depth;
|
desc.depth = depth;
|
||||||
desc.size = 0;
|
desc.size = 0;
|
||||||
|
|
||||||
if (!levels)
|
|
||||||
{
|
|
||||||
if (usage & D3DUSAGE_AUTOGENMIPMAP)
|
if (usage & D3DUSAGE_AUTOGENMIPMAP)
|
||||||
levels = 1;
|
{
|
||||||
else
|
WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n");
|
||||||
levels = wined3d_log2i(max(max(width, height), depth)) + 1;
|
return D3DERR_INVALIDCALL;
|
||||||
}
|
}
|
||||||
|
if (!levels)
|
||||||
|
levels = wined3d_log2i(max(max(width, height), depth)) + 1;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
|
hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user