wined3d: Support indexed vertex blending. Superseded

Old version!

This is an old revision. You are most probably looking for the newest revision.
Revisions: 

Revision 1

user image gofman Author
17 Aug. 17

Patchset implements an indexed vertex blending (d3d8 / d3d9 software vertex processing feature) through glsl backend fixed function pipeline, and adds a basic d3d9 test for it. This is a patch from https://bugs.winehq.org/show_bug.cgi?id=39057 (see for a full story) with the following minor changes:
- Fixed some formatting and debug messages;
- Used glBufferSubData instead of glMapBuffer for setting UBO data.

Single files Merged diff Tar archive
You have unsaved changes. Press CTRL + ENTER in a text field to submit your comments.

0001-wined3d-Support-indexed-vertex-blending.patch (23 comments)

From 4f6ca5ad86e15bb670c1452507ba0c3e8d08ff9c Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Thu, 19 Nov 2015 13:20:35 +0300
Subject: [PATCH 1/2] wined3d: Support indexed vertex blending.
Fixes https://bugs.winehq.org/show_bug.cgi?id=39057.
Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
dlls/wined3d/context.c | 2 +
dlls/wined3d/cs.c | 3 +-
dlls/wined3d/device.c | 6 +-
dlls/wined3d/directx.c | 1 +
dlls/wined3d/glsl_shader.c | 447 +++++++++++++++++++++++++++++++++++++--
dlls/wined3d/state.c | 3 +-
dlls/wined3d/utils.c | 3 +
dlls/wined3d/vertexdeclaration.c | 9 +
dlls/wined3d/wined3d_private.h | 8 +-
9 files changed, 461 insertions(+), 21 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index a2c0ba4080..8b97af07ad 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -3916,6 +3916,8 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
{
device->shader_backend->shader_load_constants(device->shader_priv, context, state);
context->constant_update_mask = 0;
+ for (i = 0; i < MAX_VB_UPD_WORDS; ++i)
+ context->blend_mat_update_mask[i] = 0;
}
if (context->update_shader_resource_bindings)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index a76598ff4c..fa81168faf 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -1452,7 +1452,8 @@ static void wined3d_cs_exec_set_transform(struct wined3d_cs *cs, const void *dat
const struct wined3d_cs_set_transform *op = data;
cs->state.transforms[op->state] = op->matrix;
- if (op->state < WINED3D_TS_WORLD_MATRIX(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices))
+ if (op->state < WINED3D_TS_WORLD_MATRIX(max(cs->device->adapter->d3d_info.limits.ffp_vertex_blend_matrices,
+ cs->device->adapter->d3d_info.limits.ffp_max_vertex_blend_matrix_index + 1)))
device_invalidate_state(cs->device, STATE_TRANSFORM(op->state));
}
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 30e7fbed02..71bdbcfc59 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3478,10 +3478,14 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d
HRESULT CDECL wined3d_device_get_device_caps(const struct wined3d_device *device, WINED3DCAPS *caps)
{
+ HRESULT hr;
TRACE("device %p, caps %p.\n", device, caps);
- return wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
+ hr = wined3d_get_device_caps(device->wined3d, device->adapter->ordinal,
device->create_parms.device_type, caps);
+ if (hr == S_OK && ((device->create_parms.flags & WINED3DCREATE_SOFTWARE_VERTEXPROCESSING) == 0))
+ caps->MaxVertexBlendMatrixIndex = min(caps->MaxVertexBlendMatrixIndex, 8);
+ return hr;
user image Michael Müller
21 Aug. 17

I would prefer to return the correct values in wined3d_get_device_caps instead of fixing them afterwards. Just pass the creation flags as additional parameter, in the same way as it is done for the device type.

user image gofman Author
21 Aug. 17

I will change that.

user image gofman Author
21 Aug. 17

wined3d_get_device_caps() is actually an exported function, and adding 'flags' as a parameter to it forces changes in all d3d libraries, from ddraw to d3d11. Besides, wined3d_get_device_caps() is often called there without any device created, so it will probably have to just pass '0' for these flags. Do you think it worth it?

user image Michael Müller
21 Aug. 17

Returning wrong results doesn't seem a good option either. Passing 0 as flag would be fine in my opinion.

user image gofman Author
21 Aug. 17

But how the result can be different from what is returned now if I pass 0? The result from wined3d_get_device_caps() is used by, e. g., IDirect3D9_GetDeviceCaps(), when no device is referenced in the call. wined3d_device_get_device_caps() is called from IDirect3DDevice9_GetDeviceCaps(), which has the device and thus creation flag, and the result may be different from IDirect3D9_GetDeviceCaps() depending on creation flags. So in my understanding these functions both return correct results. These results can just be different when we have a device created with certain flags. Or am I missing something?

user image gofman Author
21 Aug. 17

I realized that the actual value returned MaxVertexBlendMatrixIndex was not tested for IDirect3D9_GetDeviceCaps() before, and also for IDirect3DDevice9_GetDeviceCaps() for the case of mixed vertex processing and SetSoftwareVertexProcessing set to TRUE. I tested that on Window 7 on Intel & Nvidia descrete cards, and got the following:

IDirect3D9_GetDeviceCaps(): D3DDEVTYPE_HAL: 8 for Intel, 0 for NVIDIA D3DDEVTYPE_NULLREF: 255 D3DDEVTYPE_REF: 255 D3DDEVTYPE_SW: n/a (could not test it due to no pluggable software device installed. IDirect3DDevice9_GetDeviceCaps(), D3DDEVTYPE_HAL Harware vertex processing: 8 Software vertex processing: 255 Mixed vertex processing, software vertex processing flag off: 8 Mixed vertex processing, software vertex processing flag on: 255

So I suggest to do the following:
- for wined3d_get_device_caps(), return max index from vertex_caps for D3DDEVTYPE_REF, D3DDEVTYPE_NULLREF, or 8 otherwise;
- for wined3d_device_get_device_caps() set the value of max index to vertex_caps value or 8 after the call to wined3d_get_device_caps() based on device vertex processing creation flags and currently stored software processing flag (for mixed vertex processing mode).

Do you agree?

user image Michael Müller
21 Aug. 17

Seems like ATI/AMD returns either 37 or 57 from what I have found:

http://www.ozone3d.net/gpu/his_radeon_hd_3870/p11.php (HAL device)
https://www.gamedev.net/forums/topic/91446-post-your-graphics-card-caps-here/ (most probably IDirect3D9_GetDeviceCap, as NVIDIA users report zero)

I therefore don't think an application can rely on any particular value and returning 8 should be fine.

}
HRESULT CDECL wined3d_device_get_display_mode(const struct wined3d_device *device, UINT swapchain_idx,
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 919b997e2e..9b420ae6b7 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -4245,6 +4245,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
adapter->d3d_info.ffp_generic_attributes = vertex_caps.ffp_generic_attributes;
adapter->d3d_info.limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices;
adapter->d3d_info.limits.active_light_count = vertex_caps.max_active_lights;
+ adapter->d3d_info.limits.ffp_max_vertex_blend_matrix_index = vertex_caps.max_vertex_blend_matrix_index;
adapter->d3d_info.emulated_flatshading = vertex_caps.emulated_flatshading;
adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 7290fc71a1..aea993f542 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -131,6 +131,11 @@ struct shader_glsl_priv
struct wine_rb_tree ffp_fragment_shaders;
BOOL ffp_proj_control;
BOOL legacy_lighting;
+
+ BOOL ivb_use_ubo;
+ BOOL ubo_blend_mat_need_update;
+ GLuint ubo_modelview; /* World transforms matrices UBO (for vertex blending) */
+ struct wined3d_matrix *modelview_buffer;
};
struct glsl_vs_program
@@ -143,7 +148,8 @@ struct glsl_vs_program
GLint uniform_b_locations[WINED3D_MAX_CONSTS_B];
GLint pos_fixup_location;
- GLint modelview_matrix_location[MAX_VERTEX_BLENDS];
+ GLint modelview_matrix_location[MAX_VERTEX_BLEND_IND_UNF + 1];
+ GLint modelview_block_index;
GLint projection_matrix_location;
GLint normal_matrix_location;
GLint texture_matrix_location[MAX_TEXTURES];
@@ -1781,18 +1787,59 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
shader_glsl_ffp_vertex_normalmatrix_uniform(context, state, prog);
}
- if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND)
+ if (update_mask & (WINED3D_SHADER_CONST_FFP_VERTEXBLEND | WINED3D_SHADER_CONST_FFP_MODELVIEW))
{
struct wined3d_matrix mat;
-
- for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
+ for (i = 1; i <= MAX_VERTEX_BLEND_IND_UNF; ++i)
{
if (prog->vs.modelview_matrix_location[i] == -1)
break;
- get_modelview_matrix(context, state, i, &mat);
- GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11));
- checkGLcall("glUniformMatrix4fv");
+ if (context->blend_mat_update_mask[i / 32] & (1 << (i & 31)))
+ {
+ get_modelview_matrix(context, state, i, &mat);
+ GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11));
+ checkGLcall("glUniformMatrix4fv");
+ }
+ }
+ if (prog->vs.modelview_block_index != -1 && priv->ivb_use_ubo && priv->ubo_blend_mat_need_update)
+ {
+ unsigned int start, count;
+
+ if (priv->ubo_modelview == -1)
+ FIXME("UBO buffer with vertex blend matrices is not initialized.\n");
+
+ start = MAX_VERTEX_BLEND_IND_UBO + 1;
+ count = 0;
+ for (i = 0; i <= MAX_VERTEX_BLEND_IND_UBO; ++i)
+ {
+ if (context->blend_mat_update_mask[i / 32] & (1 << (i & 31)))
+ {
+ get_modelview_matrix(context, state, i, &priv->modelview_buffer[i]);
+ if (start + count == i)
+ {
+ ++count;
+ }
+ else
+ {
+ if (count)
+ {
+ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, sizeof(*priv->modelview_buffer) * start,
user image Michael Müller
21 Aug. 17

Maybe I am missing something, but is there any guarantee that the GL_UNIFORM_BUFFER binding hasn't changed in the mean time? I think it would be safer to bind the buffer again.

user image gofman Author
21 Aug. 17

I will add glBindBuffer() here before setting data. It did work without because nothing else was using UBOs within d3d9, but relying on that is terrible of course.

+ sizeof(*priv->modelview_buffer) * count, &priv->modelview_buffer[start]));
+ checkGLcall("glBufferSubData");
+ }
+ start = i;
+ count = 1;
+ }
+ }
+ }
+ if (count)
+ {
+ GL_EXTCALL(glBufferSubData(GL_UNIFORM_BUFFER, sizeof(*priv->modelview_buffer) * start,
+ sizeof(*priv->modelview_buffer) * count, &priv->modelview_buffer[start]));
+ checkGLcall("glBufferSubData");
+ }
+ priv->ubo_blend_mat_need_update = FALSE;
}
}
@@ -8438,8 +8485,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
{
{"vec4", "ffp_attrib_position"}, /* WINED3D_FFP_POSITION */
{"vec4", "ffp_attrib_blendweight"}, /* WINED3D_FFP_BLENDWEIGHT */
- /* TODO: Indexed vertex blending */
- {"float", ""}, /* WINED3D_FFP_BLENDINDICES */
+ {"vec4", "ffp_attrib_blendindices"}, /* WINED3D_FFP_BLENDINDICES */
{"vec3", "ffp_attrib_normal"}, /* WINED3D_FFP_NORMAL */
{"float", "ffp_attrib_psize"}, /* WINED3D_FFP_PSIZE */
{"vec4", "ffp_attrib_diffuse"}, /* WINED3D_FFP_DIFFUSE */
@@ -8451,10 +8497,15 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
BOOL legacy_lighting = priv->legacy_lighting;
GLuint shader_obj;
unsigned int i;
+ BOOL use_ubo;
string_buffer_clear(buffer);
shader_glsl_add_version_declaration(buffer, gl_info);
+ use_ubo = settings->vertexblends > 0 && settings->vb_indices && priv->ivb_use_ubo;
+ TRACE("settings->vb_indices %d, use_ubo: %d.\n",settings->vb_indices, use_ubo);
+ if (use_ubo)
+ shader_addline(buffer,"#extension GL_ARB_uniform_buffer_object : enable\n");
if (shader_glsl_use_explicit_attrib_location(gl_info))
shader_addline(buffer, "#extension GL_ARB_explicit_attrib_location : enable\n");
@@ -8469,7 +8520,16 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
}
shader_addline(buffer, "\n");
- shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n", MAX_VERTEX_BLENDS);
+ shader_addline(buffer, "uniform mat4 ffp_modelview_matrix[%u];\n",
+ settings->vb_indices && !use_ubo ? MAX_VERTEX_BLEND_IND_UNF + 1 : MAX_VERTEX_BLENDS);
+ if (use_ubo)
+ {
+ shader_addline(buffer,"layout(std140) uniform ffp_modelview_ubo\n\
+ { \n\
+ mat4 ffp_modelviews[%u];\n\
+ };\n", MAX_VERTEX_BLEND_IND_UBO + 1);
+ }
+
shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n");
shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n");
shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES);
@@ -8531,6 +8591,8 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
shader_addline(buffer, "\nvoid main()\n{\n");
shader_addline(buffer, "float m;\n");
shader_addline(buffer, "vec3 r;\n");
+ if (settings->vb_indices)
+ shader_addline(buffer, "int ind;\n");
for (i = 0; i < ARRAY_SIZE(attrib_info); ++i)
{
@@ -8559,9 +8621,27 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
for (i = 0; i < settings->vertexblends; ++i)
shader_addline(buffer, "ffp_attrib_blendweight[%u] -= ffp_attrib_blendweight[%u];\n", settings->vertexblends, i);
- shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
- for (i = 0; i < settings->vertexblends + 1; ++i)
- shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * (ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i);
+ if (settings->vb_indices)
+ {
+ shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
+ for (i = 0; i < settings->vertexblends + 1; ++i)
+ {
+ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i);
+ if (use_ubo)
+ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * "
+ "(ffp_modelviews[ind] * ffp_attrib_position);\n", i);
+ else
+ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * "
+ "(ffp_modelview_matrix[ind] * ffp_attrib_position);\n", i);
+ }
+ }
+ else
+ {
+ shader_addline(buffer, "vec4 ec_pos = vec4(0.0);\n");
+ for (i = 0; i < settings->vertexblends + 1; ++i)
+ shader_addline(buffer, "ec_pos += ffp_attrib_blendweight[%u] * "
+ "(ffp_modelview_matrix[%u] * ffp_attrib_position);\n", i, i);
+ }
shader_addline(buffer, "gl_Position = ffp_projection_matrix * ec_pos;\n");
if (settings->clipping)
@@ -8585,7 +8665,23 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr
else
{
for (i = 0; i < settings->vertexblends + 1; ++i)
- shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * (mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i);
+ {
+ if (settings->vb_indices)
+ {
+ shader_addline(buffer, "ind = int(ffp_attrib_blendindices[%u] + 0.1);\n", i);
user image Michael Müller
21 Aug. 17

Maybe I am overlooking something, but according to the MSDN 4 indices can be packed into the index DWORD. For me it seems, like the code only uses the first index here.

user image gofman Author
21 Aug. 17

Yes, they are packed, and this is the case in the test. ffp_attrib_blendindices (and vs_in2 from which they are initialized) are vec4. The existing workflow for vertex data loading treats FVF flag WINED3DFVF_LASTBETA_UBYTE4 as WINED3DFMT_R8G8B8A8_UINT, so that 4 indexes packed in bytes go to corresponding vs_in2 vector components (without normalization). So all up to 4 indices can be used here. Or am I misunderstanding your concern here?

user image Michael Müller
21 Aug. 17

Thats what I thought, but doesn't the int() cast discard everything but the first index? My impression would be that you need an uvec4 to store all 4 indices.

user image gofman Author
21 Aug. 17

But int() cast is made after indexing, it casts the component, not the whole vec4. E. g., ffp_attrib_blendindices[2] is the third component which is case after retrieval. 'ind' is used withing the loop iterating through each required component. It does work actually. Or am I misunderstanding something and it might be some caveat here?

user image Michael Müller
21 Aug. 17

Sorry for the noise, I thought settings->vertexblends refers to the number of used world matrices and not the number of weights / used indices.

+ if (use_ubo)
+ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * "
+ "(mat3(ffp_modelviews[ind]) * ffp_attrib_normal);\n", i);
+ else
+ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * "
+ "(mat3(ffp_modelview_matrix[ind]) * ffp_attrib_normal);\n", i);
+ }
+ else
+ {
+ shader_addline(buffer, "normal += ffp_attrib_blendweight[%u] * "
+ "(mat3(ffp_modelview_matrix[%u]) * ffp_attrib_normal);\n", i, i);
+ }
+ }
}
if (settings->normalize)
@@ -9458,11 +9554,36 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *
vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
- for (i = 0; i < MAX_VERTEX_BLENDS; ++i)
+ for (i = 0; i <= MAX_VERTEX_BLEND_IND_UNF; ++i)
{
string_buffer_sprintf(name, "ffp_modelview_matrix[%u]", i);
vs->modelview_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
}
+ vs->modelview_block_index = -1;
+ if (priv->ivb_use_ubo)
+ {
+ string_buffer_sprintf(name, "ffp_modelview_ubo");
+ vs->modelview_block_index = GL_EXTCALL(glGetUniformBlockIndex(program_id,name->buffer));
user image Michael Müller
21 Aug. 17

Why not directly pass the constant string? I don't see a reason why you would need to use string_buffer_sprintf.

user image gofman Author
21 Aug. 17

I will pass string directly.

+ checkGLcall("glGetUniformBlockIndex");
+ if (vs->modelview_block_index != -1)
+ {
+ GL_EXTCALL(glUniformBlockBinding(program_id, vs->modelview_block_index, 1));
+ checkGLcall("glUniformBlockBinding");
+ if (priv->ubo_modelview == -1)
+ {
+ GL_EXTCALL(glGenBuffers(1, &priv->ubo_modelview));
+ GL_EXTCALL(glBindBuffer(GL_UNIFORM_BUFFER, priv->ubo_modelview));
+ checkGLcall("glBindBuffer (UBO)");
+ GL_EXTCALL(glBufferData(GL_UNIFORM_BUFFER,
+ sizeof(struct wined3d_matrix) * (MAX_VERTEX_BLEND_IND_UBO + 1), NULL, GL_DYNAMIC_DRAW));
+ checkGLcall("glBufferData (UBO)");
+ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, 1, priv->ubo_modelview));
user image Michael Müller
21 Aug. 17

Doesn't this cause problems if the application binds any other constant buffers?

user image gofman Author
21 Aug. 17

AFAIK uniform buffers currently used in wined3d for shader constant blocks, which are set from d3d11 only. So in d3d9 workflow nothing is supposed to interfere and "reuse" this binding point index. This is still not nice at all of course. Do you think it will make sense to modify wined3d_gl_limits_get_uniform_block_range() and gl_limits to use it for getting the binding point index here?

+ checkGLcall("glBindBufferBase");
+ priv->ubo_blend_mat_need_update = TRUE;
+ }
+ }
+ }
+
vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix"));
vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix"));
for (i = 0; i < MAX_TEXTURES; ++i)
@@ -10015,7 +10136,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
| WINED3D_SHADER_CONST_FFP_PROJ;
- for (i = 1; i < MAX_VERTEX_BLENDS; ++i)
+ for (i = 1; i <= MAX_VERTEX_BLEND_IND_UNF; ++i)
{
if (entry->vs.modelview_matrix_location[i] != -1)
{
@@ -10024,6 +10145,9 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
}
}
+ if (entry->vs.modelview_block_index != -1)
+ entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND;
+
for (i = 0; i < MAX_TEXTURES; ++i)
{
if (entry->vs.texture_matrix_location[i] != -1)
@@ -10128,6 +10252,7 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex
struct shader_glsl_priv *priv = shader_priv;
GLenum current_vertex_color_clamp;
GLuint program_id, prev_id;
+ unsigned int i;
priv->vertex_pipe->vp_enable(gl_info, !use_vs(state));
priv->fragment_pipe->enable_extension(gl_info, !use_ps(state));
@@ -10169,7 +10294,11 @@ static void shader_glsl_select(void *shader_priv, struct wined3d_context *contex
checkGLcall("glUseProgram");
if (program_id)
+ {
context->constant_update_mask |= ctx_data->glsl_program->constant_update_mask;
+ for (i = 0; i < MAX_VB_UPD_WORDS; ++i)
+ context->blend_mat_update_mask[i] = 0xFFFFFFFF;
+ }
}
context->shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE);
@@ -10541,6 +10670,11 @@ static HRESULT shader_glsl_alloc(struct wined3d_device *device, const struct win
fragment_pipe->get_caps(gl_info, &fragment_caps);
priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
priv->legacy_lighting = device->wined3d->flags & WINED3D_LEGACY_FFP_LIGHTING;
+ priv->ivb_use_ubo = gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT];
+ priv->ubo_modelview = -1; /* To be initialized on first usage. */
+ if (priv->ivb_use_ubo)
+ priv->modelview_buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv->modelview_buffer)
user image Michael Müller
21 Aug. 17

