wined3d: Remove FLOAT16 vertex attribute conversion support.

All mayor drivers support GL_ARB_half_float_vertex now and the half
float conversion doesn't work well in practise. The only game that was
ever playable with it was Eve online.
This commit is contained in:
Stefan Dösinger 2011-02-06 23:47:49 +01:00 committed by Alexandre Julliard
parent 46d879eef6
commit 5627ee49ea
3 changed files with 65 additions and 288 deletions

View File

@ -287,11 +287,9 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This,
static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
UINT attrib_idx, const BOOL check_d3dcolor, const BOOL is_ffp_position, const BOOL is_ffp_color,
DWORD *stride_this_run, BOOL *float16_used)
DWORD *stride_this_run)
{
const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
IWineD3DDeviceImpl *device = This->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
enum wined3d_format_id format;
BOOL ret = FALSE;
@ -304,16 +302,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
format = attrib->format->id;
/* Look for newly appeared conversion */
if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX]
&& (format == WINED3DFMT_R16G16_FLOAT || format == WINED3DFMT_R16G16B16A16_FLOAT))
{
ret = buffer_process_converted_attribute(This, CONV_FLOAT16_2, attrib, stride_this_run);
if (is_ffp_position) FIXME("Test FLOAT16 fixed function processing positions\n");
else if (is_ffp_color) FIXME("test FLOAT16 fixed function processing colors\n");
*float16_used = TRUE;
}
else if (check_d3dcolor && format == WINED3DFMT_B8G8R8A8_UNORM)
if (check_d3dcolor && format == WINED3DFMT_B8G8R8A8_UNORM)
{
ret = buffer_process_converted_attribute(This, CONV_D3DCOLOR, attrib, stride_this_run);
@ -331,71 +320,6 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
return ret;
}
static UINT *find_conversion_shift(struct wined3d_buffer *This,
const struct wined3d_stream_info *strided, UINT stride)
{
UINT *ret, i, j, shift, orig_type_size;
if (!stride)
{
TRACE("No shift\n");
return NULL;
}
This->conversion_stride = stride;
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DWORD) * stride);
for (i = 0; i < MAX_ATTRIBS; ++i)
{
enum wined3d_format_id format;
if (!(strided->use_map & (1 << i)) || strided->elements[i].buffer_object != This->buffer_object) continue;
format = strided->elements[i].format->id;
if (format == WINED3DFMT_R16G16_FLOAT)
{
shift = 4;
}
else if (format == WINED3DFMT_R16G16B16A16_FLOAT)
{
shift = 8;
/* Pre-shift the last 4 bytes in the FLOAT16_4 by 4 bytes - this makes FLOAT16_2 and FLOAT16_4 conversions
* compatible
*/
for (j = 4; j < 8; ++j)
{
ret[(DWORD_PTR)strided->elements[i].data + j] += 4;
}
}
else
{
shift = 0;
}
This->conversion_stride += shift;
if (shift)
{
orig_type_size = strided->elements[i].format->component_count
* strided->elements[i].format->component_size;
for (j = (DWORD_PTR)strided->elements[i].data + orig_type_size; j < stride; ++j)
{
ret[j] += shift;
}
}
}
if (TRACE_ON(d3d))
{
TRACE("Dumping conversion shift:\n");
for (i = 0; i < stride; ++i)
{
TRACE("[%d]", ret[i]);
}
TRACE("\n");
}
return ret;
}
static BOOL buffer_find_decl(struct wined3d_buffer *This)
{
IWineD3DDeviceImpl *device = This->resource.device;
@ -403,9 +327,8 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
const struct wined3d_stream_info *si = &device->strided_streams;
const struct wined3d_state *state = &device->stateBlock->state;
UINT stride_this_run = 0;
BOOL float16_used = FALSE;
BOOL ret = FALSE;
unsigned int i;
BOOL support_d3dcolor = gl_info->supported[ARB_VERTEX_ARRAY_BGRA];
/* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
* Once we have our declaration there is no need to look it up again. Index buffers also never need
@ -416,6 +339,20 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
if(This->resource.usage & WINED3DUSAGE_STATICDECL) return FALSE;
}
if (use_vs(state))
{
TRACE("Vertex shaders used, no VBO conversion is needed\n");
if(This->conversion_map)
{
HeapFree(GetProcessHeap(), 0, This->conversion_map);
This->conversion_map = NULL;
This->stride = 0;
return TRUE;
}
return FALSE;
}
TRACE("Finding vertex buffer conversion information\n");
/* Certain declaration types need some fixups before we can pass them to
* opengl. This means D3DCOLOR attributes with fixed function vertex
@ -461,79 +398,31 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
* conversion types depend on the semantic as well, for example a FLOAT4
* texcoord needs no conversion while a FLOAT4 positiont needs one
*/
if (use_vs(state))
{
TRACE("vshader\n");
/* If the current vertex declaration is marked for no half float conversion don't bother to
* analyse the strided streams in depth, just set them up for no conversion. Return decl changed
* if we used conversion before
*/
if (!state->vertex_declaration->half_float_conv_needed)
{
if (This->conversion_map)
{
TRACE("Now using shaders without conversion, but conversion used before\n");
HeapFree(GetProcessHeap(), 0, This->conversion_map);
HeapFree(GetProcessHeap(), 0, This->conversion_shift);
This->conversion_map = NULL;
This->stride = 0;
This->conversion_shift = NULL;
This->conversion_stride = 0;
return TRUE;
}
else
{
return FALSE;
}
}
for (i = 0; i < MAX_ATTRIBS; ++i)
{
ret = buffer_check_attribute(This, si, i, FALSE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
}
/* Recalculate the conversion shift map if the declaration has changed,
* and we're using float16 conversion or used it on the last run
*/
if (ret && (float16_used || This->conversion_map))
{
HeapFree(GetProcessHeap(), 0, This->conversion_shift);
This->conversion_shift = find_conversion_shift(This, si, This->stride);
}
}
else
{
/* Fixed function is a bit trickier. We have to take care for D3DCOLOR types, FLOAT4 positions and of course
* FLOAT16s if not supported. Also, we can't iterate over the array, so use macros to generate code for all
* the attributes that our current fixed function pipeline implementation cares for.
*/
BOOL support_d3dcolor = gl_info->supported[ARB_VERTEX_ARRAY_BGRA];
ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
TRUE, TRUE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
!support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR,
!support_d3dcolor, FALSE, TRUE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7,
TRUE, FALSE, FALSE, &stride_this_run, &float16_used) || ret;
if (float16_used) FIXME("Float16 conversion used with fixed function vertex processing\n");
}
ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
TRUE, TRUE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
!support_d3dcolor, FALSE, TRUE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_SPECULAR,
!support_d3dcolor, FALSE, TRUE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD0,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD1,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD2,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD3,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD4,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD5,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD6,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
ret = buffer_check_attribute(This, si, WINED3D_FFP_TEXCOORD7,
TRUE, FALSE, FALSE, &stride_this_run) || ret;
if (!stride_this_run && This->conversion_map)
{
@ -549,36 +438,6 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
return ret;
}
/* Context activation is done by the caller. */
static void buffer_check_buffer_object_size(struct wined3d_buffer *This, const struct wined3d_gl_info *gl_info)
{
UINT size = This->conversion_stride ?
This->conversion_stride * (This->resource.size / This->stride) : This->resource.size;
if (This->buffer_object_size != size)
{
TRACE("Old size %u, creating new size %u\n", This->buffer_object_size, size);
if(This->buffer_type_hint == GL_ELEMENT_ARRAY_BUFFER_ARB)
{
IWineD3DDeviceImpl_MarkStateDirty(This->resource.device, STATE_INDEXBUFFER);
}
/* Rescue the data before resizing the buffer object if we do not have our backup copy */
if(!(This->flags & WINED3D_BUFFER_DOUBLEBUFFER))
{
buffer_get_sysmem(This, gl_info);
}
ENTER_GL();
GL_EXTCALL(glBindBufferARB(This->buffer_type_hint, This->buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferDataARB(This->buffer_type_hint, size, NULL, This->buffer_object_usage));
This->buffer_object_size = size;
checkGLcall("glBufferDataARB");
LEAVE_GL();
}
}
static inline void fixup_d3dcolor(DWORD *dst_color)
{
DWORD src_color = *dst_color;
@ -694,8 +553,6 @@ static void buffer_unload(struct wined3d_resource *resource)
context_release(context);
HeapFree(GetProcessHeap(), 0, buffer->conversion_shift);
buffer->conversion_shift = NULL;
HeapFree(GetProcessHeap(), 0, buffer->conversion_map);
buffer->conversion_map = NULL;
buffer->stride = 0;
@ -981,7 +838,6 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
IWineD3DDeviceImpl_MarkStateDirty(device, STATE_STREAMSRC);
goto end;
}
buffer_check_buffer_object_size(buffer, gl_info);
/* The declaration changed, reload the whole buffer */
WARN("Reloading buffer because of decl change\n");
@ -1057,20 +913,16 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
/* Now for each vertex in the buffer that needs conversion */
vertices = buffer->resource.size / buffer->stride;
if (buffer->conversion_shift)
{
TRACE("Shifted conversion\n");
data = HeapAlloc(GetProcessHeap(), 0, vertices * buffer->conversion_stride);
data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size);
start = 0;
len = buffer->resource.size;
while(buffer->modified_areas)
{
buffer->modified_areas--;
start = buffer->maps[buffer->modified_areas].offset;
len = buffer->maps[buffer->modified_areas].size;
end = start + len;
if (buffer->maps[0].offset || buffer->maps[0].size != buffer->resource.size)
{
FIXME("Implement partial buffer load with shifted conversion\n");
}
memcpy(data + start, buffer->resource.allocatedMemory + start, end - start);
for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertices); ++i)
{
for (j = 0; j < buffer->stride; ++j)
@ -1078,24 +930,20 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
switch (buffer->conversion_map[j])
{
case CONV_NONE:
data[buffer->conversion_stride * i + j + buffer->conversion_shift[j]]
= buffer->resource.allocatedMemory[buffer->stride * i + j];
/* Done already */
j += 3;
break;
case CONV_D3DCOLOR:
fixup_d3dcolor((DWORD *) (data + i * buffer->stride + j));
j += 3;
break;
case CONV_FLOAT16_2:
{
float *out = (float *)(&data[buffer->conversion_stride * i + j + buffer->conversion_shift[j]]);
const WORD *in = (WORD *)(&buffer->resource.allocatedMemory[i * buffer->stride + j]);
out[1] = float_16_to_32(in + 1);
out[0] = float_16_to_32(in + 0);
j += 3; /* Skip 3 additional bytes,as a FLOAT16_2 has 4 bytes */
case CONV_POSITIONT:
fixup_transformed_pos((float *) (data + i * buffer->stride + j));
j += 15;
break;
}
default:
FIXME("Unimplemented conversion %#x in shifted conversion.\n", buffer->conversion_map[j]);
break;
FIXME("Unimplemented conversion %d in shifted conversion\n", buffer->conversion_map[j]);
}
}
}
@ -1103,58 +951,10 @@ void CDECL wined3d_buffer_preload(struct wined3d_buffer *buffer)
ENTER_GL();
GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(buffer->buffer_type_hint, 0, vertices * buffer->conversion_stride, data));
GL_EXTCALL(glBufferSubDataARB(buffer->buffer_type_hint, start, len, data + start));
checkGLcall("glBufferSubDataARB");
LEAVE_GL();
}
else
{
data = HeapAlloc(GetProcessHeap(), 0, buffer->resource.size);
while (buffer->modified_areas)
{
buffer->modified_areas--;
start = buffer->maps[buffer->modified_areas].offset;
len = buffer->maps[buffer->modified_areas].size;
end = start + len;
memcpy(data + start, buffer->resource.allocatedMemory + start, end - start);
for (i = start / buffer->stride; i < min((end / buffer->stride) + 1, vertices); ++i)
{
for (j = 0; j < buffer->stride; ++j)
{
switch (buffer->conversion_map[j])
{
case CONV_NONE:
/* Done already */
j += 3;
break;
case CONV_D3DCOLOR:
fixup_d3dcolor((DWORD *)(data + i * buffer->stride + j));
j += 3;
break;
case CONV_POSITIONT:
fixup_transformed_pos((float *)(data + i * buffer->stride + j));
j += 15;
break;
case CONV_FLOAT16_2:
ERR("Did not expect FLOAT16 conversion in unshifted conversion.\n");
default:
FIXME("Unimplemented conversion %u in unshifted conversion.\n", buffer->conversion_map[j]);
}
}
}
ENTER_GL();
GL_EXTCALL(glBindBufferARB(buffer->buffer_type_hint, buffer->buffer_object));
checkGLcall("glBindBufferARB");
GL_EXTCALL(glBufferSubDataARB(buffer->buffer_type_hint, start, len, data + start));
checkGLcall("glBufferSubDataARB");
LEAVE_GL();
}
}
HeapFree(GetProcessHeap(), 0, data);

