mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 10:41:12 +00:00
wined3d: Reverse semantics maps for shaders.
This commit is contained in:
parent
c611012df5
commit
5b3c500efe
6 changed files with 172 additions and 315 deletions
|
@ -340,18 +340,9 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param,
|
|||
break;
|
||||
case D3DSPR_INPUT:
|
||||
|
||||
if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
|
||||
reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
|
||||
if (vshader_input_is_color((IWineD3DVertexShader*) This, reg))
|
||||
is_color = TRUE;
|
||||
|
||||
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, 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);
|
||||
strcat(hwLine, tmpReg);
|
||||
break;
|
||||
|
|
|
@ -171,132 +171,14 @@ unsigned int shader_get_float_offset(const DWORD reg) {
|
|||
}
|
||||
}
|
||||
|
||||
static void shader_parse_decl_usage(
|
||||
DWORD *semantics_map,
|
||||
DWORD usage_token, DWORD param) {
|
||||
|
||||
unsigned int usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
|
||||
unsigned int usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
|
||||
unsigned int regnum = param & D3DSP_REGNUM_MASK;
|
||||
|
||||
switch(usage) {
|
||||
case D3DDECLUSAGE_POSITION:
|
||||
if (usage_idx == 0) { /* tween data */
|
||||
TRACE("Setting position to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_POSITION] = param;
|
||||
} else {
|
||||
/* TODO: position indexes go from 0-8!!*/
|
||||
TRACE("Setting position 2 to %d because usage_idx = %d\n", regnum, usage_idx);
|
||||
/* robots uses positions up to 8, the position arrays are just packed.*/
|
||||
if (usage_idx > 1) {
|
||||
TRACE("Loaded for position %d (greater than 2)\n", usage_idx);
|
||||
}
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_POSITION2 + usage_idx-1] = param;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_BLENDINDICES:
|
||||
TRACE("Setting BLENDINDICES to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_BLENDINDICES] = param;
|
||||
if (usage_idx != 0) FIXME("Extended BLENDINDICES\n");
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_BLENDWEIGHT:
|
||||
TRACE("Setting BLENDWEIGHT to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_BLENDWEIGHT] = param;
|
||||
if (usage_idx != 0) FIXME("Extended blend weights\n");
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_NORMAL:
|
||||
if (usage_idx == 0) { /* tween data */
|
||||
TRACE("Setting normal to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_NORMAL] = param;
|
||||
} else {
|
||||
TRACE("Setting normal 2 to %d because usage = %d\n", regnum, usage_idx);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_NORMAL2] = param;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_PSIZE:
|
||||
TRACE("Setting PSIZE to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_PSIZE] = param;
|
||||
if (usage_idx != 0) FIXME("Extended PSIZE\n");
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_COLOR:
|
||||
if (usage_idx == 0) {
|
||||
TRACE("Setting DIFFUSE to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_DIFFUSE] = param;
|
||||
} else {
|
||||
TRACE("Setting SPECULAR to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_SPECULAR] = param;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_TEXCOORD:
|
||||
if (usage_idx > 7) {
|
||||
FIXME("Program uses texture coordinate %d but only 0-7 have been "
|
||||
"implemented\n", usage_idx);
|
||||
} else {
|
||||
TRACE("Setting TEXCOORD %d to %d\n", usage_idx, regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_TEXCOORD0 + usage_idx] = param;
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_TANGENT:
|
||||
TRACE("Setting TANGENT to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_TANGENT] = param;
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_BINORMAL:
|
||||
TRACE("Setting BINORMAL to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_BINORMAL] = param;
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_TESSFACTOR:
|
||||
TRACE("Setting TESSFACTOR to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_TESSFACTOR] = param;
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_POSITIONT:
|
||||
if (usage_idx == 0) { /* tween data */
|
||||
FIXME("Setting positiont to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_POSITIONT] = param;
|
||||
} else {
|
||||
FIXME("Setting positiont 2 to %d because usage = %d\n", regnum, usage_idx);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_POSITIONT2] = param;
|
||||
if (usage_idx != 0) FIXME("Extended positiont\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_FOG:
|
||||
TRACE("Setting FOG to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_FOG] = param;
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_DEPTH:
|
||||
TRACE("Setting DEPTH to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_DEPTH] = param;
|
||||
break;
|
||||
|
||||
case D3DDECLUSAGE_SAMPLE:
|
||||
TRACE("Setting SAMPLE to %d\n", regnum);
|
||||
semantics_map[WINED3DSHADERDECLUSAGE_SAMPLE] = param;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unrecognised dcl %#x", usage);
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that this does not count the loop register
|
||||
* as an address register. */
|
||||
|
||||
void shader_get_registers_used(
|
||||
IWineD3DBaseShader *iface,
|
||||
shader_reg_maps* reg_maps,
|
||||
DWORD* semantics_in,
|
||||
DWORD* semantics_out,
|
||||
semantic* semantics_in,
|
||||
semantic* semantics_out,
|
||||
CONST DWORD* pToken) {
|
||||
|
||||
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
||||
|
@ -350,12 +232,14 @@ void shader_get_registers_used(
|
|||
else
|
||||
reg_maps->packed_input[regnum] = 1;
|
||||
|
||||
shader_parse_decl_usage(semantics_in, usage, param);
|
||||
semantics_in[regnum].usage = usage;
|
||||
semantics_in[regnum].reg = 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(semantics_out, usage, param);
|
||||
semantics_out[regnum].usage = usage;
|
||||
semantics_out[regnum].reg = param;
|
||||
|
||||
/* Save sampler usage token */
|
||||
} else if (D3DSPR_SAMPLER == regtype)
|
||||
|
|
|
@ -464,7 +464,12 @@ void primitiveDeclarationConvertToStridedData(
|
|||
checkGLcall("glEnableVertexAttribArrayARB");
|
||||
}
|
||||
|
||||
stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx);
|
||||
if (useVertexShaderFunction)
|
||||
stride_used = vshader_get_input(This->stateBlock->vertexShader,
|
||||
element->Usage, element->UsageIndex, &idx);
|
||||
else
|
||||
stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx);
|
||||
|
||||
if (stride_used) {
|
||||
TRACE("Loaded %s array %u [usage=%s, usage_idx=%u, "
|
||||
"stream=%u, offset=%u, stride=%lu, VBO=%u]\n",
|
||||
|
@ -476,10 +481,12 @@ void primitiveDeclarationConvertToStridedData(
|
|||
strided->u.input[idx].dwType = element->Type;
|
||||
strided->u.input[idx].dwStride = stride;
|
||||
strided->u.input[idx].VBO = streamVBO;
|
||||
if (element->Usage == D3DDECLUSAGE_POSITION)
|
||||
strided->u.s.position_transformed = FALSE;
|
||||
else if (element->Usage == D3DDECLUSAGE_POSITIONT)
|
||||
strided->u.s.position_transformed = TRUE;
|
||||
if (!useVertexShaderFunction) {
|
||||
if (element->Usage == D3DDECLUSAGE_POSITION)
|
||||
strided->u.s.position_transformed = FALSE;
|
||||
else if (element->Usage == D3DDECLUSAGE_POSITIONT)
|
||||
strided->u.s.position_transformed = TRUE;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -794,105 +801,35 @@ static void draw_vertex(IWineD3DDevice *iface, /* interf
|
|||
}
|
||||
#endif /* TODO: Software shaders */
|
||||
|
||||
void loadNumberedArrays(
|
||||
IWineD3DDevice *iface,
|
||||
WineDirect3DVertexStridedData *sd,
|
||||
DWORD arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE]) {
|
||||
static void loadNumberedArrays(
|
||||
IWineD3DDevice *iface,
|
||||
IWineD3DVertexShader *shader,
|
||||
WineDirect3DVertexStridedData *strided) {
|
||||
|
||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||
GLint curVBO = -1;
|
||||
int i;
|
||||
|
||||
#define LOAD_NUMBERED_ARRAY(_arrayName, _lookupName) \
|
||||
if ((sd->u.s._arrayName.lpData != NULL || sd->u.s._arrayName.VBO != 0) && arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName]) { \
|
||||
unsigned int idx = arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName] & D3DSP_REGNUM_MASK; \
|
||||
TRACE_(d3d_shader)("Loading array %u with data from %s\n", idx, #_arrayName); \
|
||||
if(curVBO != sd->u.s._arrayName.VBO) { \
|
||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s._arrayName.VBO)); \
|
||||
checkGLcall("glBindBufferARB"); \
|
||||
curVBO = sd->u.s._arrayName.VBO; \
|
||||
} \
|
||||
GL_EXTCALL(glVertexAttribPointerARB(idx, \
|
||||
WINED3D_ATR_SIZE(sd->u.s._arrayName.dwType), \
|
||||
WINED3D_ATR_GLTYPE(sd->u.s._arrayName.dwType), \
|
||||
WINED3D_ATR_NORMALIZED(sd->u.s._arrayName.dwType), \
|
||||
sd->u.s._arrayName.dwStride, \
|
||||
sd->u.s._arrayName.lpData)); \
|
||||
GL_EXTCALL(glEnableVertexAttribArrayARB(idx)); \
|
||||
}
|
||||
for (i = 0; i < MAX_ATTRIBS; i++) {
|
||||
|
||||
if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
|
||||
continue;
|
||||
|
||||
#define LOAD_NUMBERED_POSITION_ARRAY(_lookupNumber) \
|
||||
if ((sd->u.s.position2.lpData != NULL || sd->u.s.position2.VBO != 0)&& arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber]) { \
|
||||
unsigned int idx = arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber] & D3DSP_REGNUM_MASK; \
|
||||
TRACE_(d3d_shader)("Loading array %u with data from %s\n", idx, "position2"); \
|
||||
if(curVBO != sd->u.s.position2.VBO) { \
|
||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position2.VBO)); \
|
||||
checkGLcall("glBindBufferARB"); \
|
||||
curVBO = sd->u.s.position2.VBO; \
|
||||
} \
|
||||
GL_EXTCALL(glVertexAttribPointerARB(idx, \
|
||||
WINED3D_ATR_SIZE(sd->u.s.position2.dwType), \
|
||||
WINED3D_ATR_GLTYPE(sd->u.s.position2.dwType), \
|
||||
WINED3D_ATR_NORMALIZED(sd->u.s.position2.dwType), \
|
||||
sd->u.s.position2.dwStride, \
|
||||
((char *)sd->u.s.position2.lpData) + \
|
||||
WINED3D_ATR_SIZE(sd->u.s.position2.dwType) * \
|
||||
WINED3D_ATR_TYPESIZE(sd->u.s.position2.dwType) * _lookupNumber)); \
|
||||
GL_EXTCALL(glEnableVertexAttribArrayARB(idx)); \
|
||||
}
|
||||
TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
|
||||
|
||||
/* Generate some lookup tables */
|
||||
/* drop the RHW coord, there must be a nicer way of doing this. */
|
||||
sd->u.s.position.dwType = min(D3DDECLTYPE_FLOAT3, sd->u.s.position.dwType);
|
||||
sd->u.s.position2.dwType = min(D3DDECLTYPE_FLOAT3, sd->u.s.position2.dwType);
|
||||
|
||||
LOAD_NUMBERED_ARRAY(blendWeights,BLENDWEIGHT);
|
||||
LOAD_NUMBERED_ARRAY(blendMatrixIndices,BLENDINDICES);
|
||||
LOAD_NUMBERED_ARRAY(position,POSITION);
|
||||
LOAD_NUMBERED_ARRAY(normal,NORMAL);
|
||||
LOAD_NUMBERED_ARRAY(pSize,PSIZE);
|
||||
LOAD_NUMBERED_ARRAY(diffuse,DIFFUSE);
|
||||
LOAD_NUMBERED_ARRAY(specular,SPECULAR);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[0],TEXCOORD0);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[1],TEXCOORD1);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[2],TEXCOORD2);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[3],TEXCOORD3);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[4],TEXCOORD4);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[5],TEXCOORD5);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[6],TEXCOORD6);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[7],TEXCOORD7);
|
||||
#if 0 /* TODO: Samplers may allow for more texture coords */
|
||||
LOAD_NUMBERED_ARRAY(texCoords[8],TEXCOORD8);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[9],TEXCOORD9);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[10],TEXCOORD10);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[11],TEXCOORD11);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[12],TEXCOORD12);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[13],TEXCOORD13);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[14],TEXCOORD14);
|
||||
LOAD_NUMBERED_ARRAY(texCoords[15],TEXCOORD15);
|
||||
#endif
|
||||
LOAD_NUMBERED_ARRAY(position,POSITIONT);
|
||||
/* d3d9 types */
|
||||
LOAD_NUMBERED_ARRAY(tangent,TANGENT);
|
||||
LOAD_NUMBERED_ARRAY(binormal,BINORMAL);
|
||||
LOAD_NUMBERED_ARRAY(tessFactor,TESSFACTOR);
|
||||
LOAD_NUMBERED_ARRAY(position2,POSITION2);
|
||||
/* there can be lots of position arrays */
|
||||
LOAD_NUMBERED_POSITION_ARRAY(0);
|
||||
LOAD_NUMBERED_POSITION_ARRAY(1);
|
||||
LOAD_NUMBERED_POSITION_ARRAY(2);
|
||||
LOAD_NUMBERED_POSITION_ARRAY(3);
|
||||
LOAD_NUMBERED_POSITION_ARRAY(4);
|
||||
LOAD_NUMBERED_POSITION_ARRAY(5);
|
||||
LOAD_NUMBERED_POSITION_ARRAY(6);
|
||||
LOAD_NUMBERED_POSITION_ARRAY(7);
|
||||
LOAD_NUMBERED_ARRAY(position2,POSITIONT2);
|
||||
LOAD_NUMBERED_ARRAY(normal2,NORMAL2);
|
||||
LOAD_NUMBERED_ARRAY(fog,FOG);
|
||||
LOAD_NUMBERED_ARRAY(depth,DEPTH);
|
||||
LOAD_NUMBERED_ARRAY(sample,SAMPLE);
|
||||
|
||||
#undef LOAD_NUMBERED_ARRAY
|
||||
if(curVBO != strided->u.input[i].VBO) {
|
||||
GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
|
||||
checkGLcall("glBindBufferARB");
|
||||
curVBO = strided->u.input[i].VBO;
|
||||
}
|
||||
GL_EXTCALL(glVertexAttribPointerARB(i,
|
||||
WINED3D_ATR_SIZE(strided->u.input[i].dwType),
|
||||
WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
|
||||
WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
|
||||
strided->u.input[i].dwStride,
|
||||
strided->u.input[i].lpData));
|
||||
GL_EXTCALL(glEnableVertexAttribArrayARB(i));
|
||||
}
|
||||
}
|
||||
|
||||
static void loadVertexData(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd) {
|
||||
|
@ -1803,8 +1740,7 @@ inline static void drawPrimitiveDrawStrided(
|
|||
/* Shader pipeline - load attribute arrays */
|
||||
} else if(useVertexShaderFunction) {
|
||||
|
||||
loadNumberedArrays(iface, dataLocations,
|
||||
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->semantics_in);
|
||||
loadNumberedArrays(iface, This->stateBlock->vertexShader, dataLocations);
|
||||
useDrawStridedSlow = FALSE;
|
||||
|
||||
/* Draw vertex by vertex */
|
||||
|
@ -2147,11 +2083,21 @@ void drawPrimitive(IWineD3DDevice *iface,
|
|||
ENTER_GL();
|
||||
|
||||
if(DrawPrimStrideData) {
|
||||
|
||||
/* Note: this is a ddraw fixed-function code path */
|
||||
|
||||
TRACE("================ Strided Input ===================\n");
|
||||
dataLocations = DrawPrimStrideData;
|
||||
drawPrimitiveTraceDataLocations(dataLocations);
|
||||
fixup = FALSE;
|
||||
}
|
||||
else if (This->stateBlock->vertexDecl != NULL || (useVertexShaderFunction && NULL != ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration)) {
|
||||
|
||||
else if (This->stateBlock->vertexDecl != NULL || useVertexShaderFunction) {
|
||||
|
||||
/* Note: This is a fixed function or shader codepath.
|
||||
* This means it must handle both types of strided data.
|
||||
* Shaders must go through here to zero the strided data, even if they
|
||||
* don't set any declaration at all */
|
||||
|
||||
TRACE("================ Vertex Declaration ===================\n");
|
||||
dataLocations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dataLocations));
|
||||
|
@ -2159,9 +2105,19 @@ void drawPrimitive(IWineD3DDevice *iface,
|
|||
ERR("Out of memory!\n");
|
||||
return;
|
||||
}
|
||||
primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction, dataLocations, StartVertexIndex, &fixup);
|
||||
|
||||
if (This->stateBlock->vertexDecl != NULL ||
|
||||
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->vertexDeclaration != NULL)
|
||||
|
||||
primitiveDeclarationConvertToStridedData(iface, useVertexShaderFunction,
|
||||
dataLocations, StartVertexIndex, &fixup);
|
||||
|
||||
} else {
|
||||
|
||||
/* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
|
||||
* It is reachable through d3d8, but only for fixed-function.
|
||||
* It will not work properly for shaders. */
|
||||
|
||||
TRACE("================ FVF ===================\n");
|
||||
dataLocations = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dataLocations));
|
||||
if(!dataLocations) {
|
||||
|
@ -2169,11 +2125,9 @@ void drawPrimitive(IWineD3DDevice *iface,
|
|||
return;
|
||||
}
|
||||
primitiveConvertToStridedData(iface, dataLocations, StartVertexIndex, &fixup);
|
||||
drawPrimitiveTraceDataLocations(dataLocations);
|
||||
}
|
||||
|
||||
/* write out some debug information*/
|
||||
drawPrimitiveTraceDataLocations(dataLocations);
|
||||
|
||||
/* Setup transform matrices and sort out */
|
||||
primitiveInitState(iface, dataLocations, useVertexShaderFunction, &lighting_changed, &lighting_original);
|
||||
|
||||
|
|
|
@ -501,20 +501,8 @@ static void shader_glsl_get_register_name(
|
|||
strcpy(tmpStr, "gl_SecondaryColor");
|
||||
}
|
||||
} else {
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl*) arg->shader;
|
||||
|
||||
if (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
|
||||
reg == (This->semantics_in[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
|
||||
*is_color = TRUE;
|
||||
|
||||
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, semantics are not initialized
|
||||
* in that case - how can we know if an input contains color data or not? */
|
||||
|
||||
if (vshader_input_is_color((IWineD3DVertexShader*) This, reg))
|
||||
*is_color = TRUE;
|
||||
sprintf(tmpStr, "attrib%lu", reg);
|
||||
}
|
||||
break;
|
||||
|
@ -1390,53 +1378,50 @@ void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg) {
|
|||
|
||||
void pshader_glsl_input_pack(
|
||||
SHADER_BUFFER* buffer,
|
||||
DWORD* semantics_in) {
|
||||
semantic* semantics_in) {
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < WINED3DSHADERDECLUSAGE_MAX_USAGE; i++) {
|
||||
for (i = 0; i < MAX_REG_INPUT; i++) {
|
||||
|
||||
DWORD reg = semantics_in[i];
|
||||
unsigned int regnum = reg & D3DSP_REGNUM_MASK;
|
||||
DWORD usage_token = semantics_in[i].usage;
|
||||
DWORD register_token = semantics_in[i].reg;
|
||||
DWORD usage, usage_idx;
|
||||
char reg_mask[6];
|
||||
|
||||
/* Uninitialized */
|
||||
if (!reg) continue;
|
||||
if (!usage_token) continue;
|
||||
usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
|
||||
usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
|
||||
shader_glsl_get_output_register_swizzle(register_token, reg_mask);
|
||||
|
||||
shader_glsl_get_output_register_swizzle(reg, reg_mask);
|
||||
switch(usage) {
|
||||
|
||||
switch(i) {
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_DIFFUSE:
|
||||
shader_addline(buffer, "IN%lu%s = vec4(gl_Color)%s;\n",
|
||||
regnum, reg_mask, reg_mask);
|
||||
case D3DDECLUSAGE_COLOR:
|
||||
if (usage_idx == 0)
|
||||
shader_addline(buffer, "IN%lu%s = vec4(gl_Color)%s;\n",
|
||||
i, reg_mask, reg_mask);
|
||||
if (usage_idx == 1)
|
||||
shader_addline(buffer, "IN%lu%s = vec4(gl_SecondaryColor)%s;\n",
|
||||
i, reg_mask, reg_mask);
|
||||
else
|
||||
shader_addline(buffer, "IN%lu%s = vec4(unsupported_color_input)%s;\n",
|
||||
i, reg_mask, reg_mask);
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_SPECULAR:
|
||||
shader_addline(buffer, "IN%lu%s = vec4(gl_SecondaryColor)%s;\n",
|
||||
regnum, reg_mask, reg_mask);
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD0:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD1:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD2:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD3:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD4:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD5:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD6:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD7:
|
||||
case D3DDECLUSAGE_TEXCOORD:
|
||||
shader_addline(buffer, "IN%lu%s = vec4(gl_TexCoord[%lu])%s;\n",
|
||||
regnum, reg_mask, i - WINED3DSHADERDECLUSAGE_TEXCOORD0, reg_mask );
|
||||
i, reg_mask, usage_idx, reg_mask );
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_FOG:
|
||||
case D3DDECLUSAGE_FOG:
|
||||
shader_addline(buffer, "IN%lu%s = vec4(gl_FogFragCoord)%s;\n",
|
||||
regnum, reg_mask, reg_mask);
|
||||
i, reg_mask, reg_mask);
|
||||
break;
|
||||
|
||||
default:
|
||||
shader_addline(buffer, "IN%lu%s = vec4(unsupported_input)%s;\n",
|
||||
regnum, reg_mask, reg_mask);
|
||||
i, reg_mask, reg_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1447,57 +1432,54 @@ void pshader_glsl_input_pack(
|
|||
|
||||
void vshader_glsl_output_unpack(
|
||||
SHADER_BUFFER* buffer,
|
||||
DWORD* semantics_out) {
|
||||
semantic* semantics_out) {
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < WINED3DSHADERDECLUSAGE_MAX_USAGE; i++) {
|
||||
for (i = 0; i < MAX_REG_OUTPUT; i++) {
|
||||
|
||||
DWORD reg = semantics_out[i];
|
||||
unsigned int regnum = reg & D3DSP_REGNUM_MASK;
|
||||
DWORD usage_token = semantics_out[i].usage;
|
||||
DWORD register_token = semantics_out[i].reg;
|
||||
DWORD usage, usage_idx;
|
||||
char reg_mask[6];
|
||||
|
||||
/* Uninitialized */
|
||||
if (!reg) continue;
|
||||
if (!usage_token) continue;
|
||||
|
||||
shader_glsl_get_output_register_swizzle(reg, reg_mask);
|
||||
usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
|
||||
usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
|
||||
shader_glsl_get_output_register_swizzle(register_token, reg_mask);
|
||||
|
||||
switch(i) {
|
||||
switch(usage) {
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_DIFFUSE:
|
||||
shader_addline(buffer, "gl_FrontColor%s = OUT%lu%s;\n", reg_mask, regnum, reg_mask);
|
||||
case D3DDECLUSAGE_COLOR:
|
||||
if (usage_idx == 0)
|
||||
shader_addline(buffer, "gl_FrontColor%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
|
||||
else if (usage_idx == 1)
|
||||
shader_addline(buffer, "gl_FrontSecondaryColor%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
|
||||
else
|
||||
shader_addline(buffer, "unsupported_color_output%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_SPECULAR:
|
||||
shader_addline(buffer, "gl_FrontSecondaryColor%s = OUT%lu%s;\n", reg_mask, regnum, reg_mask);
|
||||
case D3DDECLUSAGE_POSITION:
|
||||
shader_addline(buffer, "gl_Position%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_POSITION:
|
||||
shader_addline(buffer, "gl_Position%s = OUT%lu%s;\n", reg_mask, regnum, reg_mask);
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD0:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD1:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD2:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD3:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD4:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD5:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD6:
|
||||
case WINED3DSHADERDECLUSAGE_TEXCOORD7:
|
||||
|
||||
case D3DDECLUSAGE_TEXCOORD:
|
||||
shader_addline(buffer, "gl_TexCoord[%lu]%s = OUT%lu%s;\n",
|
||||
i - WINED3DSHADERDECLUSAGE_TEXCOORD0, reg_mask, regnum, reg_mask);
|
||||
usage_idx, reg_mask, i, reg_mask);
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_PSIZE:
|
||||
shader_addline(buffer, "gl_PointSize = OUT%lu.x;\n", regnum);
|
||||
shader_addline(buffer, "gl_PointSize = OUT%lu.x;\n", i);
|
||||
break;
|
||||
|
||||
case WINED3DSHADERDECLUSAGE_FOG:
|
||||
shader_addline(buffer, "gl_FogFragCoord%s = OUT%lu%s;\n", reg_mask, regnum, reg_mask);
|
||||
shader_addline(buffer, "gl_FogFragCoord%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
|
||||
break;
|
||||
|
||||
default:
|
||||
shader_addline(buffer, "unsupported_output%s = OUT%lu%s;\n", reg_mask, regnum, reg_mask);
|
||||
}
|
||||
}
|
||||
shader_addline(buffer, "unsupported_output%s = OUT%lu%s;\n", reg_mask, i, reg_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -609,6 +609,37 @@ static void vshader_set_limits(
|
|||
}
|
||||
}
|
||||
|
||||
BOOL vshader_get_input(
|
||||
IWineD3DVertexShader* iface,
|
||||
BYTE usage_req, BYTE usage_idx_req,
|
||||
unsigned int* regnum) {
|
||||
|
||||
IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_ATTRIBS; i++) {
|
||||
DWORD usage_token = This->semantics_in[i].usage;
|
||||
DWORD usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
|
||||
DWORD usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
|
||||
|
||||
if (usage_token && (usage == usage_req && usage_idx == usage_idx_req)) {
|
||||
*regnum = i;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL vshader_input_is_color(
|
||||
IWineD3DVertexShader* iface,
|
||||
unsigned int regnum) {
|
||||
|
||||
IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) iface;
|
||||
DWORD usage_token = This->semantics_in[regnum].usage;
|
||||
DWORD usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
|
||||
return usage == D3DDECLUSAGE_COLOR;
|
||||
}
|
||||
|
||||
/** Generate a vertex shader string using either GL_VERTEX_PROGRAM_ARB
|
||||
or GLSL and send it to the card */
|
||||
static VOID IWineD3DVertexShaderImpl_GenerateShader(
|
||||
|
|
|
@ -1283,6 +1283,11 @@ struct glsl_shader_prog_link {
|
|||
#define MAX_CONST_I 16
|
||||
#define MAX_CONST_B 16
|
||||
|
||||
typedef struct semantic {
|
||||
DWORD usage;
|
||||
DWORD reg;
|
||||
} semantic;
|
||||
|
||||
typedef struct shader_reg_maps {
|
||||
|
||||
char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */
|
||||
|
@ -1367,6 +1372,16 @@ extern const SHADER_OPCODE* shader_get_opcode(
|
|||
IWineD3DBaseShader *iface,
|
||||
const DWORD code);
|
||||
|
||||
/* Vertex shader utility functions */
|
||||
extern BOOL vshader_get_input(
|
||||
IWineD3DVertexShader* iface,
|
||||
BYTE usage_req, BYTE usage_idx_req,
|
||||
unsigned int* regnum);
|
||||
|
||||
extern BOOL vshader_input_is_color(
|
||||
IWineD3DVertexShader* iface,
|
||||
unsigned int regnum);
|
||||
|
||||
/* ARB_[vertex/fragment]_program helper functions */
|
||||
extern void shader_arb_load_constants(
|
||||
IWineD3DStateBlock* iface,
|
||||
|
@ -1437,12 +1452,12 @@ extern void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg);
|
|||
extern void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg);
|
||||
extern void pshader_glsl_input_pack(
|
||||
SHADER_BUFFER* buffer,
|
||||
DWORD* semantics_out);
|
||||
semantic* semantics_out);
|
||||
|
||||
/** GLSL Vertex Shader Prototypes */
|
||||
extern void vshader_glsl_output_unpack(
|
||||
SHADER_BUFFER* buffer,
|
||||
DWORD* semantics_out);
|
||||
semantic* semantics_out);
|
||||
|
||||
/*****************************************************************************
|
||||
* IDirect3DBaseShader implementation structure
|
||||
|
@ -1474,8 +1489,8 @@ typedef struct IWineD3DBaseShaderImpl {
|
|||
extern void shader_get_registers_used(
|
||||
IWineD3DBaseShader *iface,
|
||||
shader_reg_maps* reg_maps,
|
||||
DWORD* semantics_in,
|
||||
DWORD* semantics_out,
|
||||
semantic* semantics_in,
|
||||
semantic* semantics_out,
|
||||
CONST DWORD* pToken);
|
||||
|
||||
extern void shader_generate_glsl_declarations(
|
||||
|
@ -1558,8 +1573,8 @@ typedef struct IWineD3DVertexShaderImpl {
|
|||
DWORD usage;
|
||||
|
||||
/* Vertex shader input and output semantics */
|
||||
DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
|
||||
DWORD semantics_out [WINED3DSHADERDECLUSAGE_MAX_USAGE];
|
||||
semantic semantics_in [MAX_ATTRIBS];
|
||||
semantic semantics_out [MAX_REG_OUTPUT];
|
||||
|
||||
/* run time datas... */
|
||||
VSHADERDATA *data;
|
||||
|
@ -1589,7 +1604,7 @@ typedef struct IWineD3DPixelShaderImpl {
|
|||
IWineD3DDeviceImpl *wineD3DDevice;
|
||||
|
||||
/* Pixel shader input semantics */
|
||||
DWORD semantics_in [WINED3DSHADERDECLUSAGE_MAX_USAGE];
|
||||
semantic semantics_in [MAX_REG_INPUT];
|
||||
|
||||
/* run time data */
|
||||
PSHADERDATA *data;
|
||||
|
|
Loading…
Reference in a new issue