Commit 9f26fed2 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Separate the internal representation of vertex declaration elements…

wined3d: Separate the internal representation of vertex declaration elements from the struct used to create it. Internally we want to store some extra data, like ffp_valid. One of the later patches also stores the format desc in the declaration elements, instead of the current WINED3DDECLTYPE.
parent 4330d20d
...@@ -185,31 +185,31 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, ...@@ -185,31 +185,31 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
if (declaration->position_transformed) use_vshader = FALSE; if (declaration->position_transformed) use_vshader = FALSE;
/* Translate the declaration into strided data. */ /* Translate the declaration into strided data. */
for (i = 0; i < declaration->declarationWNumElements - 1; ++i) for (i = 0; i < declaration->element_count; ++i)
{ {
const WINED3DVERTEXELEMENT *element = declaration->pDeclarationWine + i; const struct wined3d_vertex_declaration_element *element = &declaration->elements[i];
GLuint buffer_object = 0; GLuint buffer_object = 0;
const BYTE *data = NULL; const BYTE *data = NULL;
BOOL stride_used; BOOL stride_used;
unsigned int idx; unsigned int idx;
DWORD stride; DWORD stride;
TRACE("%p Element %p (%u of %u)\n", declaration->pDeclarationWine, TRACE("%p Element %p (%u of %u)\n", declaration->elements,
element, i + 1, declaration->declarationWNumElements - 1); element, i + 1, declaration->element_count);
if (!This->stateBlock->streamSource[element->Stream]) continue; if (!This->stateBlock->streamSource[element->input_slot]) continue;
stride = This->stateBlock->streamStride[element->Stream]; stride = This->stateBlock->streamStride[element->input_slot];
if (This->stateBlock->streamIsUP) if (This->stateBlock->streamIsUP)
{ {
TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); TRACE("Stream %u is UP, %p\n", element->input_slot, This->stateBlock->streamSource[element->input_slot]);
buffer_object = 0; buffer_object = 0;
data = (BYTE *)This->stateBlock->streamSource[element->Stream]; data = (BYTE *)This->stateBlock->streamSource[element->input_slot];
} }
else else
{ {
TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]); TRACE("Stream %u isn't UP, %p\n", element->input_slot, This->stateBlock->streamSource[element->input_slot]);
data = buffer_get_memory(This->stateBlock->streamSource[element->Stream], 0, &buffer_object); data = buffer_get_memory(This->stateBlock->streamSource[element->input_slot], 0, &buffer_object);
/* Can't use vbo's if the base vertex index is negative. OpenGL doesn't accept negative offsets /* 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 * (or rather offsets bigger than the vbo, because the pointer is unsigned), so use system memory
...@@ -220,7 +220,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, ...@@ -220,7 +220,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
{ {
WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex); WARN("loadBaseVertexIndex is < 0 (%d), not using vbos\n", This->stateBlock->loadBaseVertexIndex);
buffer_object = 0; buffer_object = 0;
data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory; data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot])->resource.allocatedMemory;
if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride)
{ {
FIXME("System memory vertex data load offset is negative!\n"); FIXME("System memory vertex data load offset is negative!\n");
...@@ -231,8 +231,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, ...@@ -231,8 +231,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
{ {
if (buffer_object) *fixup = TRUE; if (buffer_object) *fixup = TRUE;
else if (*fixup && !use_vshader else if (*fixup && !use_vshader
&& (element->Usage == WINED3DDECLUSAGE_COLOR && (element->usage == WINED3DDECLUSAGE_COLOR
|| element->Usage == WINED3DDECLUSAGE_POSITIONT)) || element->usage == WINED3DDECLUSAGE_POSITIONT))
{ {
static BOOL warned = FALSE; static BOOL warned = FALSE;
if (!warned) if (!warned)
...@@ -244,48 +244,48 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, ...@@ -244,48 +244,48 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This,
} }
} }
} }
data += element->Offset; data += element->offset;
TRACE("Offset %d Stream %d UsageIndex %d\n", element->Offset, element->Stream, element->UsageIndex); TRACE("offset %u input_slot %u usage_idx %d\n", element->offset, element->input_slot, element->usage_idx);
if (use_vshader) if (use_vshader)
{ {
stride_used = vshader_get_input(This->stateBlock->vertexShader, element->Usage, element->UsageIndex, &idx); stride_used = vshader_get_input(This->stateBlock->vertexShader, element->usage, element->usage_idx, &idx);
} }
else else
{ {
if (!declaration->ffp_valid[i]) if (!element->ffp_valid)
{ {
WARN("Skipping unsupported fixed function element of type %s and usage %s\n", WARN("Skipping unsupported fixed function element of type %s and usage %s\n",
debug_d3ddecltype(element->Type), debug_d3ddeclusage(element->Usage)); debug_d3ddecltype(element->type), debug_d3ddeclusage(element->usage));
stride_used = FALSE; stride_used = FALSE;
} }
else else
{ {
stride_used = fixed_get_input(element->Usage, element->UsageIndex, &idx); stride_used = fixed_get_input(element->usage, element->usage_idx, &idx);
} }
} }
if (stride_used) if (stride_used)
{ {
TRACE("Load %s array %u [usage %s, usage_idx %u, " TRACE("Load %s array %u [usage %s, usage_idx %u, "
"stream %u, offset %u, stride %u, type %s, buffer_object %u]\n", "input_slot %u, offset %u, stride %u, type %s, buffer_object %u]\n",
use_vshader ? "shader": "fixed function", idx, use_vshader ? "shader": "fixed function", idx,
debug_d3ddeclusage(element->Usage), element->UsageIndex, debug_d3ddeclusage(element->usage), element->usage_idx,
element->Stream, element->Offset, stride, debug_d3ddecltype(element->Type), buffer_object); element->input_slot, element->offset, stride, debug_d3ddecltype(element->type), buffer_object);
stream_info->elements[idx].d3d_type = element->Type; stream_info->elements[idx].d3d_type = element->type;
stream_info->elements[idx].size = WINED3D_ATR_SIZE(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].format = WINED3D_ATR_FORMAT(element->type);
stream_info->elements[idx].type = WINED3D_ATR_GLTYPE(element->Type); stream_info->elements[idx].type = WINED3D_ATR_GLTYPE(element->type);
stream_info->elements[idx].stride = stride; stream_info->elements[idx].stride = stride;
stream_info->elements[idx].normalized = WINED3D_ATR_NORMALIZED(element->Type); stream_info->elements[idx].normalized = WINED3D_ATR_NORMALIZED(element->type);
stream_info->elements[idx].data = data; stream_info->elements[idx].data = data;
stream_info->elements[idx].type_size = WINED3D_ATR_TYPESIZE(element->Type); stream_info->elements[idx].type_size = WINED3D_ATR_TYPESIZE(element->type);
stream_info->elements[idx].stream_idx = element->Stream; stream_info->elements[idx].stream_idx = element->input_slot;
stream_info->elements[idx].buffer_object = buffer_object; stream_info->elements[idx].buffer_object = buffer_object;
if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && element->Type == WINED3DDECLTYPE_D3DCOLOR) if (!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) && element->type == WINED3DDECLTYPE_D3DCOLOR)
{ {
stream_info->swizzle_map |= 1 << idx; stream_info->swizzle_map |= 1 << idx;
} }
......
...@@ -73,8 +73,7 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat ...@@ -73,8 +73,7 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat
IWineD3DDeviceImpl_MarkStateDirty(This->wineD3DDevice, STATE_VDECL); IWineD3DDeviceImpl_MarkStateDirty(This->wineD3DDevice, STATE_VDECL);
} }
HeapFree(GetProcessHeap(), 0, This->pDeclarationWine); HeapFree(GetProcessHeap(), 0, This->elements);
HeapFree(GetProcessHeap(), 0, This->ffp_valid);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }
return ref; return ref;
...@@ -207,14 +206,15 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, ...@@ -207,14 +206,15 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
} }
} }
This->declarationWNumElements = element_count; /* Skip the END element. */
This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count); --element_count;
This->ffp_valid = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->ffp_valid) * element_count);
if (!This->pDeclarationWine || !This->ffp_valid) { This->element_count = element_count;
This->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->elements) * element_count);
if (!This->elements)
{
ERR("Memory allocation failed\n"); ERR("Memory allocation failed\n");
return WINED3DERR_OUTOFVIDEOMEMORY; return WINED3DERR_OUTOFVIDEOMEMORY;
} else {
CopyMemory(This->pDeclarationWine, elements, sizeof(WINED3DVERTEXELEMENT) * element_count);
} }
/* Do some static analysis on the elements to make reading the declaration more comfortable /* Do some static analysis on the elements to make reading the declaration more comfortable
...@@ -223,36 +223,45 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, ...@@ -223,36 +223,45 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This,
This->num_streams = 0; This->num_streams = 0;
This->position_transformed = FALSE; This->position_transformed = FALSE;
for (i = 0; i < element_count; ++i) { for (i = 0; i < element_count; ++i) {
This->ffp_valid[i] = declaration_element_valid_ffp(&This->pDeclarationWine[i]); struct wined3d_vertex_declaration_element *e = &This->elements[i];
if(This->pDeclarationWine[i].Usage == WINED3DDECLUSAGE_POSITIONT) { e->type = elements[i].Type;
This->position_transformed = TRUE; e->ffp_valid = declaration_element_valid_ffp(&elements[i]);
} e->input_slot = elements[i].Stream;
e->offset = elements[i].Offset;
e->output_slot = elements[i].Reg;
e->method = elements[i].Method;
e->usage = elements[i].Usage;
e->usage_idx = elements[i].UsageIndex;
if (e->usage == WINED3DDECLUSAGE_POSITIONT) This->position_transformed = TRUE;
/* Find the Streams used in the declaration. The vertex buffers have to be loaded /* Find the Streams used in the declaration. The vertex buffers have to be loaded
* when drawing, but filter tesselation pseudo streams * when drawing, but filter tesselation pseudo streams
*/ */
if(This->pDeclarationWine[i].Stream >= MAX_STREAMS) continue; if (e->input_slot >= MAX_STREAMS) continue;
if(This->pDeclarationWine[i].Type == WINED3DDECLTYPE_UNUSED) { if (e->type == WINED3DDECLTYPE_UNUSED)
{
WARN("The application tries to use WINED3DDECLTYPE_UNUSED, returning E_FAIL\n"); WARN("The application tries to use WINED3DDECLTYPE_UNUSED, returning E_FAIL\n");
/* The caller will release the vdecl, which will free This->pDeclarationWine */ /* The caller will release the vdecl, which will free This->elements */
return E_FAIL; return E_FAIL;
} }
if(This->pDeclarationWine[i].Offset & 0x3) { if (e->offset & 0x3)
WARN("Declaration element %d is not 4 byte aligned(%d), returning E_FAIL\n", i, This->pDeclarationWine[i].Offset); {
WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL\n", i, e->offset);
return E_FAIL; return E_FAIL;
} }
if(!isPreLoaded[This->pDeclarationWine[i].Stream]) { if (!isPreLoaded[e->input_slot])
This->streams[This->num_streams] = This->pDeclarationWine[i].Stream; {
This->streams[This->num_streams] = e->input_slot;
This->num_streams++; This->num_streams++;
isPreLoaded[This->pDeclarationWine[i].Stream] = 1; isPreLoaded[e->input_slot] = 1;
} }
if (This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_2 if (e->type == WINED3DDECLTYPE_FLOAT16_2 || e->type == WINED3DDECLTYPE_FLOAT16_4)
|| This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_4)
{ {
if (!GL_SUPPORT(NV_HALF_FLOAT)) This->half_float_conv_needed = TRUE; if (!GL_SUPPORT(NV_HALF_FLOAT)) This->half_float_conv_needed = TRUE;
} }
......
...@@ -369,9 +369,10 @@ static void WINAPI IWineD3DVertexShaderImpl_FakeSemantics(IWineD3DVertexShader * ...@@ -369,9 +369,10 @@ static void WINAPI IWineD3DVertexShaderImpl_FakeSemantics(IWineD3DVertexShader *
IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*)vertex_declaration; IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*)vertex_declaration;
unsigned int i; unsigned int i;
for (i = 0; i < vdecl->declarationWNumElements - 1; ++i) { for (i = 0; i < vdecl->element_count; ++i)
const WINED3DVERTEXELEMENT *element = vdecl->pDeclarationWine + i; {
vshader_set_input(This, element->Reg, element->Usage, element->UsageIndex); const struct wined3d_vertex_declaration_element *e = &vdecl->elements[i];
vshader_set_input(This, e->output_slot, e->usage, e->usage_idx);
} }
} }
......
...@@ -1745,6 +1745,18 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This); ...@@ -1745,6 +1745,18 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This);
*/ */
#define MAX_ATTRIBS 16 #define MAX_ATTRIBS 16
struct wined3d_vertex_declaration_element
{
WINED3DDECLTYPE type;
BOOL ffp_valid;
WORD input_slot;
WORD offset;
UINT output_slot;
BYTE method;
BYTE usage;
BYTE usage_idx;
};
typedef struct IWineD3DVertexDeclarationImpl { typedef struct IWineD3DVertexDeclarationImpl {
/* IUnknown Information */ /* IUnknown Information */
const IWineD3DVertexDeclarationVtbl *lpVtbl; const IWineD3DVertexDeclarationVtbl *lpVtbl;
...@@ -1753,9 +1765,8 @@ typedef struct IWineD3DVertexDeclarationImpl { ...@@ -1753,9 +1765,8 @@ typedef struct IWineD3DVertexDeclarationImpl {
IUnknown *parent; IUnknown *parent;
IWineD3DDeviceImpl *wineD3DDevice; IWineD3DDeviceImpl *wineD3DDevice;
WINED3DVERTEXELEMENT *pDeclarationWine; struct wined3d_vertex_declaration_element *elements;
BOOL *ffp_valid; UINT element_count;
UINT declarationWNumElements;
DWORD streams[MAX_STREAMS]; DWORD streams[MAX_STREAMS];
UINT num_streams; UINT num_streams;
......
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