wined3d: Handle pre-transformed vertices in the GLSL vertex pipe.

This also avoids a fallback to drawStridedSlow().
This commit is contained in:
Henri Verbeet 2013-06-14 09:07:12 +02:00 committed by Alexandre Julliard
parent 8a7ddfbb53
commit ffc9f535eb
7 changed files with 34 additions and 18 deletions

View File

@ -266,7 +266,7 @@ 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,
UINT attrib_idx, const BOOL check_d3dcolor, const BOOL check_position, const BOOL is_ffp_color,
DWORD *stride_this_run)
{
const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
@ -288,7 +288,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
if (!is_ffp_color) FIXME("Test for non-color fixed function WINED3DFMT_B8G8R8A8_UNORM format\n");
}
else if (is_ffp_position && si->position_transformed)
else if (check_position && si->position_transformed)
{
if (format != WINED3DFMT_R32G32B32A32_FLOAT)
{
@ -309,12 +309,13 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
static BOOL buffer_find_decl(struct wined3d_buffer *This)
{
struct wined3d_device *device = This->resource.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_adapter *adapter = device->adapter;
const struct wined3d_stream_info *si = &device->stream_info;
const struct wined3d_state *state = &device->stateBlock->state;
BOOL support_d3dcolor = adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA];
BOOL support_xyzrhw = adapter->d3d_info.xyzrhw;
UINT stride_this_run = 0;
BOOL ret = FALSE;
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
@ -386,7 +387,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
*/
ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
TRUE, TRUE, FALSE, &stride_this_run) || ret;
TRUE, !support_xyzrhw, 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,

View File

@ -332,15 +332,12 @@ void device_update_stream_info(struct wined3d_device *device, const struct wined
slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
& ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
if ((stream_info->position_transformed || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
{
if (((stream_info->position_transformed && !device->adapter->d3d_info.xyzrhw)
|| (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
device->useDrawStridedSlow = TRUE;
}
else
{
device->useDrawStridedSlow = FALSE;
}
}
if (prev_all_vbo != stream_info->all_vbo)
device_invalidate_state(device, STATE_INDEXBUFFER);

View File

@ -2635,6 +2635,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
struct wined3d_driver_info *driver_info = &adapter->driver_info;
const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
struct wined3d_gl_info *gl_info = &adapter->gl_info;
struct wined3d_vertex_caps vertex_caps;
enum wined3d_pci_vendor card_vendor;
struct fragment_caps fragment_caps;
struct shader_caps shader_caps;
@ -2865,6 +2866,9 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count;
adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count;
adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps);
adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw;
adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;

View File

@ -5011,11 +5011,20 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_
shader_addline(buffer, "float m;\n");
shader_addline(buffer, "vec3 r;\n");
if (settings->transformed)
{
shader_addline(buffer, "vec4 ec_pos = vec4(gl_Vertex.xyz, 1.0);\n");
shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
shader_addline(buffer, "if (gl_Vertex.w != 0.0) gl_Position /= gl_Vertex.w;\n");
}
else
{
shader_addline(buffer, "vec4 ec_pos = gl_ModelViewMatrix * gl_Vertex;\n");
shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
if (settings->clipping)
shader_addline(buffer, "gl_ClipVertex = ec_pos;\n");
shader_addline(buffer, "ec_pos /= ec_pos.w;\n");
}
if (!settings->normal)
shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
@ -6737,6 +6746,7 @@ static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BO
static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
{
caps->xyzrhw = TRUE;
caps->max_active_lights = gl_info->limits.lights;
caps->max_vertex_blend_matrices = 0;
caps->max_vertex_blend_matrix_index = 0;

View File

@ -5641,6 +5641,7 @@ static void ffp_free(struct wined3d_device *device) {}
static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
{
caps->xyzrhw = FALSE;
caps->max_active_lights = gl_info->limits.lights;
caps->max_vertex_blend_matrices = gl_info->limits.blends;
caps->max_vertex_blend_matrix_index = 0;

View File

@ -3552,8 +3552,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct
{
memset(settings, 0, sizeof(*settings));
settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
&& state->render_states[WINED3D_RS_CLIPPLANEENABLE];
settings->transformed = 1;
settings->point_size = state->gl_primitive_type == GL_POINTS;
if (!state->render_states[WINED3D_RS_FOGENABLE])
settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
@ -3573,6 +3572,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct
return;
}
settings->transformed = 0;
settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
&& state->render_states[WINED3D_RS_CLIPPLANEENABLE];
settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));

View File

@ -1193,6 +1193,7 @@ struct fragment_pipeline
struct wined3d_vertex_caps
{
BOOL xyzrhw;
DWORD max_active_lights;
DWORD max_vertex_blend_matrices;
DWORD max_vertex_blend_matrix_index;
@ -1606,6 +1607,7 @@ struct wined3d_d3d_limits
struct wined3d_d3d_info
{
struct wined3d_d3d_limits limits;
BOOL xyzrhw;
BOOL vs_clipping;
DWORD valid_rt_mask;
};
@ -1723,6 +1725,7 @@ struct wined3d_ffp_vs_settings
DWORD ambient_source : 2;
DWORD specular_source : 2;
DWORD transformed : 1;
DWORD clipping : 1;
DWORD normal : 1;
DWORD normalize : 1;
@ -1731,7 +1734,7 @@ struct wined3d_ffp_vs_settings
DWORD point_size : 1;
DWORD fog_mode : 2;
DWORD texcoords : 8; /* MAX_TEXTURES */
DWORD padding : 16;
DWORD padding : 15;
BYTE texgen[MAX_TEXTURES];
};