wined3d: Set d3d 1-9 textures in the state as SRVs.

The idea is to reuse the existing code to handle SRVs, which simplifies the GL
code and essentially allows the Vulkan code to work "for free" (which is to say,
by writing this patch, rather than by adding support for flat textures to the
Vulkan renderer.)

This is a large patch; it consists the following parts:

* Create identity SRVs for d3d 1-9 textures. Store those in
  state->shader_resource_view instead of in state->texture.

* (Re)use wined3d_context_gl_bind_shader_resources() instead of state_sampler()
  to bind them.

  - Introduce code to that function to handle FFP textures.

  - Bind the sRGB texture if necessary in wined3d_shader_resource_view_gl_bind.

* (Re)use context_gl_load_shader_resources() instead of
  context_preload_textures() to load them.

  - Introduce code to that function to handle FFP textures.

  - Load the sRGB texture if necessary.

  - Port the SRV/RTV feedback loop check from context_preload_textures().

* Invalidate STATE_GRAPHICS_SHADER_RESOURCE_BINDING in places that now need to
  account for texture binding being guarded by that state instead of
  STATE_SAMPLER.

  Transitioning the remaining users of STATE_SAMPLER to
  STATE_GRAPHICS_SHADER_RESOURCE_BINDING, and removing STATE_SAMPLER, is left
  for future patches.
This commit is contained in:
Zebediah Figura 2023-07-14 17:44:02 -05:00 committed by Alexandre Julliard
parent ff30b54791
commit 5b60f4649b
12 changed files with 177 additions and 232 deletions

View file

@ -490,11 +490,7 @@ static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info
while (active)
{
i = wined3d_bit_scan(&active);
if (!(tex = state->textures[i]))
{
ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n");
continue;
}
tex = texture_from_resource(state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][i]->resource);
idx = fixup->super.idx[i];
tex_dim = &np2fixup_constants[(idx >> 1) * 4];

View file

@ -333,74 +333,3 @@ void context_update_stream_info(struct wined3d_context *context, const struct wi
context->use_immediate_mode_draw = TRUE;
}
}
static bool is_resource_rtv_bound(const struct wined3d_state *state,
const struct wined3d_resource *resource)
{
unsigned int i;
if (!resource->rtv_bind_count_device)
return false;
for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
{
if (state->fb.render_targets[i] && state->fb.render_targets[i]->resource == resource)
return true;
}
return false;
}
/* Context activation is done by the caller. */
static void context_preload_texture(struct wined3d_context *context,
const struct wined3d_state *state, enum wined3d_shader_type shader_type, unsigned int idx)
{
struct wined3d_texture *texture;
unsigned int texture_idx = 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, state->sampler[shader_type][idx]->desc.srgb_decode);
}
/* Context activation is done by the caller. */
void context_preload_textures(struct wined3d_context *context, const struct wined3d_state *state)
{
unsigned int i;
if (use_vs(state))
{
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_SHADER_TYPE_VERTEX, i);
}
}
if (use_ps(state))
{
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, WINED3D_SHADER_TYPE_PIXEL, i);
}
}
else
{
uint32_t ffu_map = context->fixed_function_usage_map;
while (ffu_map)
{
i = wined3d_bit_scan(&ffu_map);
context_preload_texture(context, state, WINED3D_SHADER_TYPE_PIXEL, i);
}
}
}

View file

