Commit e4d2d785 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Pass a wined3d_state pointer to state handlers.

Instead of an entire stateblock. This is mainly useful is we ever want to call state handlers on state not stored in a stateblock.
parent 9375a87c
......@@ -796,17 +796,17 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
return ret;
}
static void set_tex_op_atifs(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void set_tex_op_atifs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_device *device = context->swapchain->device;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct wined3d_device *device = stateblock->device;
const struct atifs_ffp_desc *desc;
struct ffp_frag_settings settings;
struct atifs_private_data *priv = device->fragment_priv;
DWORD mapped_stage;
unsigned int i;
gen_ffp_frag_op(device, &stateblock->state, &settings, TRUE);
gen_ffp_frag_op(device, state, &settings, TRUE);
desc = (const struct atifs_ffp_desc *)find_ffp_frag_shader(&priv->fragment_shaders, &settings);
if(!desc) {
struct atifs_ffp_desc *new_desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_desc));
......@@ -839,33 +839,33 @@ static void set_tex_op_atifs(DWORD state, struct wined3d_stateblock *stateblock,
{
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
checkGLcall("glActiveTextureARB");
texture_activate_dimensions(stateblock->state.textures[i], gl_info);
texture_activate_dimensions(state->textures[i], gl_info);
}
}
GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
}
static void state_texfactor_atifs(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void state_texfactor_atifs(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_TEXTUREFACTOR], col);
D3DCOLORTOGLFLOAT4(state->render_states[WINED3DRS_TEXTUREFACTOR], col);
GL_EXTCALL(glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col));
checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_TFACTOR, col)");
}
static void set_bumpmat(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void set_bumpmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
const struct wined3d_gl_info *gl_info = context->gl_info;
float mat[2][2];
mat[0][0] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT00]);
mat[1][0] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT01]);
mat[0][1] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT10]);
mat[1][1] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT11]);
mat[0][0] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT00]);
mat[1][0] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT01]);
mat[0][1] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT10]);
mat[1][1] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT11]);
/* GL_ATI_fragment_shader allows only constants from 0.0 to 1.0, but the bumpmat
* constants can be in any range. While they should stay between [-1.0 and 1.0] because
* Shader Model 1.x pixel shaders are clamped to that range negative values are used occasionally,
......@@ -881,42 +881,43 @@ static void set_bumpmat(DWORD state, struct wined3d_stateblock *stateblock, stru
checkGLcall("glSetFragmentShaderConstantATI(ATI_FFP_CONST_BUMPMAT(stage), mat)");
}
static void textransform(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void textransform(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (!isStateDirty(context, STATE_PIXELSHADER))
set_tex_op_atifs(state, stateblock, context);
set_tex_op_atifs(context, state, state_id);
}
static void atifs_apply_pixelshader(DWORD state_id,
struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void atifs_apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_state *state = &stateblock->state;
struct wined3d_device *device = stateblock->device;
const struct wined3d_device *device = context->swapchain->device;
BOOL use_vshader = use_vs(state);
context->last_was_pshader = use_ps(state);
/* The ATIFS code does not support pixel shaders currently, but we have to provide a state handler
* to call shader_select to select a vertex shader if one is applied because the vertex shader state
* may defer calling the shader backend if the pshader state is dirty.
/* The ATIFS code does not support pixel shaders currently, but we have to
* provide a state handler to call shader_select to select a vertex shader
* if one is applied because the vertex shader state may defer calling the
* shader backend if the pshader state is dirty.
*
* In theory the application should not be able to mark the pixel shader dirty because it cannot
* create a shader, and thus has no way to set the state to something != NULL. However, a different
* pipeline part may link a different state to its pixelshader handler, thus a pshader state exists
* and can be dirtified. Also the pshader is always dirtified at startup, and blitting disables all
* shaders and dirtifies all shader states. If atifs can deal with this it keeps the rest of the code
* simpler.
*/
if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
* In theory the application should not be able to mark the pixel shader
* dirty because it cannot create a shader, and thus has no way to set the
* state to something != NULL. However, a different pipeline part may link
* a different state to its pixelshader handler, thus a pshader state
* exists and can be dirtified. Also the pshader is always dirtified at
* startup, and blitting disables all shaders and dirtifies all shader
* states. If atifs can deal with this it keeps the rest of the code
* simpler. */
if (!isStateDirty(context, device->StateTable[STATE_VSHADER].representative))
{
device->shader_backend->shader_select(context, FALSE, use_vshader);
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader)
stateblock_apply_state(STATE_VERTEXSHADERCONSTANT, stateblock, context);
context_apply_state(context, state, STATE_VERTEXSHADERCONSTANT);
}
}
static void atifs_srgbwriteenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void atifs_srgbwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (stateblock->state.render_states[WINED3DRS_SRGBWRITEENABLE])
if (state->render_states[WINED3DRS_SRGBWRITEENABLE])
WARN("sRGB writes are not supported by this fragment pipe.\n");
}
......
......@@ -2177,10 +2177,9 @@ static DWORD find_draw_buffers_mask(const struct wined3d_context *context, const
}
/* GL locking and context activation are done by the caller */
void context_state_fb(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
void context_state_fb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_state *state = &stateblock->state;
struct wined3d_device *device = stateblock->device;
const struct wined3d_device *device = context->swapchain->device;
const struct wined3d_fb_state *fb = state->fb;
DWORD rt_mask = find_draw_buffers_mask(context, device);
......@@ -2206,10 +2205,10 @@ void context_state_fb(DWORD state_id, struct wined3d_stateblock *stateblock, str
}
/* GL locking and context activation are done by the caller */
void context_state_drawbuf(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
void context_state_drawbuf(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_device *device = context->swapchain->device;
DWORD rt_mask;
struct wined3d_device *device = stateblock->device;
if (isStateDirty(context, STATE_FRAMEBUFFER)) return;
......@@ -2224,9 +2223,9 @@ void context_state_drawbuf(DWORD state, struct wined3d_stateblock *stateblock, s
/* Context activation is done by the caller. */
BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_device *device)
{
struct wined3d_stateblock *stateblock = device->stateBlock;
const struct wined3d_state *state = &device->stateBlock->state;
const struct StateEntry *state_table = device->StateTable;
const struct wined3d_fb_state *fb = stateblock->state.fb;
const struct wined3d_fb_state *fb = state->fb;
unsigned int i;
if (!context_validate_rt_config(context->gl_info->limits.buffers,
......@@ -2253,7 +2252,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
context->isStateDirty[idx] &= ~(1 << shift);
state_table[rep].apply(rep, stateblock, context);
state_table[rep].apply(context, state, rep);
}
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
......
......@@ -457,13 +457,13 @@ void set_tex_op_nvrc(const struct wined3d_gl_info *gl_info, const struct wined3d
}
static void nvrc_colorop(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void nvrc_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
DWORD mapped_stage = stateblock->device->texUnitMap[stage];
const struct wined3d_device *device = context->swapchain->device;
BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
DWORD mapped_stage = device->texUnitMap[stage];
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_state *state = &stateblock->state;
TRACE("Setting color op for stage %u.\n", stage);
......@@ -567,11 +567,10 @@ static void nvrc_colorop(DWORD state_id, struct wined3d_stateblock *stateblock,
}
}
static void nvts_texdim(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void nvts_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD sampler = state_id - STATE_SAMPLER(0);
DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
const struct wined3d_state *state = &stateblock->state;
DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
/* No need to enable / disable anything here for unused samplers. The tex_colorop
* handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
......@@ -584,10 +583,10 @@ static void nvts_texdim(DWORD state_id, struct wined3d_stateblock *stateblock, s
nvts_activate_dimensions(state, sampler, context);
}
static void nvts_bumpenvmat(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void nvts_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
DWORD mapped_stage = stateblock->device->texUnitMap[stage + 1];
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
DWORD mapped_stage = context->swapchain->device->texUnitMap[stage + 1];
const struct wined3d_gl_info *gl_info = context->gl_info;
float mat[2][2];
......@@ -602,22 +601,22 @@ static void nvts_bumpenvmat(DWORD state, struct wined3d_stateblock *stateblock,
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage))");
/* We can't just pass a pointer to the stateblock to GL due to the
/* We can't just pass a pointer to the state to GL due to the
* different matrix format (column major vs row major). */
mat[0][0] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT00]);
mat[1][0] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT01]);
mat[0][1] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT10]);
mat[1][1] = *((float *)&stateblock->state.texture_states[stage][WINED3DTSS_BUMPENVMAT11]);
mat[0][0] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT00]);
mat[1][0] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT01]);
mat[0][1] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT10]);
mat[1][1] = *((float *)&state->texture_states[stage][WINED3DTSS_BUMPENVMAT11]);
glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, (float *)mat);
checkGLcall("glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat)");
}
}
static void nvrc_texfactor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
static void nvrc_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_TEXTUREFACTOR], col);
D3DCOLORTOGLFLOAT4(state->render_states[WINED3DRS_TEXTUREFACTOR], col);
GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3126,20 +3126,22 @@ void texture_activate_dimensions(const struct wined3d_texture *texture, const st
}
/* GL locking is done by the caller (state handler) */
void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD sampler = state - STATE_SAMPLER(0);
DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
DWORD sampler = state_id - STATE_SAMPLER(0);
DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
/* No need to enable / disable anything here for unused samplers. The tex_colorop
* handler takes care. Also no action is needed with pixel shaders, or if tex_colorop
* will take care of this business
*/
if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures) return;
if (sampler >= stateblock->state.lowest_disabled_stage) return;
if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) return;
/* No need to enable / disable anything here for unused samplers. The
* tex_colorop handler takes care. Also no action is needed with pixel
* shaders, or if tex_colorop will take care of this business. */
if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
return;
if (sampler >= state->lowest_disabled_stage)
return;
if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP)))
return;
texture_activate_dimensions(stateblock->state.textures[sampler], context->gl_info);
texture_activate_dimensions(state->textures[sampler], context->gl_info);
}
void *wined3d_rb_alloc(size_t size)
......
......@@ -1136,7 +1136,7 @@ struct wined3d_fb_state
struct wined3d_surface *depth_stencil;
};
typedef void (*APPLYSTATEFUNC)(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *ctx);
typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id);
struct StateEntry
{
......@@ -1252,10 +1252,10 @@ void context_resource_unloaded(const struct wined3d_device *device,
BOOL context_set_current(struct wined3d_context *ctx) DECLSPEC_HIDDEN;
void context_set_draw_buffer(struct wined3d_context *context, GLenum buffer) DECLSPEC_HIDDEN;
void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
void context_state_drawbuf(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_state_fb(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_state_drawbuf(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void context_state_fb(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void context_surface_update(struct wined3d_context *context, const struct wined3d_surface *surface) DECLSPEC_HIDDEN;
/*****************************************************************************
......@@ -2314,14 +2314,6 @@ struct wined3d_stateblock
void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
void stateblock_init_default_state(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN;
static inline void stateblock_apply_state(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context)
{
const struct StateEntry *statetable = stateblock->device->StateTable;
DWORD rep = statetable[state].representative;
statetable[rep].apply(rep, stateblock, context);
}
/* Direct3D terminology with little modifications. We do not have an issued state
* because only the driver knows about it, but we have a created state because d3d
* allows GetData on a created issue, but opengl doesn't
......@@ -2499,20 +2491,20 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords,
BOOL transformed, enum wined3d_format_id coordtype, BOOL ffp_can_disable_proj) DECLSPEC_HIDDEN;
void texture_activate_dimensions(const struct wined3d_texture *texture,
const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
void sampler_texdim(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void tex_alphaop(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void apply_pixelshader(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void state_fogcolor(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void state_fogdensity(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void state_fogstartend(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void state_fog_fragpart(DWORD state, struct wined3d_stateblock *stateblock,
struct wined3d_context *context) DECLSPEC_HIDDEN;
void sampler_texdim(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void tex_alphaop(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void apply_pixelshader(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void state_fogcolor(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void state_fogdensity(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void state_fogstartend(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
void state_fog_fragpart(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
BOOL getColorBits(const struct wined3d_format *format,
BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) DECLSPEC_HIDDEN;
......@@ -2834,6 +2826,14 @@ static inline BOOL use_ps(const struct wined3d_state *state)
return !!state->pixel_shader;
}
static inline void context_apply_state(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
const struct StateEntry *statetable = context->swapchain->device->StateTable;
DWORD rep = statetable[state_id].representative;
statetable[rep].apply(context, state, rep);
}
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
......
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