Commit 0e39cd65 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

wined3d: Translate sampler states to sampler objects in wined3d_device_apply_stateblock().

parent be13e91c
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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. */
......
......@@ -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,
......
......@@ -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;
}
......
......@@ -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) */
......
......@@ -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;
}
......@@ -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);
......
......@@ -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)
......
......@@ -2885,7 +2885,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];
......@@ -3719,8 +3718,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,
......@@ -4570,6 +4567,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)
......@@ -4607,18 +4607,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)
{
......
......@@ -2798,6 +2798,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,
......@@ -2888,7 +2890,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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment