-- v2: wined3d: Translate sampler states to sampler objects in wined3d_device_apply_stateblock(). d3d8: Store the texture's parent device as a d3d8_device pointer. wined3d: Pass shader type and unmodified index to context_preload_texture(). wined3d: Handle texture LOD in wined3d_sampler_desc_from_sampler_states(). wined3d: Pass a wined3d_texture to wined3d_sampler_desc_from_sampler_states().
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/state.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 30b0adaa135..5bccd1acb4a 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3451,7 +3451,7 @@ static void sampler_texmatrix(struct wined3d_context *context, const struct wine } }
-static enum wined3d_texture_address wined3d_texture_gl_address_mode(const struct wined3d_texture_gl *texture_gl, +static enum wined3d_texture_address wined3d_texture_address_mode(const struct wined3d_texture *texture, enum wined3d_texture_address t) { if (t < WINED3D_TADDRESS_WRAP || t > WINED3D_TADDRESS_MIRROR_ONCE) @@ -3461,8 +3461,8 @@ static enum wined3d_texture_address wined3d_texture_gl_address_mode(const struct }
/* Cubemaps are always set to clamp, regardless of the sampler state. */ - if (texture_gl->target == GL_TEXTURE_CUBE_MAP_ARB || ((texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2) - && t == WINED3D_TADDRESS_WRAP)) + if ((texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP) + || ((texture->flags & WINED3D_TEXTURE_COND_NP2) && t == WINED3D_TADDRESS_WRAP)) return WINED3D_TADDRESS_CLAMP;
return t; @@ -3470,7 +3470,7 @@ static enum wined3d_texture_address wined3d_texture_gl_address_mode(const struct
static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc, const struct wined3d_context_gl *context_gl, const uint32_t *sampler_states, - const struct wined3d_texture_gl *texture_gl) + const struct wined3d_texture *texture) { union { @@ -3478,9 +3478,9 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc DWORD d; } lod_bias;
- desc->address_u = wined3d_texture_gl_address_mode(texture_gl, sampler_states[WINED3D_SAMP_ADDRESS_U]); - desc->address_v = wined3d_texture_gl_address_mode(texture_gl, sampler_states[WINED3D_SAMP_ADDRESS_V]); - desc->address_w = wined3d_texture_gl_address_mode(texture_gl, sampler_states[WINED3D_SAMP_ADDRESS_W]); + desc->address_u = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_U]); + desc->address_v = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_V]); + desc->address_w = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_W]); wined3d_color_from_d3dcolor((struct wined3d_color *)desc->border_color, sampler_states[WINED3D_SAMP_BORDER_COLOR]); if (sampler_states[WINED3D_SAMP_MAG_FILTER] > WINED3D_TEXF_ANISOTROPIC) @@ -3504,20 +3504,20 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC && sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC && sampler_states[WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_ANISOTROPIC) - || (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2)) + || (texture->flags & WINED3D_TEXTURE_COND_NP2)) desc->max_anisotropy = 1; - desc->compare = texture_gl->t.resource.format_caps & WINED3D_FORMAT_CAP_SHADOW; + desc->compare = texture->resource.format_caps & WINED3D_FORMAT_CAP_SHADOW; desc->comparison_func = WINED3D_CMP_LESSEQUAL; desc->srgb_decode = is_srgb_enabled(sampler_states);
- if (!(texture_gl->t.resource.format_caps & WINED3D_FORMAT_CAP_FILTERING)) + if (!(texture->resource.format_caps & WINED3D_FORMAT_CAP_FILTERING)) { desc->mag_filter = WINED3D_TEXF_POINT; desc->min_filter = WINED3D_TEXF_POINT; desc->mip_filter = WINED3D_TEXF_NONE; }
- if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2) + if (texture->flags & WINED3D_TEXTURE_COND_NP2) { desc->mip_filter = WINED3D_TEXF_NONE; if (context_gl->gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) @@ -3557,7 +3557,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state struct wined3d_sampler *sampler; struct wine_rb_entry *entry;
- wined3d_sampler_desc_from_sampler_states(&desc, context_gl, sampler_states, texture_gl); + wined3d_sampler_desc_from_sampler_states(&desc, context_gl, sampler_states, &texture_gl->t);
wined3d_texture_gl_bind(texture_gl, context_gl, srgb);
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/context_gl.c | 2 +- dlls/wined3d/sampler.c | 14 +++----------- dlls/wined3d/state.c | 10 +++++++++- dlls/wined3d/texture.c | 6 +++--- dlls/wined3d/view.c | 2 +- dlls/wined3d/wined3d_gl.h | 1 - 6 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index b81f14a86ee..0c440d12d84 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -5920,7 +5920,7 @@ static void apply_texture_blit_state(const struct wined3d_gl_info *gl_info, stru texture->sampler_desc.address_u = WINED3D_TADDRESS_CLAMP; texture->sampler_desc.address_v = WINED3D_TADDRESS_CLAMP; texture->sampler_desc.srgb_decode = FALSE; - texture->base_level = level; + texture->sampler_desc.mip_base_level = level; }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c index e93ab18f436..cebb7400631 100644 --- a/dlls/wined3d/sampler.c +++ b/dlls/wined3d/sampler.c @@ -307,24 +307,16 @@ static void texture_gl_apply_base_level(struct wined3d_texture_gl *texture_gl, const struct wined3d_sampler_desc *desc, const struct wined3d_gl_info *gl_info) { struct gl_texture *gl_tex; - unsigned int base_level; - - if (texture_gl->t.flags & WINED3D_TEXTURE_COND_NP2) - base_level = 0; - else if (desc->mip_filter == WINED3D_TEXF_NONE) - base_level = texture_gl->t.lod; - else - base_level = min(max(desc->mip_base_level, texture_gl->t.lod), texture_gl->t.level_count - 1);
gl_tex = wined3d_texture_gl_get_gl_texture(texture_gl, texture_gl->t.flags & WINED3D_TEXTURE_IS_SRGB); - if (base_level != gl_tex->base_level) + if (desc->mip_base_level != gl_tex->sampler_desc.mip_base_level) { /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest * mipmap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL * corresponds to GL_TEXTURE_BASE_LEVEL. */ - gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_BASE_LEVEL, base_level); - gl_tex->base_level = base_level; + gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_BASE_LEVEL, desc->mip_base_level); + gl_tex->sampler_desc.mip_base_level = desc->mip_base_level; } }
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 5bccd1acb4a..3e857a587ee 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3499,7 +3499,15 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc desc->lod_bias = lod_bias.f; desc->min_lod = -1000.0f; desc->max_lod = 1000.0f; - desc->mip_base_level = sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL]; + + /* The LOD is already clamped to texture->level_count in wined3d_texture_set_lod(). */ + if (texture->flags & WINED3D_TEXTURE_COND_NP2) + desc->mip_base_level = 0; + else if (desc->mip_filter == WINED3D_TEXF_NONE) + desc->mip_base_level = texture->lod; + else + desc->mip_base_level = min(max(sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL], texture->lod), texture->level_count - 1); + desc->max_anisotropy = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY]; if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC && sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index a7fbde0f529..8fec60f2640 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1319,7 +1319,7 @@ void wined3d_texture_gl_bind(struct wined3d_texture_gl *texture_gl, gl_tex->sampler_desc.srgb_decode = TRUE; else gl_tex->sampler_desc.srgb_decode = srgb; - gl_tex->base_level = 0; + gl_tex->sampler_desc.mip_base_level = 0; wined3d_texture_set_dirty(&texture_gl->t);
wined3d_context_gl_bind_texture(context_gl, target, gl_tex->name); @@ -1757,8 +1757,8 @@ unsigned int CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, unsi wined3d_resource_wait_idle(resource); texture->lod = lod;
- wined3d_texture_gl(texture)->texture_rgb.base_level = ~0u; - wined3d_texture_gl(texture)->texture_srgb.base_level = ~0u; + wined3d_texture_gl(texture)->texture_rgb.sampler_desc.mip_base_level = ~0u; + wined3d_texture_gl(texture)->texture_srgb.sampler_desc.mip_base_level = ~0u; if (resource->bind_count) wined3d_device_context_emit_set_sampler_state(&device->cs->c, texture->sampler, WINED3D_SAMP_MAX_MIP_LEVEL, device->cs->c.state->sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]); diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index aa07625eb8a..5729d5909e6 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -1350,7 +1350,7 @@ void wined3d_shader_resource_view_gl_generate_mipmap(struct wined3d_shader_resou
if (!view_gl->gl_view.name) { - gl_tex->base_level = base_level; + gl_tex->sampler_desc.mip_base_level = base_level; gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_MAX_LEVEL, texture_gl->t.level_count - 1); } diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index f5cec2ccdd7..e0253defc0f 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -943,7 +943,6 @@ static inline void wined3d_context_gl_reference_buffer(struct wined3d_context_gl struct gl_texture { struct wined3d_sampler_desc sampler_desc; - unsigned int base_level; GLuint name; };
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/wined3d/context.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index f9af58936a6..cc583fc8d26 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -353,18 +353,22 @@ static bool is_resource_rtv_bound(const struct wined3d_state *state,
/* Context activation is done by the caller. */ static void context_preload_texture(struct wined3d_context *context, - const struct wined3d_state *state, unsigned int idx) + const struct wined3d_state *state, enum wined3d_shader_type shader_type, unsigned int idx) { struct wined3d_texture *texture; + unsigned int texture_idx = idx;
- if (!(texture = state->textures[idx])) + if (shader_type == WINED3D_SHADER_TYPE_VERTEX) + texture_idx += WINED3D_VERTEX_SAMPLER_OFFSET; + + if (!(texture = state->textures[texture_idx])) return;
if (is_resource_rtv_bound(state, &texture->resource) || (state->fb.depth_stencil && state->fb.depth_stencil->resource == &texture->resource)) context->uses_fbo_attached_resources = 1;
- wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[idx])); + wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[texture_idx])); }
/* Context activation is done by the caller. */ @@ -377,7 +381,7 @@ void context_preload_textures(struct wined3d_context *context, const struct wine for (i = 0; i < WINED3D_MAX_VERTEX_SAMPLERS; ++i) { if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info[i].type) - context_preload_texture(context, state, WINED3D_MAX_FRAGMENT_SAMPLERS + i); + context_preload_texture(context, state, WINED3D_SHADER_TYPE_VERTEX, i); } }
@@ -386,7 +390,7 @@ void context_preload_textures(struct wined3d_context *context, const struct wine for (i = 0; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i) { if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info[i].type) - context_preload_texture(context, state, i); + context_preload_texture(context, state, WINED3D_SHADER_TYPE_PIXEL, i); } } else @@ -396,7 +400,7 @@ void context_preload_textures(struct wined3d_context *context, const struct wine while (ffu_map) { i = wined3d_bit_scan(&ffu_map); - context_preload_texture(context, state, i); + context_preload_texture(context, state, WINED3D_SHADER_TYPE_PIXEL, i); } } }
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3d8/d3d8_private.h | 2 +- dlls/d3d8/surface.c | 2 +- dlls/d3d8/texture.c | 19 +++++++++---------- 3 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h index 5533bf08575..cb79d082654 100644 --- a/dlls/d3d8/d3d8_private.h +++ b/dlls/d3d8/d3d8_private.h @@ -244,7 +244,7 @@ struct d3d8_texture IDirect3DBaseTexture8 IDirect3DBaseTexture8_iface; struct d3d8_resource resource; struct wined3d_texture *wined3d_texture, *draw_texture; - IDirect3DDevice8 *parent_device; + struct d3d8_device *parent_device; struct list rtv_list; };
diff --git a/dlls/d3d8/surface.c b/dlls/d3d8/surface.c index 37d225ede70..db0bdd0a73d 100644 --- a/dlls/d3d8/surface.c +++ b/dlls/d3d8/surface.c @@ -372,7 +372,7 @@ static const struct wined3d_parent_ops d3d8_view_wined3d_parent_ops = struct d3d8_device *d3d8_surface_get_device(const struct d3d8_surface *surface) { IDirect3DDevice8 *device; - device = surface->texture ? surface->texture->parent_device : surface->parent_device; + device = surface->texture ? &surface->texture->parent_device->IDirect3DDevice8_iface : surface->parent_device; return impl_from_IDirect3DDevice8(device); }
diff --git a/dlls/d3d8/texture.c b/dlls/d3d8/texture.c index 28940f6875c..a4f60c8ec2a 100644 --- a/dlls/d3d8/texture.c +++ b/dlls/d3d8/texture.c @@ -30,7 +30,7 @@ static ULONG d3d8_texture_incref(struct d3d8_texture *texture) { struct d3d8_surface *surface;
- IDirect3DDevice8_AddRef(texture->parent_device); + IDirect3DDevice8_AddRef(&texture->parent_device->IDirect3DDevice8_iface); wined3d_mutex_lock(); LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry) { @@ -51,7 +51,7 @@ static ULONG d3d8_texture_decref(struct d3d8_texture *texture)
if (!ref) { - IDirect3DDevice8 *parent_device = texture->parent_device; + IDirect3DDevice8 *parent_device = &texture->parent_device->IDirect3DDevice8_iface; struct d3d8_surface *surface;
wined3d_mutex_lock(); @@ -70,11 +70,10 @@ static ULONG d3d8_texture_decref(struct d3d8_texture *texture)
static void d3d8_texture_preload(struct d3d8_texture *texture) { - struct d3d8_device *device = impl_from_IDirect3DDevice8(texture->parent_device); - wined3d_mutex_lock(); if (texture->draw_texture) - wined3d_device_update_texture(device->wined3d_device, texture->wined3d_texture, texture->draw_texture); + wined3d_device_update_texture(texture->parent_device->wined3d_device, + texture->wined3d_texture, texture->draw_texture); else wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture)); wined3d_mutex_unlock(); @@ -135,7 +134,7 @@ static HRESULT WINAPI d3d8_texture_2d_GetDevice(IDirect3DTexture8 *iface, IDirec
TRACE("iface %p, device %p.\n", iface, device);
- *device = texture->parent_device; + *device = &texture->parent_device->IDirect3DDevice8_iface; IDirect3DDevice8_AddRef(*device);
TRACE("Returning device %p.\n", *device); @@ -436,7 +435,7 @@ static HRESULT WINAPI d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8 *iface,
TRACE("iface %p, device %p.\n", iface, device);
- *device = texture->parent_device; + *device = &texture->parent_device->IDirect3DDevice8_iface; IDirect3DDevice8_AddRef(*device);
TRACE("Returning device %p.\n", *device); @@ -760,7 +759,7 @@ static HRESULT WINAPI d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8 *iface,
TRACE("iface %p, device %p.\n", iface, device);
- *device = texture->parent_device; + *device = &texture->parent_device->IDirect3DDevice8_iface; IDirect3DDevice8_AddRef(*device);
TRACE("Returning device %p.\n", *device); @@ -1103,8 +1102,8 @@ static HRESULT d3d8_texture_init(struct d3d8_texture *texture, struct d3d8_devic } wined3d_mutex_unlock();
- texture->parent_device = &device->IDirect3DDevice8_iface; - IDirect3DDevice8_AddRef(texture->parent_device); + texture->parent_device = device; + IDirect3DDevice8_AddRef(&texture->parent_device->IDirect3DDevice8_iface);
return D3D_OK; }
From: Zebediah Figura zfigura@codeweavers.com
--- dlls/d3d8/texture.c | 9 +- dlls/d3d9/texture.c | 9 +- dlls/ddraw/surface.c | 4 +- dlls/wined3d/context.c | 2 +- dlls/wined3d/cs.c | 40 ++----- dlls/wined3d/sampler.c | 4 - dlls/wined3d/state.c | 115 ++------------------ dlls/wined3d/stateblock.c | 185 +++++++++++++++++++++++++++++---- dlls/wined3d/texture.c | 37 ------- dlls/wined3d/wined3d.spec | 2 +- dlls/wined3d/wined3d_private.h | 18 +--- include/wine/wined3d.h | 3 +- 12 files changed, 199 insertions(+), 229 deletions(-)
diff --git a/dlls/d3d8/texture.c b/dlls/d3d8/texture.c index a4f60c8ec2a..43ccdea0587 100644 --- a/dlls/d3d8/texture.c +++ b/dlls/d3d8/texture.c @@ -226,7 +226,8 @@ static DWORD WINAPI d3d8_texture_2d_SetLOD(IDirect3DTexture8 *iface, DWORD lod) TRACE("iface %p, lod %lu.\n", iface, lod);
wined3d_mutex_lock(); - ret = wined3d_texture_set_lod(d3d8_texture_get_draw_texture(texture), lod); + ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state, + d3d8_texture_get_draw_texture(texture), lod); wined3d_mutex_unlock();
return ret; @@ -527,7 +528,8 @@ static DWORD WINAPI d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8 *iface, DWORD TRACE("iface %p, lod %lu.\n", iface, lod);
wined3d_mutex_lock(); - ret = wined3d_texture_set_lod(d3d8_texture_get_draw_texture(texture), lod); + ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state, + d3d8_texture_get_draw_texture(texture), lod); wined3d_mutex_unlock();
return ret; @@ -851,7 +853,8 @@ static DWORD WINAPI d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8 *iface, DWORD TRACE("iface %p, lod %lu.\n", iface, lod);
wined3d_mutex_lock(); - ret = wined3d_texture_set_lod(d3d8_texture_get_draw_texture(texture), lod); + ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state, + d3d8_texture_get_draw_texture(texture), lod); wined3d_mutex_unlock();
return ret; diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c index 3adfaaee2f3..ecd753ee3d4 100644 --- a/dlls/d3d9/texture.c +++ b/dlls/d3d9/texture.c @@ -283,7 +283,8 @@ static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod) TRACE("iface %p, lod %lu.\n", iface, lod);
wined3d_mutex_lock(); - ret = wined3d_texture_set_lod(d3d9_texture_get_draw_texture(texture), lod); + ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state, + d3d9_texture_get_draw_texture(texture), lod); wined3d_mutex_unlock();
return ret; @@ -657,7 +658,8 @@ static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD TRACE("iface %p, lod %lu.\n", iface, lod);
wined3d_mutex_lock(); - ret = wined3d_texture_set_lod(d3d9_texture_get_draw_texture(texture), lod); + ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state, + d3d9_texture_get_draw_texture(texture), lod); wined3d_mutex_unlock();
return ret; @@ -1057,7 +1059,8 @@ static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD TRACE("iface %p, lod %lu.\n", iface, lod);
wined3d_mutex_lock(); - ret = wined3d_texture_set_lod(d3d9_texture_get_draw_texture(texture), lod); + ret = wined3d_stateblock_set_texture_lod(texture->parent_device->state, + d3d9_texture_get_draw_texture(texture), lod); wined3d_mutex_unlock();
return ret; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index f3c12bfccdb..c535ec7f48d 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -4330,9 +4330,9 @@ static HRESULT WINAPI ddraw_surface7_SetLOD(IDirectDrawSurface7 *iface, DWORD Ma return DDERR_INVALIDOBJECT; }
- hr = wined3d_texture_set_lod(surface->wined3d_texture, MaxLOD); + hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->wined3d_texture, MaxLOD); if (SUCCEEDED(hr) && surface->draw_texture) - hr = wined3d_texture_set_lod(surface->draw_texture, MaxLOD); + hr = wined3d_stateblock_set_texture_lod(surface->ddraw->state, surface->draw_texture, MaxLOD); wined3d_mutex_unlock();
return hr; diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index cc583fc8d26..ce3c18be4f1 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -368,7 +368,7 @@ static void context_preload_texture(struct wined3d_context *context, || (state->fb.depth_stencil && state->fb.depth_stencil->resource == &texture->resource)) context->uses_fbo_attached_resources = 1;
- wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[texture_idx])); + wined3d_texture_load(texture, context, state->sampler[shader_type][idx]->desc.srgb_decode); }
/* Context activation is done by the caller. */ diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index aa011ea7714..3004f308843 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -114,7 +114,6 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_DEPTH_BOUNDS, WINED3D_CS_OP_SET_RENDER_STATE, WINED3D_CS_OP_SET_TEXTURE_STATE, - WINED3D_CS_OP_SET_SAMPLER_STATE, WINED3D_CS_OP_SET_TRANSFORM, WINED3D_CS_OP_SET_CLIP_PLANE, WINED3D_CS_OP_SET_COLOR_KEY, @@ -365,14 +364,6 @@ struct wined3d_cs_set_texture_state DWORD value; };
-struct wined3d_cs_set_sampler_state -{ - enum wined3d_cs_op opcode; - UINT sampler_idx; - enum wined3d_sampler_state state; - DWORD value; -}; - struct wined3d_cs_set_transform { enum wined3d_cs_op opcode; @@ -604,7 +595,6 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_SET_DEPTH_BOUNDS); WINED3D_TO_STR(WINED3D_CS_OP_SET_RENDER_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_TEXTURE_STATE); - WINED3D_TO_STR(WINED3D_CS_OP_SET_SAMPLER_STATE); WINED3D_TO_STR(WINED3D_CS_OP_SET_TRANSFORM); WINED3D_TO_STR(WINED3D_CS_OP_SET_CLIP_PLANE); WINED3D_TO_STR(WINED3D_CS_OP_SET_COLOR_KEY); @@ -1649,8 +1639,15 @@ static void wined3d_cs_exec_set_samplers(struct wined3d_cs *cs, const void *data unsigned int i;
for (i = 0; i < op->count; ++i) + { cs->state.sampler[op->type][op->start_idx + i] = op->samplers[i];
+ if (op->type == WINED3D_SHADER_TYPE_PIXEL && i < WINED3D_MAX_FRAGMENT_SAMPLERS) + device_invalidate_state(cs->c.device, STATE_SAMPLER(i)); + else if (op->type == WINED3D_SHADER_TYPE_VERTEX && i < WINED3D_MAX_VERTEX_SAMPLERS) + device_invalidate_state(cs->c.device, STATE_SAMPLER(WINED3D_VERTEX_SAMPLER_OFFSET + i)); + } + if (op->type != WINED3D_SHADER_TYPE_COMPUTE) device_invalidate_state(cs->c.device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING); else @@ -1845,28 +1842,6 @@ void wined3d_device_context_emit_set_texture_state(struct wined3d_device_context wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
-static void wined3d_cs_exec_set_sampler_state(struct wined3d_cs *cs, const void *data) -{ - const struct wined3d_cs_set_sampler_state *op = data; - - cs->state.sampler_states[op->sampler_idx][op->state] = op->value; - device_invalidate_state(cs->c.device, STATE_SAMPLER(op->sampler_idx)); -} - -void wined3d_device_context_emit_set_sampler_state(struct wined3d_device_context *context, unsigned int sampler_idx, - enum wined3d_sampler_state state, unsigned int value) -{ - struct wined3d_cs_set_sampler_state *op; - - op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); - op->opcode = WINED3D_CS_OP_SET_SAMPLER_STATE; - op->sampler_idx = sampler_idx; - op->state = state; - op->value = value; - - wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); -} - static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_transform *op = data; @@ -2918,7 +2893,6 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_DEPTH_BOUNDS */ wined3d_cs_exec_set_depth_bounds, /* WINED3D_CS_OP_SET_RENDER_STATE */ wined3d_cs_exec_set_render_state, /* WINED3D_CS_OP_SET_TEXTURE_STATE */ wined3d_cs_exec_set_texture_state, - /* WINED3D_CS_OP_SET_SAMPLER_STATE */ wined3d_cs_exec_set_sampler_state, /* WINED3D_CS_OP_SET_TRANSFORM */ wined3d_cs_exec_set_transform, /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c index cebb7400631..afd26a527f9 100644 --- a/dlls/wined3d/sampler.c +++ b/dlls/wined3d/sampler.c @@ -311,10 +311,6 @@ static void texture_gl_apply_base_level(struct wined3d_texture_gl *texture_gl, gl_tex = wined3d_texture_gl_get_gl_texture(texture_gl, texture_gl->t.flags & WINED3D_TEXTURE_IS_SRGB); if (desc->mip_base_level != gl_tex->sampler_desc.mip_base_level) { - /* Note that WINED3D_SAMP_MAX_MIP_LEVEL specifies the largest mipmap - * (default 0), while GL_TEXTURE_MAX_LEVEL specifies the smallest - * mipmap used (default 1000). So WINED3D_SAMP_MAX_MIP_LEVEL - * corresponds to GL_TEXTURE_BASE_LEVEL. */ gl_info->gl_ops.gl.p_glTexParameteri(texture_gl->target, GL_TEXTURE_BASE_LEVEL, desc->mip_base_level); gl_tex->sampler_desc.mip_base_level = desc->mip_base_level; } diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 3e857a587ee..28daf5dacbb 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3451,88 +3451,6 @@ static void sampler_texmatrix(struct wined3d_context *context, const struct wine } }
-static enum wined3d_texture_address wined3d_texture_address_mode(const struct wined3d_texture *texture, - enum wined3d_texture_address t) -{ - if (t < WINED3D_TADDRESS_WRAP || t > WINED3D_TADDRESS_MIRROR_ONCE) - { - FIXME("Unrecognized or unsupported texture address mode %#x.\n", t); - return WINED3D_TADDRESS_WRAP; - } - - /* Cubemaps are always set to clamp, regardless of the sampler state. */ - if ((texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP) - || ((texture->flags & WINED3D_TEXTURE_COND_NP2) && t == WINED3D_TADDRESS_WRAP)) - return WINED3D_TADDRESS_CLAMP; - - return t; -} - -static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc, - const struct wined3d_context_gl *context_gl, const uint32_t *sampler_states, - const struct wined3d_texture *texture) -{ - union - { - float f; - DWORD d; - } lod_bias; - - desc->address_u = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_U]); - desc->address_v = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_V]); - desc->address_w = wined3d_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_W]); - wined3d_color_from_d3dcolor((struct wined3d_color *)desc->border_color, - sampler_states[WINED3D_SAMP_BORDER_COLOR]); - if (sampler_states[WINED3D_SAMP_MAG_FILTER] > WINED3D_TEXF_ANISOTROPIC) - FIXME("Unrecognized or unsupported WINED3D_SAMP_MAG_FILTER %#x.\n", - sampler_states[WINED3D_SAMP_MAG_FILTER]); - desc->mag_filter = min(max(sampler_states[WINED3D_SAMP_MAG_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR); - if (sampler_states[WINED3D_SAMP_MIN_FILTER] > WINED3D_TEXF_ANISOTROPIC) - FIXME("Unrecognized or unsupported WINED3D_SAMP_MIN_FILTER %#x.\n", - sampler_states[WINED3D_SAMP_MIN_FILTER]); - desc->min_filter = min(max(sampler_states[WINED3D_SAMP_MIN_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR); - if (sampler_states[WINED3D_SAMP_MIP_FILTER] > WINED3D_TEXF_ANISOTROPIC) - FIXME("Unrecognized or unsupported WINED3D_SAMP_MIP_FILTER %#x.\n", - sampler_states[WINED3D_SAMP_MIP_FILTER]); - desc->mip_filter = min(max(sampler_states[WINED3D_SAMP_MIP_FILTER], WINED3D_TEXF_NONE), WINED3D_TEXF_LINEAR); - lod_bias.d = sampler_states[WINED3D_SAMP_MIPMAP_LOD_BIAS]; - desc->lod_bias = lod_bias.f; - desc->min_lod = -1000.0f; - desc->max_lod = 1000.0f; - - /* The LOD is already clamped to texture->level_count in wined3d_texture_set_lod(). */ - if (texture->flags & WINED3D_TEXTURE_COND_NP2) - desc->mip_base_level = 0; - else if (desc->mip_filter == WINED3D_TEXF_NONE) - desc->mip_base_level = texture->lod; - else - desc->mip_base_level = min(max(sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL], texture->lod), texture->level_count - 1); - - desc->max_anisotropy = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY]; - if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC - && sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC - && sampler_states[WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_ANISOTROPIC) - || (texture->flags & WINED3D_TEXTURE_COND_NP2)) - desc->max_anisotropy = 1; - desc->compare = texture->resource.format_caps & WINED3D_FORMAT_CAP_SHADOW; - desc->comparison_func = WINED3D_CMP_LESSEQUAL; - desc->srgb_decode = is_srgb_enabled(sampler_states); - - if (!(texture->resource.format_caps & WINED3D_FORMAT_CAP_FILTERING)) - { - desc->mag_filter = WINED3D_TEXF_POINT; - desc->min_filter = WINED3D_TEXF_POINT; - desc->mip_filter = WINED3D_TEXF_NONE; - } - - if (texture->flags & WINED3D_TEXTURE_COND_NP2) - { - desc->mip_filter = WINED3D_TEXF_NONE; - if (context_gl->gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) - desc->min_filter = WINED3D_TEXF_POINT; - } -} - /* Enabling and disabling texture dimensions is done by texture stage state / * pixel shader setup, this function only has to bind textures and set the per * texture states. */ @@ -3558,36 +3476,19 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state if (state->textures[sampler_idx]) { struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(state->textures[sampler_idx]); - const uint32_t *sampler_states = state->sampler_states[sampler_idx]; - struct wined3d_device *device = context->device; - BOOL srgb = is_srgb_enabled(sampler_states); - struct wined3d_sampler_desc desc; + enum wined3d_shader_type shader_type = WINED3D_SHADER_TYPE_PIXEL; + unsigned int bind_idx = sampler_idx; struct wined3d_sampler *sampler; - struct wine_rb_entry *entry; - - wined3d_sampler_desc_from_sampler_states(&desc, context_gl, sampler_states, &texture_gl->t); - - wined3d_texture_gl_bind(texture_gl, context_gl, srgb);
- if ((entry = wine_rb_get(&device->samplers, &desc))) + if (sampler_idx >= WINED3D_VERTEX_SAMPLER_OFFSET) { - sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry); - } - else - { - if (FAILED(wined3d_sampler_create(device, &desc, NULL, &wined3d_null_parent_ops, &sampler))) - { - ERR("Failed to create sampler.\n"); - return; - } - if (wine_rb_put(&device->samplers, &desc, &sampler->entry) == -1) - { - ERR("Failed to insert sampler.\n"); - wined3d_sampler_decref(sampler); - return; - } + bind_idx -= WINED3D_VERTEX_SAMPLER_OFFSET; + shader_type = WINED3D_SHADER_TYPE_VERTEX; }
+ sampler = state->sampler[shader_type][bind_idx]; + + wined3d_texture_gl_bind(texture_gl, context_gl, sampler->desc.srgb_decode); wined3d_sampler_gl_bind(wined3d_sampler_gl(sampler), mapped_stage, texture_gl, context_gl);
/* Trigger shader constant reloading (for NP2 texcoord fixup) */ diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 6ce17311595..6d440f94a94 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1997,8 +1997,6 @@ static void state_init_default(struct wined3d_state *state, const struct wined3d init_default_texture_state(i, state->texture_states[i]); }
- init_default_sampler_states(state->sampler_states); - state->blend_factor.r = 1.0f; state->blend_factor.g = 1.0f; state->blend_factor.b = 1.0f; @@ -2529,22 +2527,6 @@ static void wined3d_device_set_texture_stage_state(struct wined3d_device *device wined3d_device_context_emit_set_texture_state(&device->cs->c, stage, state, value); }
-static void wined3d_device_set_sampler_state(struct wined3d_device *device, - unsigned int sampler_idx, enum wined3d_sampler_state state, unsigned int value) -{ - TRACE("device %p, sampler_idx %u, state %s, value %#x.\n", - device, sampler_idx, debug_d3dsamplerstate(state), value); - - if (value == device->cs->c.state->sampler_states[sampler_idx][state]) - { - TRACE("Application is setting the old value over, nothing to do.\n"); - return; - } - - device->cs->c.state->sampler_states[sampler_idx][state] = value; - wined3d_device_context_emit_set_sampler_state(&device->cs->c, sampler_idx, state, value); -} - static void wined3d_device_set_texture(struct wined3d_device *device, unsigned int stage, struct wined3d_texture *texture) { @@ -2607,6 +2589,90 @@ static void wined3d_device_set_transform(struct wined3d_device *device, wined3d_device_context_emit_set_transform(&device->cs->c, state, matrix); }
+static enum wined3d_texture_address get_texture_address_mode(const struct wined3d_texture *texture, + enum wined3d_texture_address t) +{ + if (t < WINED3D_TADDRESS_WRAP || t > WINED3D_TADDRESS_MIRROR_ONCE) + { + FIXME("Unrecognized or unsupported texture address mode %#x.\n", t); + return WINED3D_TADDRESS_WRAP; + } + + /* Cubemaps are always set to clamp, regardless of the sampler state. */ + if ((texture->resource.usage & WINED3DUSAGE_LEGACY_CUBEMAP) + || ((texture->flags & WINED3D_TEXTURE_COND_NP2) && t == WINED3D_TADDRESS_WRAP)) + return WINED3D_TADDRESS_CLAMP; + + return t; +} + +static void sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc, + const uint32_t *sampler_states, const struct wined3d_texture *texture) +{ + const struct wined3d_d3d_info *d3d_info = &texture->resource.device->adapter->d3d_info; + + desc->address_u = get_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_U]); + desc->address_v = get_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_V]); + desc->address_w = get_texture_address_mode(texture, sampler_states[WINED3D_SAMP_ADDRESS_W]); + wined3d_color_from_d3dcolor((struct wined3d_color *)desc->border_color, + sampler_states[WINED3D_SAMP_BORDER_COLOR]); + if (sampler_states[WINED3D_SAMP_MAG_FILTER] > WINED3D_TEXF_ANISOTROPIC) + FIXME("Unrecognized or unsupported WINED3D_SAMP_MAG_FILTER %#x.\n", + sampler_states[WINED3D_SAMP_MAG_FILTER]); + desc->mag_filter = min(max(sampler_states[WINED3D_SAMP_MAG_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR); + if (sampler_states[WINED3D_SAMP_MIN_FILTER] > WINED3D_TEXF_ANISOTROPIC) + FIXME("Unrecognized or unsupported WINED3D_SAMP_MIN_FILTER %#x.\n", + sampler_states[WINED3D_SAMP_MIN_FILTER]); + desc->min_filter = min(max(sampler_states[WINED3D_SAMP_MIN_FILTER], WINED3D_TEXF_POINT), WINED3D_TEXF_LINEAR); + if (sampler_states[WINED3D_SAMP_MIP_FILTER] > WINED3D_TEXF_ANISOTROPIC) + FIXME("Unrecognized or unsupported WINED3D_SAMP_MIP_FILTER %#x.\n", + sampler_states[WINED3D_SAMP_MIP_FILTER]); + desc->mip_filter = min(max(sampler_states[WINED3D_SAMP_MIP_FILTER], WINED3D_TEXF_NONE), WINED3D_TEXF_LINEAR); + desc->lod_bias = int_to_float(sampler_states[WINED3D_SAMP_MIPMAP_LOD_BIAS]); + desc->min_lod = -1000.0f; + desc->max_lod = 1000.0f; + + /* The LOD is already clamped to texture->level_count in wined3d_stateblock_set_texture_lod(). */ + if (texture->flags & WINED3D_TEXTURE_COND_NP2) + desc->mip_base_level = 0; + else if (desc->mip_filter == WINED3D_TEXF_NONE) + desc->mip_base_level = texture->lod; + else + desc->mip_base_level = min(max(sampler_states[WINED3D_SAMP_MAX_MIP_LEVEL], texture->lod), texture->level_count - 1); + + desc->max_anisotropy = sampler_states[WINED3D_SAMP_MAX_ANISOTROPY]; + if ((sampler_states[WINED3D_SAMP_MAG_FILTER] != WINED3D_TEXF_ANISOTROPIC + && sampler_states[WINED3D_SAMP_MIN_FILTER] != WINED3D_TEXF_ANISOTROPIC + && sampler_states[WINED3D_SAMP_MIP_FILTER] != WINED3D_TEXF_ANISOTROPIC) + || (texture->flags & WINED3D_TEXTURE_COND_NP2)) + desc->max_anisotropy = 1; + desc->compare = texture->resource.format_caps & WINED3D_FORMAT_CAP_SHADOW; + desc->comparison_func = WINED3D_CMP_LESSEQUAL; + + /* Only use the LSB of the WINED3D_SAMP_SRGB_TEXTURE value. This matches + * the behaviour of the AMD Windows driver. + * + * Might & Magic: Heroes VI - Shades of Darkness sets + * WINED3D_SAMP_SRGB_TEXTURE to a large value that looks like a + * pointer—presumably by accident—and expects sRGB decoding to be + * disabled. */ + desc->srgb_decode = sampler_states[WINED3D_SAMP_SRGB_TEXTURE] & 0x1; + + if (!(texture->resource.format_caps & WINED3D_FORMAT_CAP_FILTERING)) + { + desc->mag_filter = WINED3D_TEXF_POINT; + desc->min_filter = WINED3D_TEXF_POINT; + desc->mip_filter = WINED3D_TEXF_NONE; + } + + if (texture->flags & WINED3D_TEXTURE_COND_NP2) + { + desc->mip_filter = WINED3D_TEXF_NONE; + if (d3d_info->normalized_texrect) + desc->min_filter = WINED3D_TEXF_POINT; + } +} + void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_stateblock *stateblock) { @@ -3159,11 +3225,43 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
for (i = 0; i < ARRAY_SIZE(changed->samplerState); ++i) { - map = changed->samplerState[i]; - while (map) + enum wined3d_shader_type shader_type = WINED3D_SHADER_TYPE_PIXEL; + struct wined3d_sampler_desc desc; + struct wined3d_texture *texture; + struct wined3d_sampler *sampler; + unsigned int bind_index = i; + struct wine_rb_entry *entry; + + if (!changed->samplerState[i] && !(changed->textures & (1u << i))) + continue; + + if (!(texture = state->textures[i])) + continue; + + memset(&desc, 0, sizeof(desc)); + sampler_desc_from_sampler_states(&desc, state->sampler_states[i], texture); + + if (i >= WINED3D_VERTEX_SAMPLER_OFFSET) { - j = wined3d_bit_scan(&map); - wined3d_device_set_sampler_state(device, i, j, state->sampler_states[i][j]); + shader_type = WINED3D_SHADER_TYPE_VERTEX; + bind_index -= WINED3D_VERTEX_SAMPLER_OFFSET; + } + + if ((entry = wine_rb_get(&device->samplers, &desc))) + { + sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry); + + wined3d_device_context_set_samplers(context, shader_type, bind_index, 1, &sampler); + } + else if (SUCCEEDED(wined3d_sampler_create(device, &desc, NULL, &wined3d_null_parent_ops, &sampler))) + { + wined3d_device_context_set_samplers(context, shader_type, bind_index, 1, &sampler); + + if (wine_rb_put(&device->samplers, &desc, &sampler->entry) == -1) + { + ERR("Failed to insert sampler.\n"); + wined3d_sampler_decref(sampler); + } } }
@@ -3220,3 +3318,46 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
TRACE("Applied stateblock %p.\n", stateblock); } + +unsigned int CDECL wined3d_stateblock_set_texture_lod(struct wined3d_stateblock *stateblock, + struct wined3d_texture *texture, unsigned int lod) +{ + struct wined3d_resource *resource; + unsigned int old = texture->lod; + + TRACE("texture %p, lod %u.\n", texture, lod); + + /* The d3d9:texture test shows that SetLOD is ignored on non-managed + * textures. The call always returns 0, and GetLOD always returns 0. */ + resource = &texture->resource; + if (!(resource->usage & WINED3DUSAGE_MANAGED)) + { + TRACE("Ignoring LOD on texture with resource access %s.\n", + wined3d_debug_resource_access(resource->access)); + return 0; + } + + if (lod >= texture->level_count) + lod = texture->level_count - 1; + + if (texture->lod != lod) + { + texture->lod = lod; + + for (unsigned int i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i) + { + /* Mark the texture as changed. The next time the appplication + * draws from this texture, wined3d_device_apply_stateblock() will + * recompute the texture LOD. + * + * We only need to do this for the primary stateblock. + * If a recording stateblock uses a texture whose LOD is changed, + * that texture will be invalidated on the primary stateblock + * anyway when the recording stateblock is applied. */ + if (stateblock->stateblock_state.textures[i] == texture) + stateblock->changed.textures |= (1u << i); + } + } + + return old; +} diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 8fec60f2640..a89fad97ed8 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -1730,43 +1730,6 @@ void CDECL wined3d_texture_get_pitch(const struct wined3d_texture *texture, width, height, row_pitch, slice_pitch); }
-unsigned int CDECL wined3d_texture_set_lod(struct wined3d_texture *texture, unsigned int lod) -{ - struct wined3d_resource *resource; - unsigned int old = texture->lod; - - TRACE("texture %p, lod %u.\n", texture, lod); - - /* The d3d9:texture test shows that SetLOD is ignored on non-managed - * textures. The call always returns 0, and GetLOD always returns 0. */ - resource = &texture->resource; - if (!(resource->usage & WINED3DUSAGE_MANAGED)) - { - TRACE("Ignoring LOD on texture with resource access %s.\n", - wined3d_debug_resource_access(resource->access)); - return 0; - } - - if (lod >= texture->level_count) - lod = texture->level_count - 1; - - if (texture->lod != lod) - { - struct wined3d_device *device = resource->device; - - wined3d_resource_wait_idle(resource); - texture->lod = lod; - - wined3d_texture_gl(texture)->texture_rgb.sampler_desc.mip_base_level = ~0u; - wined3d_texture_gl(texture)->texture_srgb.sampler_desc.mip_base_level = ~0u; - if (resource->bind_count) - wined3d_device_context_emit_set_sampler_state(&device->cs->c, texture->sampler, WINED3D_SAMP_MAX_MIP_LEVEL, - device->cs->c.state->sampler_states[texture->sampler][WINED3D_SAMP_MAX_MIP_LEVEL]); - } - - return old; -} - unsigned int CDECL wined3d_texture_get_lod(const struct wined3d_texture *texture) { TRACE("texture %p, returning %u.\n", texture, texture->lod); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 7ab1d8c5804..2eaf83160c1 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -258,6 +258,7 @@ @ cdecl wined3d_stateblock_set_stream_source(ptr long ptr long long) @ cdecl wined3d_stateblock_set_stream_source_freq(ptr long long) @ cdecl wined3d_stateblock_set_texture(ptr long ptr) +@ cdecl wined3d_stateblock_set_texture_lod(ptr ptr long) @ cdecl wined3d_stateblock_set_texture_stage_state(ptr long long long) @ cdecl wined3d_stateblock_set_transform(ptr long ptr) @ cdecl wined3d_stateblock_set_vertex_declaration(ptr ptr) @@ -314,7 +315,6 @@ @ cdecl wined3d_texture_incref(ptr) @ cdecl wined3d_texture_release_dc(ptr long ptr) @ 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) @ cdecl wined3d_texture_set_sub_resource_parent(ptr long ptr ptr) @ cdecl wined3d_texture_update_desc(ptr long ptr long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e0841ed7595..e9ec73536a9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2884,7 +2884,6 @@ struct wined3d_state struct wined3d_unordered_access_view *unordered_access_view[WINED3D_PIPELINE_COUNT][MAX_UNORDERED_ACCESS_VIEWS];
struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS]; - uint32_t sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1]; uint32_t texture_states[WINED3D_MAX_FFP_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1]; @@ -3718,8 +3717,6 @@ void wined3d_device_context_emit_set_rendertarget_views(struct wined3d_device_co unsigned int count, struct wined3d_rendertarget_view *const *views) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_samplers(struct wined3d_device_context *context, enum wined3d_shader_type type, unsigned int start_idx, unsigned int count, struct wined3d_sampler *const *samplers) DECLSPEC_HIDDEN; -void wined3d_device_context_emit_set_sampler_state(struct wined3d_device_context *context, unsigned int sampler_idx, - enum wined3d_sampler_state state, unsigned int value) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_scissor_rects(struct wined3d_device_context *context, unsigned int rect_count, const RECT *rects) DECLSPEC_HIDDEN; void wined3d_device_context_emit_set_shader(struct wined3d_device_context *context, enum wined3d_shader_type type, @@ -4569,6 +4566,9 @@ uint32_t wined3d_format_pack(const struct wined3d_format *format, const struct w BOOL wined3d_formats_are_srgb_variants(enum wined3d_format_id format1, enum wined3d_format_id format2) DECLSPEC_HIDDEN;
+void wined3d_stateblock_invalidate_texture_lod(struct wined3d_stateblock *stateblock, + struct wined3d_texture *texture) DECLSPEC_HIDDEN; + BOOL wined3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size) DECLSPEC_HIDDEN;
static inline BOOL wined3d_format_is_typeless(const struct wined3d_format *format) @@ -4606,18 +4606,6 @@ static inline void context_apply_state(struct wined3d_context *context, state_table[rep].apply(context, state, rep); }
-static inline BOOL is_srgb_enabled(const uint32_t *sampler_states) -{ - /* Only use the LSB of the WINED3D_SAMP_SRGB_TEXTURE value. This matches - * the behaviour of the AMD Windows driver. - * - * Might & Magic: Heroes VI - Shades of Darkness sets - * WINED3D_SAMP_SRGB_TEXTURE to a large value that looks like a - * pointer—presumably by accident—and expects sRGB decoding to be - * disabled. */ - return sampler_states[WINED3D_SAMP_SRGB_TEXTURE] & 0x1; -} - static inline BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context, const struct wined3d_texture *texture) { diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index ad90c0d6b36..210f9d99b6d 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2797,6 +2797,8 @@ HRESULT __cdecl wined3d_stateblock_set_stream_source(struct wined3d_stateblock * UINT stream_idx, struct wined3d_buffer *buffer, UINT offset, UINT stride); HRESULT __cdecl wined3d_stateblock_set_stream_source_freq(struct wined3d_stateblock *stateblock, UINT stream_idx, UINT divider); void __cdecl wined3d_stateblock_set_texture(struct wined3d_stateblock *stateblock, UINT stage, struct wined3d_texture *texture); +unsigned int __cdecl wined3d_stateblock_set_texture_lod(struct wined3d_stateblock *stateblock, + struct wined3d_texture *texture, unsigned int lod); void __cdecl wined3d_stateblock_set_texture_stage_state(struct wined3d_stateblock *stateblock, UINT stage, enum wined3d_texture_stage_state state, unsigned int value); void __cdecl wined3d_stateblock_set_transform(struct wined3d_stateblock *stateblock, @@ -2887,7 +2889,6 @@ 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_color_key(struct wined3d_texture *texture, uint32_t flags, const struct wined3d_color_key *color_key); -unsigned int __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, unsigned int lod); HRESULT __cdecl wined3d_texture_set_overlay_position(struct wined3d_texture *texture, unsigned int sub_resource_idx, LONG x, LONG y); void __cdecl wined3d_texture_set_sub_resource_parent(struct wined3d_texture *texture,
I've pushed a new version that instead turns wined3d_texture_set_lod() into wined3d_stateblock_set_texture_lod(), which I think avoids the layering violation. Hopefully that's tasteful enough.
1/6 is removed and instead we check for normalized_texrect in the d3d_info.
This merge request was approved by Jan Sikorski.