wined3d: Keep track of used float constants.
This commit is contained in:
parent
bcf1361af1
commit
f9276a6429
|
@ -237,6 +237,14 @@ static void shader_delete_constant_list(struct list* clist) {
|
||||||
list_init(clist);
|
list_init(clist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
|
||||||
|
{
|
||||||
|
DWORD idx, shift;
|
||||||
|
idx = bit >> 5;
|
||||||
|
shift = bit & 0x1f;
|
||||||
|
bitmap[idx] |= (1 << shift);
|
||||||
|
}
|
||||||
|
|
||||||
static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps,
|
static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps,
|
||||||
DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader)
|
DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader)
|
||||||
{
|
{
|
||||||
|
@ -293,6 +301,10 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh
|
||||||
}
|
}
|
||||||
reg_maps->usesrelconstF = TRUE;
|
reg_maps->usesrelconstF = TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_bitmap_bit(reg_maps->constf, register_idx);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WINED3DSPR_CONSTINT:
|
case WINED3DSPR_CONSTINT:
|
||||||
|
@ -309,12 +321,32 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param)
|
||||||
|
{
|
||||||
|
switch(instr)
|
||||||
|
{
|
||||||
|
case WINED3DSIH_M4x4:
|
||||||
|
case WINED3DSIH_M3x4:
|
||||||
|
return param == 1 ? 4 : 1;
|
||||||
|
|
||||||
|
case WINED3DSIH_M4x3:
|
||||||
|
case WINED3DSIH_M3x3:
|
||||||
|
return param == 1 ? 3 : 1;
|
||||||
|
|
||||||
|
case WINED3DSIH_M3x2:
|
||||||
|
return param == 1 ? 2 : 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Note that this does not count the loop register
|
/* Note that this does not count the loop register
|
||||||
* as an address register. */
|
* as an address register. */
|
||||||
|
|
||||||
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
|
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 shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
|
||||||
struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code)
|
struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size)
|
||||||
{
|
{
|
||||||
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
||||||
void *fe_data = This->baseShader.frontend_data;
|
void *fe_data = This->baseShader.frontend_data;
|
||||||
|
@ -338,6 +370,13 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
|
||||||
reg_maps->shader_version = shader_version;
|
reg_maps->shader_version = shader_version;
|
||||||
pshader = shader_is_pshader_version(shader_version.type);
|
pshader = shader_is_pshader_version(shader_version.type);
|
||||||
|
|
||||||
|
reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
|
||||||
|
if(!reg_maps->constf) {
|
||||||
|
ERR("Out of memory\n");
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
while (!fe->shader_is_end(fe_data, &pToken))
|
while (!fe->shader_is_end(fe_data, &pToken))
|
||||||
{
|
{
|
||||||
struct wined3d_shader_instruction ins;
|
struct wined3d_shader_instruction ins;
|
||||||
|
@ -582,6 +621,24 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
|
||||||
fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
|
fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
|
||||||
shader_record_register_usage(This, reg_maps, src_param.reg.type,
|
shader_record_register_usage(This, reg_maps, src_param.reg.type,
|
||||||
src_param.reg.idx, !!src_param.reg.rel_addr, pshader);
|
src_param.reg.idx, !!src_param.reg.rel_addr, pshader);
|
||||||
|
switch(get_instr_regcount(ins.handler_idx, i))
|
||||||
|
{
|
||||||
|
case 4:
|
||||||
|
shader_record_register_usage(This, reg_maps, src_param.reg.type,
|
||||||
|
src_param.reg.idx + 3, !!src_param.reg.rel_addr, pshader);
|
||||||
|
/* drop through */
|
||||||
|
case 3:
|
||||||
|
shader_record_register_usage(This, reg_maps, src_param.reg.type,
|
||||||
|
src_param.reg.idx + 2, !!src_param.reg.rel_addr, pshader);
|
||||||
|
/* drop through */
|
||||||
|
case 2:
|
||||||
|
shader_record_register_usage(This, reg_maps, src_param.reg.type,
|
||||||
|
src_param.reg.idx + 1, !!src_param.reg.rel_addr, pshader);
|
||||||
|
/* drop through */
|
||||||
|
case 1:
|
||||||
|
shader_record_register_usage(This, reg_maps, src_param.reg.type,
|
||||||
|
src_param.reg.idx, !!src_param.reg.rel_addr, pshader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1158,6 +1215,7 @@ void shader_cleanup(IWineD3DBaseShader *iface)
|
||||||
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
|
IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
|
||||||
|
|
||||||
((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_destroy(iface);
|
((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_destroy(iface);
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->baseShader.reg_maps.constf);
|
||||||
HeapFree(GetProcessHeap(), 0, This->baseShader.function);
|
HeapFree(GetProcessHeap(), 0, This->baseShader.function);
|
||||||
shader_delete_constant_list(&This->baseShader.constantsF);
|
shader_delete_constant_list(&This->baseShader.constantsF);
|
||||||
shader_delete_constant_list(&This->baseShader.constantsB);
|
shader_delete_constant_list(&This->baseShader.constantsB);
|
||||||
|
|
|
@ -238,7 +238,8 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
|
||||||
list_init(&This->baseShader.constantsI);
|
list_init(&This->baseShader.constantsI);
|
||||||
|
|
||||||
/* Second pass: figure out which registers are used, what the semantics are, etc.. */
|
/* 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);
|
hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction,
|
||||||
|
GL_LIMITS(pshader_constantsF));
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
pshader_set_limits(This);
|
pshader_set_limits(This);
|
||||||
|
|
|
@ -279,7 +279,8 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
|
||||||
This->min_rel_offset = GL_LIMITS(vshader_constantsF);
|
This->min_rel_offset = GL_LIMITS(vshader_constantsF);
|
||||||
This->max_rel_offset = 0;
|
This->max_rel_offset = 0;
|
||||||
hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
|
hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
|
||||||
reg_maps, This->semantics_in, This->semantics_out, pFunction);
|
reg_maps, This->semantics_in, This->semantics_out, pFunction,
|
||||||
|
GL_LIMITS(vshader_constantsF));
|
||||||
if (hr != WINED3D_OK) return hr;
|
if (hr != WINED3D_OK) return hr;
|
||||||
|
|
||||||
vshader_set_limits(This);
|
vshader_set_limits(This);
|
||||||
|
|
|
@ -625,6 +625,7 @@ typedef struct shader_reg_maps
|
||||||
char packed_output[MAX_REG_OUTPUT]; /* vertex >= 3.0 */
|
char packed_output[MAX_REG_OUTPUT]; /* vertex >= 3.0 */
|
||||||
char attributes[MAX_ATTRIBS]; /* vertex */
|
char attributes[MAX_ATTRIBS]; /* vertex */
|
||||||
char labels[MAX_LABELS]; /* pixel, vertex */
|
char labels[MAX_LABELS]; /* pixel, vertex */
|
||||||
|
DWORD *constf; /* pixel, vertex */
|
||||||
DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */
|
DWORD texcoord_mask[MAX_REG_TEXCRD]; /* vertex < 3.0 */
|
||||||
WORD integer_constants; /* MAX_CONST_I, 16 */
|
WORD integer_constants; /* MAX_CONST_I, 16 */
|
||||||
WORD boolean_constants; /* MAX_CONST_B, 16 */
|
WORD boolean_constants; /* MAX_CONST_B, 16 */
|
||||||
|
@ -2579,7 +2580,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
|
||||||
const shader_reg_maps *reg_maps, const DWORD *pFunction);
|
const shader_reg_maps *reg_maps, const DWORD *pFunction);
|
||||||
HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
|
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 shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
|
||||||
struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code);
|
struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size);
|
||||||
void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device);
|
void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device);
|
||||||
const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token);
|
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);
|
void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction);
|
||||||
|
|
Loading…
Reference in New Issue