It would be better to handle heap allocation failures here.

user image gofman Author
21 Aug. 17

Yeah, sure.

+ * (MAX_VERTEX_BLEND_IND_UBO + 1));
device->vertex_priv = vertex_priv;
device->fragment_priv = fragment_priv;
@@ -10572,6 +10706,13 @@ static void shader_glsl_free(struct wined3d_device *device)
string_buffer_free(&priv->shader_buffer);
priv->fragment_pipe->free_private(device);
priv->vertex_pipe->vp_free(device);
+ if (priv->ubo_modelview != -1)
+ {
+ const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ GL_EXTCALL(glDeleteBuffers(1, &priv->ubo_modelview));
user image Michael Müller
21 Aug. 17

checkGLcall wouldn't hurt here.

+ priv->ubo_modelview = -1;
+ }
+ HeapFree(GetProcessHeap(), 0, priv->modelview_buffer);
HeapFree(GetProcessHeap(), 0, device->shader_priv);
device->shader_priv = NULL;
@@ -10977,7 +11118,11 @@ static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info,
caps->ffp_generic_attributes = TRUE;
caps->max_active_lights = MAX_ACTIVE_LIGHTS;
caps->max_vertex_blend_matrices = MAX_VERTEX_BLENDS;
- caps->max_vertex_blend_matrix_index = 0;
+ if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
+ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLEND_IND_UBO;
+ else
+ caps->max_vertex_blend_matrix_index = MAX_VERTEX_BLEND_IND_UNF;
+
caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
| WINED3DVTXPCAPS_MATERIALSOURCE7
| WINED3DVTXPCAPS_VERTEXFOG
@@ -11158,23 +11303,39 @@ static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context,
static void glsl_vertex_pipe_world(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
+ unsigned int i;
+
+ struct shader_glsl_priv *priv = context->device->shader_priv;
context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW;
+ for (i = 0; i < MAX_VB_UPD_WORDS; ++i)
+ context->blend_mat_update_mask[i] = 0xFFFFFFFF;
+ priv->ubo_blend_mat_need_update = TRUE;
}
static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id)
{
+ UINT matrix_ind;
+ struct shader_glsl_priv *priv = context->device->shader_priv;
+ matrix_ind = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND;
+ context->blend_mat_update_mask[matrix_ind / 32] |= 1 << (matrix_ind & 31);
+ priv->ubo_blend_mat_need_update = TRUE;
}
static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int k;
+ unsigned int i;
+ struct shader_glsl_priv *priv = context->device->shader_priv;
context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW
| WINED3D_SHADER_CONST_FFP_LIGHTS
| WINED3D_SHADER_CONST_FFP_VERTEXBLEND;
+ for (i = 0; i < MAX_VB_UPD_WORDS; ++i)
+ context->blend_mat_update_mask[i] = 0xFFFFFFFF;
+ priv->ubo_blend_mat_need_update = TRUE;
if (needs_legacy_glsl_syntax(gl_info))
{
@@ -11395,6 +11556,258 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
{STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(4)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(5)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(6)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(7)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(8)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(9)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(10)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(11)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(12)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(13)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(14)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(15)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(16)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(17)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(18)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(19)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(20)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(21)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(22)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(23)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(24)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(25)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(26)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(27)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(28)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(29)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(30)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(31)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(32)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(33)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(34)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(35)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(36)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(37)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(38)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(39)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(40)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(41)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(42)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(43)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(44)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(45)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(46)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(47)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(48)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(49)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(50)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(51)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(52)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(53)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(54)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(55)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(56)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(57)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(58)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(59)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(60)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(61)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(62)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(63)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(64)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(65)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(66)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(67)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(68)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(69)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(70)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(71)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(72)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(73)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(74)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(75)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(76)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(77)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(78)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(79)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(80)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(81)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(82)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(83)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(84)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(85)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(86)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(87)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(88)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(89)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(90)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(91)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(92)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(93)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(94)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(95)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(96)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(97)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(98)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(99)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), glsl_vertex_pipe_vertexblend }, ARB_UNIFORM_BUFFER_OBJECT},
{STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE },
{STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE },
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 950c4d511c..745707091f 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -5971,7 +5971,8 @@ static void prune_invalid_states(struct StateEntry *state_table, const struct wi
state_table[i].apply = state_undefined;
}
- start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(d3d_info->limits.ffp_vertex_blend_matrices));
+ start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(max(d3d_info->limits.ffp_vertex_blend_matrices,
+ d3d_info->limits.ffp_max_vertex_blend_matrix_index + 1)));
last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
for (i = start; i <= last; ++i)
{
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 1c646064bc..2209c95da5 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -5855,6 +5855,9 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
settings->flatshading = FALSE;
settings->swizzle_map = si->swizzle_map;
+
+ if (state->render_states[WINED3D_RS_INDEXEDVERTEXBLENDENABLE] && (si->use_map & (1 << WINED3D_FFP_BLENDINDICES)))
+ settings->vb_indices = 1;
}
int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
index 4fa6d54c37..c6ab0ea09c 100644
--- a/dlls/wined3d/vertexdeclaration.c
+++ b/dlls/wined3d/vertexdeclaration.c
@@ -119,6 +119,15 @@ static BOOL declaration_element_valid_ffp(const struct wined3d_vertex_element *e
return FALSE;
}
+ case WINED3D_DECL_USAGE_BLEND_INDICES:
+ switch(element->format)
+ {
+ case WINED3DFMT_R8G8B8A8_UINT:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
case WINED3D_DECL_USAGE_NORMAL:
switch(element->format)
{
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f8aeb629c9..6a4402bf29 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -164,6 +164,7 @@ struct wined3d_d3d_limits
unsigned int ffp_blend_stages;
unsigned int ffp_vertex_blend_matrices;
unsigned int active_light_count;
+ unsigned int ffp_max_vertex_blend_matrix_index;
};
typedef void (WINE_GLAPI *wined3d_ffp_attrib_func)(const void *data);
@@ -272,6 +273,9 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup
#define MAX_TGSM_REGISTERS 8192
#define MAX_VERTEX_BLENDS 4
#define MAX_MULTISAMPLE_TYPES 8
+#define MAX_VERTEX_BLEND_IND_UBO 255
user image Michael Müller
21 Aug. 17

Wouldn't it make sense to use #define MAX_VERTEX_BLEND_UBO 256 instead? You basically add + 1 everywhere, except when setting the caps.

user image gofman Author
21 Aug. 17

I will change that.

+#define MAX_VERTEX_BLEND_IND_UNF 149
+#define MAX_VB_UPD_WORDS ((MAX_VERTEX_BLEND_IND_UBO + 1 + 31) / 32)
struct min_lookup
{
@@ -1840,6 +1844,7 @@ struct wined3d_context
DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */
DWORD shader_update_mask;
DWORD constant_update_mask;
+ DWORD blend_mat_update_mask[MAX_VB_UPD_WORDS];
DWORD numbered_array_mask;
GLenum tracking_parm; /* Which source is tracking current colour */
GLenum untracked_materials[2];
@@ -2667,7 +2672,8 @@ struct wined3d_ffp_vs_settings
DWORD ortho_fog : 1;
DWORD flatshading : 1;
DWORD swizzle_map : 16; /* MAX_ATTRIBS, 16 */
- DWORD padding : 2;
+ DWORD vb_indices : 1;
+ DWORD padding : 1;
DWORD texgen[MAX_TEXTURES];
};
--
2.13.5

0002-d3d9-tests-Add-test-for-indexed-vertex-blending.patch (6 comments)

From 2d6756a03e5f7f91acdc45637e354f70f5506b82 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Thu, 17 Aug 2017 17:46:50 +0300
Subject: [PATCH 2/2] d3d9/tests: Add test for indexed vertex blending.
Signed-off-by: Paul Gofman <gofmanp@gmail.com>
---
dlls/d3d9/tests/visual.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 258 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index c8a6a1fa5a..c47eb10003 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -19713,6 +19713,263 @@ done:
DestroyWindow(window);
}
+static void do_test_indexed_vertex_blending(IDirect3DDevice9 *device, const char *test_id_str)
+{
+ D3DCAPS9 caps;
+ D3DCOLOR color;
+ HRESULT hr;
+ unsigned int i;
+
+ static const D3DMATRIX view_mat =
+ {{{
+ 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+ }}},
+ upper_left =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ -4.0f, 4.0f, 0.0f, 1.0f
+ }}},
+ lower_left =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ -4.0f, -4.0f, 0.0f, 1.0f
+ }}},
+ upper_right =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 4.0f, 4.0f, 0.0f, 1.0f
+ }}},
+ lower_right =
+ {{{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 4.0f, -4.0f, 0.0f, 1.0f
+ }}};
+
+ static const POINT quad_upper_right_points[] =
+ {
+ {576, 48}, {-1, -1},
+ },
+ quad_upper_right_empty_points[] =
+ {
+ {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
+ },
+ quad_center_points[] =
+ {
+ {320, 240}, {-1, -1}
+ },
+ quad_center_empty_points[] =
+ {
+ {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
+ },
+ quad_upper_center_points[] =
+ {
+ {320, 48}, {-1, -1}
+ },
+ quad_upper_center_empty_points[] =
+ {
+ {320, 240}, {64, 48}, {576, 48}, {-1, -1}
+ },
+ quad_fullscreen_points[] =
+ {
+ {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
+ },
+ quad_fullscreen_empty_points[] =
+ {
+ {-1, -1}
+ };
+
+ static const struct
+ {
+ struct
+ {
+ struct vec3 position;
+ struct vec3 blendweights;
+ DWORD matrixIndices;
+ }
+ vertex_data[4];
+ const POINT *quad_points;
+ const POINT *empty_points;
+ }
+ tests[] =
+ {
+ /* upper right */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405}},
+ quad_upper_right_points, quad_upper_right_empty_points
+ },
+ /* center */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}, 0x06070405}},
+ quad_center_points, quad_center_empty_points
+ },
+ /* upper center */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}, 0x06070405}},
+ quad_upper_center_points, quad_upper_center_empty_points
+ },
+ /* full screen */
+ {
+ {{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, 0x06070405},
+ {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, 0x06070405},
+ {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, 0x06070405},
+ {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, 0x06070405}},
+ quad_fullscreen_points, quad_fullscreen_empty_points
+ }
+ };
+
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ if (caps.MaxVertexBlendMatrixIndex < 7 || caps.MaxVertexBlendMatrices < 4)
+ {
+ skip("(%s) Too few vertex blend matrices supported: MaxVertexBlendMatrices=%u, MaxVertexBlendMatrixIndex=%u\n",
+ test_id_str, caps.MaxVertexBlendMatrices,caps.MaxVertexBlendMatrixIndex);
+ goto done;
user image Michael Müller
21 Aug. 17

Why not just return? Jumping to done doesn't do any cleanup or similar.

user image gofman Author
21 Aug. 17

Yeah, sure, it is actually a leftover.

+ }
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
+
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
+ ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
+
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(5), &upper_left);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(4), &lower_left);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(7), &lower_right);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(6), &upper_right);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetTransform returned %08x\n", test_id_str, hr);
+
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetRenderState failed %08x\n", test_id_str, hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
+ ok(hr == D3D_OK, "(%s) IDirect3DDevice9_SetRenderState D3DRS_INDEXEDVERTEXBLENDENABLE failed %08x\n",
+ test_id_str, hr);
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
+ {
+ const POINT *point;
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
+ ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
+
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4);
+ ok(SUCCEEDED(hr), "(%s) Failed to set FVF, hr %#x.\n", test_id_str, hr);
+
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].vertex_data,
+ 6 * sizeof(float) + sizeof(DWORD));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ point = tests[i].quad_points;
+ while (point->x != -1 && point->y != -1)
+ {
+ color = getPixelColor(device, point->x, point->y);
+ ok(color_match(color, 0x00ffffff, 1), "(%s) Expected quad at %dx%d.\n", test_id_str, point->x, point->y);
+ ++point;
+ }
+
+ point = tests[i].empty_points;
+ while (point->x != -1 && point->y != -1)
+ {
+ color = getPixelColor(device, point->x, point->y);
+ ok(color_match(color, 0x00000000, 1), "(%s) Unexpected quad at %dx%d.\n", test_id_str, point->x, point->y);
+ ++point;
+ }
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
+ }
+done:
+ ;
+}
+
+static void test_indexed_vertex_blending(void)
+{
+IDirect3D9 *d3d;
+IDirect3DDevice9 *device;
+ULONG refcount;
+HWND window;
+D3DPRESENT_PARAMETERS present_parameters = {0};
user image Michael Müller
21 Aug. 17

Why not indent the code?

+
+ window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 0, 0, 640, 480, NULL, NULL, NULL, NULL);
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
user image Michael Müller
21 Aug. 17

Isn't this device leaked (and never used anywhere)?

user image gofman Author
21 Aug. 17

Oh, this create_device() looks like a leftover. I will check once again and remove it.

+ present_parameters.Windowed = TRUE;
+ present_parameters.hDeviceWindow = window;
+ present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ present_parameters.BackBufferWidth = 640;
+ present_parameters.BackBufferHeight = 480;
+ present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
+ present_parameters.EnableAutoDepthStencil = TRUE;
+ present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
+
+ if (!SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
user image Michael Müller
21 Aug. 17

Its better to use FAILED().

+ D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+ do_test_indexed_vertex_blending(device,"IVB software");
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+
+ if (!SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+ do_test_indexed_vertex_blending(device,"IVB hardware");
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+
+ if (!SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+ D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+ do_test_indexed_vertex_blending(device,"IVB mixed");
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+
+done:
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
static void test_updatetexture(void)
{
BOOL r32f_supported, ati2n_supported, do_visual_test;
@@ -22750,6 +23007,7 @@ START_TEST(visual)
test_multisample_mismatch();
test_texcoordindex();
test_vertex_blending();
+ test_indexed_vertex_blending();
test_updatetexture();
test_depthbias();
test_flip();
--
2.13.5