[WINED3D 2] Hook software shaders into drawStridedSlow
Ivan Gyurdiev
ivg231 at gmail.com
Fri Jul 7 01:21:28 CDT 2006
- split drawStridedSlow into "prepare" and "draw" segments -
fixed_prepare_draw (vs swshader_prepare_draw), and draw_vertex.
- do not load or unload attribute arrays for software shaders
make software shaders go through the drawStridedSlow code path
- disable VBOs for software shaders
- delete the old (disabled) swshader hook.
-------------- next part --------------
---
dlls/wined3d/device.c | 4
dlls/wined3d/drawprim.c | 786 +++++++++++++---------------------------
dlls/wined3d/wined3d_private.h | 9
3 files changed, 267 insertions(+), 532 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 7176954..a61eaae 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -732,10 +732,12 @@ static HRESULT WINAPI IWineD3DDeviceImpl
* dx7 apps.
* There is a IDirect3DVertexBuffer7::Optimize call after which the buffer can't be locked any
* more. In this call we can convert dx7 buffers too.
+ *
+ * Also, disable VBOs for software shaders.
*/
conv = ((FVF & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW ) || (FVF & (D3DFVF_DIFFUSE | D3DFVF_SPECULAR));
if( GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) && Pool != WINED3DPOOL_SYSTEMMEM && !(Usage & WINED3DUSAGE_DYNAMIC) &&
- (dxVersion > 7 || !conv) ) {
+ (dxVersion > 7 || !conv) && wined3d_settings.vs_selected_mode != SHADER_SW) {
CreateVBO(object);
/* DX7 buffers can be locked directly into the VBO(no conversion, see above */
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 7b9d133..e15f74b 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -791,137 +791,6 @@ #endif
}
}
-#if 0 /* TODO: Software Shaders */
-/* Draw a single vertex using this information */
-static void draw_vertex(IWineD3DDevice *iface, /* interface */
- BOOL isXYZ, float x, float y, float z, float rhw, /* xyzn position*/
- BOOL isNormal, float nx, float ny, float nz, /* normal */
- BOOL isDiffuse, float *dRGBA, /* 1st colors */
- BOOL isSpecular, float *sRGB, /* 2ndry colors */
- BOOL isPtSize, float ptSize, /* pointSize */
- WINED3DVECTOR_4 *texcoords, int *numcoords) /* texture info */
-{
- unsigned int textureNo;
- float s, t, r, q;
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- /* Diffuse -------------------------------- */
- if (isDiffuse) {
- glColor4fv(dRGBA);
- VTRACE(("glColor4f: r,g,b,a=%f,%f,%f,%f\n", dRGBA[0], dRGBA[1], dRGBA[2], dRGBA[3]));
- }
-
- /* Specular Colour ------------------------------------------*/
- if (isSpecular) {
- if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- GL_EXTCALL(glSecondaryColor3fvEXT(sRGB));
- VTRACE(("glSecondaryColor4f: r,g,b=%f,%f,%f\n", sRGB[0], sRGB[1], sRGB[2]));
- } else {
- VTRACE(("Specular color extensions not supplied\n"));
- }
- }
-
- /* Normal -------------------------------- */
- if (isNormal) {
- VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
- glNormal3f(nx, ny, nz);
- }
-
- /* Point Size ----------------------------------------------*/
- if (isPtSize) {
-
- /* no such functionality in the fixed function GL pipeline */
- FIXME("Cannot change ptSize here in openGl\n");
- }
-
- /* Texture coords --------------------------- */
- for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
-
- if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
- FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
- continue ;
- }
-
- /* Query tex coords */
- if (This->stateBlock->textures[textureNo] != NULL) {
-
- int coordIdx = This->stateBlock->textureState[textureNo][D3DTSS_TEXCOORDINDEX];
- if (coordIdx >= MAX_TEXTURES) {
- VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
- continue;
- } else if (numcoords[coordIdx] == 0) {
- TRACE("tex: %d - Skipping tex coords, as no data supplied or no coords supplied\n", textureNo);
- continue;
- } else {
-
- /* Initialize vars */
- s = 0.0f;
- t = 0.0f;
- r = 0.0f;
- q = 0.0f;
-
- switch (numcoords[coordIdx]) {
- case 4: q = texcoords[coordIdx].w; /* drop through */
- case 3: r = texcoords[coordIdx].z; /* drop through */
- case 2: t = texcoords[coordIdx].y; /* drop through */
- case 1: s = texcoords[coordIdx].x;
- }
-
- switch (numcoords[coordIdx]) { /* Supply the provided texture coords */
- case D3DTTFF_COUNT1:
- VTRACE(("tex:%d, s=%f\n", textureNo, s));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GLMULTITEXCOORD1F(textureNo, s);
- } else {
- glTexCoord1f(s);
- }
- break;
- case D3DTTFF_COUNT2:
- VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GLMULTITEXCOORD2F(textureNo, s, t);
- } else {
- glTexCoord2f(s, t);
- }
- break;
- case D3DTTFF_COUNT3:
- VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GLMULTITEXCOORD3F(textureNo, s, t, r);
- } else {
- glTexCoord3f(s, t, r);
- }
- break;
- case D3DTTFF_COUNT4:
- VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GLMULTITEXCOORD4F(textureNo, s, t, r, q);
- } else {
- glTexCoord4f(s, t, r, q);
- }
- break;
- default:
- FIXME("Should not get here as numCoords should be 0->4 (%x)!\n", numcoords[coordIdx]);
- }
- }
- }
- } /* End of textures */
-
- /* Position -------------------------------- */
- if (isXYZ) {
- if (1.0f == rhw || rhw < 0.00001f) {
- VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
- glVertex3f(x, y, z);
- } else {
- /* Cannot optimize by dividing through by rhw as rhw is required
- later for perspective in the GL pipeline for vertex shaders */
- VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
- glVertex4f(x,y,z,rhw);
- }
- }
-}
-#endif /* TODO: Software shaders */
-
void loadNumberedArrays(
IWineD3DDevice *iface,
WineDirect3DVertexStridedData *sd,
@@ -1400,350 +1269,275 @@ #endif
return;
}
-/*
- * Actually draw using the supplied information.
- * Slower GL version which extracts info about each vertex in turn
- */
-
-static void drawStridedSlow(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd,
- UINT NumVertexes, GLenum glPrimType,
- const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
-
- unsigned int textureNo = 0;
- unsigned int texture_idx = 0;
- const short *pIdxBufS = NULL;
- const long *pIdxBufL = NULL;
- LONG SkipnStrides = 0;
- LONG vx_index;
- float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */
- float nx = 0.0f, ny = 0.0, nz = 0.0f; /* normal x,y,z coordinates */
- float rhw = 0.0f; /* rhw */
- float ptSize = 0.0f; /* Point size */
- DWORD diffuseColor = 0xFFFFFFFF; /* Diffuse Color */
- DWORD specularColor = 0; /* Specular Color */
- IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
-
- TRACE("Using slow vertex array code\n");
+static inline void swshader_prepare_draw(
+ IWineD3DDeviceImpl* This,
+ WineDirect3DVertexStridedData *strided,
+ int skip_strides,
+ draw_context* draw) {
+
+ This = NULL;
+ strided = NULL;
+ skip_strides = 0;
+ draw = NULL;
+ FIXME("Stub\n");
+}
- /* Variable Initialization */
- if (idxData != NULL) {
- if (idxSize == 2) pIdxBufS = (const short *) idxData;
- else pIdxBufL = (const long *) idxData;
+static inline void fixed_prepare_draw(
+ IWineD3DDeviceImpl* This,
+ WineDirect3DVertexStridedData *strided,
+ int skip_strides,
+ draw_context* draw) {
+
+ int i, textureNo;
+
+ const WINED3DSHADERVECTOR def_position = { 0.0f, 0.0f, 0.0f, 0.0f };
+ const WINED3DSHADERVECTOR def_diffuse = { 1.0f, 1.0f, 1.0f, 1.0f };
+ const WINED3DSHADERVECTOR def_specular = { 0.0f, 0.0f, 0.0f, 1.0f };
+ const WINED3DSHADERVECTOR def_normal = { 0.0f, 0.0f, 1.0f, 0.0f };
+ const WINED3DSHADERVECTOR def_texcoord = { 0.0f, 0.0f, 0.0f, 1.0f };
+
+ /* Defaults */
+ draw->is_transformed = FALSE;
+ memcpy(&draw->diffuse, &def_diffuse, sizeof(WINED3DSHADERVECTOR));
+ memcpy(&draw->specular, &def_specular, sizeof(WINED3DSHADERVECTOR));
+ memcpy(&draw->position, &def_position, sizeof(WINED3DSHADERVECTOR));
+ memcpy(&draw->normal, &def_normal, sizeof(WINED3DSHADERVECTOR));
+ for (i = 0; i < GL_LIMITS(texture_stages); i++) {
+ if (This->stateBlock->textures[i] != NULL)
+ memcpy(&draw->texcoords[i], &def_texcoord, sizeof(WINED3DSHADERVECTOR));
}
- /* Start drawing in GL */
- VTRACE(("glBegin(%x)\n", glPrimType));
- glBegin(glPrimType);
+ /* Position ---------------------------- */
+ if (strided->u.s.position.lpData) {
+ float *ptrToCoords =
+ (float *)(strided->u.s.position.lpData + (skip_strides * strided->u.s.position.dwStride));
- /* We shouldn't start this function if any VBO is involved. Should I put a safety check here?
- * Guess it's not necessary(we crash then anyway) and would only eat CPU time
- */
+ draw->position.x = ptrToCoords[0];
+ draw->position.y = ptrToCoords[1];
+ draw->position.z = ptrToCoords[2];
+ draw->position.w = 1.0;
- /* For each primitive */
- for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
+ /* Data contains rhw */
+ if (strided->u.s.position.dwType == D3DDECLTYPE_FLOAT4) {
+ float rhw = ptrToCoords[3];
- /* Initialize diffuse color */
- diffuseColor = 0xFFFFFFFF;
+ draw->is_transformed = TRUE;
- /* For indexed data, we need to go a few more strides in */
- if (idxData != NULL) {
+ /* FIXUP: divide by rhw */
+ if (rhw > eps && rhw < -eps) {
+ draw->position.w = 1.0 / rhw;
+ draw->position.x /= rhw;
+ draw->position.y /= rhw;
+ draw->position.z /= rhw;
- /* Indexed so work out the number of strides to skip */
- if (idxSize == 2) {
- VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
- SkipnStrides = pIdxBufS[startIdx + vx_index];
- } else {
- VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index]));
- SkipnStrides = pIdxBufL[startIdx + vx_index];
- }
+ } else draw->position.w = rhw;
}
+ VTRACE(("position = { %f, %f, %f, %f }\n",
+ draw->position.x, draw->position.y, draw->position.z, draw->position.w));
+ }
- /* Position Information ------------------ */
- if (sd->u.s.position.lpData != NULL) {
+ /* Normal --------------------------------- */
+ if (strided->u.s.normal.lpData) {
+ float *ptrToCoords =
+ (float *)(strided->u.s.normal.lpData + (skip_strides * strided->u.s.normal.dwStride));
+ draw->normal.x = ptrToCoords[0];
+ draw->normal.y = ptrToCoords[1];
+ draw->normal.z = ptrToCoords[2];
+ VTRACE(("normal = { %f, %f, %f }\n", draw->normal.x, draw->normal.y, draw->normal.z));
+ }
+
+ /* Diffuse -------------------------------- */
+ if (strided->u.s.diffuse.lpData) {
+
+ DWORD *ptrToCoords =
+ (DWORD *)(strided->u.s.diffuse.lpData + (skip_strides * strided->u.s.diffuse.dwStride));
+ draw->diffuse.x = D3DCOLOR_B(ptrToCoords[0]);
+ draw->diffuse.y = D3DCOLOR_G(ptrToCoords[0]);
+ draw->diffuse.z = D3DCOLOR_R(ptrToCoords[0]);
+ draw->diffuse.w = D3DCOLOR_A(ptrToCoords[0]);
+ VTRACE(("diffuse = { %f, %f, %f, %f }\n",
+ draw->diffuse.x, draw->diffuse.y, draw->diffuse.z, draw->diffuse.w));
+ }
+ /* Specular -------------------------------- */
+ if (strided->u.s.specular.lpData) {
+
+ DWORD *ptrToCoords =
+ (DWORD *)(strided->u.s.specular.lpData + (skip_strides * strided->u.s.specular.dwStride));
+ draw->specular.x = D3DCOLOR_B(ptrToCoords[0]);
+ draw->specular.y = D3DCOLOR_G(ptrToCoords[0]);
+ draw->specular.z = D3DCOLOR_R(ptrToCoords[0]);
+ draw->specular.w = D3DCOLOR_A(ptrToCoords[0]);
+ VTRACE(("specular = { %f, %f, %f, %f }\n",
+ draw->specular.x, draw->specular.y, draw->specular.z, draw->specular.w));
+ }
- float *ptrToCoords = (float *)(sd->u.s.position.lpData + (SkipnStrides * sd->u.s.position.dwStride));
- x = ptrToCoords[0];
- y = ptrToCoords[1];
- z = ptrToCoords[2];
- rhw = 1.0;
- VTRACE(("x,y,z=%f,%f,%f\n", x,y,z));
+ /* Blending ---------------------------------- */
+ if (strided->u.s.blendWeights.lpData != NULL ||
+ strided->u.s.blendMatrixIndices.lpData != NULL) {
- /* RHW follows, only if transformed, ie 4 floats were provided */
- if (sd->u.s.position.dwType == D3DDECLTYPE_FLOAT4) {
- rhw = ptrToCoords[3];
- VTRACE(("rhw=%f\n", rhw));
- }
- }
+ FIXME("Blending not supported yet\n");
+ }
- /* Blending data -------------------------- */
- if (sd->u.s.blendWeights.lpData != NULL) {
- /* float *ptrToCoords = (float *)(sd->u.s.blendWeights.lpData + (SkipnStrides * sd->u.s.blendWeights.dwStride)); */
- FIXME("Blending not supported yet\n");
+ /* Point Size -------------------------------- */
+ if (strided->u.s.pSize.lpData != NULL) {
- if (sd->u.s.blendMatrixIndices.lpData != NULL) {
- /*DWORD *ptrToCoords = (DWORD *)(sd->u.s.blendMatrixIndices.lpData + (SkipnStrides * sd->u.s.blendMatrixIndices.dwStride));*/
- }
- }
+ FIXME("Point Size not supported yet\n");
+ }
- /* Vertex Normal Data (untransformed only)- */
- if (sd->u.s.normal.lpData != NULL) {
+ /* Texture ---------------------------------- */
+ for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
- float *ptrToCoords = (float *)(sd->u.s.normal.lpData + (SkipnStrides * sd->u.s.normal.dwStride));
- nx = ptrToCoords[0];
- ny = ptrToCoords[1];
- nz = ptrToCoords[2];
- VTRACE(("nx,ny,nz=%f,%f,%f\n", nx, ny, nz));
- }
+ unsigned int idx;
+ if (This->stateBlock->textures[textureNo] == NULL)
+ continue;
- /* Point Size ----------------------------- */
- if (sd->u.s.pSize.lpData != NULL) {
+ idx = This->stateBlock->textureState[textureNo][D3DTSS_TEXCOORDINDEX];
+ if (strided->u.s.texCoords[idx].lpData) {
+
+ float* ptrToCoords =
+ (float *)(strided->u.s.texCoords[idx].lpData + (skip_strides * strided->u.s.texCoords[idx].dwStride));
+ unsigned int numcoords = strided->u.s.texCoords[idx].dwType + 1;
+ switch (numcoords) {
+ case 4: draw->texcoords[textureNo].w = ptrToCoords[3]; /* drop through */
+ case 3: draw->texcoords[textureNo].z = ptrToCoords[2]; /* drop through */
+ case 2: draw->texcoords[textureNo].y = ptrToCoords[1]; /* drop through */
+ case 1: draw->texcoords[textureNo].x = ptrToCoords[0];
+ }
+
+ /* Projected is more 'fun' - Move the last coord to the 'q'
+ * parameter (see comments under D3DTSS_TEXTURETRANSFORMFLAGS */
+ if ((This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) &&
+ (This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED)) {
+
+ if (This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
+ switch (numcoords) {
+ case 0: /* Drop Through */
+ case 1:
+ FIXME("D3DTTFF_PROJECTED but only zero or one coordinate?\n");
+ break;
+ case 2:
+ draw->texcoords[textureNo].w = draw->texcoords[textureNo].y;
+ draw->texcoords[textureNo].y = 0.0;
+ break;
+ case 3:
+ draw->texcoords[textureNo].w = draw->texcoords[textureNo].z;
+ draw->texcoords[textureNo].z = 0.0;
+ break;
+ case 4: /* Nop here */
+ break;
+ default:
+ FIXME("Unexpected D3DTSS_TEXTURETRANSFORMFLAGS value of %ld\n",
+ This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] &
+ D3DTTFF_PROJECTED);
+ }
+ }
+ }
- float *ptrToCoords = (float *)(sd->u.s.pSize.lpData + (SkipnStrides * sd->u.s.pSize.dwStride));
- ptSize = ptrToCoords[0];
- VTRACE(("ptSize=%f\n", ptSize));
- FIXME("No support for ptSize yet\n");
- }
+ VTRACE(("tex: %d (%u coords) = { %f %f %f %f }\n", idx,
+ numcoords, draw->texcoords[textureNo].x, draw->texcoords[textureNo].y,
+ draw->texcoords[textureNo].z, draw->texcoords[textureNo].w));
+ }
+ }
+}
- /* Diffuse -------------------------------- */
- if (sd->u.s.diffuse.lpData != NULL) {
+/* Draw a single vertex using the supplied data */
+static inline void draw_vertex(
+ IWineD3DDeviceImpl* This,
+ draw_context* draw) {
- DWORD *ptrToCoords = (DWORD *)(sd->u.s.diffuse.lpData + (SkipnStrides * sd->u.s.diffuse.dwStride));
- diffuseColor = ptrToCoords[0];
- VTRACE(("diffuseColor=%lx\n", diffuseColor));
- }
+ unsigned int textureNo, texture_idx;
- /* Specular -------------------------------- */
- if (sd->u.s.specular.lpData != NULL) {
+ /* Draw Vertex: Texture coords --------------------------- */
+ for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
- DWORD *ptrToCoords = (DWORD *)(sd->u.s.specular.lpData + (SkipnStrides * sd->u.s.specular.dwStride));
- specularColor = ptrToCoords[0];
- VTRACE(("specularColor=%lx\n", specularColor));
+ if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
+ FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
+ continue ;
}
- /* Texture coords --------------------------- */
- for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
-
- if (!GL_SUPPORT(ARB_MULTITEXTURE) && textureNo > 0) {
- FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
- continue ;
- }
-
- /* Query tex coords */
- if (This->stateBlock->textures[textureNo] != NULL) {
-
- int coordIdx = This->stateBlock->textureState[textureNo][D3DTSS_TEXCOORDINDEX];
- float *ptrToCoords = NULL;
- float s = 0.0, t = 0.0, r = 0.0, q = 0.0;
-
- if (coordIdx > 7) {
- VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
- continue;
- } else if (coordIdx < 0) {
- FIXME("tex: %d - Coord index %d is less than zero, expect a crash.\n", textureNo, coordIdx);
- continue;
- }
-
- ptrToCoords = (float *)(sd->u.s.texCoords[coordIdx].lpData + (SkipnStrides * sd->u.s.texCoords[coordIdx].dwStride));
- if (sd->u.s.texCoords[coordIdx].lpData == NULL) {
- TRACE("tex: %d - Skipping tex coords, as no data supplied\n", textureNo);
- continue;
- } else {
-
- int coordsToUse = sd->u.s.texCoords[coordIdx].dwType + 1; /* 0 == D3DDECLTYPE_FLOAT1 etc */
-
- /* The coords to supply depend completely on the fvf / vertex shader */
- switch (coordsToUse) {
- case 4: q = ptrToCoords[3]; /* drop through */
- case 3: r = ptrToCoords[2]; /* drop through */
- case 2: t = ptrToCoords[1]; /* drop through */
- case 1: s = ptrToCoords[0];
- }
-
- /* Projected is more 'fun' - Move the last coord to the 'q'
- parameter (see comments under D3DTSS_TEXTURETRANSFORMFLAGS */
- if ((This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) &&
- (This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED)) {
-
- if (This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED) {
- switch (coordsToUse) {
- case 0: /* Drop Through */
- case 1:
- FIXME("D3DTTFF_PROJECTED but only zero or one coordinate?\n");
- break;
- case 2:
- q = t;
- t = 0.0;
- coordsToUse = 4;
- break;
- case 3:
- q = r;
- r = 0.0;
- coordsToUse = 4;
- break;
- case 4: /* Nop here */
- break;
- default:
- FIXME("Unexpected D3DTSS_TEXTURETRANSFORMFLAGS value of %ld\n",
- This->stateBlock->textureState[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
- }
- }
- }
-
- switch (coordsToUse) { /* Supply the provided texture coords */
- case D3DTTFF_COUNT1:
- VTRACE(("tex:%d, s=%f\n", textureNo, s));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GL_EXTCALL(glMultiTexCoord1fARB(texture_idx, s));
- } else {
- glTexCoord1f(s);
- }
- break;
- case D3DTTFF_COUNT2:
- VTRACE(("tex:%d, s=%f, t=%f\n", textureNo, s, t));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GL_EXTCALL(glMultiTexCoord2fARB(texture_idx, s, t));
- } else {
- glTexCoord2f(s, t);
- }
- break;
- case D3DTTFF_COUNT3:
- VTRACE(("tex:%d, s=%f, t=%f, r=%f\n", textureNo, s, t, r));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GL_EXTCALL(glMultiTexCoord3fARB(texture_idx, s, t, r));
- } else {
- glTexCoord3f(s, t, r);
- }
- break;
- case D3DTTFF_COUNT4:
- VTRACE(("tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
- if (GL_SUPPORT(ARB_MULTITEXTURE)) {
- GL_EXTCALL(glMultiTexCoord4fARB(texture_idx, s, t, r, q));
- } else {
- glTexCoord4f(s, t, r, q);
- }
- break;
- default:
- FIXME("Should not get here as coordsToUse is two bits only (%x)!\n", coordsToUse);
- }
- }
- }
- if (!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]) ++texture_idx;
- } /* End of textures */
-
- /* Diffuse -------------------------------- */
- if (sd->u.s.diffuse.lpData != NULL) {
- glColor4ub(D3DCOLOR_B_R(diffuseColor),
- D3DCOLOR_B_G(diffuseColor),
- D3DCOLOR_B_B(diffuseColor),
- D3DCOLOR_B_A(diffuseColor));
- VTRACE(("glColor4ub: r,g,b,a=%lu,%lu,%lu,%lu\n",
- D3DCOLOR_B_R(diffuseColor),
- D3DCOLOR_B_G(diffuseColor),
- D3DCOLOR_B_B(diffuseColor),
- D3DCOLOR_B_A(diffuseColor)));
- } else {
- if (vx_index == 0) glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- }
+ if (This->stateBlock->textures[textureNo] != NULL) {
- /* Specular ------------------------------- */
- if (sd->u.s.specular.lpData != NULL) {
- /* special case where the fog density is stored in the diffuse alpha channel */
- if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
- (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == D3DFOG_NONE || sd->u.s.position.dwType == D3DDECLTYPE_FLOAT4 )&&
- This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == D3DFOG_NONE) {
- if(GL_SUPPORT(EXT_FOG_COORD)) {
- GL_EXTCALL(glFogCoordfEXT(specularColor >> 24));
- } else {
- static BOOL warned = FALSE;
- if(!warned) {
- /* TODO: Use the fog table code from old ddraw */
- FIXME("Implement fog for transformed vertices in software\n");
- warned = TRUE;
- }
- }
- }
+ float s = draw->texcoords[textureNo].x;
+ float t = draw->texcoords[textureNo].y;
+ float r = draw->texcoords[textureNo].z;
+ float q = draw->texcoords[textureNo].w;
- VTRACE(("glSecondaryColor4ub: r,g,b=%lu,%lu,%lu\n",
- D3DCOLOR_B_R(specularColor),
- D3DCOLOR_B_G(specularColor),
- D3DCOLOR_B_B(specularColor)));
- if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- GL_EXTCALL(glSecondaryColor3ubEXT)(
- D3DCOLOR_B_R(specularColor),
- D3DCOLOR_B_G(specularColor),
- D3DCOLOR_B_B(specularColor));
- } else {
- /* Do not worry if specular colour missing and disable request */
- VTRACE(("Specular color extensions not supplied\n"));
- }
- } else {
- if (vx_index == 0) {
- if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
- } else {
- /* Do not worry if specular colour missing and disable request */
- VTRACE(("Specular color extensions not supplied\n"));
- }
- }
+ VTRACE(("DRAW tex:%d, s=%f, t=%f, r=%f, q=%f\n", textureNo, s, t, r, q));
+ if (GL_SUPPORT(ARB_MULTITEXTURE))
+ GL_EXTCALL(glMultiTexCoord4fARB(texture_idx, s, t, r, q));
+ else
+ glTexCoord4f(s, t, r, q);
}
+ if (!GL_SUPPORT(NV_REGISTER_COMBINERS) || This->stateBlock->textures[textureNo]) ++texture_idx;
+ } /* End of textures */
- /* Normal -------------------------------- */
- if (sd->u.s.normal.lpData != NULL) {
- VTRACE(("glNormal:nx,ny,nz=%f,%f,%f\n", nx,ny,nz));
- glNormal3f(nx, ny, nz);
- } else {
- if (vx_index == 0) glNormal3f(0, 0, 1);
- }
+ /* Draw Vertex: Diffuse -------------------------------- */
+ glColor4f(draw->diffuse.z, draw->diffuse.y, draw->diffuse.x, draw->diffuse.w);
+ VTRACE(("DRAW diffuse: r,g,b,a=%f,%f,%f,%f\n",
+ draw->diffuse.z, draw->diffuse.y, draw->diffuse.x, draw->diffuse.w));
+
+ /* Draw Vertex: Fog (non-table, non-vertex) ------------------------------- */
+ /* special case where the fog density is stored in the diffuse alpha channel */
+ /* FIXME: then why is this looking in the specular alpha channel? */
+ if(This->stateBlock->renderState[WINED3DRS_FOGENABLE] &&
+ (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == D3DFOG_NONE || draw->is_transformed ) &&
+ This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == D3DFOG_NONE) {
+
+ if (GL_SUPPORT(EXT_FOG_COORD))
+ GL_EXTCALL(glFogCoordfEXT(draw->specular.w));
+
+ else {
+ static BOOL warned = FALSE;
+ if(!warned) {
+ /* TODO: Use the fog table code from old ddraw */
+ FIXME("Implement fog for transformed vertices in software\n");
+ warned = TRUE;
+ }
+ }
+ }
- /* Position -------------------------------- */
- if (sd->u.s.position.lpData != NULL) {
- if (1.0f == rhw || ((rhw < eps) && (rhw > -eps))) {
- VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f\n", x,y,z));
- glVertex3f(x, y, z);
- } else {
- GLfloat w = 1.0 / rhw;
- VTRACE(("Vertex: glVertex:x,y,z=%f,%f,%f / rhw=%f\n", x,y,z,rhw));
- glVertex4f(x*w, y*w, z*w, w);
- }
- }
+ /* Draw Vertex: Specular ------------------------------- */
+ VTRACE(("DRAW specular: r,g,b=%f,%f,%f\n",
+ draw->specular.z, draw->specular.y, draw->specular.x));
+ if (GL_SUPPORT(EXT_SECONDARY_COLOR))
+ GL_EXTCALL(glSecondaryColor3fEXT(draw->specular.z, draw->specular.y, draw->specular.x));
+ else
+ /* Do not worry if specular colour missing and disable request */
+ VTRACE(("Specular color extensions not supplied\n"));
- /* For non indexed mode, step onto next parts */
- if (idxData == NULL) {
- ++SkipnStrides;
- }
- }
+ /* Draw Vertex: Normal -------------------------------- */
+ VTRACE(("DRAW normal:nx,ny,nz=%f,%f,%f\n", draw->normal.x, draw->normal.y, draw->normal.z));
+ glNormal3f(draw->normal.x, draw->normal.y, draw->normal.z);
- glEnd();
- checkGLcall("glEnd and previous calls");
+ /* Draw Vertex: Position -------------------------------- */
+ VTRACE(("DRAW position: x,y,z,w=%f,%f,%f,%f\n",
+ draw->position.x, draw->position.y, draw->position.z, draw->position.w));
+ glVertex4f(draw->position.x, draw->position.y, draw->position.z, draw->position.w);
}
-#if 0 /* TODO: Software/Hardware vertex blending support */
/*
- * Draw with emulated vertex shaders
- * Note: strided data is uninitialized, as we need to pass the vertex
- * shader directly as ordering irs yet
+ * Actually draw using the supplied information.
+ * Slower GL version which extracts info about each vertex in turn
*/
-void drawStridedSoftwareVS(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd,
- int PrimitiveType, ULONG NumPrimitives,
- const void *idxData, short idxSize, ULONG minIndex, ULONG startIdx) {
- unsigned int textureNo = 0;
- GLenum glPrimType = GL_POINTS;
- int NumVertexes = NumPrimitives;
+static void drawStridedSlow(
+ IWineD3DDevice *iface,
+ WineDirect3DVertexStridedData *strided,
+ UINT NumVertexes,
+ GLenum glPrimType,
+ const void *idxData,
+ short idxSize,
+ ULONG minIndex,
+ ULONG startIdx,
+ BOOL software_shader) {
+
const short *pIdxBufS = NULL;
const long *pIdxBufL = NULL;
LONG SkipnStrides = 0;
LONG vx_index;
- float x = 0.0f, y = 0.0f, z = 0.0f; /* x,y,z coordinates */
- float rhw = 0.0f; /* rhw */
- float ptSize = 0.0f; /* Point size */
- D3DVECTOR_4 texcoords[8]; /* Texture Coords */
- int numcoords[8]; /* Number of coords */
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
- IDirect3DVertexShaderImpl* vertexShader = NULL;
-
- TRACE("Using slow software vertex shader code\n");
+ TRACE("Using slow vertex array code\n");
/* Variable Initialization */
if (idxData != NULL) {
@@ -1751,115 +1545,44 @@ void drawStridedSoftwareVS(IWineD3DDevic
else pIdxBufL = (const long *) idxData;
}
- /* Ok, Work out which primitive is requested and how many vertexes that will be */
- NumVertexes = primitiveToGl(PrimitiveType, NumPrimitives, &glPrimType);
-
- /* Retrieve the VS information */
- vertexShader = (IWineD3DVertexShaderImp *)This->stateBlock->VertexShader;
-
/* Start drawing in GL */
VTRACE(("glBegin(%x)\n", glPrimType));
glBegin(glPrimType);
- /* For each primitive */
- for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
+ /* For each primitive */
+ for (vx_index = 0; vx_index < NumVertexes; ++vx_index) {
- /* For indexed data, we need to go a few more strides in */
- if (idxData != NULL) {
+ draw_context draw;
- /* Indexed so work out the number of strides to skip */
- if (idxSize == 2) {
- VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
- SkipnStrides = pIdxBufS[startIdx+vx_index];
- } else {
- VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index]));
- SkipnStrides = pIdxBufL[startIdx+vx_index];
- }
- }
+ /* For indexed data, we need to go a few more strides in */
+ if (idxData != NULL) {
- /* Fill the vertex shader input */
- IDirect3DDeviceImpl_FillVertexShaderInputSW(This, vertexShader, SkipnStrides);
-
- /* Initialize the output fields to the same defaults as it would normally have */
- memset(&vertexShader->output, 0, sizeof(VSHADEROUTPUTDATA8));
- vertexShader->output.oD[0].x = 1.0;
- vertexShader->output.oD[0].y = 1.0;
- vertexShader->output.oD[0].z = 1.0;
- vertexShader->output.oD[0].w = 1.0;
-
- /* Now execute the vertex shader */
- IDirect3DVertexShaderImpl_ExecuteSW(vertexShader, &vertexShader->input, &vertexShader->output);
-
- /*
- TRACE_VECTOR(vertexShader->output.oPos);
- TRACE_VECTOR(vertexShader->output.oD[0]);
- TRACE_VECTOR(vertexShader->output.oD[1]);
- TRACE_VECTOR(vertexShader->output.oT[0]);
- TRACE_VECTOR(vertexShader->output.oT[1]);
- TRACE_VECTOR(vertexShader->input.V[0]);
- TRACE_VECTOR(vertexShader->data->C[0]);
- TRACE_VECTOR(vertexShader->data->C[1]);
- TRACE_VECTOR(vertexShader->data->C[2]);
- TRACE_VECTOR(vertexShader->data->C[3]);
- TRACE_VECTOR(vertexShader->data->C[4]);
- TRACE_VECTOR(vertexShader->data->C[5]);
- TRACE_VECTOR(vertexShader->data->C[6]);
- TRACE_VECTOR(vertexShader->data->C[7]);
- */
+ /* Indexed so work out the number of strides to skip */
+ if (idxSize == 2) {
+ VTRACE(("Idx for vertex %ld = %d\n", vx_index, pIdxBufS[startIdx+vx_index]));
+ SkipnStrides = pIdxBufS[startIdx + vx_index];
+ } else {
+ VTRACE(("Idx for vertex %ld = %ld\n", vx_index, pIdxBufL[startIdx+vx_index]));
+ SkipnStrides = pIdxBufL[startIdx + vx_index];
+ }
+ }
- /* Extract out the output */
- /* FIXME: Fog coords? */
- x = vertexShader->output.oPos.x;
- y = vertexShader->output.oPos.y;
- z = vertexShader->output.oPos.z;
- rhw = vertexShader->output.oPos.w;
- ptSize = vertexShader->output.oPts.x; /* Fixme - Is this right? */
-
- /** Update textures coords using vertexShader->output.oT[0->7] */
- memset(texcoords, 0x00, sizeof(texcoords));
- memset(numcoords, 0x00, sizeof(numcoords));
- for (textureNo = 0; textureNo < GL_LIMITS(textures); ++textureNo) {
- if (This->stateBlock->textures[textureNo] != NULL) {
- texcoords[textureNo].x = vertexShader->output.oT[textureNo].x;
- texcoords[textureNo].y = vertexShader->output.oT[textureNo].y;
- texcoords[textureNo].z = vertexShader->output.oT[textureNo].z;
- texcoords[textureNo].w = vertexShader->output.oT[textureNo].w;
- if (This->stateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] != D3DTTFF_DISABLE) {
- numcoords[textureNo] = This->stateBlock->texture_state[textureNo][D3DTSS_TEXTURETRANSFORMFLAGS] & ~D3DTTFF_PROJECTED;
- } else {
- switch (IDirect3DBaseTexture8Impl_GetType((LPDIRECT3DBASETEXTURE8) This->stateBlock->textures[textureNo])) {
- case WINED3DRTYPE_TEXTURE: numcoords[textureNo] = 2; break;
- case WINED3DRTYPE_VOLUMETEXTURE: numcoords[textureNo] = 3; break;
- default: numcoords[textureNo] = 4;
- }
- }
- } else {
- numcoords[textureNo] = 0;
- }
- }
+ if (software_shader)
+ swshader_prepare_draw(This, strided, SkipnStrides, &draw);
+ else
+ fixed_prepare_draw(This, strided, SkipnStrides, &draw);
- /* Draw using this information */
- draw_vertex(iface,
- TRUE, x, y, z, rhw,
- TRUE, 0.0f, 0.0f, 1.0f,
- TRUE, (float*) &vertexShader->output.oD[0],
- TRUE, (float*) &vertexShader->output.oD[1],
- FALSE, ptSize, /* FIXME: Change back when supported */
- texcoords, numcoords);
-
- /* For non indexed mode, step onto next parts */
- if (idxData == NULL) {
- ++SkipnStrides;
- }
+ draw_vertex(This, &draw);
- } /* for each vertex */
+ /* For non indexed mode, step onto next parts */
+ if (idxData == NULL)
+ ++SkipnStrides;
+ }
glEnd();
checkGLcall("glEnd and previous calls");
}
-#endif
-
static inline void drawPrimitiveDrawStrided(
IWineD3DDevice *iface,
BOOL useVertexShaderFunction,
@@ -1913,8 +1636,8 @@ #undef BUFFER_OR_DATA
loadVertexData(iface, dataLocations);
useDrawStridedSlow = FALSE;
- /* Shader pipeline - load attribute arrays */
- } else if(useVertexShaderFunction) {
+ /* Hardware Shader pipeline - load attribute arrays */
+ } else if(useVertexShaderFunction && wined3d_settings.vs_selected_mode != SHADER_SW) {
loadNumberedArrays(iface, dataLocations,
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->semantics_in);
@@ -1988,12 +1711,13 @@ #undef BUFFER_OR_DATA
/* Draw vertex-by-vertex */
if (useDrawStridedSlow)
- drawStridedSlow(iface, dataLocations, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx);
+ drawStridedSlow(iface, dataLocations, numberOfIndicies, glPrimType,
+ idxData, idxSize, minIndex, StartIdx, useVertexShaderFunction);
else
drawStridedFast(iface, numberOfIndicies, glPrimType, idxData, idxSize, minIndex, StartIdx);
/* Cleanup vertex program */
- if (useVertexShaderFunction) {
+ if (useVertexShaderFunction && wined3d_settings.vs_selected_mode != SHADER_SW) {
/* disable any attribs (this is the same for both GLSL and ARB modes) */
GLint maxAttribs;
int i;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a71539a..e70a9a0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1284,6 +1284,15 @@ #define MAX_CONST_F 256
#define MAX_CONST_I 16
#define MAX_CONST_B 16
+typedef struct draw_context {
+ WINED3DSHADERVECTOR position;
+ WINED3DSHADERVECTOR diffuse;
+ WINED3DSHADERVECTOR specular;
+ WINED3DSHADERVECTOR texcoords[D3DDP_MAXTEXCOORD];
+ WINED3DSHADERVECTOR normal;
+ BOOL is_transformed;
+} draw_context;
+
typedef struct shader_reg_maps {
char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */
--
1.4.0
More information about the wine-patches
mailing list