d3d8: Move loading local d3d8 vertex shader constants from wined3d to d3d8.

This commit is contained in:
H. Verbeet 2007-02-13 23:12:40 +01:00 committed by Alexandre Julliard
parent dea795f7ac
commit efed9aea1f
9 changed files with 221 additions and 116 deletions

View File

@ -618,6 +618,7 @@ typedef struct IDirect3DPixelShader8Impl {
*
* to see how not defined it here
*/
void load_local_constants(const DWORD *d3d8_elements, IWineD3DVertexShader *wined3d_vertex_shader);
/* Callbacks */
extern HRESULT WINAPI D3D8CB_CreateSurface(IUnknown *device, IUnknown *pSuperior, UINT Width, UINT Height,

View File

@ -1237,6 +1237,8 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateVertexShader(LPDIRECT3DDEVICE8
object->handle = handle;
*handle = object;
*ppShader = (handle - This->shader_handles) + VS_HIGHESTFIXEDFXF + 1;
load_local_constants(pDeclaration, object->wineD3DVertexShader);
}
}
TRACE("(%p) : returning %p (handle %#x)\n", This, object, *ppShader);

View File

@ -68,6 +68,162 @@ static ULONG WINAPI IDirect3DVertexDeclaration8Impl_Release(IDirect3DVertexDecla
return ref_count;
}
static const char *debug_d3dvsdt_type(D3DVSDT_TYPE d3dvsdt_type)
{
switch (d3dvsdt_type)
{
#define D3DVSDT_TYPE_TO_STR(u) case u: return #u
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT1);
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT2);
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT3);
D3DVSDT_TYPE_TO_STR(D3DVSDT_FLOAT4);
D3DVSDT_TYPE_TO_STR(D3DVSDT_D3DCOLOR);
D3DVSDT_TYPE_TO_STR(D3DVSDT_UBYTE4);
D3DVSDT_TYPE_TO_STR(D3DVSDT_SHORT2);
D3DVSDT_TYPE_TO_STR(D3DVSDT_SHORT4);
#undef D3DVSDT_TYPE_TO_STR
default:
FIXME("Unrecognized D3DVSDT_TYPE %#x\n", d3dvsdt_type);
return "unrecognized";
}
}
static const char *debug_d3dvsde_register(D3DVSDE_REGISTER d3dvsde_register)
{
switch (d3dvsde_register)
{
#define D3DVSDE_REGISTER_TO_STR(u) case u: return #u
D3DVSDE_REGISTER_TO_STR(D3DVSDE_POSITION);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_BLENDWEIGHT);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_BLENDINDICES);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_NORMAL);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_PSIZE);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_DIFFUSE);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_SPECULAR);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD0);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD1);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD2);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD3);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD4);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD5);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD6);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_TEXCOORD7);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_POSITION2);
D3DVSDE_REGISTER_TO_STR(D3DVSDE_NORMAL2);
#undef D3DVSDE_REGISTER_TO_STR
default:
FIXME("Unrecognized D3DVSDE_REGISTER %#x\n", d3dvsde_register);
return "unrecognized";
}
}
static size_t parse_token(const DWORD* pToken)
{
const DWORD token = *pToken;
size_t tokenlen = 1;
switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */
case D3DVSD_TOKEN_NOP:
TRACE(" 0x%08x NOP()\n", token);
break;
case D3DVSD_TOKEN_STREAM:
if (token & D3DVSD_STREAMTESSMASK)
{
TRACE(" 0x%08x STREAM_TESS()\n", token);
} else {
TRACE(" 0x%08x STREAM(%u)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT));
}
break;
case D3DVSD_TOKEN_STREAMDATA:
if (token & 0x10000000)
{
TRACE(" 0x%08x SKIP(%u)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
} else {
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
TRACE(" 0x%08x REG(%s, %s)\n", token, debug_d3dvsde_register(reg), debug_d3dvsdt_type(type));
}
break;
case D3DVSD_TOKEN_TESSELLATOR:
if (token & 0x10000000)
{
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
TRACE(" 0x%08x TESSUV(%s) as %s\n", token, debug_d3dvsde_register(reg), debug_d3dvsdt_type(type));
} else {
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
DWORD regout = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
DWORD regin = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT);
TRACE(" 0x%08x TESSNORMAL(%s, %s) as %s\n", token, debug_d3dvsde_register(regin),
debug_d3dvsde_register(regout), debug_d3dvsdt_type(type));
}
break;
case D3DVSD_TOKEN_CONSTMEM:
{
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
tokenlen = (4 * count) + 1;
}
break;
case D3DVSD_TOKEN_EXT:
{
DWORD count = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
DWORD extinfo = ((token & D3DVSD_EXTINFOMASK) >> D3DVSD_EXTINFOSHIFT);
TRACE(" 0x%08x EXT(%u, %u)\n", token, count, extinfo);
/* todo ... print extension */
tokenlen = count + 1;
}
break;
case D3DVSD_TOKEN_END:
TRACE(" 0x%08x END()\n", token);
break;
default:
TRACE(" 0x%08x UNKNOWN\n", token);
/* argg error */
}
return tokenlen;
}
void load_local_constants(const DWORD *d3d8_elements, IWineD3DVertexShader *wined3d_vertex_shader)
{
const DWORD *token = d3d8_elements;
while (*token != D3DVSD_END())
{
if (((*token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) == D3DVSD_TOKEN_CONSTMEM)
{
DWORD count = ((*token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
DWORD constant_idx = ((*token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
HRESULT hr;
if (TRACE_ON(d3d8))
{
DWORD i;
for (i = 0; i < count; ++i)
{
TRACE("c[%u] = (%8f, %8f, %8f, %8f)\n",
constant_idx,
*(const float *)(token + i * 4 + 1),
*(const float *)(token + i * 4 + 2),
*(const float *)(token + i * 4 + 3),
*(const float *)(token + i * 4 + 4));
}
}
hr = IWineD3DVertexShader_SetLocalConstantsF(wined3d_vertex_shader, constant_idx, (const float *)token+1, count);
if (FAILED(hr)) ERR("Failed setting shader constants\n");
}
token += parse_token(token);
}
}
const IDirect3DVertexDeclaration8Vtbl Direct3DVertexDeclaration8_Vtbl =
{
IDirect3DVertexDeclaration8Impl_QueryInterface,

View File

@ -54,19 +54,6 @@ static void shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_
local_constant* lconst;
int i;
if (!constant_list) {
if (TRACE_ON(d3d_shader)) {
for (i = 0; i < max_constants; ++i) {
TRACE_(d3d_constants)("Loading constants %i: %f, %f, %f, %f\n", i,
constants[i * 4 + 0], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
}
}
for (i = 0; i < max_constants; ++i) {
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4)));
}
checkGLcall("glProgramEnvParameter4fvARB()");
} else {
if (TRACE_ON(d3d_shader)) {
LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
i = constant->idx;
@ -80,7 +67,6 @@ static void shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, i, constants + (i * 4)));
}
checkGLcall("glProgramEnvParameter4fvARB()");
}
/* Load immediate constants */
if (TRACE_ON(d3d_shader)) {
@ -113,14 +99,6 @@ void shader_arb_load_constants(
if (useVertexShader) {
IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl*) stateBlock->vertexDecl;
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
/* Load DirectX 8 float constants for vertex shader */
shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
GL_LIMITS(vshader_constantsF),
vertexDeclaration->constants, NULL);
}
/* Load DirectX 9 float constants for vertex shader */
shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,

View File

@ -105,31 +105,11 @@ void shader_glsl_load_psamplers(
static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL_Info *gl_info,
unsigned int max_constants, float* constants, GLhandleARB *constant_locations,
struct list *constant_list) {
constant_entry *constant;
local_constant* lconst;
GLhandleARB tmp_loc;
int i;
if (!constant_list) {
if (TRACE_ON(d3d_shader)) {
for (i = 0; i < max_constants; ++i) {
tmp_loc = constant_locations[i];
if (tmp_loc != -1) {
TRACE_(d3d_constants)("Loading constants %i: %f, %f, %f, %f\n", i,
constants[i * 4 + 0], constants[i * 4 + 1],
constants[i * 4 + 2], constants[i * 4 + 3]);
}
}
}
for (i = 0; i < max_constants; ++i) {
tmp_loc = constant_locations[i];
if (tmp_loc != -1) {
/* We found this uniform name in the program - go ahead and send the data */
GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, constants + (i * 4)));
}
}
checkGLcall("glUniform4fvARB()");
} else {
constant_entry *constant;
if (TRACE_ON(d3d_shader)) {
LIST_FOR_EACH_ENTRY(constant, constant_list, constant_entry, entry) {
i = constant->idx;
@ -150,7 +130,6 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl* This, WineD3D_GL
}
}
checkGLcall("glUniform4fvARB()");
}
/* Load immediate constants */
if (TRACE_ON(d3d_shader)) {
@ -313,18 +292,11 @@ void shader_glsl_load_constants(
if (useVertexShader) {
IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl*)stateBlock->vertexDecl;
GLint pos;
constant_locations = stateBlock->glsl_program->vuniformF_locations;
constant_list = &stateBlock->set_vconstantsF;
if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
/* Load DirectX 8 float constants/uniforms for vertex shader */
shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF),
vertexDeclaration->constants, constant_locations, NULL);
}
/* Load DirectX 9 float constants/uniforms for vertex shader */
shader_glsl_load_constantsF(vshader, gl_info, GL_LIMITS(vshader_constantsF),
stateBlock->vertexShaderConstantF, constant_locations, constant_list);