@ -3808,6 +3808,7 @@ static void wined3d_context_gl_map_fixed_function_samplers(struct wined3d_contex
{
wined3d_context_gl_map_stage(context_gl, i, i);
context_invalidate_state(&context_gl->c, STATE_SAMPLER(i));
context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
context_invalidate_texture_stage(&context_gl->c, i);
}
}
@ -3823,6 +3824,7 @@ static void wined3d_context_gl_map_fixed_function_samplers(struct wined3d_contex
{
wined3d_context_gl_map_stage(context_gl, i, tex);
context_invalidate_state(&context_gl->c, STATE_SAMPLER(i));
context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
context_invalidate_texture_stage(&context_gl->c, i);
}
@ -3843,6 +3845,7 @@ static void wined3d_context_gl_map_psamplers(struct wined3d_context_gl *context_
{
wined3d_context_gl_map_stage(context_gl, i, i);
context_invalidate_state(&context_gl->c, STATE_SAMPLER(i));
context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
if (i < d3d_info->ffp_fragment_caps.max_blend_stages)
context_invalidate_texture_stage(&context_gl->c, i);
}
@ -3905,6 +3908,7 @@ static void wined3d_context_gl_map_vsamplers(struct wined3d_context_gl *context_
{
wined3d_context_gl_map_stage(context_gl, vsampler_idx, start);
context_invalidate_state(&context_gl->c, STATE_SAMPLER(vsampler_idx));
context_invalidate_state(&context_gl->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
}
--start;
@ -3976,7 +3980,37 @@ static void wined3d_context_gl_bind_shader_resources(struct wined3d_context_gl *
struct wined3d_sampler *sampler;
if (!(shader = state->shader[shader_type]))
{
if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
{
uint32_t ffu_map = context_gl->c.fixed_function_usage_map;
while (ffu_map)
{
i = wined3d_bit_scan(&ffu_map);
bind_idx = context_gl->tex_unit_map[i];
view = state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][i];
sampler = state->sampler[WINED3D_SHADER_TYPE_PIXEL][i];
if (view)
{
wined3d_shader_resource_view_gl_bind(wined3d_shader_resource_view_gl(view),
bind_idx, wined3d_sampler_gl(sampler), context_gl);
}
else
{
WARN("No resource view bound at index %u.\n", i);
wined3d_context_gl_active_texture(context_gl, gl_info, bind_idx);
wined3d_context_gl_bind_texture(context_gl, GL_NONE, 0);
if (gl_info->supported[ARB_SAMPLER_OBJECTS])
GL_EXTCALL(glBindSampler(bind_idx, 0));
}
}
}
return;
}
tex_unit_map = wined3d_context_gl_get_tex_unit_mapping(context_gl,
&shader->reg_maps.shader_version, &base, &count);
@ -4067,12 +4101,32 @@ static void wined3d_context_gl_bind_unordered_access_views(struct wined3d_contex
checkGLcall("Bind unordered access views");
}
static bool is_resource_rtv_bound(const struct wined3d_state *state, const struct wined3d_resource *resource)
{
unsigned int i;
if (state->fb.depth_stencil && state->fb.depth_stencil->resource == resource)
return true;
if (!resource->rtv_bind_count_device)
return false;
for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
{
if (state->fb.render_targets[i] && state->fb.render_targets[i]->resource == resource)
return true;
}
return false;
}
static void context_gl_load_shader_resources(struct wined3d_context_gl *context_gl,
const struct wined3d_state *state, unsigned int shader_mask)
{
struct wined3d_shader_sampler_map_entry *entry;
struct wined3d_shader_resource_view_gl *srv_gl;
struct wined3d_shader_resource_view *view;
struct wined3d_sampler *sampler;
struct wined3d_shader *shader;
struct wined3d_buffer *buffer;
unsigned int i, j;
@ -4083,7 +4137,26 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
continue;
if (!(shader = state->shader[i]))
{
if (i == WINED3D_SHADER_TYPE_PIXEL)
{
uint32_t ffu_map = context_gl->c.fixed_function_usage_map;
while (ffu_map)
{
i = wined3d_bit_scan(&ffu_map);
view = state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][i];
sampler = state->sampler[WINED3D_SHADER_TYPE_PIXEL][i];
if (view)
wined3d_texture_load(texture_from_resource(view->resource),
&context_gl->c, sampler->desc.srgb_decode);
}
}
continue;
}
for (j = 0; j < WINED3D_MAX_CBS; ++j)
{
@ -4104,6 +4177,9 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
if (!(view = state->shader_resource_view[i][entry->resource_idx]))
continue;
if (is_resource_rtv_bound(state, view->resource))
context_gl->c.uses_fbo_attached_resources = 1;
if (view->resource->type == WINED3D_RTYPE_BUFFER)
{
buffer = buffer_from_resource(view->resource);
@ -4116,7 +4192,13 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
}
else
{
wined3d_texture_load(texture_from_resource(view->resource), &context_gl->c, FALSE);
BOOL srgb = TRUE;
if (entry->sampler_idx != WINED3D_SAMPLER_DEFAULT
&& (sampler = state->sampler[i][entry->sampler_idx]))
srgb = sampler->desc.srgb_decode;
wined3d_texture_load(texture_from_resource(view->resource), &context_gl->c, srgb);
}
}
}
@ -4213,7 +4295,6 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
* result in changes to the current FBO, due to using e.g. FBO blits for
* updating a resource location. */
wined3d_context_gl_update_tex_unit_map(context_gl, state);
context_preload_textures(context, state);
context_gl_load_shader_resources(context_gl, state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE));
context_gl_load_unordered_access_resources(context_gl, state->shader[WINED3D_SHADER_TYPE_PIXEL],
state->unordered_access_view[WINED3D_PIPELINE_GRAPHICS]);

View file

@ -270,8 +270,9 @@ struct wined3d_cs_set_constant_buffers
struct wined3d_cs_set_texture
{
enum wined3d_cs_op opcode;
UINT stage;
struct wined3d_texture *texture;
enum wined3d_shader_type shader_type;
unsigned int bind_index;
struct wined3d_shader_resource_view *view;
};
struct wined3d_cs_set_color_key
@ -1036,11 +1037,6 @@ static void reference_graphics_pipeline_resources(struct wined3d_device_context
if (state->stream_output[i].buffer)
wined3d_device_context_reference_resource(context, &state->stream_output[i].buffer->resource);
}
for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
{
if (state->textures[i])
wined3d_device_context_reference_resource(context, &state->textures[i]->resource);
}
for (i = 0; i < d3d_info->limits.max_rt_count; ++i)
{
if (state->fb.render_targets[i])
@ -1454,8 +1450,8 @@ void wined3d_device_context_emit_set_constant_buffers(struct wined3d_device_cont
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
}
static bool texture_binding_might_invalidate_ps(struct wined3d_texture *texture,
struct wined3d_texture *prev, const struct wined3d_d3d_info *d3d_info)
static bool texture_binding_might_invalidate_ps(struct wined3d_shader_resource_view *view,
struct wined3d_shader_resource_view *prev, const struct wined3d_d3d_info *d3d_info)
{
unsigned int old_usage, new_usage, old_caps, new_caps;
const struct wined3d_format *old_format, *new_format;
@ -1464,16 +1460,16 @@ static bool texture_binding_might_invalidate_ps(struct wined3d_texture *texture,
return true;
/* 1.x pixel shaders need to be recompiled based on the resource type. */
old_usage = prev->resource.usage;
new_usage = texture->resource.usage;
if (texture->resource.type != prev->resource.type
old_usage = prev->resource->usage;
new_usage = view->resource->usage;
if (view->resource->type != prev->resource->type
|| ((old_usage & WINED3DUSAGE_LEGACY_CUBEMAP) != (new_usage & WINED3DUSAGE_LEGACY_CUBEMAP)))
return true;
old_format = prev->resource.format;
new_format = texture->resource.format;
old_caps = prev->resource.format_caps;
new_caps = texture->resource.format_caps;
old_format = prev->resource->format;
new_format = view->resource->format;
old_caps = prev->resource->format_caps;
new_caps = view->resource->format_caps;
if ((old_caps & WINED3D_FORMAT_CAP_SHADOW) != (new_caps & WINED3D_FORMAT_CAP_SHADOW))
return true;
@ -1490,47 +1486,61 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
{
const struct wined3d_d3d_info *d3d_info = &cs->c.device->adapter->d3d_info;
const struct wined3d_cs_set_texture *op = data;
struct wined3d_texture *prev;
struct wined3d_shader_resource_view *prev;
BOOL old_use_color_key = FALSE, new_use_color_key = FALSE;
prev = cs->state.textures[op->stage];
cs->state.textures[op->stage] = op->texture;
prev = cs->state.shader_resource_view[op->shader_type][op->bind_index];
cs->state.shader_resource_view[op->shader_type][op->bind_index] = op->view;
if (op->texture)
if (op->view)
{
++op->texture->resource.bind_count;
struct wined3d_texture *texture = texture_from_resource(op->view->resource);
if (texture_binding_might_invalidate_ps(op->texture, prev, d3d_info))
device_invalidate_state(cs->c.device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
++op->view->resource->bind_count;
if (!prev && op->stage < d3d_info->ffp_fragment_caps.max_blend_stages)
if (op->shader_type == WINED3D_SHADER_TYPE_PIXEL)
{
/* The source arguments for color and alpha ops have different
* meanings when a NULL texture is bound, so the COLOR_OP and
* ALPHA_OP have to be dirtified. */
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
}
if (texture_binding_might_invalidate_ps(op->view, prev, d3d_info))
device_invalidate_state(cs->c.device, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL));
if (!op->stage && op->texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
new_use_color_key = TRUE;
if (!prev && op->bind_index < d3d_info->ffp_fragment_caps.max_blend_stages)
{
/* The source arguments for color and alpha ops have different
* meanings when a NULL texture is bound, so the COLOR_OP and
* ALPHA_OP have to be dirtified. */
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->bind_index, WINED3D_TSS_COLOR_OP));
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->bind_index, WINED3D_TSS_ALPHA_OP));
}
if (!op->bind_index && texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
new_use_color_key = TRUE;
}
}
if (prev)
{
--prev->resource.bind_count;
struct wined3d_texture *prev_texture = texture_from_resource(prev->resource);
if (!op->texture && op->stage < d3d_info->ffp_fragment_caps.max_blend_stages)
--prev->resource->bind_count;
if (op->shader_type == WINED3D_SHADER_TYPE_PIXEL)
{
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_COLOR_OP));
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->stage, WINED3D_TSS_ALPHA_OP));
}
if (!op->view && op->bind_index < d3d_info->ffp_fragment_caps.max_blend_stages)
{
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->bind_index, WINED3D_TSS_COLOR_OP));
device_invalidate_state(cs->c.device, STATE_TEXTURESTAGE(op->bind_index, WINED3D_TSS_ALPHA_OP));
}
if (!op->stage && prev->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
old_use_color_key = TRUE;
if (!op->bind_index && prev_texture->async.color_key_flags & WINED3D_CKEY_SRC_BLT)
old_use_color_key = TRUE;
}
}
device_invalidate_state(cs->c.device, STATE_SAMPLER(op->stage));
if (op->shader_type == WINED3D_SHADER_TYPE_VERTEX)
device_invalidate_state(cs->c.device, STATE_SAMPLER(WINED3D_VERTEX_SAMPLER_OFFSET + op->bind_index));
else
device_invalidate_state(cs->c.device, STATE_SAMPLER(op->bind_index));
device_invalidate_state(cs->c.device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
if (new_use_color_key != old_use_color_key)
device_invalidate_state(cs->c.device, STATE_RENDER(WINED3D_RS_COLORKEYENABLE));
@ -1539,15 +1549,16 @@ static void wined3d_cs_exec_set_texture(struct wined3d_cs *cs, const void *data)
device_invalidate_state(cs->c.device, STATE_COLOR_KEY);
}
void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage,
struct wined3d_texture *texture)
void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context,
enum wined3d_shader_type shader_type, unsigned int bind_index, struct wined3d_shader_resource_view *view)
{
struct wined3d_cs_set_texture *op;
op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
op->opcode = WINED3D_CS_OP_SET_TEXTURE;
op->stage = stage;
op->texture = texture;
op->shader_type = shader_type;
op->bind_index = bind_index;
op->view = view;
wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT);
}

