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
/* TODO: merge with pixel shader */
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 */
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,
break;
case D3DSPR_INPUT:
if (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
is_color = TRUE;
if (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (arg->reg_maps->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
if (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
is_color = TRUE;
/* 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? */
sprintf(tmpReg, "vertex.attrib[%lu]", reg);
......
......@@ -295,6 +295,8 @@ static void shader_parse_decl_usage(
void shader_get_registers_used(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
DWORD* semantics_in,
DWORD* semantics_out,
CONST DWORD* pToken) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
......@@ -348,12 +350,12 @@ void shader_get_registers_used(
else
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 */
} else if (D3DSPR_OUTPUT == regtype) {
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 */
} else if (D3DSPR_SAMPLER == regtype)
......
......@@ -1951,7 +1951,7 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
/* load the array data using ordinal mapping */
loadNumberedArrays(iface, dataLocations,
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->arrayUsageMap);
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->semantics_in);
useDrawStridedSlow = FALSE;
} else { /* If this happens we must drawStridedSlow later on */
......
......@@ -501,18 +501,18 @@ static void shader_glsl_get_register_name(
strcpy(tmpStr, "gl_SecondaryColor");
}
} else {
IWineD3DVertexShaderImpl *vshader = (IWineD3DVertexShaderImpl*) arg->shader;
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl*) arg->shader;
if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
*is_color = TRUE;
if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
if (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
*is_color = TRUE;
/* 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? */
sprintf(tmpStr, "attrib%lu", reg);
......
......@@ -798,22 +798,12 @@ static void pshader_set_limits(
or GLSL and send it to the card */
inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
IWineD3DPixelShader *iface,
shader_reg_maps* reg_maps,
CONST DWORD *pFunction) {
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
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
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) {
......@@ -835,14 +825,14 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
/* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* Pack 3.0 inputs */
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 */
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 */
if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
......@@ -871,10 +861,10 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
/* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* 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))
shader_addline(&buffer, "MOV result.color, R0;\n");
......@@ -908,15 +898,23 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
shader_reg_maps reg_maps;
/* First pass: trace shader */
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
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 */
This->baseShader.shader_mode = wined3d_settings.ps_selected_mode;
if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) {
TRACE("(%p) : Generating hardware program\n", This);
IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction);
IWineD3DPixelShaderImpl_GenerateShader(iface, &reg_maps, pFunction);
}
TRACE("(%p) : Copying the function\n", This);
......
......@@ -611,24 +611,14 @@ static void vshader_set_limits(
/** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
or GLSL and send it to the card */
inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
static VOID IWineD3DVertexShaderImpl_GenerateShader(
IWineD3DVertexShader *iface,
shader_reg_maps* reg_maps,
CONST DWORD *pFunction) {
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
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
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) {
......@@ -650,14 +640,14 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
/* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* 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 */
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");
......@@ -680,10 +670,10 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
min(95, This->baseShader.limits.constant_float);
/* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, reg_maps, &buffer);
/* 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");
......@@ -1050,14 +1040,21 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_GetFunction(IWineD3DVertexShader*
static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
shader_reg_maps reg_maps;
/* First pass: trace shader */
shader_trace_init((IWineD3DBaseShader*) This, pFunction);
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 */
This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
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 */
if (NULL != pFunction) {
......
......@@ -1297,11 +1297,6 @@ typedef struct shader_reg_maps {
char constantsI[MAX_CONST_I]; /* 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
* Use 0 as default (bit 31 is always 1 on a valid token) */
DWORD samplers[MAX_SAMPLERS];
......@@ -1480,6 +1475,8 @@ typedef struct IWineD3DBaseShaderImpl {
extern void shader_get_registers_used(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
DWORD* semantics_in,
DWORD* semantics_out,
CONST DWORD* pToken);
extern void shader_generate_glsl_declarations(
......@@ -1561,9 +1558,10 @@ typedef struct IWineD3DVertexShaderImpl {
DWORD usage;
/* vertex declaration array mapping */
DWORD arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE];
/* Vertex shader input and output semantics */
DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
DWORD semantics_out [WINED3DSHADERDECLUSAGE_MAX_USAGE];
/* run time datas... */
VSHADERDATA *data;
IWineD3DVertexDeclaration *vertexDeclaration;
......@@ -1591,6 +1589,9 @@ typedef struct IWineD3DPixelShaderImpl {
IUnknown *parent;
IWineD3DDeviceImpl *wineD3DDevice;
/* Pixel shader input semantics */
DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
/* run time 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