View File

@ -315,35 +315,6 @@ IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
} else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0x10000000 & tokentype ) {
TRACE(" 0x%08x SKIP(%u)\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,
((IWineD3DImpl*)This->wineD3DDevice->wineD3D)->gl_info.max_vshader_constantsF * 4 * sizeof(float));
}
TRACE(" 0x%08x CONST(%u, %u)\n", token, constaddress, count);
for (i = 0; i < count; ++i) {
TRACE(" c[%u] = (0x%08x, 0x%08x, 0x%08x, 0x%08x)\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[%u] = (%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;
@ -405,7 +376,6 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat
if (ref == 0) {
HeapFree(GetProcessHeap(), 0, This->pDeclaration8);
HeapFree(GetProcessHeap(), 0, This->pDeclarationWine);
HeapFree(GetProcessHeap(), 0, This->constants);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;

View File

@ -1221,6 +1221,32 @@ static void WINAPI IWineD3DVertexShaderImpl_FakeSemantics(IWineD3DVertexShader *
}
}
/* Set local constants for d3d8 shaders */
static HRESULT WINAPI IWIneD3DVertexShaderImpl_SetLocalConstantsF(IWineD3DVertexShader *iface,
UINT start_idx, const float *src_data, UINT count) {
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
UINT i, end_idx;
TRACE("(%p) : start_idx %u, src_data %p, count %u\n", This, start_idx, src_data, count);
end_idx = start_idx + count;
if (end_idx > GL_LIMITS(vshader_constantsF)) {
WARN("end_idx %u > float constants limit %u\n", end_idx, GL_LIMITS(vshader_constantsF));
end_idx = GL_LIMITS(vshader_constantsF);
}
for (i = start_idx; i < end_idx; ++i) {
local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
if (!lconst) return E_OUTOFMEMORY;
lconst->idx = i;
CopyMemory(lconst->value, src_data + i * 4, 4 * sizeof(float));
list_add_head(&This->baseShader.constantsF, &lconst->entry);
}
return D3D_OK;
}
static HRESULT WINAPI IWineD3DVertexShaderImpl_CompileShader(IWineD3DVertexShader *iface) {
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
CONST DWORD *function = This->baseShader.function;
@ -1259,5 +1285,6 @@ const IWineD3DVertexShaderVtbl IWineD3DVertexShader_Vtbl =
/*** IWineD3DVertexShader methods ***/
IWineD3DVertexShaderImpl_GetDevice,
IWineD3DVertexShaderImpl_GetFunction,
IWineD3DVertexShaderImpl_FakeSemantics
IWineD3DVertexShaderImpl_FakeSemantics,
IWIneD3DVertexShaderImpl_SetLocalConstantsF
};

View File

@ -1122,9 +1122,6 @@ typedef struct IWineD3DVertexDeclarationImpl {
WINED3DVERTEXELEMENT *pDeclarationWine;
UINT declarationWNumElements;
float *constants;
} IWineD3DVertexDeclarationImpl;
extern const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl;

View File

@ -1450,6 +1450,7 @@ DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader)
STDMETHOD(GetDevice)(THIS_ IWineD3DDevice** ppDevice) PURE;
STDMETHOD(GetFunction)(THIS_ VOID *pData, UINT *pSizeOfData) PURE;
STDMETHOD_(void, FakeSemantics)(THIS_ struct IWineD3DVertexDeclaration *vertex_declaration) PURE;
STDMETHOD(SetLocalConstantsF)(THIS_ UINT start_idx, const float *src_data, UINT count) PURE;
};
#undef INTERFACE
@ -1467,6 +1468,7 @@ DECLARE_INTERFACE_(IWineD3DVertexShader,IWineD3DBaseShader)
#define IWineD3DVertexShader_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
#define IWineD3DVertexShader_GetFunction(p,a,b) (p)->lpVtbl->GetFunction(p,a,b)
#define IWineD3DVertexShader_FakeSemantics(p,a) (p)->lpVtbl->FakeSemantics(p,a)
#define IWineD3DVertexShader_SetLocalConstantsF(p,a,b,c) (p)->lpVtbl->SetLocalConstantsF(p,a,b,c)
#endif
/*****************************************************************************