View file

@ -5108,19 +5108,6 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso
switch (type)
{
case WINED3D_RTYPE_TEXTURE_1D:
case WINED3D_RTYPE_TEXTURE_2D:
case WINED3D_RTYPE_TEXTURE_3D:
for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i)
{
if (&state->textures[i]->resource == resource)
{
ERR("Texture resource %p is still in use, stage %u.\n", resource, i);
state->textures[i] = NULL;
}
}
break;
case WINED3D_RTYPE_BUFFER:
for (i = 0; i < WINED3D_MAX_STREAMS; ++i)
{

View file

@ -1299,15 +1299,10 @@ static void shader_glsl_load_np2fixup_constants(const struct glsl_ps_program *ps
for (i = 0; fixup; fixup >>= 1, ++i)
{
const struct wined3d_texture *tex = state->textures[i];
unsigned char idx = ps->np2_fixup_info->idx[i];
const struct wined3d_texture *tex;
if (!tex)
{
ERR("Nonexistent texture is flagged for NP2 texcoord fixup.\n");
continue;
}
tex = texture_from_resource(state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][i]->resource);
np2fixup_constants[idx].sx = tex->pow2_matrix[0];
np2fixup_constants[idx].sy = tex->pow2_matrix[5];
}

View file

@ -2778,6 +2778,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
BOOL position_transformed, struct ps_compile_args *args, const struct wined3d_context *context)
{
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
struct wined3d_shader_resource_view *view;
struct wined3d_texture *texture;
unsigned int i;
@ -2859,8 +2860,9 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
/* Treat unbound textures as 2D. The dummy texture will provide
* the proper sample value. The tex_types bitmap defaults to
* 2D because of the memset. */
if (!(texture = state->textures[i]))
if (!(view = state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][i]))
continue;
texture = texture_from_resource(view->resource);
switch (wined3d_texture_gl(texture)->target)
{
@ -2901,8 +2903,9 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
break;
}
if ((texture = state->textures[i]))
if ((view = state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][i]))
{
texture = texture_from_resource(view->resource);
/* Star Wars: The Old Republic uses mismatched samplers for rendering water. */
if (texture->resource.type == WINED3D_RTYPE_TEXTURE_2D
&& resource_type == WINED3D_SHADER_RESOURCE_TEXTURE_3D
@ -2931,11 +2934,13 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
if (!shader->reg_maps.resource_info[i].type)
continue;
if (!(texture = state->textures[i]))
if (!(view = state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][i]))
{
args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
continue;
}
texture = texture_from_resource(view->resource);
if (can_use_texture_swizzle(d3d_info, texture->resource.format))
args->color_fixup[i] = COLOR_FIXUP_IDENTITY;
else

View file

@ -3453,59 +3453,8 @@ static void sampler_texmatrix(struct wined3d_context *context, const struct wine
}
}
/* 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. */
static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
unsigned int sampler_idx = state_id - STATE_SAMPLER(0);
unsigned int mapped_stage = context_gl->tex_unit_map[sampler_idx];
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
TRACE("Sampler %u.\n", sampler_idx);
if (mapped_stage == WINED3D_UNMAPPED_STAGE)
{
TRACE("No sampler mapped to stage %u. Returning.\n", sampler_idx);
return;
}
if (mapped_stage >= gl_info->limits.graphics_samplers)
return;
wined3d_context_gl_active_texture(context_gl, gl_info, mapped_stage);
if (state->textures[sampler_idx])
{
struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(state->textures[sampler_idx]);
enum wined3d_shader_type shader_type = WINED3D_SHADER_TYPE_PIXEL;
unsigned int bind_idx = sampler_idx;
struct wined3d_sampler *sampler;
if (sampler_idx >= WINED3D_VERTEX_SAMPLER_OFFSET)
{
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) */
if (!(texture_gl->t.flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
context->constant_update_mask |= WINED3D_SHADER_CONST_PS_NP2_FIXUP;
}
else
{
wined3d_context_gl_bind_texture(context_gl, GL_NONE, 0);
if (gl_info->supported[ARB_SAMPLER_OBJECTS])
{
GL_EXTCALL(glBindSampler(mapped_stage, 0));
checkGLcall("glBindSampler");
}
}
}
void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -3519,11 +3468,7 @@ void apply_pixelshader(struct wined3d_context *context, const struct wined3d_sta
/* Former draw without a pixel shader, some samplers may be
* disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
* make sure to enable them. */
for (i = 0; i < WINED3D_MAX_FRAGMENT_SAMPLERS; ++i)
{
if (!isStateDirty(context, STATE_SAMPLER(i)))
sampler(context, state, STATE_SAMPLER(i));
}
context->update_shader_resource_bindings = 1;
context->last_was_pshader = TRUE;
}
else

View file

@ -431,7 +431,6 @@ void state_unbind_resources(struct wined3d_state *state)
struct wined3d_blend_state *blend_state;
struct wined3d_rendertarget_view *rtv;
struct wined3d_sampler *sampler;
struct wined3d_texture *texture;
struct wined3d_buffer *buffer;
struct wined3d_shader *shader;
unsigned int i, j;
@ -442,15 +441,6 @@ void state_unbind_resources(struct wined3d_state *state)
wined3d_vertex_declaration_decref(decl);
}
for (i = 0; i < WINED3D_MAX_COMBINED_SAMPLERS; ++i)
{
if ((texture = state->textures[i]))
{
state->textures[i] = NULL;
wined3d_texture_decref(texture);
}
}
for (i = 0; i < WINED3D_MAX_STREAM_OUTPUT_BUFFERS; ++i)
{
if ((buffer = state->stream_output[i].buffer))
@ -2530,28 +2520,37 @@ static void wined3d_device_set_texture_stage_state(struct wined3d_device *device
static void wined3d_device_set_texture(struct wined3d_device *device,
unsigned int stage, struct wined3d_texture *texture)
{
enum wined3d_shader_type shader_type = WINED3D_SHADER_TYPE_PIXEL;
struct wined3d_shader_resource_view *srv = NULL, *prev;
struct wined3d_state *state = device->cs->c.state;
struct wined3d_texture *prev;
TRACE("device %p, stage %u, texture %p.\n", device, stage, texture);
prev = state->textures[stage];
if (stage >= WINED3D_VERTEX_SAMPLER_OFFSET)
{
shader_type = WINED3D_SHADER_TYPE_VERTEX;
stage -= WINED3D_VERTEX_SAMPLER_OFFSET;
}
if (texture && !(srv = wined3d_texture_acquire_identity_srv(texture)))
return;
prev = state->shader_resource_view[shader_type][stage];
TRACE("Previous texture %p.\n", prev);
if (texture == prev)
if (srv == prev)
{
TRACE("App is setting the same texture again, nothing to do.\n");
return;
}
TRACE("Setting new texture to %p.\n", texture);
state->textures[stage] = texture;
state->shader_resource_view[shader_type][stage] = srv;
if (texture)
wined3d_texture_incref(texture);
wined3d_device_context_emit_set_texture(&device->cs->c, stage, texture);
if (srv)
wined3d_shader_resource_view_incref(srv);
wined3d_device_context_emit_set_texture(&device->cs->c, shader_type, stage, srv);
if (prev)
wined3d_texture_decref(prev);
wined3d_shader_resource_view_decref(prev);
return;
}

View file

@ -3515,7 +3515,6 @@ static void texture_resource_unload(struct wined3d_resource *resource)
{
struct wined3d_texture *texture = texture_from_resource(resource);
struct wined3d_device *device = resource->device;
const struct wined3d_state *state = &device->cs->state;
unsigned int location = resource->map_binding;
struct wined3d_context *context;
unsigned int sub_count, i;
@ -3561,11 +3560,8 @@ static void texture_resource_unload(struct wined3d_resource *resource)
wined3d_texture_force_reload(texture);
for (i = 0; i < ARRAY_SIZE(state->textures); ++i)
{
if (state->textures[i] == texture)
device_invalidate_state(device, STATE_SAMPLER(i));
}
if (texture->resource.bind_count && (texture->resource.bind_flags & WINED3D_BIND_SHADER_RESOURCE))
device_invalidate_state(device, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
wined3d_texture_set_dirty(texture);

View file

@ -1288,7 +1288,7 @@ void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl
}
texture_gl = wined3d_texture_gl(wined3d_texture_from_resource(view_gl->v.resource));
wined3d_texture_gl_bind(texture_gl, context_gl, FALSE);
wined3d_texture_gl_bind(texture_gl, context_gl, sampler_gl->s.desc.srgb_decode);
wined3d_sampler_gl_bind(sampler_gl, unit, texture_gl, context_gl);
/* Trigger shader constant reloading (for NP2 texcoord fixup) */

View file

@ -1976,7 +1976,6 @@ struct wined3d_context
void wined3d_context_cleanup(struct wined3d_context *context);
void wined3d_context_init(struct wined3d_context *context, struct wined3d_swapchain *swapchain);
void context_preload_textures(struct wined3d_context *context, const struct wined3d_state *state);
void context_update_stream_info(struct wined3d_context *context, const struct wined3d_state *state);
HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d,
@ -2884,7 +2883,6 @@ struct wined3d_state
struct wined3d_shader_resource_view *shader_resource_view[WINED3D_SHADER_TYPE_COUNT][MAX_SHADER_RESOURCE_VIEWS];
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 texture_states[WINED3D_MAX_FFP_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1];
@ -3730,8 +3728,9 @@ void wined3d_device_context_emit_set_stream_outputs(struct wined3d_device_contex
const struct wined3d_stream_output outputs[WINED3D_MAX_STREAM_OUTPUT_BUFFERS]);
void wined3d_device_context_emit_set_stream_sources(struct wined3d_device_context *context,
unsigned int start_idx, unsigned int count, const struct wined3d_stream_state *streams);
void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context, unsigned int stage,
struct wined3d_texture *texture);
void wined3d_device_context_emit_set_texture(struct wined3d_device_context *context,
enum wined3d_shader_type shader_type, unsigned int bind_index,
struct wined3d_shader_resource_view *view);
void wined3d_device_context_emit_set_texture_state(struct wined3d_device_context *context, unsigned int stage,
enum wined3d_texture_stage_state state, unsigned int value);
void wined3d_device_context_emit_set_transform(struct wined3d_device_context *context,
@ -3941,8 +3940,10 @@ void wined3d_shader_resource_view_destroy(struct wined3d_shader_resource_view *v
static inline struct wined3d_texture *wined3d_state_get_ffp_texture(const struct wined3d_state *state, unsigned int idx)
{
struct wined3d_shader_resource_view *view = state->shader_resource_view[WINED3D_SHADER_TYPE_PIXEL][idx];
assert(idx <= WINED3D_MAX_FFP_TEXTURES);
return state->textures[idx];
return view ? texture_from_resource(view->resource) : NULL;
}
struct wined3d_unordered_access_view