Module: wine Branch: master Commit: 19cb4594e333f88f008cc4def74101a809bf7966 URL: http://source.winehq.org/git/wine.git/?a=commit;h=19cb4594e333f88f008cc4def7...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Wed May 27 10:24:50 2009 +0200
wined3d: Use a separate structure for vertex shader attributes.
In D3D10 shaders input/output semantics are strings rather than predefined types. Unfortunately, the code in vshader_get_input() can be performance critical, depending on application behaviour. Since vshader_get_input() is only relevant for d3d9 shaders anyway, just store the usage and usage_idx for these shaders.
---
dlls/wined3d/baseshader.c | 15 ++++++++++++--- dlls/wined3d/pixelshader.c | 5 +++-- dlls/wined3d/vertexshader.c | 18 ++++++------------ dlls/wined3d/wined3d_private.h | 13 ++++++++++--- 4 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index ab3354f..91c656c 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -345,8 +345,9 @@ static unsigned int get_instr_extra_regcount(enum WINED3D_SHADER_INSTRUCTION_HAN * as an address register. */
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe, - struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in, - struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size) + struct shader_reg_maps *reg_maps, struct wined3d_shader_attribute *attributes, + struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out, + const DWORD *byte_code, DWORD constf_size) { IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; void *fe_data = This->baseShader.frontend_data; @@ -411,7 +412,15 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3 * Pshader: mark 3.0 input registers used, save token */ case WINED3DSPR_INPUT: reg_maps->input_registers |= 1 << semantic.reg.reg.idx; - semantics_in[semantic.reg.reg.idx] = semantic; + if (shader_version.type == WINED3D_SHADER_TYPE_VERTEX) + { + attributes[semantic.reg.reg.idx].usage = semantic.usage; + attributes[semantic.reg.reg.idx].usage_idx = semantic.usage_idx; + } + else + { + semantics_in[semantic.reg.reg.idx] = semantic; + } break;
/* Vshader: mark 3.0 output registers used, save token */ diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 26904a8..9ebe77b 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -242,8 +242,9 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i list_init(&This->baseShader.constantsI);
/* Second pass: figure out which registers are used, what the semantics are, etc.. */ - hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction, - GL_LIMITS(pshader_constantsF)); + hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, + reg_maps, NULL, This->semantics_in, NULL, + pFunction, GL_LIMITS(pshader_constantsF)); if (FAILED(hr)) return hr;
pshader_set_limits(This); diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 9b8fcfd..aceaa97 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -115,14 +115,8 @@ static void vshader_set_input( unsigned int regnum, BYTE usage, BYTE usage_idx) {
- This->semantics_in[regnum].usage = usage; - This->semantics_in[regnum].usage_idx = usage_idx; - This->semantics_in[regnum].reg.reg.type = WINED3DSPR_INPUT; - This->semantics_in[regnum].reg.reg.idx = regnum; - This->semantics_in[regnum].reg.write_mask = WINED3DSP_WRITEMASK_ALL; - This->semantics_in[regnum].reg.modifiers = 0; - This->semantics_in[regnum].reg.shift = 0; - This->semantics_in[regnum].reg.reg.rel_addr = NULL; + This->attributes[regnum].usage = usage; + This->attributes[regnum].usage_idx = usage_idx; }
static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2) { @@ -144,8 +138,8 @@ BOOL vshader_get_input(IWineD3DVertexShader* iface, BYTE usage_req, BYTE usage_i { if (!(map & 1)) continue;
- if (match_usage(This->semantics_in[i].usage, - This->semantics_in[i].usage_idx, usage_req, usage_idx_req)) + if (match_usage(This->attributes[i].usage, + This->attributes[i].usage_idx, usage_req, usage_idx_req)) { *regnum = i; return TRUE; @@ -283,8 +277,8 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader This->min_rel_offset = GL_LIMITS(vshader_constantsF); This->max_rel_offset = 0; hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe, - reg_maps, This->semantics_in, This->semantics_out, pFunction, - GL_LIMITS(vshader_constantsF)); + reg_maps, This->attributes, NULL, This->semantics_out, + pFunction, GL_LIMITS(vshader_constantsF)); if (hr != WINED3D_OK) return hr;
vshader_set_limits(This); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 36c2da9..b68dc60 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -695,6 +695,12 @@ struct wined3d_shader_semantic struct wined3d_shader_dst_param reg; };
+struct wined3d_shader_attribute +{ + WINED3DDECLUSAGE usage; + UINT usage_idx; +}; + struct wined3d_shader_frontend { void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature); @@ -2577,8 +2583,9 @@ void shader_dump_dst_param(const struct wined3d_shader_dst_param *param, void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer, const shader_reg_maps *reg_maps, const DWORD *pFunction, void *backend_ctx); HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe, - struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in, - struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size); + struct shader_reg_maps *reg_maps, struct wined3d_shader_attribute *attributes, + struct wined3d_shader_semantic *semantics_in, struct wined3d_shader_semantic *semantics_out, + const DWORD *byte_code, DWORD constf_size); void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device); const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token); void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction); @@ -2671,7 +2678,7 @@ typedef struct IWineD3DVertexShaderImpl { UINT num_gl_shaders, shader_array_size;
/* Vertex shader input and output semantics */ - struct wined3d_shader_semantic semantics_in[MAX_ATTRIBS]; + struct wined3d_shader_attribute attributes[MAX_ATTRIBS]; struct wined3d_shader_semantic semantics_out[MAX_REG_OUTPUT];
UINT min_rel_offset, max_rel_offset;