View File

@ -4132,7 +4132,6 @@ static void loadNumberedArrays(struct wined3d_stateblock *stateblock,
GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
int i;
struct wined3d_buffer *vb;
DWORD_PTR shift_index;
/* Default to no instancing */
stateblock->device->instancedDraw = FALSE;
@ -4172,31 +4171,12 @@ static void loadNumberedArrays(struct wined3d_stateblock *stateblock,
* curVBO will be 0. If there is a vertex buffer but no vbo we
* won't be load converted attributes anyway. */
vb = stream->buffer;
if (curVBO && vb->conversion_shift)
{
TRACE("Loading attribute from shifted buffer\n");
TRACE("Attrib %d has original stride %d, new stride %d\n",
i, stream_info->elements[i].stride, vb->conversion_stride);
TRACE("Original offset %p, additional offset 0x%08x\n",
stream_info->elements[i].data, vb->conversion_shift[(DWORD_PTR)stream_info->elements[i].data]);
TRACE("Opengl type %#x\n", stream_info->elements[i].format->gl_vtx_type);
shift_index = ((DWORD_PTR)stream_info->elements[i].data + stream->offset);
shift_index = shift_index % stream_info->elements[i].stride;
GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
stream_info->elements[i].format->gl_vtx_type,
stream_info->elements[i].format->gl_normalized,
vb->conversion_stride, stream_info->elements[i].data + vb->conversion_shift[shift_index]
+ stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
+ stream->offset));
} else {
GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
stream_info->elements[i].format->gl_vtx_type,
stream_info->elements[i].format->gl_normalized,
stream_info->elements[i].stride, stream_info->elements[i].data
+ stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
+ stream->offset));
}
GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
stream_info->elements[i].format->gl_vtx_type,
stream_info->elements[i].format->gl_normalized,
stream_info->elements[i].stride, stream_info->elements[i].data
+ stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
+ stream->offset));
if (!(context->numbered_array_mask & (1 << i)))
{

View File

@ -2451,7 +2451,6 @@ enum wined3d_buffer_conversion_type
CONV_NONE,
CONV_D3DCOLOR,
CONV_POSITIONT,
CONV_FLOAT16_2, /* Also handles FLOAT16_4 */
};
struct wined3d_map_range
@ -2493,8 +2492,6 @@ struct wined3d_buffer
UINT stride; /* 0 if no conversion */
UINT conversion_stride; /* 0 if no shifted conversion */
enum wined3d_buffer_conversion_type *conversion_map; /* NULL if no conversion */
/* Extra load offsets, for FLOAT16 conversion */
UINT *conversion_shift; /* NULL if no shifted conversion */
};
static inline struct wined3d_buffer *buffer_from_resource(struct wined3d_resource *resource)