wined3d: Use separate structures for ddraw style strided data and wined3d's internal stream info.

This commit is contained in:
Henri Verbeet 2009-03-27 10:25:55 +01:00 committed by Alexandre Julliard
parent 5390628e6f
commit d7c7c76850
7 changed files with 594 additions and 536 deletions

View file

@ -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));
}

View file

@ -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");

View file

@ -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);
}

View file

@ -32,173 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
#include <stdio.h>
#include <math.h>
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;

View file

@ -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;

View file

@ -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);

View file

@ -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