static inline BOOL swizzled_attribs_differ(IWineD3DVertexShaderImpl *This, IWineD3DVertexDeclarationImpl *vdecl) { UINT i, j, k; BOOL found; DWORD usage_token; DWORD usage; DWORD usage_idx; for(i = 0; i < vdecl->declarationWNumElements; i++) { /* Ignore tesselated streams and the termination entry(position0, stream 255, unused) */ if(vdecl->pDeclarationWine[i].Stream >= MAX_STREAMS || vdecl->pDeclarationWine[i].Type == WINED3DDECLTYPE_UNUSED) continue; for(j = 0; j < MAX_ATTRIBS; j++) { if(!This->baseShader.reg_maps.attributes[j]) continue; usage_token = This->semantics_in[j].usage; usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; if(vdecl->pDeclarationWine[i].Usage != usage || vdecl->pDeclarationWine[i].UsageIndex != usage_idx) { continue; } found = FALSE; for(k = 0; k < This->num_swizzled_attribs; k++) { if(This->swizzled_attribs[k].usage == usage && This->swizzled_attribs[k].idx == usage_idx) { found = TRUE; } } if(!found && vdecl->pDeclarationWine[i].Type == WINED3DDECLTYPE_D3DCOLOR) { TRACE("Attribute %s%d is D3DCOLOR now but wasn't before\n", debug_d3ddeclusage(usage), usage_idx); return TRUE; } if( found && vdecl->pDeclarationWine[i].Type != WINED3DDECLTYPE_D3DCOLOR) { TRACE("Attribute %s%d was D3DCOLOR before but is not any more\n", debug_d3ddeclusage(usage), usage_idx); return TRUE; } } } return FALSE; }
static void dump_wined3dvertexelement(const WINED3DVERTEXELEMENT *element) { TRACE(" format: %s (%#x)\n", debug_d3dformat(element->format), element->format); TRACE(" input_slot: %u\n", element->input_slot); TRACE(" offset: %u\n", element->offset); TRACE("output_slot: %u\n", element->output_slot); TRACE(" method: %s (%#x)\n", debug_d3ddeclmethod(element->method), element->method); TRACE(" usage: %s (%#x)\n", debug_d3ddeclusage(element->usage), element->usage); TRACE(" usage_idx: %u\n", element->usage_idx); }
static inline void find_swizzled_attribs(IWineD3DVertexDeclaration *declaration, IWineD3DVertexShaderImpl *This) { UINT num = 0, i, j; UINT numoldswizzles = This->num_swizzled_attribs; IWineD3DVertexDeclarationImpl *decl = (IWineD3DVertexDeclarationImpl *) declaration; DWORD usage_token, usage, usage_idx; BOOL found; attrib_declaration oldswizzles[sizeof(This->swizzled_attribs) / sizeof(This->swizzled_attribs[0])]; /* Back up the old swizzles to keep attributes that are undefined in the current declaration */ memcpy(oldswizzles, This->swizzled_attribs, sizeof(oldswizzles)); memset(This->swizzled_attribs, 0, sizeof(This->swizzled_attribs[0]) * MAX_ATTRIBS); for(i = 0; i < decl->num_swizzled_attribs; i++) { for(j = 0; j < MAX_ATTRIBS; j++) { if(!This->baseShader.reg_maps.attributes[j]) continue; usage_token = This->semantics_in[j].usage; usage = (usage_token & WINED3DSP_DCL_USAGE_MASK) >> WINED3DSP_DCL_USAGE_SHIFT; usage_idx = (usage_token & WINED3DSP_DCL_USAGEINDEX_MASK) >> WINED3DSP_DCL_USAGEINDEX_SHIFT; if(decl->swizzled_attribs[i].usage == usage && decl->swizzled_attribs[i].idx == usage_idx) { This->swizzled_attribs[num].usage = usage; This->swizzled_attribs[num].idx = usage_idx; num++; } } } /* Add previously converted attributes back in if they are not defined in the current declaration */ for(i = 0; i < numoldswizzles; i++) { found = FALSE; for(j = 0; j < decl->declarationWNumElements; j++) { if(oldswizzles[i].usage == decl->pDeclarationWine[j].Usage && oldswizzles[i].idx == decl->pDeclarationWine[j].UsageIndex) { found = TRUE; } } if(found) { /* This previously converted attribute is declared in the current declaration. Either it is * already in the new array, or it should not be there. Skip it */ continue; } /* We have a previously swizzled attribute that is not defined by the current vertex declaration. * Insert it into the new conversion array to keep it in the old defined state. Otherwise we end up * recompiling if the old decl is used again because undefined attributes are reset to no swizzling. * In the reverse way(attribute was not swizzled and is not declared in new declaration) the attrib * stays unswizzled as well because it isn't found in the oldswizzles array */ for(j = 0; j < num; j++) { if(oldswizzles[i].usage > This->swizzled_attribs[j].usage || ( oldswizzles[i].usage == This->swizzled_attribs[j].usage && oldswizzles[i].idx > This->swizzled_attribs[j].idx)) { memmove(&This->swizzled_attribs[j + 1], &This->swizzled_attribs[j], sizeof(This->swizzled_attribs) - (sizeof(This->swizzled_attribs[0]) * (j + 1))); break; } } This->swizzled_attribs[j].usage = oldswizzles[i].usage; This->swizzled_attribs[j].idx = oldswizzles[i].idx; num++; } TRACE("New swizzled attributes array\n"); for(i = 0; i < num; i++) { TRACE("%d: %s(%d), %d\n", i, debug_d3ddeclusage(This->swizzled_attribs[i].usage), This->swizzled_attribs[i].usage, This->swizzled_attribs[i].idx); } This->num_swizzled_attribs = num; }