Commit 276609e1 authored by Ivan Gyurdiev's avatar Ivan Gyurdiev Committed by Alexandre Julliard

wined3d: Move register count pass to SetFunction.

Move semantics pointers out of the reg_maps, make them persistent data in the shader (again, for future software shaders).
parent bbe7b40a
...@@ -317,6 +317,8 @@ static void pshader_get_register_name(const DWORD param, char* regstr, CHAR *con ...@@ -317,6 +317,8 @@ static void pshader_get_register_name(const DWORD param, char* regstr, CHAR *con
/* TODO: merge with pixel shader */ /* TODO: merge with pixel shader */
static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, BOOL is_input, char *hwLine) { static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, BOOL is_input, char *hwLine) {
IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) arg->shader;
/* oPos, oFog and oPts in D3D */ /* oPos, oFog and oPts in D3D */
static const char* hwrastout_reg_names[] = { "result.position", "result.fogcoord", "result.pointsize" }; static const char* hwrastout_reg_names[] = { "result.position", "result.fogcoord", "result.pointsize" };
...@@ -338,16 +340,16 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, ...@@ -338,16 +340,16 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param,
break; break;
case D3DSPR_INPUT: case D3DSPR_INPUT:
if (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] && if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK)) reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
is_color = TRUE; is_color = TRUE;
if (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] && if (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK)) reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
is_color = TRUE; is_color = TRUE;
/* FIXME: Shaders in 8.1 appear to not require a dcl statement - use /* FIXME: Shaders in 8.1 appear to not require a dcl statement - use
* the reg value from the vertex declaration. However, usage map is not initialized * the reg value from the vertex declaration. However, semantics are not initialized
* in that case - how can we know if an input contains color data or not? */ * in that case - how can we know if an input contains color data or not? */
sprintf(tmpReg, "vertex.attrib[%lu]", reg); sprintf(tmpReg, "vertex.attrib[%lu]", reg);
......
...@@ -295,6 +295,8 @@ static void shader_parse_decl_usage( ...@@ -295,6 +295,8 @@ static void shader_parse_decl_usage(
void shader_get_registers_used( void shader_get_registers_used(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
DWORD* semantics_in,
DWORD* semantics_out,
CONST DWORD* pToken) { CONST DWORD* pToken) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
...@@ -348,12 +350,12 @@ void shader_get_registers_used( ...@@ -348,12 +350,12 @@ void shader_get_registers_used(
else else
reg_maps->packed_input[regnum] = 1; reg_maps->packed_input[regnum] = 1;
shader_parse_decl_usage(reg_maps->semantics_in, usage, param); shader_parse_decl_usage(semantics_in, usage, param);
/* Vshader: mark 3.0 output registers used, save token */ /* Vshader: mark 3.0 output registers used, save token */
} else if (D3DSPR_OUTPUT == regtype) { } else if (D3DSPR_OUTPUT == regtype) {
reg_maps->packed_output[regnum] = 1; reg_maps->packed_output[regnum] = 1;
shader_parse_decl_usage(reg_maps->semantics_out, usage, param); shader_parse_decl_usage(semantics_out, usage, param);
/* Save sampler usage token */ /* Save sampler usage token */
} else if (D3DSPR_SAMPLER == regtype) } else if (D3DSPR_SAMPLER == regtype)
......
...@@ -1951,7 +1951,7 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx ...@@ -1951,7 +1951,7 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
/* load the array data using ordinal mapping */ /* load the array data using ordinal mapping */
loadNumberedArrays(iface, dataLocations, loadNumberedArrays(iface, dataLocations,
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->arrayUsageMap); ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->semantics_in);
useDrawStridedSlow = FALSE; useDrawStridedSlow = FALSE;
} else { /* If this happens we must drawStridedSlow later on */ } else { /* If this happens we must drawStridedSlow later on */
......
...@@ -501,18 +501,18 @@ static void shader_glsl_get_register_name( ...@@ -501,18 +501,18 @@ static void shader_glsl_get_register_name(
strcpy(tmpStr, "gl_SecondaryColor"); strcpy(tmpStr, "gl_SecondaryColor");
} }
} else { } else {
IWineD3DVertexShaderImpl *vshader = (IWineD3DVertexShaderImpl*) arg->shader; IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl*) arg->shader;
if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] && if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK)) reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
*is_color = TRUE; *is_color = TRUE;
if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] && if (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK)) reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
*is_color = TRUE; *is_color = TRUE;
/* FIXME: Shaders in 8.1 appear to not require a dcl statement - use /* FIXME: Shaders in 8.1 appear to not require a dcl statement - use
* the reg value from the vertex declaration. However, arrayUsageMap is not initialized * the reg value from the vertex declaration. However, semantics are not initialized
* in that case - how can we know if an input contains color data or not? */ * in that case - how can we know if an input contains color data or not? */
sprintf(tmpStr, "attrib%lu", reg); sprintf(tmpStr, "attrib%lu", reg);
......
...@@ -798,22 +798,12 @@ static void pshader_set_limits( ...@@ -798,22 +798,12 @@ static void pshader_set_limits(
or GLSL and send it to the card */ or GLSL and send it to the card */
inline static VOID IWineD3DPixelShaderImpl_GenerateShader( inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
IWineD3DPixelShader *iface, IWineD3DPixelShader *iface,
shader_reg_maps* reg_maps,
CONST DWORD *pFunction) { CONST DWORD *pFunction) {
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface; IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
SHADER_BUFFER buffer; SHADER_BUFFER buffer;
/* First pass: figure out which registers are used, what the semantics are, etc.. */
shader_reg_maps reg_maps;
DWORD semantics_in[WINED3DSHADERDECLUSAGE_MAX_USAGE];
memset(&reg_maps, 0, sizeof(shader_reg_maps));
memset(semantics_in, 0, WINED3DSHADERDECLUSAGE_MAX_USAGE * sizeof(DWORD));
reg_maps.semantics_in = semantics_in;
reg_maps.semantics_out = NULL;
shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps, pFunction);
/* FIXME: validate against OpenGL */
#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders #if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */ it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) { if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
...@@ -835,14 +825,14 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -835,14 +825,14 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
/* Base Declarations */ /* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer); shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* Pack 3.0 inputs */ /* Pack 3.0 inputs */
if (This->baseShader.hex_version >= D3DPS_VERSION(3,0)) if (This->baseShader.hex_version >= D3DPS_VERSION(3,0))
pshader_glsl_input_pack(&buffer, semantics_in); pshader_glsl_input_pack(&buffer, This->semantics_in);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */ /* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if (This->baseShader.hex_version < D3DPS_VERSION(2,0)) if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
...@@ -871,10 +861,10 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -871,10 +861,10 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n"); shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
/* Base Declarations */ /* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer); shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
if (This->baseShader.hex_version < D3DPS_VERSION(2,0)) if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
shader_addline(&buffer, "MOV result.color, R0;\n"); shader_addline(&buffer, "MOV result.color, R0;\n");
...@@ -908,15 +898,23 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -908,15 +898,23 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) { static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
shader_reg_maps reg_maps;
/* First pass: trace shader */
shader_trace_init((IWineD3DBaseShader*) This, pFunction); shader_trace_init((IWineD3DBaseShader*) This, pFunction);
pshader_set_limits(This); pshader_set_limits(This);
/* Second pass: figure out which registers are used, what the semantics are, etc.. */
memset(&reg_maps, 0, sizeof(shader_reg_maps));
shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
This->semantics_in, NULL, pFunction);
/* FIXME: validate reg_maps against OpenGL */
/* Generate HW shader in needed */ /* Generate HW shader in needed */
This->baseShader.shader_mode = wined3d_settings.ps_selected_mode; This->baseShader.shader_mode = wined3d_settings.ps_selected_mode;
if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) { if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) {
TRACE("(%p) : Generating hardware program\n", This); TRACE("(%p) : Generating hardware program\n", This);
IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction); IWineD3DPixelShaderImpl_GenerateShader(iface, &reg_maps, pFunction);
} }
TRACE("(%p) : Copying the function\n", This); TRACE("(%p) : Copying the function\n", This);
......
...@@ -611,24 +611,14 @@ static void vshader_set_limits( ...@@ -611,24 +611,14 @@ static void vshader_set_limits(
/** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB /** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
or GLSL and send it to the card */ or GLSL and send it to the card */
inline static VOID IWineD3DVertexShaderImpl_GenerateShader( static VOID IWineD3DVertexShaderImpl_GenerateShader(
IWineD3DVertexShader *iface, IWineD3DVertexShader *iface,
shader_reg_maps* reg_maps,
CONST DWORD *pFunction) { CONST DWORD *pFunction) {
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface; IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
SHADER_BUFFER buffer; SHADER_BUFFER buffer;
/* First pass: figure out which registers are used, what the semantics are, etc.. */
shader_reg_maps reg_maps;
DWORD semantics_out[WINED3DSHADERDECLUSAGE_MAX_USAGE];
memset(&reg_maps, 0, sizeof(shader_reg_maps));
memset(semantics_out, 0, WINED3DSHADERDECLUSAGE_MAX_USAGE * sizeof(DWORD));
reg_maps.semantics_in = This->arrayUsageMap;
reg_maps.semantics_out = semantics_out;
shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps, pFunction);
/* FIXME: validate against OpenGL */
#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders #if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */ it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) { if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
...@@ -650,14 +640,14 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader( ...@@ -650,14 +640,14 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
/* Base Declarations */ /* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer); shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
/* Unpack 3.0 outputs */ /* Unpack 3.0 outputs */
if (This->baseShader.hex_version >= D3DVS_VERSION(3,0)) if (This->baseShader.hex_version >= D3DVS_VERSION(3,0))
vshader_glsl_output_unpack(&buffer, semantics_out); vshader_glsl_output_unpack(&buffer, This->semantics_out);
shader_addline(&buffer, "}\n\0"); shader_addline(&buffer, "}\n\0");
...@@ -680,10 +670,10 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader( ...@@ -680,10 +670,10 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
min(95, This->baseShader.limits.constant_float); min(95, This->baseShader.limits.constant_float);
/* Base Declarations */ /* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer); shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, reg_maps, pFunction);
shader_addline(&buffer, "END\n\0"); shader_addline(&buffer, "END\n\0");
...@@ -1050,14 +1040,21 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader* ...@@ -1050,14 +1040,21 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader*
static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) { static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface; IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
shader_reg_maps reg_maps;
/* First pass: trace shader */
shader_trace_init((IWineD3DBaseShader*) This, pFunction); shader_trace_init((IWineD3DBaseShader*) This, pFunction);
vshader_set_limits(This); vshader_set_limits(This);
/* Second pass: figure out registers used, semantics, etc.. */
memset(&reg_maps, 0, sizeof(shader_reg_maps));
shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
This->semantics_in, This->semantics_out, pFunction);
/* Generate HW shader in needed */ /* Generate HW shader in needed */
This->baseShader.shader_mode = wined3d_settings.vs_selected_mode; This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW)
IWineD3DVertexShaderImpl_GenerateShader(iface, pFunction); IWineD3DVertexShaderImpl_GenerateShader(iface, &reg_maps, pFunction);
/* copy the function ... because it will certainly be released by application */ /* copy the function ... because it will certainly be released by application */
if (NULL != pFunction) { if (NULL != pFunction) {
......
...@@ -1297,11 +1297,6 @@ typedef struct shader_reg_maps { ...@@ -1297,11 +1297,6 @@ typedef struct shader_reg_maps {
char constantsI[MAX_CONST_I]; /* pixel & vertex >= 2.0 */ char constantsI[MAX_CONST_I]; /* pixel & vertex >= 2.0 */
char constantsB[MAX_CONST_B]; /* pixel & vertex >= 2.0 */ char constantsB[MAX_CONST_B]; /* pixel & vertex >= 2.0 */
/* Semantics maps (semantic -> reg_token)
* Use 0 as default (bit 31 is always 1 on a valid token) */
DWORD* semantics_in; /* vertex, pixel */
DWORD* semantics_out; /* vertex */
/* Sampler usage tokens /* Sampler usage tokens
* Use 0 as default (bit 31 is always 1 on a valid token) */ * Use 0 as default (bit 31 is always 1 on a valid token) */
DWORD samplers[MAX_SAMPLERS]; DWORD samplers[MAX_SAMPLERS];
...@@ -1480,6 +1475,8 @@ typedef struct IWineD3DBaseShaderImpl { ...@@ -1480,6 +1475,8 @@ typedef struct IWineD3DBaseShaderImpl {
extern void shader_get_registers_used( extern void shader_get_registers_used(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
DWORD* semantics_in,
DWORD* semantics_out,
CONST DWORD* pToken); CONST DWORD* pToken);
extern void shader_generate_glsl_declarations( extern void shader_generate_glsl_declarations(
...@@ -1561,8 +1558,9 @@ typedef struct IWineD3DVertexShaderImpl { ...@@ -1561,8 +1558,9 @@ typedef struct IWineD3DVertexShaderImpl {
DWORD usage; DWORD usage;
/* vertex declaration array mapping */ /* Vertex shader input and output semantics */
DWORD arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE]; DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
DWORD semantics_out [WINED3DSHADERDECLUSAGE_MAX_USAGE];
/* run time datas... */ /* run time datas... */
VSHADERDATA *data; VSHADERDATA *data;
...@@ -1591,6 +1589,9 @@ typedef struct IWineD3DPixelShaderImpl { ...@@ -1591,6 +1589,9 @@ typedef struct IWineD3DPixelShaderImpl {
IUnknown *parent; IUnknown *parent;
IWineD3DDeviceImpl *wineD3DDevice; IWineD3DDeviceImpl *wineD3DDevice;
/* Pixel shader input semantics */
DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
/* run time data */ /* run time data */
PSHADERDATA *data; PSHADERDATA *data;
......
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