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:
parent
4330d20d0d
commit
9f26fed28d
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue