Commit 47a8a6bd authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Implement and test vertex fixups with per stream offsets.

parent e27cf6ff
......@@ -5449,7 +5449,7 @@ struct vertex_floatcolor {
static void fixed_function_decl_test(IDirect3DDevice9 *device)
{
HRESULT hr;
DWORD color, size;
DWORD color, size, i;
void *data;
static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
......@@ -5818,9 +5818,6 @@ static void fixed_function_decl_test(IDirect3DDevice9 *device)
/* This test is pointless without those two declarations: */
if(!dcl_color_2 || !dcl_ubyte_2) goto out;
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
memcpy(data, quads, sizeof(quads));
......@@ -5835,46 +5832,70 @@ static void fixed_function_decl_test(IDirect3DDevice9 *device)
hr = IDirect3DVertexBuffer9_Unlock(vb2);
ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
for(i = 0; i < 2; i++) {
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_BeginScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr)) {
hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
if(i == 0) {
hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
} else {
hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
}
ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
hr = IDirect3DDevice9_BeginScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr)) {
hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
hr = IDirect3DDevice9_EndScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
}
hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
color = getPixelColor(device, 480, 360);
ok(color == 0x00ff0000,
"D3DDECLTYPE_USHORT4N returned color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 160, 120);
ok(color == 0x00ffffff,
"Unused quad returned color %08x, expected 0x00ffffff\n", color);
color = getPixelColor(device, 160, 360);
ok(color == 0x000000ff,
"D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
color = getPixelColor(device, 480, 120);
ok(color == 0x000000ff,
"D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x000000ff\n", color);
hr = IDirect3DDevice9_EndScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
}
IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
if(i == 0) {
color = getPixelColor(device, 480, 360);
ok(color == 0x00ff0000,
"D3DDECLTYPE_USHORT4N returned color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 160, 120);
ok(color == 0x00ffffff,
"Unused quad returned color %08x, expected 0x00ffffff\n", color);
color = getPixelColor(device, 160, 360);
ok(color == 0x000000ff,
"D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
color = getPixelColor(device, 480, 120);
ok(color == 0x000000ff,
"D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x000000ff\n", color);
} else {
color = getPixelColor(device, 480, 360);
ok(color == 0x000000ff,
"D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
color = getPixelColor(device, 160, 120);
ok(color == 0x00ffffff,
"Unused quad returned color %08x, expected 0x00ffffff\n", color);
color = getPixelColor(device, 160, 360);
ok(color == 0x00ff0000,
"D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 480, 120);
ok(color == 0x00ff0000,
"D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
}
}
hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
......
......@@ -2881,6 +2881,7 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDi
int i;
UINT *offset = stateblock->streamOffset;
IWineD3DVertexBufferImpl *vb;
DWORD_PTR shift_index;
/* Default to no instancing */
stateblock->wineD3DDevice->instancedDraw = FALSE;
......@@ -2915,13 +2916,15 @@ static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDi
TRACE("Attrib %d has original stride %d, new stride %d\n", i, strided->u.input[i].dwStride, vb->conv_stride);
TRACE("Original offset %p, additional offset 0x%08x\n",strided->u.input[i].lpData, vb->conv_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_SIZE(strided->u.input[i].dwType),
WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
vb->conv_stride,
strided->u.input[i].lpData + vb->conv_shift[(DWORD_PTR) strided->u.input[i].lpData] +
strided->u.input[i].lpData + vb->conv_shift[shift_index] +
stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride +
offset[strided->u.input[i].streamNo]));
......
......@@ -197,6 +197,8 @@ static inline BOOL process_converted_attribute(IWineD3DVertexBufferImpl *This,
DWORD attrib_size;
BOOL ret = FALSE;
int i;
DWORD offset = This->resource.wineD3DDevice->stateBlock->streamOffset[attrib->streamNo];
DWORD_PTR data;
/* Check for some valid situations which cause us pain. One is if the buffer is used for
* constant attributes(stride = 0), the other one is if the buffer is used on two streams
......@@ -223,13 +225,14 @@ static inline BOOL process_converted_attribute(IWineD3DVertexBufferImpl *This,
}
}
data = (((DWORD_PTR) attrib->lpData) + offset) % This->stride;
attrib_size = WINED3D_ATR_SIZE(type) * WINED3D_ATR_TYPESIZE(type);
for(i = 0; i < attrib_size; i++) {
if(This->conv_map[(DWORD_PTR) attrib->lpData + i] != conv_type) {
TRACE("Byte %ld in vertex changed\n", i + (DWORD_PTR) attrib->lpData);
TRACE("It was type %d, is %d now\n", This->conv_map[(DWORD_PTR) attrib->lpData + i], conv_type);
if(This->conv_map[(DWORD_PTR) data + i] != conv_type) {
TRACE("Byte %ld in vertex changed\n", i + (DWORD_PTR) data);
TRACE("It was type %d, is %d now\n", This->conv_map[(DWORD_PTR) data + i], conv_type);
ret = TRUE;
This->conv_map[(DWORD_PTR) attrib->lpData + i] = conv_type;
This->conv_map[(DWORD_PTR) data + i] = conv_type;
}
}
return ret;
......@@ -239,8 +242,7 @@ static inline BOOL check_attribute(IWineD3DVertexBufferImpl *This, const WineDir
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, attrib_size;
int i;
DWORD type;
/* Ignore attributes that do not have our vbo. After that check we can be sure that the attribute is
* there, on nonexistant attribs the vbo is 0.
......@@ -271,16 +273,7 @@ static inline BOOL check_attribute(IWineD3DVertexBufferImpl *This, const WineDir
} else if(is_ffp_position && type == WINED3DDECLTYPE_FLOAT4) {
ret = process_converted_attribute(This, CONV_POSITIONT, attrib, stride_this_run, WINED3DDECLTYPE_FLOAT4);
} else if(This->conv_map) {
attrib_size = WINED3D_ATR_SIZE(type) * WINED3D_ATR_TYPESIZE(type);
for(i = 0; i < attrib_size; i++) {
if(This->conv_map[(DWORD_PTR) attrib->lpData + i] != CONV_NONE) {
TRACE("Byte %ld in vertex changed\n", i + (DWORD_PTR) attrib->lpData);
TRACE("It was type %d, is CONV_NONE now\n", This->conv_map[(DWORD_PTR) attrib->lpData + i]);
ret = TRUE;
This->conv_map[(DWORD_PTR) attrib->lpData + i] = CONV_NONE;
}
}
ret = process_converted_attribute(This, CONV_NONE, attrib, stride_this_run, type);
}
return ret;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment