- pixel shader program dump code

- pixel shader code split into a new "COM object" (as done before for
  vertex shader)
- some fixes on Validate* functions call types
- add pixel shader (ie fragment_program) detection on caps code
This commit is contained in:
Raphael Junqueira 2003-06-04 22:45:57 +00:00 committed by Alexandre Julliard
parent 3d51c865d4
commit b050a3dbf1
6 changed files with 640 additions and 105 deletions

View File

@ -1,5 +1,5 @@
@ stdcall D3D8GetSWInfo()
@ stdcall DebugSetMute(long)
@ stdcall DebugSetMute()
@ stdcall Direct3DCreate8(long)
@ stdcall ValidatePixelShader(ptr ptr)
@ stdcall ValidateVertexShader(ptr ptr)

View File

@ -38,10 +38,9 @@ HRESULT WINAPI D3D8GetSWInfo(void)
return 0;
}
HRESULT WINAPI DebugSetMute(void)
void DebugSetMute(void)
{
FIXME("(void): stub\n");
return 0;
/* nothing to do */
}
IDirect3D8* WINAPI Direct3DCreate8(UINT SDKVersion)

View File

@ -99,17 +99,16 @@ typedef struct D3DSHADERSCALAR {
} D3DSHADERSCALAR;
#define D3D8_VSHADER_MAX_CONSTANTS 96
#define D3D8_PSHADER_MAX_CONSTANTS 96
typedef D3DSHADERVECTOR VSHADERCONSTANTS8[D3D8_VSHADER_MAX_CONSTANTS];
typedef struct SHADERDATA8 {
typedef struct VSHADERDATA8 {
/** Run Time Shader Function Constants */
/*D3DXBUFFER* constants;*/
VSHADERCONSTANTS8 C;
/** Shader Code as char ... */
CONST DWORD* code;
UINT codeLength;
} SHADERDATA8;
} VSHADERDATA8;
/** temporary here waiting for buffer code */
typedef struct VSHADERINPUTDATA8 {
@ -125,6 +124,34 @@ typedef struct VSHADEROUTPUTDATA8 {
D3DSHADERVECTOR oPts;
} VSHADEROUTPUTDATA8;
#define D3D8_PSHADER_MAX_CONSTANTS 32
typedef D3DSHADERVECTOR PSHADERCONSTANTS8[D3D8_PSHADER_MAX_CONSTANTS];
typedef struct PSHADERDATA8 {
/** Run Time Shader Function Constants */
/*D3DXBUFFER* constants;*/
PSHADERCONSTANTS8 C;
/** Shader Code as char ... */
CONST DWORD* code;
UINT codeLength;
} PSHADERDATA8;
/** temporary here waiting for buffer code */
typedef struct PSHADERINPUTDATA8 {
D3DSHADERVECTOR V[2];
D3DSHADERVECTOR T[8];
D3DSHADERVECTOR S[16];
/*D3DSHADERVECTOR R[12];*/
} PSHADERINPUTDATA8;
/** temporary here waiting for buffer code */
typedef struct PSHADEROUTPUTDATA8 {
D3DSHADERVECTOR oC[4];
D3DSHADERVECTOR oDepth;
} PSHADEROUTPUTDATA8;
/*
* External prototypes
*/
@ -155,6 +182,7 @@ void CreateStateBlock(LPDIRECT3DDEVICE8 iface);
typedef enum _GL_SupportedExt {
/* ARB */
ARB_FRAGMENT_PROGRAM,
ARB_MULTISAMPLE,
ARB_MULTITEXTURE,
ARB_POINT_PARAMETERS,
@ -173,6 +201,7 @@ typedef enum _GL_SupportedExt {
EXT_TEXTURE_LOD_BIAS,
EXT_VERTEX_WEIGHTING,
/* NVIDIA */
NV_FRAGMENT_PROGRAM,
NV_VERTEX_PROGRAM,
/* ATI */
EXT_VERTEX_SHADER,
@ -190,6 +219,19 @@ typedef enum _GL_VSVersion {
VS_VERSION_FORCE_DWORD = 0x7FFFFFFF
} GL_VSVersion;
typedef enum _GL_PSVersion {
PS_VERSION_NOT_SUPPORTED = 0x0,
PS_VERSION_10 = 0x10,
PS_VERSION_11 = 0x11,
PS_VERSION_12 = 0x12,
PS_VERSION_13 = 0x13,
PS_VERSION_14 = 0x14,
PS_VERSION_20 = 0x20,
PS_VERSION_30 = 0x30,
/*Force 32-bits*/
PS_VERSION_FORCE_DWORD = 0x7FFFFFFF
} GL_PSVersion;
typedef struct _GL_Info {
/**
* CAPS Constants
@ -198,11 +240,14 @@ typedef struct _GL_Info {
UINT max_textures;
UINT max_clipplanes;
GL_PSVersion ps_arb_version;
GL_PSVersion ps_nv_version;
GL_VSVersion vs_arb_version;
GL_VSVersion vs_nv_version;
GL_VSVersion vs_ati_version;
BOOL supported[25];
BOOL supported[30];
} GL_Info;
#define GL_LIMITS(ExtName) (This->direct3d8->gl_info.max_##ExtName)
@ -1017,6 +1062,7 @@ typedef struct SAVEDSTATES {
BOOL vertexShaderConstant;
BOOL vertexShaderDecl;
BOOL pixelShader;
BOOL pixelShaderConstant;
BOOL renderstate[HIGHEST_RENDER_STATE];
BOOL texture_state[8][HIGHEST_TEXTURE_STATE];
BOOL clipplane[MAX_CLIPPLANES];
@ -1091,7 +1137,6 @@ struct IDirect3DStateBlockImpl {
/* Pixel Shader */
DWORD PixelShader;
/* TODO: Pixel Shader Constant */
/* Indexed Vertex Blending */
D3DVERTEXBLENDFLAGS vertex_blend;
@ -1099,6 +1144,8 @@ struct IDirect3DStateBlockImpl {
/* Vertex Shader Constant */
D3DSHADERVECTOR vertexShaderConstant[D3D8_VSHADER_MAX_CONSTANTS];
/* Pixel Shader Constant */
D3DSHADERVECTOR pixelShaderConstant[D3D8_PSHADER_MAX_CONSTANTS];
};
/* exported Interfaces */
@ -1171,7 +1218,7 @@ struct IDirect3DVertexShaderImpl {
DWORD usage; /* 0 || D3DUSAGE_SOFTWAREPROCESSING */
DWORD version;
/* run time datas */
SHADERDATA8* data;
VSHADERDATA8* data;
VSHADERINPUTDATA8 input;
VSHADEROUTPUTDATA8 output;
};
@ -1210,18 +1257,21 @@ struct IDirect3DPixelShaderImpl {
/* The device, to be replaced by a IDirect3DDeviceImpl */
IDirect3DDevice8Impl* device;
/* TODO: Pixel Shader */
CONST DWORD* function;
DWORD* function;
UINT functionLength;
DWORD version;
/* run time datas */
SHADERDATA8* data;
PSHADERDATA8* data;
PSHADERINPUTDATA8 input;
PSHADEROUTPUTDATA8 output;
};
/* exported Interfaces */
extern HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData);
/* internal Interfaces */
extern DWORD WINAPI IDirect3DPixelShaderImpl_GetVersion(IDirect3DPixelShaderImpl* This);
/* temporary internal Interfaces */
extern HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader);
/**
@ -1229,7 +1279,10 @@ extern DWORD WINAPI IDirect3DPixelShaderImpl_GetVersion(IDirect3DPixelShaderImpl
*
* to see how not defined it here
*/
void GetSrcAndOpFromValue(DWORD iValue, BOOL isAlphaArg, GLenum* source, GLenum* operand);
void setupTextureStates(LPDIRECT3DDEVICE8 iface, DWORD Stage);
void set_tex_op(LPDIRECT3DDEVICE8 iface, BOOL isAlpha, int Stage, D3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
SHORT D3DFmtGetBpp(IDirect3DDevice8Impl* This, D3DFORMAT fmt);
GLint D3DFmt2GLIntFmt(IDirect3DDevice8Impl* This, D3DFORMAT fmt);

View File

@ -3570,7 +3570,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetTexture(LPDIRECT3DDEVICE8 iface, DWORD
IDirect3DBaseTexture8Impl_AddRef(*ppTexture);
return D3D_OK;
}
HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage,IDirect3DBaseTexture8* pTexture) {
HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD Stage, IDirect3DBaseTexture8* pTexture) {
IDirect3DBaseTexture8 *oldTxt;
BOOL reapplyStates = TRUE;
@ -3610,22 +3610,20 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
}
/* Decrement the count of the previous texture */
if (oldTxt != NULL) {
if (NULL != oldTxt) {
IDirect3DBaseTexture8Impl_Release(oldTxt);
}
if (pTexture) {
IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8)This->UpdateStateBlock->textures[Stage]);
if (NULL != pTexture) {
IDirect3DBaseTexture8Impl_AddRef((LPDIRECT3DBASETEXTURE8) This->UpdateStateBlock->textures[Stage]);
/* Now setup the texture appropraitly */
textureType = IDirect3DBaseTexture8Impl_GetType(pTexture);
if (textureType == D3DRTYPE_TEXTURE) {
IDirect3DTexture8Impl *pTexture2 = (IDirect3DTexture8Impl*) pTexture;
if ((void*) oldTxt == (void*) pTexture2 && pTexture2->Dirty == FALSE) {
TRACE("Skipping setting texture as old == new\n");
reapplyStates = FALSE;
if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
TRACE("Skipping setting texture as old == new\n");
reapplyStates = FALSE;
} else {
/* Standard 2D texture */
TRACE("Standard 2d texture\n");
@ -3635,19 +3633,29 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
IDirect3DTexture8Impl_PreLoad((LPDIRECT3DTEXTURE8) pTexture);
}
} else if (textureType == D3DRTYPE_VOLUMETEXTURE) {
/* Standard 3D (volume) texture */
if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
TRACE("Skipping setting texture as old == new\n");
reapplyStates = FALSE;
} else {
/* Standard 3D (volume) texture */
TRACE("Standard 3d texture\n");
This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_3D;
/* Load up the texture now */
IDirect3DVolumeTexture8Impl_PreLoad((LPDIRECT3DVOLUMETEXTURE8) pTexture);
}
} else if (textureType == D3DRTYPE_CUBETEXTURE) {
if (oldTxt == pTexture && TRUE == IDirect3DBaseTexture8Impl_IsDirty(pTexture)) {
TRACE("Skipping setting texture as old == new\n");
reapplyStates = FALSE;
} else {
/* Standard Cube texture */
TRACE("Standard Cube texture\n");
This->UpdateStateBlock->textureDimensions[Stage] = GL_TEXTURE_CUBE_MAP_ARB;
/* Load up the texture now */
IDirect3DCubeTexture8Impl_PreLoad((LPDIRECT3DCUBETEXTURE8) pTexture);
}
} else {
FIXME("(%p) : Incorrect type for a texture : (%d,%s)\n", This, textureType, debug_d3dressourcetype(textureType));
}
@ -3662,7 +3670,7 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetTexture(LPDIRECT3DDEVICE8 iface, DWORD
/* Even if the texture has been set to null, reapply the stages as a null texture to directx requires
a dummy texture in opengl, and we always need to ensure the current view of the TextureStates apply */
if (reapplyStates) {
setupTextureStates (iface, Stage);
setupTextureStates(iface, Stage);
}
return D3D_OK;
@ -4439,9 +4447,10 @@ HRESULT WINAPI IDirect3DDevice8Impl_GetIndices(LPDIRECT3DDEVICE8 iface, IDirec
HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface, CONST DWORD* pFunction, DWORD* pHandle) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
IDirect3DPixelShaderImpl* object;
HRESULT res;
UINT i;
FIXME("(%p) : PixelShader not fully supported yet\n", This);
TRACE_(d3d_shader)("(%p) : PixelShader not fully supported yet : Func=%p\n", This, pFunction);
if (NULL == pFunction || NULL == pHandle) {
return D3DERR_INVALIDCALL;
}
@ -4449,21 +4458,16 @@ HRESULT WINAPI IDirect3DDevice8Impl_CreatePixelShader(LPDIRECT3DDEVICE8 iface,
if (i >= sizeof(PixelShaders) / sizeof(IDirect3DPixelShaderImpl*)) {
return D3DERR_OUTOFVIDEOMEMORY;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
if (NULL == object) {
return D3DERR_OUTOFVIDEOMEMORY;
}
object->data = NULL; /* TODO */
PixelShaders[i] = object;
*pHandle = VS_HIGHESTFIXEDFXF + i;
object->function = pFunction;
for (i = 0; D3DPS_END() != pFunction[i]; ++i) ;
object->functionLength = i + 1;
return D3D_OK;
/** Create the Pixel Shader */
res = IDirect3DDeviceImpl_CreatePixelShader(This, pFunction, &object);
if (SUCCEEDED(res)) {
PixelShaders[i] = object;
*pHandle = VS_HIGHESTFIXEDFXF + i;
return D3D_OK;
}
*pHandle = 0xFFFFFFFF;
return res;
}
HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD Handle) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
@ -4474,22 +4478,22 @@ HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShader(LPDIRECT3DDEVICE8 iface, DW
/* Handle recording of state blocks */
if (This->isRecordingState) {
TRACE("Recording... not performing anything\n");
TRACE_(d3d_shader)("Recording... not performing anything\n");
return D3D_OK;
}
/* FIXME: Quieten when not being used */
if (Handle != 0) {
FIXME("(%p) : stub %ld\n", This, Handle);
FIXME_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
} else {
TRACE("(%p) : stub %ld\n", This, Handle);
TRACE_(d3d_shader)("(%p) : stub %ld\n", This, Handle);
}
return D3D_OK;
}
HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShader(LPDIRECT3DDEVICE8 iface, DWORD* pHandle) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
TRACE("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
TRACE_(d3d_shader)("(%p) : GetPixelShader returning %ld\n", This, This->StateBlock->PixelShader);
*pHandle = This->StateBlock->PixelShader;
return D3D_OK;
}
@ -4502,42 +4506,63 @@ HRESULT WINAPI IDirect3DDevice8Impl_DeletePixelShader(LPDIRECT3DDEVICE8 iface,
return D3DERR_INVALIDCALL;
}
object = PixelShaders[Handle - VS_HIGHESTFIXEDFXF];
TRACE("(%p) : freeing PixelShader %p\n", This, object);
TRACE_(d3d_shader)("(%p) : freeing PixelShader %p\n", This, object);
/* TODO: check validity of object before free */
if (NULL != object->function) HeapFree(GetProcessHeap(), 0, (void *)object->function);
HeapFree(GetProcessHeap(), 0, (void *)object->data);
HeapFree(GetProcessHeap(), 0, (void *)object);
PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = 0;
PixelShaders[Handle - VS_HIGHESTFIXEDFXF] = NULL;
return D3D_OK;
}
HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,CONST void* pConstantData, DWORD ConstantCount) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
FIXME("(%p) : stub\n", This);
return D3D_OK;
HRESULT WINAPI IDirect3DDevice8Impl_SetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, CONST void* pConstantData, DWORD ConstantCount) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
ERR_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu] invalid\n", This, Register);
return D3DERR_INVALIDCALL;
}
if (NULL == pConstantData) {
return D3DERR_INVALIDCALL;
}
if (ConstantCount > 1) {
FLOAT* f = (FLOAT*)pConstantData;
UINT i;
TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant C[%lu..%lu]=\n", This, Register, Register + ConstantCount - 1);
for (i = 0; i < ConstantCount; ++i) {
TRACE_(d3d_shader)("{%f, %f, %f, %f}\n", f[0], f[1], f[2], f[3]);
f += 4;
}
} else {
FLOAT* f = (FLOAT*) pConstantData;
TRACE_(d3d_shader)("(%p) : SetPixelShaderConstant, C[%lu]={%f, %f, %f, %f}\n", This, Register, f[0], f[1], f[2], f[3]);
}
This->UpdateStateBlock->Changed.pixelShaderConstant = TRUE;
memcpy(&This->UpdateStateBlock->pixelShaderConstant[Register], pConstantData, ConstantCount * 4 * sizeof(FLOAT));
return D3D_OK;
}
HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register,void* pConstantData, DWORD ConstantCount) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
FIXME("(%p) : stub\n", This);
return D3D_OK;
HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderConstant(LPDIRECT3DDEVICE8 iface, DWORD Register, void* pConstantData, DWORD ConstantCount) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
TRACE_(d3d_shader)("(%p) : C[%lu] count=%ld\n", This, Register, ConstantCount);
if (Register + ConstantCount > D3D8_PSHADER_MAX_CONSTANTS) {
return D3DERR_INVALIDCALL;
}
if (NULL == pConstantData) {
return D3DERR_INVALIDCALL;
}
memcpy(pConstantData, &This->UpdateStateBlock->pixelShaderConstant[Register], ConstantCount * 4 * sizeof(FLOAT));
return D3D_OK;
}
HRESULT WINAPI IDirect3DDevice8Impl_GetPixelShaderFunction(LPDIRECT3DDEVICE8 iface, DWORD Handle, void* pData, DWORD* pSizeOfData) {
ICOM_THIS(IDirect3DDevice8Impl,iface);
IDirect3DPixelShaderImpl* object;
object = PIXEL_SHADER(Handle);
if (NULL == object) {
return D3DERR_INVALIDCALL;
}
if (NULL == pData) {
*pSizeOfData = object->functionLength;
return D3D_OK;
}
if (*pSizeOfData < object->functionLength) {
*pSizeOfData = object->functionLength;
return D3DERR_MOREDATA;
}
TRACE("(%p) : GetPixelShaderFunction copying to %p\n", This, pData);
memcpy(pData, object->function, object->functionLength);
return D3D_OK;
}
return IDirect3DPixelShaderImpl_GetFunction(object, pData, (UINT*) pSizeOfData);
}
HRESULT WINAPI IDirect3DDevice8Impl_DrawRectPatch(LPDIRECT3DDEVICE8 iface, UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
ICOM_THIS(IDirect3DDevice8Impl,iface);

View File

@ -681,12 +681,6 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
int dblBuf[] = {GLX_RGBA,
GLX_STENCIL_SIZE, 8, /* 2 */
GLX_DEPTH_SIZE, 16, /* 4 */
#if 0
GLX_RED_SIZE, 8, /* 6 */
GLX_GREEN_SIZE, 8, /* 8 */
GLX_BLUE_SIZE, 8, /* 10 */
GLX_ALPHA_SIZE, 8, /* 12 */
#endif
GLX_DOUBLEBUFFER, None};
/* FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat */
@ -889,8 +883,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
*/
memset(&This->gl_info.supported, 0, sizeof(This->gl_info.supported));
This->gl_info.max_textures = 1;
This->gl_info.ps_arb_version = PS_VERSION_NOT_SUPPORTED;
This->gl_info.vs_arb_version = VS_VERSION_NOT_SUPPORTED;
This->gl_info.vs_nv_version = VS_VERSION_NOT_SUPPORTED;
This->gl_info.vs_ati_version = VS_VERSION_NOT_SUPPORTED;
/* Retrieve opengl defaults */
glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
@ -922,7 +918,11 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
/**
* ARB
*/
if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) {
if (strcmp(ThisExtn, "GL_ARB_fragment_program") == 0) {
This->gl_info.ps_arb_version = PS_VERSION_11;
FIXME(" FOUND: ARB Pixel Shader support - version=%02x\n", This->gl_info.ps_arb_version);
This->gl_info.supported[ARB_FRAGMENT_PROGRAM] = TRUE;
} else if (strcmp(ThisExtn, "GL_ARB_multisample") == 0) {
FIXME(" FOUND: ARB Multisample support\n");
This->gl_info.supported[ARB_MULTISAMPLE] = TRUE;
} else if (strcmp(ThisExtn, "GL_ARB_multitexture") == 0) {
@ -976,6 +976,10 @@ HRESULT WINAPI IDirect3D8Impl_CreateDevice (LPDIRECT3D8 iface,
/**
* NVIDIA
*/
} else if (strstr(ThisExtn, "GL_NV_fragment_program")) {
This->gl_info.ps_nv_version = PS_VERSION_11;
FIXME(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", This->gl_info.ps_nv_version);
This->gl_info.supported[NV_FRAGMENT_PROGRAM] = TRUE;
} else if (strstr(ThisExtn, "GL_NV_vertex_program")) {
This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program1_1")) ? VS_VERSION_11 : VS_VERSION_10);
This->gl_info.vs_nv_version = max(This->gl_info.vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2")) ? VS_VERSION_20 : VS_VERSION_10);

View File

@ -34,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
/* Shader debugging - Change the following line to enable debugging of software
vertex shaders */
#if 1
#if 0
# define VSTRACE(A) TRACE A
# define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w)
#else
@ -82,6 +82,8 @@ typedef struct SHADER_OPCODE {
const char* name;
CONST UINT num_params;
shader_fct_t soft_fct;
DWORD min_version;
DWORD max_version;
} SHADER_OPCODE;
/*******************************
@ -345,36 +347,36 @@ void vshader_lrp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D
* log, exp, frc, m*x* seems to be macros ins ... to see
*/
static CONST SHADER_OPCODE vshader_ins [] = {
{D3DSIO_NOP, "nop", 0, vshader_nop},
{D3DSIO_MOV, "mov", 2, vshader_mov},
{D3DSIO_ADD, "add", 3, vshader_add},
{D3DSIO_SUB, "sub", 3, vshader_sub},
{D3DSIO_MAD, "mad", 4, vshader_mad},
{D3DSIO_MUL, "mul", 3, vshader_mul},
{D3DSIO_RCP, "rcp", 2, vshader_rcp},
{D3DSIO_RSQ, "rsq", 2, vshader_rsq},
{D3DSIO_DP3, "dp3", 3, vshader_dp3},
{D3DSIO_DP4, "dp4", 3, vshader_dp4},
{D3DSIO_MIN, "min", 3, vshader_min},
{D3DSIO_MAX, "max", 3, vshader_max},
{D3DSIO_SLT, "slt", 3, vshader_slt},
{D3DSIO_SGE, "sge", 3, vshader_sge},
{D3DSIO_EXP, "exp", 2, vshader_exp},
{D3DSIO_LOG, "log", 2, vshader_log},
{D3DSIO_LIT, "lit", 2, vshader_lit},
{D3DSIO_DST, "dst", 3, vshader_dst},
{D3DSIO_LRP, "lrp", 5, vshader_lrp},
{D3DSIO_FRC, "frc", 2, vshader_frc},
{D3DSIO_M4x4, "m4x4", 3, vshader_m4x4},
{D3DSIO_M4x3, "m4x3", 3, vshader_m4x3},
{D3DSIO_M3x4, "m3x4", 3, vshader_m3x4},
{D3DSIO_M3x3, "m3x3", 3, vshader_m3x3},
{D3DSIO_M3x2, "m3x2", 3, vshader_m3x2},
{D3DSIO_NOP, "nop", 0, vshader_nop, 0, 0},
{D3DSIO_MOV, "mov", 2, vshader_mov, 0, 0},
{D3DSIO_ADD, "add", 3, vshader_add, 0, 0},
{D3DSIO_SUB, "sub", 3, vshader_sub, 0, 0},
{D3DSIO_MAD, "mad", 4, vshader_mad, 0, 0},
{D3DSIO_MUL, "mul", 3, vshader_mul, 0, 0},
{D3DSIO_RCP, "rcp", 2, vshader_rcp, 0, 0},
{D3DSIO_RSQ, "rsq", 2, vshader_rsq, 0, 0},
{D3DSIO_DP3, "dp3", 3, vshader_dp3, 0, 0},
{D3DSIO_DP4, "dp4", 3, vshader_dp4, 0, 0},
{D3DSIO_MIN, "min", 3, vshader_min, 0, 0},
{D3DSIO_MAX, "max", 3, vshader_max, 0, 0},
{D3DSIO_SLT, "slt", 3, vshader_slt, 0, 0},
{D3DSIO_SGE, "sge", 3, vshader_sge, 0, 0},
{D3DSIO_EXP, "exp", 2, vshader_exp, 0, 0},
{D3DSIO_LOG, "log", 2, vshader_log, 0, 0},
{D3DSIO_LIT, "lit", 2, vshader_lit, 0, 0},
{D3DSIO_DST, "dst", 3, vshader_dst, 0, 0},
{D3DSIO_LRP, "lrp", 5, vshader_lrp, 0, 0},
{D3DSIO_FRC, "frc", 2, vshader_frc, 0, 0},
{D3DSIO_M4x4, "m4x4", 3, vshader_m4x4, 0, 0},
{D3DSIO_M4x3, "m4x3", 3, vshader_m4x3, 0, 0},
{D3DSIO_M3x4, "m3x4", 3, vshader_m3x4, 0, 0},
{D3DSIO_M3x3, "m3x3", 3, vshader_m3x3, 0, 0},
{D3DSIO_M3x2, "m3x2", 3, vshader_m3x2, 0, 0},
/** FIXME: use direct access so add the others opcodes as stubs */
{D3DSIO_EXPP, "expp", 2, vshader_expp},
{D3DSIO_LOGP, "logp", 2, vshader_logp},
{D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0},
{D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0},
{0, NULL, 0, NULL}
{0, NULL, 0, NULL, 0, 0}
};
@ -546,7 +548,7 @@ HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShader(IDirect3DDevice8Impl* This
object->ref = 1;
object->usage = Usage;
object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SHADERDATA8));
object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VSHADERDATA8));
IDirect3DVertexShaderImpl_ParseProgram(object, pFunction);
@ -839,6 +841,458 @@ HRESULT WINAPI IDirect3DVertexShaderImpl_GetConstantF(IDirect3DVertexShaderImpl*
}
/**********************************************************************************************************************************************
**********************************************************************************************************************************************
**********************************************************************************************************************************************
**********************************************************************************************************************************************
**********************************************************************************************************************************************/
void pshader_texcoord(D3DSHADERVECTOR* d) {
}
void pshader_texkill(D3DSHADERVECTOR* d) {
}
void pshader_tex(D3DSHADERVECTOR* d) {
}
void pshader_texbem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texbeml(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texreg2ar(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texreg2gb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x2pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x2tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x3pad(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x3diff(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x3spec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
}
void pshader_texm3x3vspec(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_cnd(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) {
}
void pshader_def(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2, D3DSHADERVECTOR* s3) {
}
void pshader_texreg2rgb(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texdp3tex(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x2depth(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texdp3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texm3x3(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0) {
}
void pshader_texdepth(D3DSHADERVECTOR* d) {
}
void pshader_cmp(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1, D3DSHADERVECTOR* s2) {
}
void pshader_bem(D3DSHADERVECTOR* d, D3DSHADERVECTOR* s0, D3DSHADERVECTOR* s1) {
}
static CONST SHADER_OPCODE pshader_ins [] = {
{D3DSIO_NOP, "nop", 0, vshader_nop, 0, 0},
{D3DSIO_MOV, "mov", 2, vshader_mov, 0, 0},
{D3DSIO_ADD, "add", 3, vshader_add, 0, 0},
{D3DSIO_SUB, "sub", 3, vshader_sub, 0, 0},
{D3DSIO_MAD, "mad", 4, vshader_mad, 0, 0},
{D3DSIO_MUL, "mul", 3, vshader_mul, 0, 0},
{D3DSIO_RCP, "rcp", 2, vshader_rcp, 0, 0},
{D3DSIO_RSQ, "rsq", 2, vshader_rsq, 0, 0},
{D3DSIO_DP3, "dp3", 3, vshader_dp3, 0, 0},
{D3DSIO_DP4, "dp4", 3, vshader_dp4, 0, 0},
{D3DSIO_MIN, "min", 3, vshader_min, 0, 0},
{D3DSIO_MAX, "max", 3, vshader_max, 0, 0},
{D3DSIO_SLT, "slt", 3, vshader_slt, 0, 0},
{D3DSIO_SGE, "sge", 3, vshader_sge, 0, 0},
{D3DSIO_EXP, "exp", 2, vshader_exp, 0, 0},
{D3DSIO_LOG, "log", 2, vshader_log, 0, 0},
{D3DSIO_LIT, "lit", 2, vshader_lit, 0, 0},
{D3DSIO_DST, "dst", 3, vshader_dst, 0, 0},
{D3DSIO_LRP, "lrp", 5, vshader_lrp, 0, 0},
{D3DSIO_FRC, "frc", 2, vshader_frc, 0, 0},
{D3DSIO_M4x4, "m4x4", 3, vshader_m4x4, 0, 0},
{D3DSIO_M4x3, "m4x3", 3, vshader_m4x3, 0, 0},
{D3DSIO_M3x4, "m3x4", 3, vshader_m3x4, 0, 0},
{D3DSIO_M3x3, "m3x3", 3, vshader_m3x3, 0, 0},
{D3DSIO_M3x2, "m3x2", 3, vshader_m3x2, 0, 0},
{D3DSIO_TEXCOORD, "texcoord", 1, pshader_texcoord, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXKILL, "texkill", 1, pshader_texkill, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEX, "tex", 1, pshader_tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)},
{D3DSIO_TEXBEM, "texbem", 2, pshader_texbem, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXBEML, "texbeml", 2, pshader_texbeml, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXREG2AR, "texreg2ar", 2, pshader_texreg2ar, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXREG2GB, "texreg2gb", 2, pshader_texreg2gb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x2PAD, "texm3x2pad", 2, pshader_texm3x2pad, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x2TEX, "texm3x2tex", 2, pshader_texm3x2tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x3PAD, "texm3x3pad", 2, pshader_texm3x3pad, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x3TEX, "texm3x3tex", 2, pshader_texm3x3tex, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x3DIFF, "texm3x3diff", 2, pshader_texm3x3diff, D3DPS_VERSION(0,0), D3DPS_VERSION(0,0)},
{D3DSIO_TEXM3x3SPEC, "texm3x3spec", 3, pshader_texm3x3spec, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 2, pshader_texm3x3vspec, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
{D3DSIO_EXPP, "expp", 2, vshader_expp, 0, 0},
{D3DSIO_LOGP, "logp", 2, vshader_logp, 0, 0},
{D3DSIO_CND, "cnd", 4, pshader_cnd, D3DPS_VERSION(1,1), D3DPS_VERSION(1,4)},
{D3DSIO_DEF, "def", 5, pshader_def, D3DPS_VERSION(1,1), D3DPS_VERSION(3,0)},
{D3DSIO_TEXREG2RGB, "texbreg2rgb", 2, pshader_texreg2rgb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
{D3DSIO_TEXDP3TEX, "texdp3tex", 2, pshader_texdp3tex, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x2DEPTH, "texm3x2depth", 2, pshader_texm3x2depth, D3DPS_VERSION(1,3), D3DPS_VERSION(1,3)},
{D3DSIO_TEXDP3, "texdp3", 2, pshader_texdp3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
{D3DSIO_TEXM3x3, "texm3x3", 2, pshader_texm3x3, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
{D3DSIO_TEXDEPTH, "texdepth", 1, pshader_texdepth, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)},
{D3DSIO_CMP, "cmp", 4, pshader_cmp, D3DPS_VERSION(1,1), D3DPS_VERSION(3,0)},
{D3DSIO_BEM, "bem", 3, pshader_bem, D3DPS_VERSION(1,4), D3DPS_VERSION(1,4)},
{0, NULL, 0, NULL}
};
inline static const SHADER_OPCODE* pshader_program_get_opcode(const DWORD code) {
DWORD i = 0;
/** TODO: use dichotomic search */
while (NULL != pshader_ins[i].name) {
if ((code & D3DSI_OPCODE_MASK) == pshader_ins[i].opcode) {
return &pshader_ins[i];
}
++i;
}
return NULL;
}
inline static void pshader_program_dump_opcode(const SHADER_OPCODE* curOpcode, const DWORD code, const DWORD output) {
if (0 != (code & ~D3DSI_OPCODE_MASK)) {
DWORD mask = (code & ~D3DSI_OPCODE_MASK);
switch (mask) {
case 0x40000000: TRACE("+"); break;
default:
TRACE(" unhandled modifier(0x%08lx) ", mask);
}
}
TRACE("%s", curOpcode->name);
/**
* normally this is a destination reg modifier
* but in pixel shaders asm code its specified as:
* dp3_x4 t1.rgba, r1, c1
* or
* dp3_x2_sat r0, t0_bx2, v0_bx2
* so for better debbuging i use the same norm
*/
if (0 != (output & D3DSP_DSTSHIFT_MASK)) {
DWORD shift = (output & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT;
if (shift > 0) {
TRACE("_x%u", 1 << shift);
}
}
/**
* TODO: fix the divide shifts: d2, d4, d8
* so i have to find a sample
*/
if (0 != (output & D3DSP_DSTMOD_MASK)) {
DWORD mask = output & D3DSP_DSTMOD_MASK;
switch (mask) {
case D3DSPDM_SATURATE: TRACE("_sat"); break;
default:
TRACE("_unhandled_modifier(0x%08lx)", mask);
}
}
TRACE(" ");
}
inline static void pshader_program_dump_param(const DWORD param, int input) {
static const char* rastout_reg_names[] = { "oC0", "oC1", "oC2", "oC3", "oDepth" };
static const char swizzle_reg_chars[] = "rgba";
DWORD reg = param & 0x00001FFF;
DWORD regtype = ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT);
if ((param & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) {
TRACE("-");
}
switch (regtype << D3DSP_REGTYPE_SHIFT) {
case D3DSPR_TEMP:
TRACE("R[%lu]", reg);
break;
case D3DSPR_INPUT:
TRACE("V[%lu]", reg);
break;
case D3DSPR_CONST:
TRACE("C[%s%lu]", (reg & D3DVS_ADDRMODE_RELATIVE) ? "a0.x + " : "", reg);
break;
case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
TRACE("t[%lu]", reg);
break;
case D3DSPR_RASTOUT:
TRACE("%s", rastout_reg_names[reg]);
break;
case D3DSPR_ATTROUT:
TRACE("oD[%lu]", reg);
break;
case D3DSPR_TEXCRDOUT:
TRACE("oT[%lu]", reg);
break;
default:
break;
}
if (!input) {
/** operand output */
/**
* for better debugging traces it's done into opcode dump code
* @see pshader_program_dump_opcode
if (0 != (param & D3DSP_DSTMOD_MASK)) {
DWORD mask = param & D3DSP_DSTMOD_MASK;
switch (mask) {
case D3DSPDM_SATURATE: TRACE("_sat"); break;
default:
TRACE("_unhandled_modifier(0x%08lx)", mask);
}
}
if (0 != (param & D3DSP_DSTSHIFT_MASK)) {
DWORD shift = (param & D3DSP_DSTSHIFT_MASK) >> D3DSP_DSTSHIFT_SHIFT;
if (shift > 0) {
TRACE("_x%u", 1 << shift);
}
}
*/
if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) {
if (param & D3DSP_WRITEMASK_0) TRACE(".r");
if (param & D3DSP_WRITEMASK_1) TRACE(".g");
if (param & D3DSP_WRITEMASK_2) TRACE(".b");
if (param & D3DSP_WRITEMASK_3) TRACE(".a");
}
} else {
/** operand input */
DWORD swizzle = (param & D3DSP_SWIZZLE_MASK) >> D3DSP_SWIZZLE_SHIFT;
DWORD swizzle_x = swizzle & 0x03;
DWORD swizzle_y = (swizzle >> 2) & 0x03;
DWORD swizzle_z = (swizzle >> 4) & 0x03;
DWORD swizzle_w = (swizzle >> 6) & 0x03;
/**
* swizzle bits fields:
* WWZZYYXX
*/
if ((D3DSP_NOSWIZZLE >> D3DSP_SWIZZLE_SHIFT) != swizzle) { /* ! D3DVS_NOSWIZZLE == 0xE4 << D3DVS_SWIZZLE_SHIFT */
if (swizzle_x == swizzle_y &&
swizzle_x == swizzle_z &&
swizzle_x == swizzle_w) {
TRACE(".%c", swizzle_reg_chars[swizzle_x]);
} else {
TRACE(".%c%c%c%c",
swizzle_reg_chars[swizzle_x],
swizzle_reg_chars[swizzle_y],
swizzle_reg_chars[swizzle_z],
swizzle_reg_chars[swizzle_w]);
}
}
if (0 != (param & D3DSP_SRCMOD_MASK)) {
DWORD mask = param & D3DSP_SRCMOD_MASK;
/*TRACE("_modifier(0x%08lx) ", mask);*/
switch (mask) {
case D3DSPSM_NONE: break;
case D3DSPSM_NEG: break;
case D3DSPSM_BIAS: TRACE("_bias"); break;
case D3DSPSM_BIASNEG: TRACE("_bias"); break;
case D3DSPSM_SIGN: TRACE("_sign"); break;
case D3DSPSM_SIGNNEG: TRACE("_sign"); break;
case D3DSPSM_COMP: TRACE("_comp"); break;
case D3DSPSM_X2: TRACE("_x2"); break;
case D3DSPSM_X2NEG: TRACE("_bx2"); break;
case D3DSPSM_DZ: TRACE("_dz"); break;
case D3DSPSM_DW: TRACE("_dw"); break;
default:
TRACE("_unknown(0x%08lx)", mask);
}
}
}
}
inline static BOOL pshader_is_version_token(DWORD token) {
return 0xFFFF0000 == (token & 0xFFFF0000);
}
inline static BOOL pshader_is_comment_token(DWORD token) {
return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK);
}
/**
* Pixel Shaders
*
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader1_X/modifiers/sourceregistermodifiers.asp
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/PixelShader2_0/Registers/Registers.asp
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/d3d/interfaces/IDirect3DPixelShader9/_IDirect3DPixelShader9.asp
*
*/
inline static VOID IDirect3DPixelShaderImpl_ParseProgram(IDirect3DPixelShaderImpl* pshader, CONST DWORD* pFunction) {
const DWORD* pToken = pFunction;
const SHADER_OPCODE* curOpcode = NULL;
DWORD code;
DWORD len = 0;
DWORD i;
if (NULL != pToken) {
while (D3DPS_END() != *pToken) {
if (pshader_is_version_token(*pToken)) { /** version */
TRACE("ps.%lu.%lu\n", (*pToken >> 8) & 0x0F, (*pToken & 0x0F));
++pToken;
++len;
continue;
}
if (pshader_is_comment_token(*pToken)) { /** comment */
DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
++pToken;
/*TRACE("comment[%ld] ;%s\n", comment_len, (char*)pToken);*/
pToken += comment_len;
len += comment_len + 1;
continue;
}
code = *pToken;
curOpcode = pshader_program_get_opcode(code);
++pToken;
++len;
if (NULL == curOpcode) {
/* unkown current opcode ... */
while (*pToken & 0x80000000) {
TRACE("unrecognized opcode: %08lx\n", *pToken);
++pToken;
++len;
}
} else {
TRACE(" ");
pshader_program_dump_opcode(curOpcode, code, *pToken);
if (curOpcode->num_params > 0) {
pshader_program_dump_param(*pToken, 0);
++pToken;
++len;
for (i = 1; i < curOpcode->num_params; ++i) {
TRACE(", ");
if (D3DSIO_DEF != code) {
pshader_program_dump_param(*pToken, 1);
} else {
TRACE("%f", *((float*) pToken));
}
++pToken;
++len;
}
}
TRACE("\n");
}
pshader->functionLength = (len + 1) * sizeof(DWORD);
}
} else {
pshader->functionLength = 1; /* no Function defined use fixed function vertex processing */
}
if (NULL != pFunction) {
pshader->function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, pshader->functionLength);
memcpy(pshader->function, pFunction, pshader->functionLength);
} else {
pshader->function = NULL;
}
}
HRESULT WINAPI IDirect3DDeviceImpl_CreatePixelShader(IDirect3DDevice8Impl* This, CONST DWORD* pFunction, IDirect3DPixelShaderImpl** ppPixelShader) {
IDirect3DPixelShaderImpl* object;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DPixelShaderImpl));
if (NULL == object) {
*ppPixelShader = NULL;
return D3DERR_OUTOFVIDEOMEMORY;
}
/*object->lpVtbl = &Direct3DPixelShader9_Vtbl;*/
object->device = This;
object->ref = 1;
object->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PSHADERDATA8));
IDirect3DPixelShaderImpl_ParseProgram(object, pFunction);
*ppPixelShader = object;
return D3D_OK;
}
HRESULT WINAPI IDirect3DPixelShaderImpl_GetFunction(IDirect3DPixelShaderImpl* This, VOID* pData, UINT* pSizeOfData) {
if (NULL == pData) {
*pSizeOfData = This->functionLength;
return D3D_OK;
}
if (*pSizeOfData < This->functionLength) {
*pSizeOfData = This->functionLength;
return D3DERR_MOREDATA;
}
if (NULL == This->function) { /* no function defined */
TRACE("(%p) : GetFunction no User Function defined using NULL to %p\n", This, pData);
(*(DWORD **) pData) = NULL;
} else {
TRACE("(%p) : GetFunction copying to %p\n", This, pData);
memcpy(pData, This->function, This->functionLength);
}
return D3D_OK;
}
HRESULT WINAPI IDirect3DPixelShaderImpl_SetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, CONST FLOAT* pConstantData, UINT Vector4fCount) {
if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) {
return D3DERR_INVALIDCALL;
}
if (NULL == This->data) { /* temporary while datas not supported */
FIXME("(%p) : VertexShader_SetConstant not fully supported yet\n", This);
return D3DERR_INVALIDCALL;
}
memcpy(&This->data->C[StartRegister], pConstantData, Vector4fCount * 4 * sizeof(FLOAT));
return D3D_OK;
}
HRESULT WINAPI IDirect3DPixelShaderImpl_GetConstantF(IDirect3DPixelShaderImpl* This, UINT StartRegister, FLOAT* pConstantData, UINT Vector4fCount) {
if (StartRegister + Vector4fCount > D3D8_VSHADER_MAX_CONSTANTS) {
return D3DERR_INVALIDCALL;
}
if (NULL == This->data) { /* temporary while datas not supported */
return D3DERR_INVALIDCALL;
}
memcpy(pConstantData, &This->data->C[StartRegister], Vector4fCount * 4 * sizeof(FLOAT));
return D3D_OK;
}
/**********************************************************************************************************************************************
**********************************************************************************************************************************************
**********************************************************************************************************************************************
**********************************************************************************************************************************************
**********************************************************************************************************************************************/
/***********************************************************************
* ValidateVertexShader (D3D8.@)
*/
@ -850,7 +1304,7 @@ BOOL WINAPI ValidateVertexShader(LPVOID what, LPVOID toto) {
/***********************************************************************
* ValidatePixelShader (D3D8.@)
*/
BOOL WINAPI ValidatePixelShader(LPVOID what) {
FIXME("(void): stub: %p\n", what);
BOOL WINAPI ValidatePixelShader(LPVOID what, LPVOID toto) {
FIXME("(void): stub: %p %p\n", what, toto);
return TRUE;
}