From d7c7c768507a923902e9178f98343e22e4e22652 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 27 Mar 2009 10:25:55 +0100 Subject: [PATCH] wined3d: Use separate structures for ddraw style strided data and wined3d's internal stream info. --- dlls/ddraw/device.c | 76 ++++---- dlls/wined3d/buffer.c | 58 +++--- dlls/wined3d/device.c | 270 ++++++++++++++++++++++++--- dlls/wined3d/drawprim.c | 331 +++++++++------------------------ dlls/wined3d/state.c | 301 +++++++++++++++--------------- dlls/wined3d/wined3d_private.h | 59 +++++- include/wine/wined3d.idl | 35 +--- 7 files changed, 594 insertions(+), 536 deletions(-) diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index 4d642e5021c..26224d9135c 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3827,12 +3827,12 @@ IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, */ if(VertexType & D3DFVF_POSITION_MASK) { - WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData; - WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride; - WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3; + WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData; + WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride; + WineD3DStrided.position.dwType = WINED3DDECLTYPE_FLOAT3; if (VertexType & D3DFVF_XYZRHW) { - WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4; + WineD3DStrided.position.dwType = WINED3DDECLTYPE_FLOAT4; WineD3DStrided.position_transformed = TRUE; } else WineD3DStrided.position_transformed = FALSE; @@ -3840,35 +3840,35 @@ IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, if(VertexType & D3DFVF_NORMAL) { - WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData; - WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride; - WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3; + WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData; + WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride; + WineD3DStrided.normal.dwType = WINED3DDECLTYPE_FLOAT3; } if(VertexType & D3DFVF_DIFFUSE) { - WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData; - WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride; - WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR; + WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData; + WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride; + WineD3DStrided.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR; } if(VertexType & D3DFVF_SPECULAR) { - WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData; - WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride; - WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR; + WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData; + WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride; + WineD3DStrided.specular.dwType = WINED3DDECLTYPE_D3DCOLOR; } for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++) { - WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData; - WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride; + WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData; + WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride; switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)) { - case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break; - case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break; - case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break; - case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break; + case 1: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break; + case 2: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break; + case 3: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break; + case 4: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break; default: ERR("Unexpected texture coordinate size %d\n", GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)); } @@ -3968,12 +3968,12 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, */ if(VertexType & D3DFVF_POSITION_MASK) { - WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData; - WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride; - WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3; + WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData; + WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride; + WineD3DStrided.position.dwType = WINED3DDECLTYPE_FLOAT3; if (VertexType & D3DFVF_XYZRHW) { - WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4; + WineD3DStrided.position.dwType = WINED3DDECLTYPE_FLOAT4; WineD3DStrided.position_transformed = TRUE; } else WineD3DStrided.position_transformed = FALSE; @@ -3981,35 +3981,35 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, if(VertexType & D3DFVF_NORMAL) { - WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData; - WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride; - WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3; + WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData; + WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride; + WineD3DStrided.normal.dwType = WINED3DDECLTYPE_FLOAT3; } if(VertexType & D3DFVF_DIFFUSE) { - WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData; - WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride; - WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR; + WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData; + WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride; + WineD3DStrided.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR; } if(VertexType & D3DFVF_SPECULAR) { - WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData; - WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride; - WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR; + WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData; + WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride; + WineD3DStrided.specular.dwType = WINED3DDECLTYPE_D3DCOLOR; } for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++) { - WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData; - WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride; + WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData; + WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride; switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)) { - case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break; - case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break; - case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break; - case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break; + case 1: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break; + case 2: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break; + case 3: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break; + case 4: WineD3DStrided.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break; default: ERR("Unexpected texture coordinate size %d\n", GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)); } diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 2bf4fb4f524..f11e3e21c53 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -129,12 +129,12 @@ fail: static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, const enum wined3d_buffer_conversion_type conversion_type, - const WineDirect3DStridedData *attrib, DWORD *stride_this_run, const DWORD type) + const struct wined3d_stream_info_element *attrib, DWORD *stride_this_run, const DWORD type) { DWORD attrib_size; BOOL ret = FALSE; unsigned int i; - DWORD offset = This->resource.wineD3DDevice->stateBlock->streamOffset[attrib->streamNo]; + DWORD offset = This->resource.wineD3DDevice->stateBlock->streamOffset[attrib->stream_idx]; DWORD_PTR data; /* Check for some valid situations which cause us pain. One is if the buffer is used for @@ -142,18 +142,18 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, * with different strides. In the 2nd case we might have to drop conversion entirely, * it is possible that the same bytes are once read as FLOAT2 and once as UBYTE4N. */ - if (attrib->dwStride == 0) + if (!attrib->stride) { FIXME("%s used with stride 0, let's hope we get the vertex stride from somewhere else\n", debug_d3ddecltype(type)); } - else if(attrib->dwStride != *stride_this_run && *stride_this_run) + else if(attrib->stride != *stride_this_run && *stride_this_run) { - FIXME("Got two concurrent strides, %d and %d\n", attrib->dwStride, *stride_this_run); + FIXME("Got two concurrent strides, %d and %d\n", attrib->stride, *stride_this_run); } else { - *stride_this_run = attrib->dwStride; + *stride_this_run = attrib->stride; if (This->stride != *stride_this_run) { /* We rely that this happens only on the first converted attribute that is found, @@ -168,7 +168,7 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, } } - data = (((DWORD_PTR) attrib->lpData) + offset) % This->stride; + data = (((DWORD_PTR)attrib->data) + offset) % This->stride; attrib_size = WINED3D_ATR_SIZE(type) * WINED3D_ATR_TYPESIZE(type); for (i = 0; i < attrib_size; ++i) { @@ -185,18 +185,18 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This, } static BOOL buffer_check_attribute(struct wined3d_buffer *This, - const WineDirect3DStridedData *attrib, const BOOL check_d3dcolor, const BOOL is_ffp_position, + const struct wined3d_stream_info_element *attrib, const BOOL check_d3dcolor, const BOOL is_ffp_position, const BOOL is_ffp_color, DWORD *stride_this_run, BOOL *float16_used) { BOOL ret = FALSE; - DWORD type; + WINED3DDECLTYPE type; /* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is * there, on nonexistent attribs the vbo is 0. */ - if (attrib->VBO != This->buffer_object) return FALSE; + if (attrib->buffer_object != This->buffer_object) return FALSE; - type = attrib->dwType; + type = attrib->d3d_type; /* Look for newly appeared conversion */ if (!GL_SUPPORT(NV_HALF_FLOAT) && (type == WINED3DDECLTYPE_FLOAT16_2 || type == WINED3DDECLTYPE_FLOAT16_4)) { @@ -228,7 +228,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, } static UINT *find_conversion_shift(struct wined3d_buffer *This, - const WineDirect3DVertexStridedData *strided, UINT stride) + const struct wined3d_stream_info *strided, UINT stride) { UINT *ret, i, j, shift, orig_type_size; DWORD type; @@ -243,9 +243,9 @@ static UINT *find_conversion_shift(struct wined3d_buffer *This, ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DWORD) * stride); for (i = 0; i < MAX_ATTRIBS; ++i) { - if (strided->u.input[i].VBO != This->buffer_object) continue; + if (strided->elements[i].buffer_object != This->buffer_object) continue; - type = strided->u.input[i].dwType; + type = strided->elements[i].d3d_type; if (type == WINED3DDECLTYPE_FLOAT16_2) { shift = 4; @@ -258,7 +258,7 @@ static UINT *find_conversion_shift(struct wined3d_buffer *This, */ for (j = 4; j < 8; ++j) { - ret[(DWORD_PTR)strided->u.input[i].lpData + j] += 4; + ret[(DWORD_PTR)strided->elements[i].data + j] += 4; } } else @@ -270,7 +270,7 @@ static UINT *find_conversion_shift(struct wined3d_buffer *This, if (shift) { orig_type_size = WINED3D_ATR_TYPESIZE(type) * WINED3D_ATR_SIZE(type); - for (j = (DWORD_PTR)strided->u.input[i].lpData + orig_type_size; j < stride; ++j) + for (j = (DWORD_PTR)strided->elements[i].data + orig_type_size; j < stride; ++j) { ret[j] += shift; } @@ -371,7 +371,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) } for (i = 0; i < MAX_ATTRIBS; ++i) { - ret = buffer_check_attribute(This, &device->strided_streams.u.input[i], + ret = buffer_check_attribute(This, &device->strided_streams.elements[i], FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; } @@ -391,29 +391,29 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This) * the attributes that our current fixed function pipeline implementation cares for. */ BOOL support_d3dcolor = GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA); - ret = buffer_check_attribute(This, &device->strided_streams.u.s.position, + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_POSITION], TRUE, TRUE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.normal, + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_NORMAL], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.diffuse, + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_DIFFUSE], !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.specular, + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_SPECULAR], !support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[0], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD0], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[1], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD1], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[2], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD2], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[3], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD3], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[4], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD4], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[5], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD5], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[6], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD6], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; - ret = buffer_check_attribute(This, &device->strided_streams.u.s.texCoords[7], + ret = buffer_check_attribute(This, &device->strided_streams.elements[WINED3D_FFP_TEXCOORD7], TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret; if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n"); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c0f0d85177b..70e6f6332d1 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -141,6 +141,221 @@ static WINED3DPRIMITIVETYPE d3d_primitive_type_from_gl(GLenum primitive_type) } } +static BOOL fixed_get_input(BYTE usage, BYTE usage_idx, unsigned int *regnum) +{ + if ((usage == WINED3DDECLUSAGE_POSITION || usage == WINED3DDECLUSAGE_POSITIONT) && usage_idx == 0) + *regnum = WINED3D_FFP_POSITION; + else if (usage == WINED3DDECLUSAGE_BLENDWEIGHT && usage_idx == 0) + *regnum = WINED3D_FFP_BLENDWEIGHT; + else if (usage == WINED3DDECLUSAGE_BLENDINDICES && usage_idx == 0) + *regnum = WINED3D_FFP_BLENDINDICES; + else if (usage == WINED3DDECLUSAGE_NORMAL && usage_idx == 0) + *regnum = WINED3D_FFP_NORMAL; + else if (usage == WINED3DDECLUSAGE_PSIZE && usage_idx == 0) + *regnum = WINED3D_FFP_PSIZE; + else if (usage == WINED3DDECLUSAGE_COLOR && usage_idx == 0) + *regnum = WINED3D_FFP_DIFFUSE; + else if (usage == WINED3DDECLUSAGE_COLOR && usage_idx == 1) + *regnum = WINED3D_FFP_SPECULAR; + else if (usage == WINED3DDECLUSAGE_TEXCOORD && usage_idx < WINED3DDP_MAXTEXCOORD) + *regnum = WINED3D_FFP_TEXCOORD0 + usage_idx; + else + { + FIXME("Unsupported input stream [usage=%s, usage_idx=%u]\n", debug_d3ddeclusage(usage), usage_idx); + *regnum = ~0U; + return FALSE; + } + + return TRUE; +} + +void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, + BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup) +{ + /* We need to deal with frequency data! */ + IWineD3DVertexDeclarationImpl *declaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl; + UINT stream_count = This->stateBlock->streamIsUP ? 0 : declaration->num_streams; + const DWORD *streams = declaration->streams; + unsigned int i; + + memset(stream_info, 0, sizeof(*stream_info)); + + /* Check for transformed vertices, disable vertex shader if present. */ + stream_info->position_transformed = declaration->position_transformed; + if (declaration->position_transformed) use_vshader = FALSE; + + /* Translate the declaration into strided data. */ + for (i = 0; i < declaration->declarationWNumElements - 1; ++i) + { + const WINED3DVERTEXELEMENT *element = declaration->pDeclarationWine + i; + GLuint buffer_object = 0; + const BYTE *data = NULL; + BOOL stride_used; + unsigned int idx; + DWORD stride; + + TRACE("%p Element %p (%u of %u)\n", declaration->pDeclarationWine, + element, i + 1, declaration->declarationWNumElements - 1); + + if (!This->stateBlock->streamSource[element->Stream]) continue; + + stride = This->stateBlock->streamStride[element->Stream]; + if (This->stateBlock->streamIsUP) + { + TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); + buffer_object = 0; + data = (BYTE *)This->stateBlock->streamSource[element->Stream]; + } + else + { + TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); + data = buffer_get_memory(This->stateBlock->streamSource[element->Stream], 0, &buffer_object); + + /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets + * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory + * sources. In most sane cases the pointer - offset will still be > 0, otherwise it will wrap + * around to some big value. Hope that with the indices, the driver wraps it back internally. If + * not, drawStridedSlow is needed, including a vertex buffer path. */ + if (This->stateBlock->loadBaseVertexIndex < 0) + { + WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); + buffer_object = 0; + data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory; + if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) + { + FIXME("System memory vertex data load offset is negative!\n"); + } + } + + if (fixup) + { + if (buffer_object) *fixup = TRUE; + else if (*fixup && !use_vshader + && (element->Usage == WINED3DDECLUSAGE_COLOR + || element->Usage == WINED3DDECLUSAGE_POSITIONT)) + { + static BOOL warned = FALSE; + if (!warned) + { + /* This may be bad with the fixed function pipeline. */ + FIXME("Missing vbo streams with unfixed colors or transformed position, expect problems\n"); + warned = TRUE; + } + } + } + } + data += element->Offset; + + TRACE("Offset %d Stream %d UsageIndex %d\n", element->Offset, element->Stream, element->UsageIndex); + + if (use_vshader) + { + stride_used = vshader_get_input(This->stateBlock->vertexShader, element->Usage, element->UsageIndex, &idx); + } + else + { + if (!declaration->ffp_valid[i]) + { + WARN("Skipping unsupported fixed function element of type %s and usage %s\n", + debug_d3ddecltype(element->Type), debug_d3ddeclusage(element->Usage)); + stride_used = FALSE; + } + else + { + stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx); + } + } + + if (stride_used) + { + TRACE("Load %s array %u [usage %s, usage_idx %u, " + "stream %u, offset %u, stride %u, type %s, buffer_object %u]\n", + use_vshader ? "shader": "fixed function", idx, + debug_d3ddeclusage(element->Usage), element->UsageIndex, + element->Stream, element->Offset, stride, debug_d3ddecltype(element->Type), buffer_object); + + stream_info->elements[idx].d3d_type = element->Type; + stream_info->elements[idx].size = WINED3D_ATR_SIZE(element->Type); + stream_info->elements[idx].format = WINED3D_ATR_FORMAT(element->Type); + stream_info->elements[idx].type = WINED3D_ATR_GLTYPE(element->Type); + stream_info->elements[idx].stride = stride; + stream_info->elements[idx].normalized = WINED3D_ATR_NORMALIZED(element->Type); + stream_info->elements[idx].data = data; + stream_info->elements[idx].type_size = WINED3D_ATR_TYPESIZE(element->Type); + stream_info->elements[idx].stream_idx = element->Stream; + stream_info->elements[idx].buffer_object = buffer_object; + + if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && element->Type == WINED3DDECLTYPE_D3DCOLOR) + { + stream_info->swizzle_map |= 1 << idx; + } + stream_info->use_map |= 1 << idx; + } + } + + /* Now call PreLoad on all the vertex buffers. In the very rare case + * that the buffers stopps converting PreLoad will dirtify the VDECL again. + * The vertex buffer can now use the strided structure in the device instead of finding its + * own again. + * + * NULL streams won't be recorded in the array, UP streams won't be either. A stream is only + * once in there. */ + for (i = 0; i < stream_count; ++i) + { + IWineD3DBuffer *vb = This->stateBlock->streamSource[streams[i]]; + if (vb) IWineD3DBuffer_PreLoad(vb); + } +} + +static void stream_info_element_from_strided(IWineD3DDeviceImpl *This, + const struct WineDirect3DStridedData *strided, struct wined3d_stream_info_element *e) +{ + e->d3d_type = strided->dwType; + e->size = WINED3D_ATR_SIZE(strided->dwType); + e->format = WINED3D_ATR_FORMAT(strided->dwType); + e->type = WINED3D_ATR_GLTYPE(strided->dwType); + e->stride = strided->dwStride; + e->normalized = WINED3D_ATR_NORMALIZED(strided->dwType); + e->data = strided->lpData; + e->type_size = WINED3D_ATR_TYPESIZE(strided->dwType); + e->stream_idx = 0; + e->buffer_object = 0; +} + +void device_stream_info_from_strided(IWineD3DDeviceImpl *This, + const struct WineDirect3DVertexStridedData *strided, struct wined3d_stream_info *stream_info) +{ + unsigned int i; + + memset(stream_info, 0, sizeof(*stream_info)); + + if (strided->position.lpData) + stream_info_element_from_strided(This, &strided->position, &stream_info->elements[WINED3D_FFP_POSITION]); + if (strided->normal.lpData) + stream_info_element_from_strided(This, &strided->normal, &stream_info->elements[WINED3D_FFP_NORMAL]); + if (strided->diffuse.lpData) + stream_info_element_from_strided(This, &strided->diffuse, &stream_info->elements[WINED3D_FFP_DIFFUSE]); + if (strided->specular.lpData) + stream_info_element_from_strided(This, &strided->specular, &stream_info->elements[WINED3D_FFP_SPECULAR]); + + for (i = 0; i < WINED3DDP_MAXTEXCOORD; ++i) + { + if (strided->texCoords[i].lpData) + stream_info_element_from_strided(This, &strided->texCoords[i], + &stream_info->elements[WINED3D_FFP_TEXCOORD0 + i]); + } + + stream_info->position_transformed = strided->position_transformed; + + for (i = 0; i < sizeof(stream_info->elements) / sizeof(*stream_info->elements); ++i) + { + if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && stream_info->elements[i].d3d_type == WINED3DDECLTYPE_D3DCOLOR) + { + stream_info->swizzle_map |= 1 << i; + } + stream_info->use_map |= 1 << i; + } +} /********************************************************** * IUnknown parts follows @@ -4292,7 +4507,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_GetPixelShaderConstantF( #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIndex, DWORD dwCount, - const WineDirect3DVertexStridedData *lpStrideData, struct wined3d_buffer *dest, DWORD dwFlags) + const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, DWORD dwFlags) { char *dest_ptr, *dest_conv = NULL, *dest_conv_addr = NULL; unsigned int i; @@ -4302,11 +4517,13 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn BOOL doClip; DWORD numTextures; - if (lpStrideData->u.s.normal.lpData) { + if (stream_info->elements[WINED3D_FFP_NORMAL].data) + { WARN(" lighting state not saved yet... Some strange stuff may happen !\n"); } - if (lpStrideData->u.s.position.lpData == NULL) { + if (!stream_info->elements[WINED3D_FFP_POSITION].data) + { ERR("Source has no position mask\n"); return WINED3DERR_INVALIDCALL; } @@ -4429,8 +4646,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn if ( ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZ ) || ((DestFVF & WINED3DFVF_POSITION_MASK) == WINED3DFVF_XYZRHW ) ) { /* The position first */ - const float *p = - (const float *)(lpStrideData->u.s.position.lpData + i * lpStrideData->u.s.position.dwStride); + const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_POSITION]; + const float *p = (const float *)(element->data + i * element->stride); float x, y, z, rhw; TRACE("In: ( %06.2f %06.2f %06.2f )\n", p[0], p[1], p[2]); @@ -4545,8 +4762,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn if(dest_conv) dest_conv += sizeof(DWORD); } if (DestFVF & WINED3DFVF_NORMAL) { - const float *normal = - (const float *)(lpStrideData->u.s.normal.lpData + i * lpStrideData->u.s.normal.dwStride); + const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_NORMAL]; + const float *normal = (const float *)(element->data + i * element->stride); /* AFAIK this should go into the lighting information */ FIXME("Didn't expect the destination to have a normal\n"); copy_and_next(dest_ptr, normal, 3 * sizeof(float)); @@ -4556,8 +4773,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn } if (DestFVF & WINED3DFVF_DIFFUSE) { - const DWORD *color_d = - (const DWORD *)(lpStrideData->u.s.diffuse.lpData + i * lpStrideData->u.s.diffuse.dwStride); + const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_DIFFUSE]; + const DWORD *color_d = (const DWORD *)(element->data + i * element->stride); if(!color_d) { static BOOL warned = FALSE; @@ -4587,8 +4804,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn if (DestFVF & WINED3DFVF_SPECULAR) { /* What's the color value in the feedback buffer? */ - const DWORD *color_s = - (const DWORD *)(lpStrideData->u.s.specular.lpData + i * lpStrideData->u.s.specular.dwStride); + const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_SPECULAR]; + const DWORD *color_s = (const DWORD *)(element->data + i * element->stride); if(!color_s) { static BOOL warned = FALSE; @@ -4617,9 +4834,8 @@ static HRESULT process_vertices_strided(IWineD3DDeviceImpl *This, DWORD dwDestIn } for (tex_index = 0; tex_index < numTextures; tex_index++) { - const float *tex_coord = - (const float *)(lpStrideData->u.s.texCoords[tex_index].lpData + - i * lpStrideData->u.s.texCoords[tex_index].dwStride); + const struct wined3d_stream_info_element *element = &stream_info->elements[WINED3D_FFP_TEXCOORD0 + tex_index]; + const float *tex_coord = (const float *)(element->data + i * element->stride); if(!tex_coord) { ERR("No source texture, but destination requests one\n"); dest_ptr+=GET_TEXCOORD_SIZE_FROM_FVF(DestFVF, tex_index) * sizeof(float); @@ -4654,7 +4870,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, UINT VertexCount, IWineD3DBuffer *pDestBuffer, IWineD3DVertexDeclaration *pVertexDecl, DWORD Flags) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - WineDirect3DVertexStridedData strided; + struct wined3d_stream_info stream_info; BOOL vbo = FALSE, streamWasUP = This->stateBlock->streamIsUP; TRACE("(%p)->(%d,%d,%d,%p,%p,%d\n", This, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags); @@ -4669,38 +4885,34 @@ static HRESULT WINAPI IWineD3DDeviceImpl_ProcessVertices(IWineD3DDevice *iface, * control the streamIsUP flag, thus restore it afterwards. */ This->stateBlock->streamIsUP = FALSE; - memset(&strided, 0, sizeof(strided)); - primitiveDeclarationConvertToStridedData(iface, FALSE, &strided, &vbo); + device_stream_info_from_declaration(This, FALSE, &stream_info, &vbo); This->stateBlock->streamIsUP = streamWasUP; if(vbo || SrcStartIndex) { unsigned int i; /* ProcessVertices can't convert FROM a vbo, and vertex buffers used to source into ProcessVertices are - * unlikely to ever be used for drawing. Release vbos in those buffers and fix up the strided structure + * unlikely to ever be used for drawing. Release vbos in those buffers and fix up the stream_info structure * * Also get the start index in, but only loop over all elements if there's something to add at all. */ - for (i = 0; i < (sizeof(strided.u.input) / sizeof(*strided.u.input)); ++i) + for (i = 0; i < (sizeof(stream_info.elements) / sizeof(*stream_info.elements)); ++i) { - if (strided.u.input[i].VBO) + struct wined3d_stream_info_element *e = &stream_info.elements[i]; + if (e->buffer_object) { - struct wined3d_buffer *vb = - (struct wined3d_buffer *)This->stateBlock->streamSource[strided.u.input[i].streamNo]; - strided.u.input[i].VBO = 0; - strided.u.input[i].lpData = (BYTE *)((unsigned long)strided.u.input[i].lpData + (unsigned long)vb->resource.allocatedMemory); + struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; + e->buffer_object = 0; + e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory); ENTER_GL(); GL_EXTCALL(glDeleteBuffersARB(1, &vb->buffer_object)); vb->buffer_object = 0; LEAVE_GL(); } - if (strided.u.input[i].lpData) - { - strided.u.input[i].lpData += strided.u.input[i].dwStride * SrcStartIndex; - } + if (e->data) e->data += e->stride * SrcStartIndex; } } - return process_vertices_strided(This, DestIndex, VertexCount, &strided, + return process_vertices_strided(This, DestIndex, VertexCount, &stream_info, (struct wined3d_buffer *)pDestBuffer, Flags); } diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 4718969e1ae..004b0c5ac12 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -32,173 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw); #include #include -static BOOL fixed_get_input( - BYTE usage, BYTE usage_idx, - unsigned int* regnum) { - - *regnum = -1; - - /* Those positions must have the order in the - * named part of the strided data */ - - if ((usage == WINED3DDECLUSAGE_POSITION || usage == WINED3DDECLUSAGE_POSITIONT) && usage_idx == 0) - *regnum = 0; - else if (usage == WINED3DDECLUSAGE_BLENDWEIGHT && usage_idx == 0) - *regnum = 1; - else if (usage == WINED3DDECLUSAGE_BLENDINDICES && usage_idx == 0) - *regnum = 2; - else if (usage == WINED3DDECLUSAGE_NORMAL && usage_idx == 0) - *regnum = 3; - else if (usage == WINED3DDECLUSAGE_PSIZE && usage_idx == 0) - *regnum = 4; - else if (usage == WINED3DDECLUSAGE_COLOR && usage_idx == 0) - *regnum = 5; - else if (usage == WINED3DDECLUSAGE_COLOR && usage_idx == 1) - *regnum = 6; - else if (usage == WINED3DDECLUSAGE_TEXCOORD && usage_idx < WINED3DDP_MAXTEXCOORD) - *regnum = 7 + usage_idx; - - if (*regnum == -1) { - FIXME("Unsupported input stream [usage=%s, usage_idx=%u]\n", - debug_d3ddeclusage(usage), usage_idx); - return FALSE; - } - return TRUE; -} - -void primitiveDeclarationConvertToStridedData( - IWineD3DDevice *iface, - BOOL useVertexShaderFunction, - WineDirect3DVertexStridedData *strided, - BOOL *fixup) { - - /* We need to deal with frequency data!*/ - - const BYTE *data = NULL; - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl *)This->stateBlock->vertexDecl; - unsigned int i; - const WINED3DVERTEXELEMENT *element; - DWORD stride; - DWORD numPreloadStreams = This->stateBlock->streamIsUP ? 0 : vertexDeclaration->num_streams; - const DWORD *streams = vertexDeclaration->streams; - - /* Check for transformed vertices, disable vertex shader if present */ - strided->position_transformed = vertexDeclaration->position_transformed; - if(vertexDeclaration->position_transformed) { - useVertexShaderFunction = FALSE; - } - - /* Translate the declaration into strided data */ - strided->swizzle_map = 0; - for (i = 0 ; i < vertexDeclaration->declarationWNumElements - 1; ++i) { - GLuint streamVBO = 0; - BOOL stride_used; - unsigned int idx; - - element = vertexDeclaration->pDeclarationWine + i; - TRACE("%p Element %p (%u of %u)\n", vertexDeclaration->pDeclarationWine, - element, i + 1, vertexDeclaration->declarationWNumElements - 1); - - if (This->stateBlock->streamSource[element->Stream] == NULL) - continue; - - stride = This->stateBlock->streamStride[element->Stream]; - if (This->stateBlock->streamIsUP) { - TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); - streamVBO = 0; - data = (BYTE *)This->stateBlock->streamSource[element->Stream]; - } else { - TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); - data = buffer_get_memory(This->stateBlock->streamSource[element->Stream], 0, &streamVBO); - - /* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets - * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory - * sources. In most sane cases the pointer - offset will still be > 0, otherwise it will wrap - * around to some big value. Hope that with the indices, the driver wraps it back internally. If - * not, drawStridedSlow is needed, including a vertex buffer path. - */ - if(This->stateBlock->loadBaseVertexIndex < 0) { - WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); - streamVBO = 0; - data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory; - if((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) { - FIXME("System memory vertex data load offset is negative!\n"); - } - } - - if(fixup) { - if( streamVBO != 0) *fixup = TRUE; - else if(*fixup && !useVertexShaderFunction && - (element->Usage == WINED3DDECLUSAGE_COLOR || - element->Usage == WINED3DDECLUSAGE_POSITIONT)) { - static BOOL warned = FALSE; - if(!warned) { - /* This may be bad with the fixed function pipeline */ - FIXME("Missing vbo streams with unfixed colors or transformed position, expect problems\n"); - warned = TRUE; - } - } - } - } - data += element->Offset; - - TRACE("Offset %d Stream %d UsageIndex %d\n", element->Offset, element->Stream, element->UsageIndex); - - if (useVertexShaderFunction) - { - stride_used = vshader_get_input(This->stateBlock->vertexShader, - element->Usage, element->UsageIndex, &idx); - } - else - { - if (!vertexDeclaration->ffp_valid[i]) - { - WARN("Skipping unsupported fixed function element of type %s and usage %s\n", - debug_d3ddecltype(element->Type), debug_d3ddeclusage(element->Usage)); - stride_used = FALSE; - } - else - { - stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx); - } - } - - if (stride_used) { - TRACE("Load %s array %u [usage=%s, usage_idx=%u, " - "stream=%u, offset=%u, stride=%u, type=%s, VBO=%u]\n", - useVertexShaderFunction? "shader": "fixed function", idx, - debug_d3ddeclusage(element->Usage), element->UsageIndex, - element->Stream, element->Offset, stride, debug_d3ddecltype(element->Type), streamVBO); - - strided->u.input[idx].lpData = data; - strided->u.input[idx].dwType = element->Type; - strided->u.input[idx].dwStride = stride; - strided->u.input[idx].VBO = streamVBO; - strided->u.input[idx].streamNo = element->Stream; - if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && element->Type == WINED3DDECLTYPE_D3DCOLOR) - { - strided->swizzle_map |= 1 << idx; - } - strided->use_map |= 1 << idx; - } - } - /* Now call PreLoad on all the vertex buffers. In the very rare case - * that the buffers stopps converting PreLoad will dirtify the VDECL again. - * The vertex buffer can now use the strided structure in the device instead of finding its - * own again. - * - * NULL streams won't be recorded in the array, UP streams won't be either. A stream is only - * once in there. - */ - for(i=0; i < numPreloadStreams; i++) { - IWineD3DBuffer *vb = This->stateBlock->streamSource[streams[i]]; - if(vb) { - IWineD3DBuffer_PreLoad(vb); - } - } -} - static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type, UINT min_vertex_idx, UINT max_vertex_idx, UINT count, UINT idx_size, const void *idx_data, UINT start_idx) @@ -235,7 +68,7 @@ static void drawStridedFast(IWineD3DDevice *iface, GLenum primitive_type, * Slower GL version which extracts info about each vertex in turn */ -static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT NumVertexes, +static void drawStridedSlow(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT NumVertexes, GLenum glPrimType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) { unsigned int textureNo = 0; @@ -250,6 +83,7 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid UINT texture_stages = GL_LIMITS(texture_stages); const BYTE *texCoords[WINED3DDP_MAXTEXCOORD]; const BYTE *diffuse = NULL, *specular = NULL, *normal = NULL, *position = NULL; + const struct wined3d_stream_info_element *element; DWORD tex_mask = 0; TRACE("Using slow vertex array code\n"); @@ -275,30 +109,34 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid VTRACE(("glBegin(%x)\n", glPrimType)); glBegin(glPrimType); - if (sd->u.s.position.lpData) position = sd->u.s.position.lpData + streamOffset[sd->u.s.position.streamNo]; + element = &si->elements[WINED3D_FFP_POSITION]; + if (element->data) position = element->data + streamOffset[element->stream_idx]; - if (sd->u.s.normal.lpData) normal = sd->u.s.normal.lpData + streamOffset[sd->u.s.normal.streamNo]; + element = &si->elements[WINED3D_FFP_NORMAL]; + if (element->data) normal = element->data + streamOffset[element->stream_idx]; else glNormal3f(0, 0, 0); - if (sd->u.s.diffuse.lpData) diffuse = sd->u.s.diffuse.lpData + streamOffset[sd->u.s.diffuse.streamNo]; + element = &si->elements[WINED3D_FFP_DIFFUSE]; + if (element->data) diffuse = element->data + streamOffset[element->stream_idx]; else glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - if (This->activeContext->num_untracked_materials && sd->u.s.diffuse.dwType != WINED3DDECLTYPE_D3DCOLOR) - FIXME("Implement diffuse color tracking from %s\n", debug_d3ddecltype(sd->u.s.diffuse.dwType)); + if (This->activeContext->num_untracked_materials && element->d3d_type != WINED3DDECLTYPE_D3DCOLOR) + FIXME("Implement diffuse color tracking from %s\n", debug_d3ddecltype(element->d3d_type)); - if (sd->u.s.specular.lpData) + element = &si->elements[WINED3D_FFP_SPECULAR]; + if (element->data) { - specular = sd->u.s.specular.lpData + streamOffset[sd->u.s.specular.streamNo]; + specular = element->data + streamOffset[element->stream_idx]; /* special case where the fog density is stored in the specular alpha channel */ if (This->stateBlock->renderState[WINED3DRS_FOGENABLE] && (This->stateBlock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE - || sd->u.s.position.dwType == WINED3DDECLTYPE_FLOAT4) + || si->elements[WINED3D_FFP_POSITION].d3d_type == WINED3DDECLTYPE_FLOAT4) && This->stateBlock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) { if (GL_SUPPORT(EXT_FOG_COORD)) { - if (sd->u.s.specular.dwType == WINED3DDECLTYPE_D3DCOLOR) specular_fog = TRUE; - else FIXME("Implement fog coordinates from %s\n", debug_d3ddecltype(sd->u.s.specular.dwType)); + if (element->d3d_type == WINED3DDECLTYPE_D3DCOLOR) specular_fog = TRUE; + else FIXME("Implement fog coordinates from %s\n", debug_d3ddecltype(element->d3d_type)); } else { @@ -344,10 +182,10 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid continue; } - if(sd->u.s.texCoords[coordIdx].lpData) + element = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx]; + if (element->data) { - texCoords[coordIdx] = - sd->u.s.texCoords[coordIdx].lpData + streamOffset[sd->u.s.texCoords[coordIdx].streamNo]; + texCoords[coordIdx] = element->data + streamOffset[element->stream_idx]; tex_mask |= (1 << textureNo); } else @@ -394,17 +232,18 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid if (!(tmp_tex_mask & 1)) continue; coord_idx = This->stateBlock->textureState[texture][WINED3DTSS_TEXCOORDINDEX]; - ptr = texCoords[coord_idx] + (SkipnStrides * sd->u.s.texCoords[coord_idx].dwStride); + ptr = texCoords[coord_idx] + (SkipnStrides * si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].stride); texture_idx = This->texUnitMap[texture]; - multi_texcoord_funcs[sd->u.s.texCoords[coord_idx].dwType](GL_TEXTURE0_ARB + texture_idx, ptr); + multi_texcoord_funcs[si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].d3d_type]( + GL_TEXTURE0_ARB + texture_idx, ptr); } /* Diffuse -------------------------------- */ if (diffuse) { - const void *ptrToCoords = diffuse + SkipnStrides * sd->u.s.diffuse.dwStride; + const void *ptrToCoords = diffuse + SkipnStrides * si->elements[WINED3D_FFP_DIFFUSE].stride; - diffuse_funcs[sd->u.s.diffuse.dwType](ptrToCoords); + diffuse_funcs[si->elements[WINED3D_FFP_DIFFUSE].d3d_type](ptrToCoords); if(This->activeContext->num_untracked_materials) { DWORD diffuseColor = ((const DWORD *)ptrToCoords)[0]; unsigned char i; @@ -423,9 +262,9 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid /* Specular ------------------------------- */ if (specular) { - const void *ptrToCoords = specular + SkipnStrides * sd->u.s.specular.dwStride; + const void *ptrToCoords = specular + SkipnStrides * si->elements[WINED3D_FFP_SPECULAR].stride; - specular_funcs[sd->u.s.specular.dwType](ptrToCoords); + specular_funcs[si->elements[WINED3D_FFP_SPECULAR].d3d_type](ptrToCoords); if (specular_fog) { @@ -436,14 +275,14 @@ static void drawStridedSlow(IWineD3DDevice *iface, const WineDirect3DVertexStrid /* Normal -------------------------------- */ if (normal != NULL) { - const void *ptrToCoords = normal + SkipnStrides * sd->u.s.normal.dwStride; - normal_funcs[sd->u.s.normal.dwType](ptrToCoords); + const void *ptrToCoords = normal + SkipnStrides * si->elements[WINED3D_FFP_NORMAL].stride; + normal_funcs[si->elements[WINED3D_FFP_NORMAL].d3d_type](ptrToCoords); } /* Position -------------------------------- */ if (position) { - const void *ptrToCoords = position + SkipnStrides * sd->u.s.position.dwStride; - position_funcs[sd->u.s.position.dwType](ptrToCoords); + const void *ptrToCoords = position + SkipnStrides * si->elements[WINED3D_FFP_POSITION].stride; + position_funcs[si->elements[WINED3D_FFP_POSITION].d3d_type](ptrToCoords); } /* For non indexed mode, step onto next parts */ @@ -555,7 +394,7 @@ static inline void send_attribute(IWineD3DDeviceImpl *This, const DWORD type, co } } -static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, UINT numberOfVertices, +static void drawStridedSlowVs(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; @@ -601,13 +440,13 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStr } for(i = MAX_ATTRIBS - 1; i >= 0; i--) { - if(!sd->u.input[i].lpData) continue; + if(!si->elements[i].data) continue; - ptr = sd->u.input[i].lpData + - sd->u.input[i].dwStride * SkipnStrides + - stateblock->streamOffset[sd->u.input[i].streamNo]; + ptr = si->elements[i].data + + si->elements[i].stride * SkipnStrides + + stateblock->streamOffset[si->elements[i].stream_idx]; - send_attribute(This, sd->u.input[i].dwType, i, ptr); + send_attribute(This, si->elements[i].d3d_type, i, ptr); } SkipnStrides++; } @@ -615,13 +454,13 @@ static void drawStridedSlowVs(IWineD3DDevice *iface, const WineDirect3DVertexStr glEnd(); } -static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3DVertexStridedData *sd, +static inline void drawStridedInstanced(IWineD3DDevice *iface, const struct wined3d_stream_info *si, UINT numberOfVertices, GLenum glPrimitiveType, const void *idxData, UINT idxSize, UINT minIndex, UINT startIdx) { UINT numInstances = 0, i; int numInstancedAttribs = 0, j; - UINT instancedData[sizeof(sd->u.input) / sizeof(sd->u.input[0]) /* 16 */]; + UINT instancedData[sizeof(si->elements) / sizeof(*si->elements) /* 16 */]; IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; IWineD3DStateBlockImpl *stateblock = This->stateBlock; @@ -652,8 +491,10 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3 } } - for(i = 0; i < sizeof(sd->u.input) / sizeof(sd->u.input[0]); i++) { - if(stateblock->streamFlags[sd->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) { + for (i = 0; i < sizeof(si->elements) / sizeof(*si->elements); ++i) + { + if (stateblock->streamFlags[si->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA) + { instancedData[numInstancedAttribs] = i; numInstancedAttribs++; } @@ -663,15 +504,17 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3 for(i = 0; i < numInstances; i++) { /* Specify the instanced attributes using immediate mode calls */ for(j = 0; j < numInstancedAttribs; j++) { - const BYTE *ptr = sd->u.input[instancedData[j]].lpData + - sd->u.input[instancedData[j]].dwStride * i + - stateblock->streamOffset[sd->u.input[instancedData[j]].streamNo]; - if(sd->u.input[instancedData[j]].VBO) { - struct wined3d_buffer *vb = (struct wined3d_buffer *)stateblock->streamSource[sd->u.input[instancedData[j]].streamNo]; + const BYTE *ptr = si->elements[instancedData[j]].data + + si->elements[instancedData[j]].stride * i + + stateblock->streamOffset[si->elements[instancedData[j]].stream_idx]; + if (si->elements[instancedData[j]].buffer_object) + { + struct wined3d_buffer *vb = + (struct wined3d_buffer *)stateblock->streamSource[si->elements[instancedData[j]].stream_idx]; ptr += (long) vb->resource.allocatedMemory; } - send_attribute(This, sd->u.input[instancedData[j]].dwType, instancedData[j], ptr); + send_attribute(This, si->elements[instancedData[j]].d3d_type, instancedData[j], ptr); } glDrawElements(glPrimitiveType, numberOfVertices, idxSize == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, @@ -680,17 +523,18 @@ static inline void drawStridedInstanced(IWineD3DDevice *iface, const WineDirect3 } } -static inline void remove_vbos(IWineD3DDeviceImpl *This, WineDirect3DVertexStridedData *s) { +static inline void remove_vbos(IWineD3DDeviceImpl *This, struct wined3d_stream_info *s) +{ unsigned int i; - for (i = 0; i < (sizeof(s->u.input) / sizeof(*s->u.input)); ++i) + for (i = 0; i < (sizeof(s->elements) / sizeof(*s->elements)); ++i) { - if (s->u.input[i].VBO) + struct wined3d_stream_info_element *e = &s->elements[i]; + if (e->buffer_object) { - struct wined3d_buffer *vb = - (struct wined3d_buffer *)This->stateBlock->streamSource[s->u.input[i].streamNo]; - s->u.input[i].VBO = 0; - s->u.input[i].lpData = (BYTE *)((unsigned long)s->u.input[i].lpData + (unsigned long)vb->resource.allocatedMemory); + struct wined3d_buffer *vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; + e->buffer_object = 0; + e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory); } } } @@ -733,8 +577,8 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice { GLenum glPrimType = This->stateBlock->gl_primitive_type; BOOL emulation = FALSE; - const WineDirect3DVertexStridedData *strided = &This->strided_streams; - WineDirect3DVertexStridedData stridedlcl; + const struct wined3d_stream_info *stream_info = &This->strided_streams; + struct wined3d_stream_info stridedlcl; if (!numberOfVertices) numberOfVertices = index_count; @@ -767,7 +611,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice } if(emulation) { - strided = &stridedlcl; + stream_info = &stridedlcl; memcpy(&stridedlcl, &This->strided_streams, sizeof(stridedlcl)); remove_vbos(This, &stridedlcl); } @@ -784,9 +628,9 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertice } else { TRACE("Using immediate mode with vertex shaders for half float emulation\n"); } - drawStridedSlowVs(iface, strided, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx); + drawStridedSlowVs(iface, stream_info, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx); } else { - drawStridedSlow(iface, strided, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx); + drawStridedSlow(iface, stream_info, index_count, glPrimType, idxData, idxSize, minIndex, StartIdx); } } else if(This->instancedDraw) { /* Instancing emulation with mixing immediate mode and arrays */ @@ -881,7 +725,8 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, struct WineD3DRectPatch *patch) { unsigned int i, j, num_quads, out_vertex_size, buffer_size, d3d_out_vertex_size; float max_x = 0.0, max_y = 0.0, max_z = 0.0, neg_z = 0.0; - WineDirect3DVertexStridedData strided; + struct wined3d_stream_info stream_info; + struct wined3d_stream_info_element *e; const BYTE *data; const WINED3DRECTPATCH_INFO *info = &patch->RectPatchInfo; DWORD vtxStride; @@ -891,21 +736,22 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, /* First, locate the position data. This is provided in a vertex buffer in the stateblock. * Beware of vbos */ - memset(&strided, 0, sizeof(strided)); - primitiveDeclarationConvertToStridedData((IWineD3DDevice *) This, FALSE, &strided, NULL); - if(strided.u.s.position.VBO) { + device_stream_info_from_declaration(This, FALSE, &stream_info, NULL); + + e = &stream_info.elements[WINED3D_FFP_POSITION]; + if (e->buffer_object) + { struct wined3d_buffer *vb; - vb = (struct wined3d_buffer *)This->stateBlock->streamSource[strided.u.s.position.streamNo]; - strided.u.s.position.lpData = (BYTE *) ((unsigned long) strided.u.s.position.lpData + - (unsigned long) vb->resource.allocatedMemory); + vb = (struct wined3d_buffer *)This->stateBlock->streamSource[e->stream_idx]; + e->data = (BYTE *)((unsigned long)e->data + (unsigned long)vb->resource.allocatedMemory); } - vtxStride = strided.u.s.position.dwStride; - data = strided.u.s.position.lpData + + vtxStride = e->stride; + data = e->data + vtxStride * info->Stride * info->StartVertexOffsetHeight + vtxStride * info->StartVertexOffsetWidth; /* Not entirely sure about what happens with transformed vertices */ - if (strided.position_transformed) FIXME("Transformed position in rectpatch generation\n"); + if (stream_info.position_transformed) FIXME("Transformed position in rectpatch generation\n"); if(vtxStride % sizeof(GLfloat)) { /* glMap2f reads vertex sizes in GLfloats, the d3d stride is in bytes. @@ -1203,29 +1049,22 @@ HRESULT tesselate_rectpatch(IWineD3DDeviceImpl *This, vtxStride += 4 * sizeof(float); } memset(&patch->strided, 0, sizeof(&patch->strided)); - patch->strided.u.s.position.lpData = (BYTE *) patch->mem; - patch->strided.u.s.position.dwStride = vtxStride; - patch->strided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3; - patch->strided.u.s.position.streamNo = 255; + patch->strided.position.dwType = WINED3DDECLTYPE_FLOAT3; + patch->strided.position.lpData = (BYTE *) patch->mem; + patch->strided.position.dwStride = vtxStride; if(patch->has_normals) { - patch->strided.u.s.normal.lpData = (BYTE *) patch->mem + 3 * sizeof(float) /* pos */; - patch->strided.u.s.normal.dwStride = vtxStride; - patch->strided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3; - patch->strided.u.s.normal.streamNo = 255; + patch->strided.normal.dwType = WINED3DDECLTYPE_FLOAT3; + patch->strided.normal.lpData = (BYTE *) patch->mem + 3 * sizeof(float) /* pos */; + patch->strided.normal.dwStride = vtxStride; } if(patch->has_texcoords) { - patch->strided.u.s.texCoords[0].lpData = (BYTE *) patch->mem + 3 * sizeof(float) /* pos */; + patch->strided.texCoords[0].dwType = WINED3DDECLTYPE_FLOAT4; + patch->strided.texCoords[0].lpData = (BYTE *) patch->mem + 3 * sizeof(float) /* pos */; if(patch->has_normals) { - patch->strided.u.s.texCoords[0].lpData += 3 * sizeof(float); + patch->strided.texCoords[0].lpData += 3 * sizeof(float); } - patch->strided.u.s.texCoords[0].dwStride = vtxStride; - patch->strided.u.s.texCoords[0].dwType = WINED3DDECLTYPE_FLOAT4; - /* MAX_STREAMS index points to an unused element in stateblock->streamOffsets which - * always remains set to 0. Windows uses stream 255 here, but this is not visible to the - * application. - */ - patch->strided.u.s.texCoords[0].streamNo = MAX_STREAMS; + patch->strided.texCoords[0].dwStride = vtxStride; } return WINED3D_OK; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index b4e5642a189..278e52b26d8 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1150,7 +1150,7 @@ void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; GLenum Parm = 0; - const WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse; + const struct wined3d_stream_info_element *diffuse = &device->strided_streams.elements[WINED3D_FFP_DIFFUSE]; BOOL isDiffuseSupplied; /* Depends on the decoded vertex declaration to read the existence of diffuse data. @@ -1161,7 +1161,7 @@ static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, Wine return; } - isDiffuseSupplied = diffuse->lpData || diffuse->VBO; + isDiffuseSupplied = diffuse->data || diffuse->buffer_object; context->num_untracked_materials = 0; if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) { @@ -1315,9 +1315,10 @@ static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, Win * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division * by zero and is not properly defined in opengl, so avoid it */ - if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS] && ( - stateblock->wineD3DDevice->strided_streams.u.s.normal.lpData || - stateblock->wineD3DDevice->strided_streams.u.s.normal.VBO)) { + if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS] + && (stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_NORMAL].data + || stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_NORMAL].buffer_object)) + { glEnable(GL_NORMALIZE); checkGLcall("glEnable(GL_NORMALIZE);"); } else { @@ -3010,13 +3011,11 @@ static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, W coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1); set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0], - stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], - generated, - context->last_was_rhw, - stateblock->wineD3DDevice->strided_streams.u.s.texCoords[coordIdx].dwStride ? - stateblock->wineD3DDevice->strided_streams.u.s.texCoords[coordIdx].dwType: - WINED3DDECLTYPE_UNUSED, - stateblock->wineD3DDevice->frag_pipe->ffp_proj_control); + stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw, + stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].stride + ? stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].d3d_type + : WINED3DDECLTYPE_UNUSED, + stateblock->wineD3DDevice->frag_pipe->ffp_proj_control); /* The sampler applying function calls us if this changes */ if ((context->lastWasPow2Texture & (1 << texUnit)) && stateblock->textures[texUnit]) @@ -3038,7 +3037,7 @@ static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) { } } -static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3DVertexStridedData *sd, GLuint *curVBO) +static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const struct wined3d_stream_info *si, GLuint *curVBO) { const UINT *offset = stateblock->streamOffset; unsigned int mapped_stage = 0; @@ -3046,29 +3045,30 @@ static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, const WineDirect3D for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) { int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX]; + const struct wined3d_stream_info_element *e; mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo]; if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue; - if (coordIdx < MAX_TEXTURES && (sd->u.s.texCoords[coordIdx].lpData || sd->u.s.texCoords[coordIdx].VBO)) { + e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx]; + if (coordIdx < MAX_TEXTURES && (e->data || e->buffer_object)) + { TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n", - textureNo, mapped_stage, coordIdx, sd->u.s.texCoords[coordIdx].lpData); + textureNo, mapped_stage, coordIdx, e->data); - if (*curVBO != sd->u.s.texCoords[coordIdx].VBO) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO)); + if (*curVBO != e->buffer_object) + { + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); checkGLcall("glBindBufferARB"); - *curVBO = sd->u.s.texCoords[coordIdx].VBO; + *curVBO = e->buffer_object; } GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage)); checkGLcall("glClientActiveTextureARB"); /* The coords to supply depend completely on the fvf / vertex shader */ - glTexCoordPointer( - WINED3D_ATR_FORMAT(sd->u.s.texCoords[coordIdx].dwType), - WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType), - sd->u.s.texCoords[coordIdx].dwStride, - sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]); + glTexCoordPointer(e->format, e->type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } else { GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1)); @@ -3837,7 +3837,7 @@ static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, Wine } static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, - const WineDirect3DVertexStridedData *strided, WineD3DContext *context) + const struct wined3d_stream_info *stream_info, WineD3DContext *context) { GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0; int i; @@ -3849,28 +3849,31 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, stateblock->wineD3DDevice->instancedDraw = FALSE; for (i = 0; i < MAX_ATTRIBS; i++) { - if (!(strided->use_map & (1 << i))) + if (!(stream_info->use_map & (1 << i))) { if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); continue; } /* Do not load instance data. It will be specified using glTexCoord by drawprim */ - if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) { + if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA) + { if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); stateblock->wineD3DDevice->instancedDraw = TRUE; continue; } - TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO); + TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].buffer_object); - if(strided->u.input[i].dwStride) { - if(curVBO != strided->u.input[i].VBO) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO)); + if (stream_info->elements[i].stride) + { + if (curVBO != stream_info->elements[i].buffer_object) + { + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].buffer_object)); checkGLcall("glBindBufferARB"); - curVBO = strided->u.input[i].VBO; + curVBO = stream_info->elements[i].buffer_object; } - vb = (struct wined3d_buffer *)stateblock->streamSource[strided->u.input[i].streamNo]; + vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx]; /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no * vbo we won't be load converted attributes anyway @@ -3879,30 +3882,24 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, { TRACE("Loading attribute from shifted buffer\n"); TRACE("Attrib %d has original stride %d, new stride %d\n", - i, strided->u.input[i].dwStride, vb->conversion_stride); + i, stream_info->elements[i].stride, vb->conversion_stride); TRACE("Original offset %p, additional offset 0x%08x\n", - strided->u.input[i].lpData, vb->conversion_shift[(DWORD_PTR) strided->u.input[i].lpData]); - TRACE("Opengl type %x\n", WINED3D_ATR_GLTYPE(strided->u.input[i].dwType)); - shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]); - shift_index = shift_index % strided->u.input[i].dwStride; - GL_EXTCALL(glVertexAttribPointerARB(i, WINED3D_ATR_FORMAT(strided->u.input[i].dwType), - WINED3D_ATR_GLTYPE(strided->u.input[i].dwType), - WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType), - vb->conversion_stride, - strided->u.input[i].lpData + vb->conversion_shift[shift_index] - + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride - + offset[strided->u.input[i].streamNo])); + stream_info->elements[i].data, vb->conversion_shift[(DWORD_PTR)stream_info->elements[i].data]); + TRACE("Opengl type %#x\n", stream_info->elements[i].type); + shift_index = ((DWORD_PTR)stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx]); + shift_index = shift_index % stream_info->elements[i].stride; + GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format, + stream_info->elements[i].type, stream_info->elements[i].normalized, + vb->conversion_stride, stream_info->elements[i].data + vb->conversion_shift[shift_index] + + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride + + offset[stream_info->elements[i].stream_idx])); } else { - GL_EXTCALL(glVertexAttribPointerARB(i, - WINED3D_ATR_FORMAT(strided->u.input[i].dwType), - WINED3D_ATR_GLTYPE(strided->u.input[i].dwType), - WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType), - strided->u.input[i].dwStride, - - strided->u.input[i].lpData + - stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + - offset[strided->u.input[i].streamNo]) ); + GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format, + stream_info->elements[i].type, stream_info->elements[i].normalized, + stream_info->elements[i].stride, stream_info->elements[i].data + + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride + + offset[stream_info->elements[i].stream_idx])); } if (!(context->numbered_array_mask & (1 << i))) @@ -3914,15 +3911,17 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and * set up the attribute statically. But we have to figure out the system memory address. */ - const BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]; - if(strided->u.input[i].VBO) { - vb = (struct wined3d_buffer *)stateblock->streamSource[strided->u.input[i].streamNo]; + const BYTE *ptr = stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx]; + if (stream_info->elements[i].buffer_object) + { + vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx]; ptr += (long) vb->resource.allocatedMemory; } if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i); - switch(strided->u.input[i].dwType) { + switch(stream_info->elements[i].d3d_type) + { case WINED3DDECLTYPE_FLOAT1: GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr)); break; @@ -4011,10 +4010,11 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, } /* Used from 2 different functions, and too big to justify making it inlined */ -static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3DVertexStridedData *sd) +static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const struct wined3d_stream_info *si) { const UINT *offset = stateblock->streamOffset; GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0; + const struct wined3d_stream_info_element *e; TRACE("Using fast vertex array code\n"); @@ -4022,38 +4022,40 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 stateblock->wineD3DDevice->instancedDraw = FALSE; /* Blend Data ---------------------------------------------- */ - if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) || - (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) { - + e = &si->elements[WINED3D_FFP_BLENDWEIGHT]; + if (e->data || e->buffer_object + || si->elements[WINED3D_FFP_BLENDINDICES].data + || si->elements[WINED3D_FFP_BLENDINDICES].buffer_object) + { if (GL_SUPPORT(ARB_VERTEX_BLEND)) { - TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType), - sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]); + TRACE("Blend %d %p %d\n", e->size, + e->data + stateblock->loadBaseVertexIndex * e->stride, e->stride + offset[e->stream_idx]); glEnableClientState(GL_WEIGHT_ARRAY_ARB); checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)"); - GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1)); + GL_EXTCALL(glVertexBlendARB(e->size + 1)); VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n", WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) , sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo])); - if(curVBO != sd->u.s.blendWeights.VBO) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO)); + if (curVBO != e->buffer_object) + { + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); checkGLcall("glBindBufferARB"); - curVBO = sd->u.s.blendWeights.VBO; + curVBO = e->buffer_object; } - GL_EXTCALL(glWeightPointerARB)( - WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType), - WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType), - sd->u.s.blendWeights.dwStride, - sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]); + GL_EXTCALL(glWeightPointerARB)(e->format, e->type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glWeightPointerARB"); - if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){ + if (si->elements[WINED3D_FFP_BLENDINDICES].data + || (si->elements[WINED3D_FFP_BLENDINDICES].buffer_object)) + { static BOOL warned; if (!warned) { @@ -4076,26 +4078,25 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 } /* Point Size ----------------------------------------------*/ - if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) { - + e = &si->elements[WINED3D_FFP_PSIZE]; + if (e->data || e->buffer_object) + { /* no such functionality in the fixed function GL pipeline */ TRACE("Cannot change ptSize here in openGl\n"); /* TODO: Implement this function in using shaders if they are available */ - } /* Vertex Pointers -----------------------------------------*/ - if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) { - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", - sd->u.s.position.dwStride, - sd->u.s.position.dwType + 1, - sd->u.s.position.lpData)); + e = &si->elements[WINED3D_FFP_POSITION]; + if (e->data || e->buffer_object) + { + VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data)); - if(curVBO != sd->u.s.position.VBO) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO)); + if (curVBO != e->buffer_object) + { + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); checkGLcall("glBindBufferARB"); - curVBO = sd->u.s.position.VBO; + curVBO = e->buffer_object; } /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord @@ -4106,15 +4107,13 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 This only applies to user pointer sources, in VBOs the vertices are fixed up */ - if(sd->u.s.position.VBO == 0) { - glVertexPointer(3 /* min(WINED3D_ATR_FORMAT(sd->u.s.position.dwType),3) */, - WINED3D_ATR_GLTYPE(sd->u.s.position.dwType), - sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]); + if (!e->buffer_object) + { + glVertexPointer(3 /* min(e->format, 3) */, e->type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); } else { - glVertexPointer( - WINED3D_ATR_FORMAT(sd->u.s.position.dwType), - WINED3D_ATR_GLTYPE(sd->u.s.position.dwType), - sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]); + glVertexPointer(e->format, e->type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); } checkGLcall("glVertexPointer(...)"); glEnableClientState(GL_VERTEX_ARRAY); @@ -4122,20 +4121,18 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 } /* Normals -------------------------------------------------*/ - if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) { - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", - sd->u.s.normal.dwStride, - sd->u.s.normal.lpData)); - if(curVBO != sd->u.s.normal.VBO) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO)); + e = &si->elements[WINED3D_FFP_NORMAL]; + if (e->data || e->buffer_object) + { + VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data)); + if (curVBO != e->buffer_object) + { + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); checkGLcall("glBindBufferARB"); - curVBO = sd->u.s.normal.VBO; + curVBO = e->buffer_object; } - glNormalPointer( - WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType), - sd->u.s.normal.dwStride, - sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]); + glNormalPointer(e->type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glNormalPointer(...)"); glEnableClientState(GL_NORMAL_ARRAY); checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); @@ -4154,22 +4151,20 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 /* NOTE: Unless we write a vertex shader to swizzle the colour*/ /* , or the user doesn't care and wants the speed advantage */ - if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) { - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", - sd->u.s.diffuse.dwStride, - sd->u.s.diffuse.lpData)); + e = &si->elements[WINED3D_FFP_DIFFUSE]; + if (e->data || e->buffer_object) + { + VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); - if(curVBO != sd->u.s.diffuse.VBO) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO)); + if (curVBO != e->buffer_object) + { + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); checkGLcall("glBindBufferARB"); - curVBO = sd->u.s.diffuse.VBO; + curVBO = e->buffer_object; } - glColorPointer(WINED3D_ATR_FORMAT(sd->u.s.diffuse.dwType), - WINED3D_ATR_GLTYPE(sd->u.s.diffuse.dwType), - sd->u.s.diffuse.dwStride, - sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]); + glColorPointer(e->format, e->type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); glEnableClientState(GL_COLOR_ARRAY); checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); @@ -4180,22 +4175,21 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 } /* Specular Colour ------------------------------------------*/ - if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) { + e = &si->elements[WINED3D_FFP_SPECULAR]; + if (e->data || e->buffer_object) + { TRACE("setting specular colour\n"); - /* Note dwType == float3 or float4 == 2 or 3 */ - VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", - sd->u.s.specular.dwStride, - sd->u.s.specular.lpData)); + VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data)); + if (GL_SUPPORT(EXT_SECONDARY_COLOR)) { - if(curVBO != sd->u.s.specular.VBO) { - GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO)); + if (curVBO != e->buffer_object) + { + GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object)); checkGLcall("glBindBufferARB"); - curVBO = sd->u.s.specular.VBO; + curVBO = e->buffer_object; } - GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_FORMAT(sd->u.s.specular.dwType), - WINED3D_ATR_GLTYPE(sd->u.s.specular.dwType), - sd->u.s.specular.dwStride, - sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]); + GL_EXTCALL(glSecondaryColorPointerEXT)(e->format, e->type, e->stride, + e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]); checkGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)"); glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); @@ -4217,28 +4211,28 @@ static void loadVertexData(IWineD3DStateBlockImpl *stateblock, const WineDirect3 } /* Texture coords -------------------------------------------*/ - loadTexCoords(stateblock, sd, &curVBO); + loadTexCoords(stateblock, si, &curVBO); } -static inline void drawPrimitiveTraceDataLocations(const WineDirect3DVertexStridedData *dataLocations) +static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations) { /* Dump out what parts we have supplied */ TRACE("Strided Data:\n"); - TRACE_STRIDED((dataLocations), position); - TRACE_STRIDED((dataLocations), blendWeights); - TRACE_STRIDED((dataLocations), blendMatrixIndices); - TRACE_STRIDED((dataLocations), normal); - TRACE_STRIDED((dataLocations), pSize); - TRACE_STRIDED((dataLocations), diffuse); - TRACE_STRIDED((dataLocations), specular); - TRACE_STRIDED((dataLocations), texCoords[0]); - TRACE_STRIDED((dataLocations), texCoords[1]); - TRACE_STRIDED((dataLocations), texCoords[2]); - TRACE_STRIDED((dataLocations), texCoords[3]); - TRACE_STRIDED((dataLocations), texCoords[4]); - TRACE_STRIDED((dataLocations), texCoords[5]); - TRACE_STRIDED((dataLocations), texCoords[6]); - TRACE_STRIDED((dataLocations), texCoords[7]); + TRACE_STRIDED((dataLocations), WINED3D_FFP_POSITION); + TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDWEIGHT); + TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDINDICES); + TRACE_STRIDED((dataLocations), WINED3D_FFP_NORMAL); + TRACE_STRIDED((dataLocations), WINED3D_FFP_PSIZE); + TRACE_STRIDED((dataLocations), WINED3D_FFP_DIFFUSE); + TRACE_STRIDED((dataLocations), WINED3D_FFP_SPECULAR); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD0); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD1); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD2); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD3); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD4); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD5); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD6); + TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD7); return; } @@ -4246,7 +4240,7 @@ static inline void drawPrimitiveTraceDataLocations(const WineDirect3DVertexStrid static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; BOOL fixup = FALSE; - WineDirect3DVertexStridedData *dataLocations = &device->strided_streams; + struct wined3d_stream_info *dataLocations = &device->strided_streams; BOOL useVertexShaderFunction; BOOL load_numbered = FALSE; BOOL load_named = FALSE; @@ -4256,7 +4250,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo if(device->up_strided) { /* Note: this is a ddraw fixed-function code path */ TRACE("================ Strided Input ===================\n"); - memcpy(dataLocations, device->up_strided, sizeof(*dataLocations)); + device_stream_info_from_strided(device, device->up_strided, dataLocations); if(TRACE_ON(d3d)) { drawPrimitiveTraceDataLocations(dataLocations); @@ -4268,9 +4262,7 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo * don't set any declaration at all */ TRACE("================ Vertex Declaration ===================\n"); - memset(dataLocations, 0, sizeof(*dataLocations)); - primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, - useVertexShaderFunction, dataLocations, &fixup); + device_stream_info_from_declaration(device, useVertexShaderFunction, dataLocations, &fixup); } if (dataLocations->position_transformed) useVertexShaderFunction = FALSE; @@ -4283,11 +4275,12 @@ static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCo load_numbered = TRUE; device->useDrawStridedSlow = FALSE; } - } else if (fixup || (!dataLocations->u.s.pSize.lpData + } + else if (fixup || (!dataLocations->elements[WINED3D_FFP_PSIZE].data && !dataLocations->position_transformed && (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) - || (!dataLocations->u.s.diffuse.lpData - && !dataLocations->u.s.specular.lpData)))) + || (!dataLocations->elements[WINED3D_FFP_DIFFUSE].data + && !dataLocations->elements[WINED3D_FFP_SPECULAR].data)))) { /* Load the vertex data using named arrays */ load_named = TRUE; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d53f2d5f1bb..73c394f9f44 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -591,8 +591,9 @@ do { \ /* Trace vector and strided data information */ #define TRACE_VECTOR(name) TRACE( #name "=(%f, %f, %f, %f)\n", name.x, name.y, name.z, name.w); -#define TRACE_STRIDED(sd,name) TRACE( #name "=(data:%p, stride:%d, type:%d, vbo %d, stream %u)\n", \ - sd->u.s.name.lpData, sd->u.s.name.dwStride, sd->u.s.name.dwType, sd->u.s.name.VBO, sd->u.s.name.streamNo); +#define TRACE_STRIDED(si, name) TRACE( #name "=(data:%p, stride:%d, type:%d, vbo %d, stream %u)\n", \ + si->elements[name].data, si->elements[name].stride, si->elements[name].d3d_type, \ + si->elements[name].buffer_object, si->elements[name].stream_idx); /* Defines used for optimizations */ @@ -650,6 +651,47 @@ extern BOOL isDumpingFrames; extern LONG primCounter; #endif +enum wined3d_ffp_idx +{ + WINED3D_FFP_POSITION = 0, + WINED3D_FFP_BLENDWEIGHT = 1, + WINED3D_FFP_BLENDINDICES = 2, + WINED3D_FFP_NORMAL = 3, + WINED3D_FFP_PSIZE = 4, + WINED3D_FFP_DIFFUSE = 5, + WINED3D_FFP_SPECULAR = 6, + WINED3D_FFP_TEXCOORD0 = 7, + WINED3D_FFP_TEXCOORD1 = 8, + WINED3D_FFP_TEXCOORD2 = 9, + WINED3D_FFP_TEXCOORD3 = 10, + WINED3D_FFP_TEXCOORD4 = 11, + WINED3D_FFP_TEXCOORD5 = 12, + WINED3D_FFP_TEXCOORD6 = 13, + WINED3D_FFP_TEXCOORD7 = 14, +}; + +struct wined3d_stream_info_element +{ + WINED3DDECLTYPE d3d_type; + GLint size; + GLint format; + GLenum type; + GLsizei stride; + GLboolean normalized; + const BYTE *data; + int type_size; + UINT stream_idx; + GLuint buffer_object; +}; + +struct wined3d_stream_info +{ + struct wined3d_stream_info_element elements[MAX_ATTRIBS]; + BOOL position_transformed; + WORD swizzle_map; /* MAX_ATTRIBS, 16 */ + WORD use_map; /* MAX_ATTRIBS, 16 */ +}; + /***************************************************************************** * Prototypes */ @@ -657,13 +699,6 @@ extern LONG primCounter; /* Routine common to the draw primitive and draw indexed primitive routines */ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT numberOfVertices, UINT start_idx, UINT idxBytes, const void *idxData, UINT minIndex); - -void primitiveDeclarationConvertToStridedData( - IWineD3DDevice *iface, - BOOL useVertexShaderFunction, - WineDirect3DVertexStridedData *strided, - BOOL *fixup); - DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); typedef void (WINE_GLAPI *glAttribFunc)(const void *data); @@ -1174,7 +1209,7 @@ struct IWineD3DDeviceImpl DWORD rev_tex_unit_map[MAX_COMBINED_SAMPLERS]; /* Stream source management */ - WineDirect3DVertexStridedData strided_streams; + struct wined3d_stream_info strided_streams; const WineDirect3DVertexStridedData *up_strided; /* Context management */ @@ -1194,6 +1229,10 @@ struct IWineD3DDeviceImpl extern const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl; +void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, + BOOL use_vshader, struct wined3d_stream_info *stream_info, BOOL *fixup); +void device_stream_info_from_strided(IWineD3DDeviceImpl *This, + const struct WineDirect3DVertexStridedData *strided, struct wined3d_stream_info *stream_info); HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *target, DWORD Count, CONST WINED3DRECT* pRects, DWORD Flags, WINED3DCOLOR Color, float Z, DWORD Stencil); diff --git a/include/wine/wined3d.idl b/include/wine/wined3d.idl index 4cf9159b714..783c3fa9f92 100644 --- a/include/wine/wined3d.idl +++ b/include/wine/wined3d.idl @@ -1918,41 +1918,16 @@ typedef struct WineDirect3DStridedData const BYTE *lpData; /* Pointer to start of data */ DWORD dwStride; /* Stride between occurrences of this data */ DWORD dwType; /* Type (as in D3DVSDT_TYPE) */ - unsigned int VBO; /* Vertex buffer object this data is in */ - UINT streamNo; /* D3D stream number */ } WineDirect3DStridedData; typedef struct WineDirect3DVertexStridedData { - /* - * IMPORTANT: - * This structure can be accessed in two ways: Named access, and array - * access. Please note that named access is only valid with the fixed - * function vertex pipeline, and the arrays are only valid with the - * programmable vertex pipeline(vertex shaders). - */ - union - { - struct - { - /* Do not add or reorder fields here, - * so this can be indexed as an array */ - WineDirect3DStridedData position; - WineDirect3DStridedData blendWeights; - WineDirect3DStridedData blendMatrixIndices; - WineDirect3DStridedData normal; - WineDirect3DStridedData pSize; - WineDirect3DStridedData diffuse; - WineDirect3DStridedData specular; - WineDirect3DStridedData texCoords[WINED3DDP_MAXTEXCOORD]; - /* Add fields here */ - } s; - WineDirect3DStridedData input[16]; /* Indexed by constants in D3DVSDE_REGISTER */ - } u; - + WineDirect3DStridedData position; + WineDirect3DStridedData normal; + WineDirect3DStridedData diffuse; + WineDirect3DStridedData specular; + WineDirect3DStridedData texCoords[WINED3DDP_MAXTEXCOORD]; BOOL position_transformed; - WORD swizzle_map; /* MAX_ATTRIBS, 16 */ - WORD use_map; /* MAX_ATTRIBS, 16 */ } WineDirect3DVertexStridedData; typedef struct _WINED3DVSHADERCAPS2_0