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.
This commit is contained in:
Henri Verbeet 2009-03-27 10:25:56 +01:00 committed by Alexandre Julliard
parent 4330d20d0d
commit 9f26fed28d
4 changed files with 79 additions and 58 deletions

View File

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

View File

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

View File

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

View File

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