Commit 7c482cb9 authored by Oliver Stieber's avatar Oliver Stieber Committed by Alexandre Julliard

wined3d: Vertex shader 8 support.

Start to add support for DirectX 8 vertex shaders, constants and registers are now correctly assigned and loaded allowing support for most basic d3d8 shaders.
parent 38bfd5e6
......@@ -114,7 +114,7 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexShader(LPDIRECT3DDEVICE9 iface,
object->ref = 1;
object->lpVtbl = &Direct3DVertexShader9_Vtbl;
hrc= IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
hrc= IWineD3DDevice_CreateVertexShader(This->WineD3DDevice, NULL /* declaration */, pFunction, &object->wineD3DVertexShader, (IUnknown *)object);
if (FAILED(hrc)) {
......
......@@ -1611,13 +1611,44 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* iface,
}
/* http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/programmable/vertexshaders/vscreate.asp */
HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, CONST DWORD *pFunction, IWineD3DVertexShader** ppVertexShader, IUnknown *parent) {
HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice *iface, CONST DWORD *pDeclaration, CONST DWORD *pFunction, IWineD3DVertexShader **ppVertexShader, IUnknown *parent) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVertexShaderImpl *object; /* NOTE: impl usage is ok, this is a create */
HRESULT hr = D3D_OK;
D3DCREATEOBJECTINSTANCE(object, VertexShader)
TRACE("(%p) : Created Vertex shader %p\n", This, *ppVertexShader);
IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction);
hr = IWineD3DVertexShader_SetFunction(*ppVertexShader, pFunction);
if (D3D_OK != hr) {
FIXME("(%p) : Failed to set the function, returning D3DERR_INVALIDCALL\n", iface);
IWineD3DVertexShader_Release(*ppVertexShader);
return D3DERR_INVALIDCALL;
}
#if 0 /* TODO: In D3D* SVP is atatched to the shader, in D3D9 it's attached to the device and isn't stored in the stateblock. */
if(Usage == WINED3DUSAGE_SOFTWAREVERTEXPROCESSING) {
/* Foo */
} else {
/* Bar */
}
#endif
/* If a vertex declaration has been passed, save it to the vertex shader, this affects d3d8 only. */
if (pDeclaration != NULL) {
IWineD3DVertexDeclaration *vertexDeclaration;
hr = IWineD3DDevice_CreateVertexDeclaration(iface, pDeclaration, &vertexDeclaration ,NULL);
if (D3D_OK == hr) {
TRACE("(%p) : Setting vertex declaration to %p\n", This, vertexDeclaration);
object->vertexDeclaration = vertexDeclaration;
} else {
FIXME("(%p) : Failed to set the declaration, returning D3DERR_INVALIDCALL\n", iface);
IWineD3DVertexShader_Release(*ppVertexShader);
return D3DERR_INVALIDCALL;
}
}
return D3D_OK;
}
......
......@@ -208,29 +208,7 @@ static DWORD IWineD3DVertexDeclarationImpl_ParseToken8(const DWORD* pToken) {
break;
case D3DVSD_TOKEN_CONSTMEM:
{
DWORD i;
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count);
++pToken;
for (i = 0; i < count; ++i) {
#if 0
TRACE(" c[%lu] = (0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
constaddress,
*pToken,
*(pToken + 1),
*(pToken + 2),
*(pToken + 3));
#endif
TRACE(" c[%lu] = (%8f, %8f, %8f, %8f)\n",
constaddress,
*(const float*) pToken,
*(const float*) (pToken + 1),
*(const float*) (pToken + 2),
*(const float*) (pToken + 3));
pToken += 4;
++constaddress;
}
tokenlen = (4 * count) + 1;
}
break;
......@@ -270,8 +248,9 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
DWORD tokenlen;
DWORD tokentype;
DWORD nTokens = 0;
DWORD offset = 0;
D3DVERTEXELEMENT9 convTo9[128];
int offset = 0;
WINED3DVERTEXELEMENT convToW[128];
/* TODO: find out where rhw (or positionT) is for declaration8 */
Decl8to9Lookup decl8to9Lookup[MAX_D3DVSDE];
MAKE_LOOKUP(D3DVSDE_POSITION, D3DDECLUSAGE_POSITION, 0);
......@@ -311,15 +290,48 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
convTo9[nTokens].Stream = stream;
convTo9[nTokens].Method = D3DDECLMETHOD_DEFAULT;
convTo9[nTokens].Usage = decl8to9Lookup[reg].usage;
convTo9[nTokens].UsageIndex = decl8to9Lookup[reg].usageIndex;
convTo9[nTokens].Type = type;
convTo9[nTokens].Offset = offset;
convToW[nTokens].Stream = stream;
convToW[nTokens].Method = D3DDECLMETHOD_DEFAULT;
convToW[nTokens].Usage = decl8to9Lookup[reg].usage;
convToW[nTokens].UsageIndex = decl8to9Lookup[reg].usageIndex;
convToW[nTokens].Type = type;
convToW[nTokens].Offset = offset;
convToW[nTokens].Reg = reg;
offset += glTypeLookup[type][1] * glTypeLookup[type][4];
++nTokens;
}/* TODO: Constants. */
} else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0x10000000 & tokentype ) {
TRACE(" 0x%08lx SKIP(%lu)\n", tokentype, ((tokentype & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
offset += sizeof(DWORD) * ((tokentype & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT);
} else if (D3DVSD_TOKEN_CONSTMEM == tokentype) {
DWORD i;
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
if (This->constants == NULL ) {
This->constants = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_VSHADER_CONSTANTS * 4 * sizeof(float));
}
TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count);
for (i = 0; i < count; ++i) {
TRACE(" c[%lu] = (0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n",
constaddress,
*pToken,
*(pToken + 1),
*(pToken + 2),
*(pToken + 3));
This->constants[constaddress * 4] = *(const float*) (pToken+ i * 4 + 1);
This->constants[constaddress * 4 + 1] = *(const float *)(pToken + i * 4 + 2);
This->constants[constaddress * 4 + 2] = *(const float *)(pToken + i * 4 + 3);
This->constants[constaddress * 4 + 3] = *(const float *)(pToken + i * 4 + 4);
FIXME(" c[%lu] = (%8f, %8f, %8f, %8f)\n",
constaddress,
*(const float*) (pToken+ i * 4 + 1),
*(const float*) (pToken + i * 4 + 2),
*(const float*) (pToken + i * 4 +3),
*(const float*) (pToken + i * 4 + 4));
++constaddress;
}
}
len += tokenlen;
pToken += tokenlen;
}
......@@ -327,8 +339,8 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
/* here D3DVSD_END() */
len += IWineD3DVertexDeclarationImpl_ParseToken8(pToken);
convTo9[nTokens].Stream = 0xFF;
convTo9[nTokens].Type = D3DDECLTYPE_UNUSED;
convToW[nTokens].Stream = 0xFF;
convToW[nTokens].Type = D3DDECLTYPE_UNUSED;
++nTokens;
/* compute size */
......@@ -337,22 +349,12 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
This->pDeclaration8 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->declaration8Length);
memcpy(This->pDeclaration8, pDecl, This->declaration8Length);
/* compute convTo9 size */
This->declaration9NumElements = nTokens;
/* compute convToW size */
This->declarationWNumElements = nTokens;
/* copy the convTo9 declaration */
This->pDeclaration9 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nTokens * sizeof(D3DVERTEXELEMENT9));
memcpy(This->pDeclaration9, convTo9, nTokens * sizeof(D3DVERTEXELEMENT9));
#if 0 /* TODO: This looks like overkill so I've removed it. */
{
D3DVERTEXELEMENT9* pIt = This->pDeclaration9;
TRACE("dumping of D3D9 Conversion:\n");
while (0xFF != pIt->Stream) {
IWineD3DVertexDeclarationImpl_ParseToken9(pIt);
++pIt;
}
IWineD3DVertexDeclarationImpl_ParseToken9(pIt);
}
#endif
This->pDeclarationWine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nTokens * sizeof(WINED3DVERTEXELEMENT));
memcpy(This->pDeclarationWine, convToW, nTokens * sizeof(WINED3DVERTEXELEMENT));
/* returns */
return D3D_OK;
}
......@@ -360,6 +362,7 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
static HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DVertexDeclaration* iface, const D3DVERTEXELEMENT9* pDecl) {
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
const D3DVERTEXELEMENT9* pToken = pDecl;
int i;
TRACE("(%p) : pDecl(%p)\n", This, pDecl);
......@@ -376,6 +379,13 @@ static HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DVertexDec
This->pDeclaration9 = HeapAlloc(GetProcessHeap(), 0, This->declaration9NumElements * sizeof(D3DVERTEXELEMENT9));
memcpy(This->pDeclaration9, pDecl, This->declaration9NumElements * sizeof(D3DVERTEXELEMENT9));
/* copy to wine style declaration */
This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, This->declaration9NumElements * sizeof(WINED3DVERTEXELEMENT));
for(i = 0; i < This->declaration9NumElements; ++i) {
memcpy(This->pDeclarationWine + i, This->pDeclaration9 + i, sizeof(D3DVERTEXELEMENT9));
}
This->declarationWNumElements = This->declaration9NumElements;
return D3D_OK;
}
......
......@@ -2000,6 +2000,7 @@ ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface) {
TRACE("(%p) : Releasing from %ld\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
if (ref == 0) {
if (This->vertexDeclaration) IWineD3DVertexDeclaration_Release(This->vertexDeclaration);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
......
......@@ -854,8 +854,14 @@ typedef struct IWineD3DVertexDeclarationImpl {
DWORD declaration8Length;
/** dx9+ */
D3DVERTEXELEMENT9* pDeclaration9;
D3DVERTEXELEMENT9 *pDeclaration9;
UINT declaration9NumElements;
WINED3DVERTEXELEMENT *pDeclarationWine;
UINT declarationWNumElements;
float *constants;
} IWineD3DVertexDeclarationImpl;
extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl;
......@@ -1168,8 +1174,9 @@ typedef struct IWineD3DVertexShaderImpl {
CHAR constantsUsedBitmap[256];
/* FIXME: This needs to be populated with some flags of VS_CONSTANT_NOT_USED, VS_CONSTANT_CONSTANT, VS_CONSTANT_INTEGER, VS_CONSTANT_BOOLEAN, VS_CONSTANT_FLOAT, a half byte bitmap will be the best option, but I'll keep it as chards for siplicity */
/* run time datas... */
VSHADERDATA* data;
VSHADERDATA *data;
GLuint prgId;
IWineD3DVertexDeclaration *vertexDeclaration;
#if 0 /* needs reworking */
/* run time datas */
VSHADERINPUTDATA input;
......
......@@ -282,7 +282,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
STDMETHOD(CreateQuery)(THIS_ WINED3DQUERYTYPE Type, struct IWineD3DQuery **ppQuery, IUnknown *pParent);
STDMETHOD(CreateAdditionalSwapChain)(THIS_ WINED3DPRESENT_PARAMETERS *pPresentationParameters, struct IWineD3DSwapChain **pSwapChain, IUnknown *pParent, D3DCB_CREATERENDERTARGETFN pFn, D3DCB_CREATEDEPTHSTENCILSURFACEFN pFn2);
STDMETHOD(CreateVertexDeclaration)(THIS_ CONST VOID* pDeclaration, struct IWineD3DVertexDeclaration** ppDecl, IUnknown* pParent) PURE;
STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pFunction, struct IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE;
STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD *pDeclaration, CONST DWORD* pFunction, struct IWineD3DVertexShader** ppShader, IUnknown *pParent) PURE;
STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction, struct IWineD3DPixelShader** ppShader, IUnknown *pParent) PURE;
STDMETHOD(EvictManagedResources)(THIS) PURE;
STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE;
......@@ -414,7 +414,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IUnknown)
#define IWineD3DDevice_CreateQuery(p,a,b,c) (p)->lpVtbl->CreateQuery(p,a,b,c)
#define IWineD3DDevice_CreateAdditionalSwapChain(p,a,b,c,d,e) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b,c,d,e)
#define IWineD3DDevice_CreateVertexDeclaration(p,b,c,d) (p)->lpVtbl->CreateVertexDeclaration(p,b,c,d)
#define IWineD3DDevice_CreateVertexShader(p,a,b,c) (p)->lpVtbl->CreateVertexShader(p,a,b,c)
#define IWineD3DDevice_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d)
#define IWineD3DDevice_CreatePixelShader(p,a,b,c) (p)->lpVtbl->CreatePixelShader(p,a,b,c)
#define IWineD3DDevice_EvictManagedResources(p) (p)->lpVtbl->EvictManagedResources(p)
#define IWineD3DDevice_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p)
......
......@@ -449,6 +449,7 @@ typedef struct _WINED3DVERTEXELEMENT {
BYTE Method;
BYTE Usage;
BYTE UsageIndex;
BYTE Reg; /* DirectX 8 */
} WINED3DVERTEXELEMENT, *LPWINED3DVERTEXELEMENT;
......
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