[Bug 25298] Divinity2 crashes
wine-bugs at winehq.org
wine-bugs at winehq.org
Sat Feb 5 13:30:40 CST 2011
http://bugs.winehq.org/show_bug.cgi?id=25298
--- Comment #26 from Vadim <vadim.home at gmail.com> 2011-02-05 13:30:39 CST ---
(From update of attachment 33150)
diff -Naur a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
--- a/dlls/wined3d/directx.c 2011-02-03 14:37:38.000000000 +0300
+++ b/dlls/wined3d/directx.c 2011-02-05 22:04:50.000000000 +0300
@@ -4489,8 +4489,13 @@
caps->MaxUserClipPlanes = gl_info->limits.clipplanes;
caps->MaxActiveLights = gl_info->limits.lights;
- caps->MaxVertexBlendMatrices = gl_info->limits.blends;
- caps->MaxVertexBlendMatrixIndex = 0;
+ if (gl_info->supported[ARB_VERTEX_BLEND]) {
+ caps->MaxVertexBlendMatrices = gl_info->limits.blends;
+ caps->MaxVertexBlendMatrixIndex = 0;
+ } else {
+ caps->MaxVertexBlendMatrices = 4;
+ caps->MaxVertexBlendMatrixIndex = 255;
+ }
caps->MaxAnisotropy = gl_info->limits.anisotropy;
caps->MaxPointSize = gl_info->limits.pointsize_max;
diff -Naur a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
--- a/dlls/wined3d/drawprim.c 2011-01-29 03:46:55.000000000 +0300
+++ b/dlls/wined3d/drawprim.c 2011-02-05 22:04:50.000000000 +0300
@@ -50,6 +50,75 @@
}
/*
+ * Emit a vertex using swoftware vertex blending
+ */
+static void emitBlendedVertex(struct wined3d_stateblock *stateBlock,
+ const float *weights, int nweights, const BYTE
*indices,
+ const float *pos, const float *norm)
+{
+ const float *m;
+ float vec[4];
+ float mat[4*4];
+ float last = 1.f;
+ int i, j;
+
+ /* compute the weighted sum of the matrices */
+ m = &stateBlock->state.transforms[WINED3DTS_WORLDMATRIX((indices ?
indices[0] : 0))].u.m[0][0];
+ for (j = 0; j < 16; j++)
+ mat[j] = m[j] * weights[0];
+ last -= weights[0];
+
+ for (i = 1; i < nweights; i++) {
+ if (weights[i]) {
+ m = &stateBlock->state.transforms[WINED3DTS_WORLDMATRIX((indices ?
indices[i] : i))].u.m[0][0];
+ for (j = 0; j < 16; j++)
+ mat[j] += m[j] * weights[i];
+ last -= weights[i];
+ }
+ }
+
+ /* do the last */
+ if (last) {
+ m = &stateBlock->state.transforms[WINED3DTS_WORLDMATRIX((indices ?
indices[i] : i))].u.m[0][0];
+ for (j = 0; j < 16; j++)
+ mat[j] += m[j] * last;
+ }
+
+ if (norm) {
+ /* compute the resulting normal */
+ vec[0] = norm[0] * mat[0] + norm[1] * mat[4] + norm[2] * mat[8];
+ vec[1] = norm[0] * mat[1] + norm[1] * mat[5] + norm[2] * mat[9];
+ vec[2] = norm[0] * mat[2] + norm[1] * mat[6] + norm[2] * mat[10];
+ /* normalize */
+ vec[3] = vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2];
+ if (vec[3]) {
+ vec[3] = 1.f / sqrtf(vec[3]);
+ vec[0] *= vec[3];
+ vec[1] *= vec[3];
+ vec[2] *= vec[3];
+ }
+
+ glNormal3fv(vec);
+ }
+
+ if (pos) {
+ /* compute the resulting position */
+ vec[0] = pos[0] * mat[0] + pos[1] * mat[4] + pos[2] * mat[8] +
mat[12];
+ vec[1] = pos[0] * mat[1] + pos[1] * mat[5] + pos[2] * mat[9] +
mat[13];
+ vec[2] = pos[0] * mat[2] + pos[1] * mat[6] + pos[2] * mat[10] +
mat[14];
+ vec[3] = pos[0] * mat[3] + pos[1] * mat[7] + pos[2] * mat[11] +
mat[15];
+ /* normalize */
+ if (vec[3]) {
+ vec[0] /= vec[3];
+ vec[1] /= vec[3];
+ vec[2] /= vec[3];
+ }
+
+ glVertex3fv(vec);
+ }
+}
+
+/*
* Actually draw using the supplied information.
* Slower GL version which extracts info about each vertex in turn
*/
@@ -69,7 +138,8 @@
BOOL pixelShader = use_ps(state);
BOOL specular_fog = FALSE;
const BYTE *texCoords[WINED3DDP_MAXTEXCOORD];
- const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position =
NULL;
+ const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position =
NULL, *weights = NULL, *indices = NULL;
+ int nweights = 0;
const struct wined3d_gl_info *gl_info = context->gl_info;
UINT texture_stages = gl_info->limits.texture_stages;
const struct wined3d_stream_info_element *element;
@@ -161,6 +231,31 @@
{
GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
}
+
+ if (device->vertexBlendSW) {
+ if (!si->elements[WINED3D_FFP_BLENDWEIGHT].data) {
+ WARN("vertex blending enabled but blendWeights.data=NULL\n");
+ } else if (si->elements[WINED3D_FFP_BLENDWEIGHT].format->gl_vtx_type
!= GL_FLOAT) {
+ FIXME("unsupported blend weights datatype (%d)\n",
si->elements[WINED3D_FFP_BLENDWEIGHT].format->id);
+ } else if (position &&
si->elements[WINED3D_FFP_POSITION].format->emit_idx != WINED3D_FFP_EMIT_FLOAT3)
{
+ FIXME("unsupported postion datatype (%d)\n",
si->elements[WINED3D_FFP_POSITION].format->id);
+ } else if (normal && si->elements[WINED3D_FFP_NORMAL].format->emit_idx
!= WINED3D_FFP_EMIT_FLOAT3) {
+ FIXME("unsupported normal datatype (%d)\n",
si->elements[WINED3D_FFP_NORMAL].format->id);
+ } else {
+ element = &si->elements[WINED3D_FFP_BLENDWEIGHT];
+ weights = element->data + streams[element->stream_idx].offset;
+ nweights = element->format->gl_vtx_format;
+ }
+
+ if (si->elements[WINED3D_FFP_BLENDINDICES].data) {
+ if (si->elements[WINED3D_FFP_BLENDINDICES].format->emit_idx !=
WINED3D_FFP_EMIT_UBYTE4) {
+ FIXME("unsupported blend indices datatype (%d)\n",
si->elements[WINED3D_FFP_BLENDINDICES].format->id);
+ } else {
+ element = &si->elements[WINED3D_FFP_BLENDINDICES];
+ indices = element->data + streams[element->stream_idx].offset;
+ }
+ }
+ }
for (textureNo = 0; textureNo < texture_stages; ++textureNo)
{
@@ -278,17 +373,24 @@
}
}
- /* Normal -------------------------------- */
- if (normal)
- {
- const void *ptrToCoords = normal + SkipnStrides *
si->elements[WINED3D_FFP_NORMAL].stride;
-
normal_funcs[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptrToCoords);
- }
-
- /* Position -------------------------------- */
- if (position) {
- const void *ptrToCoords = position + SkipnStrides *
si->elements[WINED3D_FFP_POSITION].stride;
-
position_funcs[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptrToCoords);
+ if (weights) {
+ emitBlendedVertex(device->stateBlock,
+ (const float*)(weights + SkipnStrides *
si->elements[WINED3D_FFP_BLENDWEIGHT].stride), nweights,
+ indices ? (indices + SkipnStrides *
si->elements[WINED3D_FFP_BLENDINDICES].stride) : NULL,
+ (const float*)(position ? (position +
SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride) : NULL),
+ (const float*)(normal ? (normal + SkipnStrides *
si->elements[WINED3D_FFP_NORMAL].stride) : NULL));
+ } else {
+ /* Normal -------------------------------- */
+ if (normal != NULL) {
+ const void *ptrToCoords = normal + SkipnStrides *
si->elements[WINED3D_FFP_NORMAL].stride;
+
normal_funcs[si->elements[WINED3D_FFP_NORMAL].format->emit_idx](ptrToCoords);
+ }
+
+ /* Position -------------------------------- */
+ if (position) {
+ const void *ptrToCoords = position + SkipnStrides *
si->elements[WINED3D_FFP_POSITION].stride;
+
position_funcs[si->elements[WINED3D_FFP_POSITION].format->emit_idx](ptrToCoords);
+ }
}
/* For non indexed mode, step onto next parts */
@@ -678,6 +780,17 @@
}
emulation = TRUE;
}
+ else if (device->vertexBlendSW)
+ {
+ static BOOL warned;
+ if (!warned) {
+ FIXME("Using software emulation because vertex blending is
enabled\n");
+ warned = TRUE;
+ } else {
+ TRACE("Using software emulation because vertex blending is
enabled\n");
+ }
+ emulation = TRUE;
+ }
if(emulation) {
stream_info = &stridedlcl;
diff -Naur a/dlls/wined3d/state.c b/dlls/wined3d/state.c
--- a/dlls/wined3d/state.c 2011-02-01 16:17:23.000000000 +0300
+++ b/dlls/wined3d/state.c 2011-02-05 22:18:26.000000000 +0300
@@ -3771,7 +3771,7 @@
if(context->last_was_rhw) {
glLoadIdentity();
checkGLcall("glLoadIdentity()");
- } else {
+ } else if (!stateblock->device->vertexBlendSW) {
/* In the general case, the view matrix is the identity matrix */
if (stateblock->device->view_ident)
{
@@ -3785,6 +3785,9 @@
glMultMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
checkGLcall("glMultMatrixf");
}
+ } else {
+
glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
+ checkGLcall("glLoadMatrixf");
}
}
@@ -3874,13 +3877,33 @@
static void state_vertexblend_w(DWORD state, struct wined3d_stateblock
*stateblock, struct wined3d_context *context)
{
- WINED3DVERTEXBLENDFLAGS f =
stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
+ WINED3DVERTEXBLENDFLAGS val =
stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
static unsigned int once;
- if (f == WINED3DVBF_DISABLE) return;
-
- if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
- else WARN("Vertex blend flags %#x not supported.\n", f);
+ switch (val) {
+ case WINED3DVBF_0WEIGHTS:
+ case WINED3DVBF_1WEIGHTS:
+ case WINED3DVBF_2WEIGHTS:
+ case WINED3DVBF_3WEIGHTS:
+ if(!once) {
+ once = TRUE;
+ FIXME("Vertex blending enabled, but not supported by hardware.
Using software emulation.\n");
+ }
+ if (!stateblock->device->vertexBlendSW) {
+ stateblock->device->vertexBlendSW = TRUE;
+ transform_world(state, stateblock, context);
+ }
+ break;
+ case WINED3DVBF_TWEENING:
+ WARN("Vertex blend flags %#x not supported.\n", val);
+ /* fall through */
+ default:
+ if (stateblock->device->vertexBlendSW) {
+ stateblock->device->vertexBlendSW = FALSE;
+ transform_world(state, stateblock, context);
+ }
+ break;
+ }
}
static void state_vertexblend(DWORD state, struct wined3d_stateblock
*stateblock, struct wined3d_context *context)
diff -Naur a/dlls/wined3d/vertexdeclaration.c
b/dlls/wined3d/vertexdeclaration.c
--- a/dlls/wined3d/vertexdeclaration.c 2011-02-05 15:14:05.000000000 +0300
+++ b/dlls/wined3d/vertexdeclaration.c 2011-02-05 22:04:50.000000000 +0300
@@ -106,6 +106,15 @@
default:
return FALSE;
}
+
+ case WINED3DDECLUSAGE_BLENDINDICES:
+ switch(element->format)
+ {
+ case WINED3DFMT_R8G8B8A8_UINT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
case WINED3DDECLUSAGE_NORMAL:
switch(element->format)
diff -Naur a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
--- a/dlls/wined3d/wined3d_private.h 2011-02-05 15:14:05.000000000 +0300
+++ b/dlls/wined3d/wined3d_private.h 2011-02-05 22:04:50.000000000 +0300
@@ -1670,6 +1670,7 @@
WORD view_ident : 1; /* true iff view matrix is identity */
WORD untransformed : 1;
WORD vertexBlendUsed : 1; /* To avoid needless setting of the
blend matrices */
+ WORD vertexBlendSW : 1; /* vertexBlend software fallback used
*/
WORD isRecordingState : 1;
WORD isInDraw : 1;
WORD bCursorVisible : 1;
--
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.
More information about the wine-bugs
mailing list