From 9f26fed28dc0c7f356dc9822e82dbae05245cafb Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Fri, 27 Mar 2009 10:25:56 +0100 Subject: [PATCH] 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. --- dlls/wined3d/device.c | 60 ++++++++++++++++---------------- dlls/wined3d/vertexdeclaration.c | 53 ++++++++++++++++------------ dlls/wined3d/vertexshader.c | 7 ++-- dlls/wined3d/wined3d_private.h | 17 +++++++-- 4 files changed, 79 insertions(+), 58 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a115192c672..dd493f5a521 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -185,31 +185,31 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, if (declaration->position_transformed) use_vshader = FALSE; /* 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; 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); + TRACE("%p Element %p (%u of %u)\n", declaration->elements, + 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) { - 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; - data = (BYTE *)This->stateBlock->streamSource[element->Stream]; + data = (BYTE *)This->stateBlock->streamSource[element->input_slot]; } 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); + 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->input_slot], 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 @@ -220,7 +220,7 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, { 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; + data = ((struct wined3d_buffer *)This->stateBlock->streamSource[element->input_slot])->resource.allocatedMemory; if ((UINT_PTR)data < -This->stateBlock->loadBaseVertexIndex * stride) { FIXME("System memory vertex data load offset is negative!\n"); @@ -231,8 +231,8 @@ void device_stream_info_from_declaration(IWineD3DDeviceImpl *This, { if (buffer_object) *fixup = TRUE; else if (*fixup && !use_vshader - && (element->Usage == WINED3DDECLUSAGE_COLOR - || element->Usage == WINED3DDECLUSAGE_POSITIONT)) + && (element->usage == WINED3DDECLUSAGE_COLOR + || element->usage == WINED3DDECLUSAGE_POSITIONT)) { static BOOL warned = FALSE; if (!warned) @@ -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) { - 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 { - if (!declaration->ffp_valid[i]) + if (!element->ffp_valid) { 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; } 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) { 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, - debug_d3ddeclusage(element->Usage), element->UsageIndex, - element->Stream, element->Offset, stride, debug_d3ddecltype(element->Type), buffer_object); + debug_d3ddeclusage(element->usage), element->usage_idx, + element->input_slot, 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].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].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].type_size = WINED3D_ATR_TYPESIZE(element->type); + stream_info->elements[idx].stream_idx = element->input_slot; 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; } diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c index ae3bbc1e6f5..cb2915daeb9 100644 --- a/dlls/wined3d/vertexdeclaration.c +++ b/dlls/wined3d/vertexdeclaration.c @@ -73,8 +73,7 @@ static ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclarat IWineD3DDeviceImpl_MarkStateDirty(This->wineD3DDevice, STATE_VDECL); } - HeapFree(GetProcessHeap(), 0, This->pDeclarationWine); - HeapFree(GetProcessHeap(), 0, This->ffp_valid); + HeapFree(GetProcessHeap(), 0, This->elements); HeapFree(GetProcessHeap(), 0, This); } return ref; @@ -207,14 +206,15 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, } } - This->declarationWNumElements = element_count; - This->pDeclarationWine = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DVERTEXELEMENT) * element_count); - This->ffp_valid = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->ffp_valid) * element_count); - if (!This->pDeclarationWine || !This->ffp_valid) { + /* Skip the END element. */ + --element_count; + + This->element_count = element_count; + This->elements = HeapAlloc(GetProcessHeap(), 0, sizeof(*This->elements) * element_count); + if (!This->elements) + { ERR("Memory allocation failed\n"); 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 @@ -223,36 +223,45 @@ HRESULT vertexdeclaration_init(IWineD3DVertexDeclarationImpl *This, This->num_streams = 0; This->position_transformed = FALSE; 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) { - This->position_transformed = TRUE; - } + e->type = elements[i].Type; + 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 * 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"); - /* 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; } - if(This->pDeclarationWine[i].Offset & 0x3) { - WARN("Declaration element %d is not 4 byte aligned(%d), returning E_FAIL\n", i, This->pDeclarationWine[i].Offset); + if (e->offset & 0x3) + { + WARN("Declaration element %u is not 4 byte aligned(%u), returning E_FAIL\n", i, e->offset); return E_FAIL; } - if(!isPreLoaded[This->pDeclarationWine[i].Stream]) { - This->streams[This->num_streams] = This->pDeclarationWine[i].Stream; + if (!isPreLoaded[e->input_slot]) + { + This->streams[This->num_streams] = e->input_slot; This->num_streams++; - isPreLoaded[This->pDeclarationWine[i].Stream] = 1; + isPreLoaded[e->input_slot] = 1; } - if (This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_2 - || This->pDeclarationWine[i].Type == WINED3DDECLTYPE_FLOAT16_4) + if (e->type == WINED3DDECLTYPE_FLOAT16_2 || e->type == WINED3DDECLTYPE_FLOAT16_4) { if (!GL_SUPPORT(NV_HALF_FLOAT)) This->half_float_conv_needed = TRUE; } diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index 90d6cd86b64..402d5bdfcb8 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -369,9 +369,10 @@ static void WINAPI IWineD3DVertexShaderImpl_FakeSemantics(IWineD3DVertexShader * IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*)vertex_declaration; unsigned int i; - for (i = 0; i < vdecl->declarationWNumElements - 1; ++i) { - const WINED3DVERTEXELEMENT *element = vdecl->pDeclarationWine + i; - vshader_set_input(This, element->Reg, element->Usage, element->UsageIndex); + for (i = 0; i < vdecl->element_count; ++i) + { + const struct wined3d_vertex_declaration_element *e = &vdecl->elements[i]; + vshader_set_input(This, e->output_slot, e->usage, e->usage_idx); } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fd37ef56830..0f8f7619f27 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1745,6 +1745,18 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This); */ #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 { /* IUnknown Information */ const IWineD3DVertexDeclarationVtbl *lpVtbl; @@ -1753,9 +1765,8 @@ typedef struct IWineD3DVertexDeclarationImpl { IUnknown *parent; IWineD3DDeviceImpl *wineD3DDevice; - WINED3DVERTEXELEMENT *pDeclarationWine; - BOOL *ffp_valid; - UINT declarationWNumElements; + struct wined3d_vertex_declaration_element *elements; + UINT element_count; DWORD streams[MAX_STREAMS]; UINT num_streams;