Module: wine Branch: master Commit: 20010235ad07b7be1f68da4c9b36e3ed00d0ca14 URL: http://source.winehq.org/git/wine.git/?a=commit;h=20010235ad07b7be1f68da4c9b...
Author: Matteo Bruni mbruni@codeweavers.com Date: Thu Sep 30 12:16:16 2010 +0200
wined3d: Keep track of texture transformation states in compiled pixel shaders.
---
dlls/wined3d/arb_program_shader.c | 26 +++++++++++++------------- dlls/wined3d/glsl_shader.c | 18 ++++++++++-------- dlls/wined3d/shader.c | 13 ++++++++++++- dlls/wined3d/wined3d_private.h | 9 +++++++-- 4 files changed, 42 insertions(+), 24 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 9be5cd2..dec7a10 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1884,8 +1884,7 @@ static void pshader_hw_texkill(const struct wined3d_shader_instruction *ins)
static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) { - IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device; + struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; const struct wined3d_shader_dst_param *dst = &ins->dst[0]; DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major, ins->ctx->reg_maps->shader_version.minor); @@ -1927,8 +1926,8 @@ static void pshader_hw_tex(const struct wined3d_shader_instruction *ins) { DWORD flags = 0; if (reg_sampler_code < MAX_TEXTURES) - flags = deviceImpl->stateBlock->state.texture_states[reg_sampler_code][WINED3DTSS_TEXTURETRANSFORMFLAGS]; - if (flags & WINED3DTTFF_PROJECTED) + flags = priv->cur_ps_args->super.tex_transform >> reg_sampler_code * WINED3D_PSARGS_TEXTRANSFORM_SHIFT; + if (flags & WINED3D_PSARGS_PROJECTED) myflags |= TEX_PROJ; } else if (shader_version < WINED3D_SHADER_VERSION(2,0)) @@ -1977,9 +1976,7 @@ static void pshader_hw_texcoord(const struct wined3d_shader_instruction *ins) static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins) { struct wined3d_shader_buffer *buffer = ins->ctx->buffer; - IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device; - DWORD flags; + DWORD flags = 0;
DWORD reg1 = ins->dst[0].reg.idx; char dst_str[50]; @@ -1991,8 +1988,12 @@ static void pshader_hw_texreg2ar(const struct wined3d_shader_instruction *ins) /* Move .x first in case src_str is "TA" */ shader_addline(buffer, "MOV TA.y, %s.x;\n", src_str); shader_addline(buffer, "MOV TA.x, %s.w;\n", src_str); - flags = reg1 < MAX_TEXTURES ? deviceImpl->stateBlock->state.texture_states[reg1][WINED3DTSS_TEXTURETRANSFORMFLAGS] : 0; - shader_hw_sample(ins, reg1, dst_str, "TA", flags & WINED3DTTFF_PROJECTED ? TEX_PROJ : 0, NULL, NULL); + if (reg1 < MAX_TEXTURES) + { + struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; + flags = priv->cur_ps_args->super.tex_transform >> reg1 * WINED3D_PSARGS_TEXTRANSFORM_SHIFT; + } + shader_hw_sample(ins, reg1, dst_str, "TA", flags & WINED3D_PSARGS_PROJECTED ? TEX_PROJ : 0, NULL, NULL); }
static void pshader_hw_texreg2gb(const struct wined3d_shader_instruction *ins) @@ -2025,8 +2026,7 @@ static void pshader_hw_texreg2rgb(const struct wined3d_shader_instruction *ins)
static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) { - IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)shader->baseShader.device; + struct shader_arb_ctx_priv *priv = ins->ctx->backend_data; const struct wined3d_shader_dst_param *dst = &ins->dst[0]; struct wined3d_shader_buffer *buffer = ins->ctx->buffer; char reg_coord[40], dst_reg[50], src_reg[50]; @@ -2058,8 +2058,8 @@ static void pshader_hw_texbem(const struct wined3d_shader_instruction *ins) /* with projective textures, texbem only divides the static texture coord, not the displacement, * so we can't let the GL handle this. */ - if (device->stateBlock->state.texture_states[reg_dest_code][WINED3DTSS_TEXTURETRANSFORMFLAGS] - & WINED3DTTFF_PROJECTED) + if ((priv->cur_ps_args->super.tex_transform >> reg_dest_code * WINED3D_PSARGS_TEXTRANSFORM_SHIFT) + & WINED3D_PSARGS_PROJECTED) { shader_addline(buffer, "RCP TB.w, %s.w;\n", reg_coord); shader_addline(buffer, "MUL TB.xy, %s, TB.w;\n", reg_coord); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 28a3350..b71a17e 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -3031,13 +3031,15 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
if (shader_version < WINED3D_SHADER_VERSION(1,4)) { - DWORD flags = deviceImpl->stateBlock->state.texture_states[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; + const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; + DWORD flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT) + & WINED3D_PSARGS_TEXTRANSFORM_MASK; WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
/* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */ - if (flags & WINED3DTTFF_PROJECTED && sampler_type != WINED3DSTT_CUBE) { + if (flags & WINED3D_PSARGS_PROJECTED && sampler_type != WINED3DSTT_CUBE) { sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED; - switch (flags & ~WINED3DTTFF_PROJECTED) { + switch (flags & ~WINED3D_PSARGS_PROJECTED) { case WINED3DTTFF_COUNT1: FIXME("WINED3DTTFF_PROJECTED with WINED3DTTFF_COUNT1?\n"); break; case WINED3DTTFF_COUNT2: mask = WINED3DSP_WRITEMASK_1; break; case WINED3DTTFF_COUNT3: mask = WINED3DSP_WRITEMASK_2; break; @@ -3467,8 +3469,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in */ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) { - IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader; - IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *)shader->baseShader.device; + const struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data; glsl_sample_function_t sample_function; glsl_src_param_t coord_param; DWORD sampler_idx; @@ -3477,7 +3478,8 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) char coord_mask[6];
sampler_idx = ins->dst[0].reg.idx; - flags = deviceImpl->stateBlock->state.texture_states[sampler_idx][WINED3DTSS_TEXTURETRANSFORMFLAGS]; + flags = (priv->cur_ps_args->tex_transform >> sampler_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT) + & WINED3D_PSARGS_TEXTRANSFORM_MASK;
/* Dependent read, not valid with conditional NP2 */ shader_glsl_get_sample_function(ins->ctx, sampler_idx, 0, &sample_function); @@ -3488,10 +3490,10 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins) /* with projective textures, texbem only divides the static texture coord, not the displacement, * so we can't let the GL handle this. */ - if (flags & WINED3DTTFF_PROJECTED) { + if (flags & WINED3D_PSARGS_PROJECTED) { DWORD div_mask=0; char coord_div_mask[3]; - switch (flags & ~WINED3DTTFF_PROJECTED) { + switch (flags & ~WINED3D_PSARGS_PROJECTED) { case WINED3DTTFF_COUNT1: FIXME("WINED3DTTFF_PROJECTED with WINED3DTTFF_COUNT1?\n"); break; case WINED3DTTFF_COUNT2: div_mask = WINED3DSP_WRITEMASK_1; break; case WINED3DTTFF_COUNT3: div_mask = WINED3DSP_WRITEMASK_2; break; diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 3bbf5ed..323f010 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -2081,7 +2081,18 @@ void find_ps_compile_args(const struct wined3d_state *state, if(rt->resource.format->Flags & WINED3DFMT_FLAG_SRGB_WRITE) args->srgb_correction = 1; }
- args->np2_fixup = 0; + if (shader->baseShader.reg_maps.shader_version.major == 1 + && shader->baseShader.reg_maps.shader_version.minor <= 3) + { + for (i = 0; i < 4; ++i) + { + DWORD flags = state->texture_states[i][WINED3DTSS_TEXTURETRANSFORMFLAGS]; + DWORD tex_transform = flags & ~WINED3DTTFF_PROJECTED; + if (flags & WINED3DTTFF_PROJECTED) + tex_transform |= WINED3D_PSARGS_PROJECTED; + args->tex_transform |= tex_transform << i * WINED3D_PSARGS_TEXTRANSFORM_SHIFT; + } + }
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 33bb437..dc5d144 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -677,13 +677,18 @@ enum fogmode { /* Stateblock dependent parameters which have to be hardcoded * into the shader code */ + +#define WINED3D_PSARGS_PROJECTED (1 << 3) +#define WINED3D_PSARGS_TEXTRANSFORM_SHIFT 4 +#define WINED3D_PSARGS_TEXTRANSFORM_MASK 0xf + struct ps_compile_args { struct color_fixup_desc color_fixup[MAX_FRAGMENT_SAMPLERS]; enum vertexprocessing_mode vp_mode; enum fogmode fog; - /* Projected textures(ps 1.0-1.3) */ + WORD tex_transform; /* ps 1.0-1.3, 4 textures */ /* Texture types(2D, Cube, 3D) in ps 1.x */ - BOOL srgb_correction; + WORD srgb_correction; WORD np2_fixup; /* Bitmap for NP2 texcoord fixups (16 samplers max currently). D3D9 has a limit of 16 samplers and the fixup is superfluous