[PATCH 1/5] wined3d: Add support for GLSL based fixed function vertex shaders.
Henri Verbeet
hverbeet at codeweavers.com
Wed May 29 02:45:35 CDT 2013
This is (very loosely) based on Stefan's patch from October 2008 or so for the
ARB shader backend.
---
dlls/wined3d/directx.c | 10 +-
dlls/wined3d/glsl_shader.c | 541 ++++++++++++++++++++++++++++++++++++++++-
dlls/wined3d/state.c | 41 ++--
dlls/wined3d/utils.c | 96 ++++++++
dlls/wined3d/wined3d_private.h | 83 +++++++
5 files changed, 738 insertions(+), 33 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 3ef5eeb..d308322 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2316,6 +2316,14 @@ static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *
return select_card_fallback_nvidia(gl_info);
}
+static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const struct wined3d_gl_info *gl_info,
+ const struct wined3d_shader_backend_ops *shader_backend_ops)
+{
+ if (shader_backend_ops == &glsl_shader_backend)
+ return &glsl_vertex_pipe;
+ return &ffp_vertex_pipe;
+}
+
static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info,
const struct wined3d_shader_backend_ops *shader_backend_ops)
{
@@ -2843,7 +2851,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
checkGLcall("extension detection");
adapter->shader_backend = select_shader_backend(gl_info);
- adapter->vertex_pipe = &ffp_vertex_pipe;
+ adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend);
adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
adapter->blitter = select_blit_implementation(gl_info, adapter->shader_backend);
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 8816229..60a904a 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -99,6 +99,7 @@ struct shader_glsl_priv {
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
+ struct wine_rb_tree ffp_vertex_shaders;
struct wine_rb_tree ffp_fragment_shaders;
BOOL ffp_proj_control;
};
@@ -188,6 +189,13 @@ struct glsl_shader_private
UINT num_gl_shaders, shader_array_size;
};
+struct glsl_ffp_vertex_shader
+{
+ struct wined3d_ffp_vs_desc desc;
+ GLhandleARB id;
+ struct list linked_programs;
+};
+
struct glsl_ffp_fragment_shader
{
struct ffp_frag_desc entry;
@@ -195,6 +203,12 @@ struct glsl_ffp_fragment_shader
struct list linked_programs;
};
+struct glsl_ffp_destroy_ctx
+{
+ struct shader_glsl_priv *priv;
+ const struct wined3d_gl_info *gl_info;
+};
+
static const char *debug_gl_shader_type(GLenum type)
{
switch (type)
@@ -4789,6 +4803,223 @@ static GLhandleARB find_glsl_geometry_shader(const struct wined3d_context *conte
return ret;
}
+static const char *shader_glsl_ffp_mcs(enum wined3d_material_color_source mcs, const char *material)
+{
+ switch (mcs)
+ {
+ case WINED3D_MCS_MATERIAL:
+ return material;
+ case WINED3D_MCS_COLOR1:
+ return "gl_Color";
+ case WINED3D_MCS_COLOR2:
+ return "gl_SecondaryColor";
+ default:
+ ERR("Invalid material color source %#x.\n", mcs);
+ return "<invalid>";
+ }
+}
+
+static void shader_glsl_ffp_vertex_lighting(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ const char *diffuse, *specular, *emission, *ambient;
+ enum wined3d_light_type light_type;
+ unsigned int i;
+
+ if (!settings->lighting)
+ {
+ shader_addline(buffer, "gl_FrontColor = gl_Color;\n");
+ shader_addline(buffer, "gl_FrontSecondaryColor = gl_SecondaryColor;\n");
+ return;
+ }
+
+ shader_addline(buffer, "vec3 ambient = gl_LightModel.ambient.xyz;\n");
+ shader_addline(buffer, "vec3 diffuse = vec3(0.0);\n");
+ shader_addline(buffer, "vec4 specular = vec4(0.0);\n");
+ shader_addline(buffer, "vec3 dir, dst, half;\n");
+ shader_addline(buffer, "float att, t;\n");
+
+ ambient = shader_glsl_ffp_mcs(settings->ambient_source, "gl_FrontMaterial.ambient");
+ diffuse = shader_glsl_ffp_mcs(settings->diffuse_source, "gl_FrontMaterial.diffuse");
+ specular = shader_glsl_ffp_mcs(settings->specular_source, "gl_FrontMaterial.specular");
+ emission = shader_glsl_ffp_mcs(settings->emission_source, "gl_FrontMaterial.emission");
+
+ for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
+ {
+
+ light_type = (settings->light_type >> WINED3D_FFP_LIGHT_TYPE_SHIFT(i)) & WINED3D_FFP_LIGHT_TYPE_MASK;
+ switch (light_type)
+ {
+ case WINED3D_LIGHT_POINT:
+ shader_addline(buffer, "dir = gl_LightSource[%u].position.xyz - ec_pos.xyz;\n", i);
+ shader_addline(buffer, "dst.z = dot(dir, dir);\n");
+ shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
+ shader_addline(buffer, "dst.x = 1.0;\n");
+ shader_addline(buffer, "att = dot(dst.xyz, vec3(gl_LightSource[%u].constantAttenuation,"
+ " gl_LightSource[%u].linearAttenuation, gl_LightSource[%u].quadraticAttenuation));\n", i, i, i);
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz / att;\n", i);
+ if (!settings->normal)
+ break;
+ shader_addline(buffer, "dir = normalize(dir);\n");
+ shader_addline(buffer, "diffuse += (max(0.0, dot(dir, normal))"
+ " * gl_LightSource[%u].diffuse.xyz) / att;\n", i);
+ if (settings->localviewer)
+ shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
+ else
+ shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, 1.0)));\n");
+ shader_addline(buffer, "if (t > 0.0) specular += (pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular) / att;\n", i);
+ break;
+
+ case WINED3D_LIGHT_SPOT:
+ shader_addline(buffer, "dir = gl_LightSource[%u].position.xyz - ec_pos.xyz;\n", i);
+ shader_addline(buffer, "dst.z = dot(dir, dir);\n");
+ shader_addline(buffer, "dst.y = sqrt(dst.z);\n");
+ shader_addline(buffer, "dst.x = 1.0;\n");
+ shader_addline(buffer, "dir = normalize(dir);\n");
+ shader_addline(buffer, "t = dot(-dir, normalize(gl_LightSource[%u].spotDirection));\n", i);
+ shader_addline(buffer, "if (t < gl_LightSource[%u].spotCosCutoff) att = 0.0;\n", i);
+ shader_addline(buffer, "else att = pow(t, gl_LightSource[%u].spotExponent)"
+ " / dot(dst.xyz, vec3(gl_LightSource[%u].constantAttenuation,"
+ " gl_LightSource[%u].linearAttenuation, gl_LightSource[%u].quadraticAttenuation));\n",
+ i, i, i, i);
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz * att;\n", i);
+ if (!settings->normal)
+ break;
+ shader_addline(buffer, "diffuse += (max(0.0, dot(dir, normal))"
+ " * gl_LightSource[%u].diffuse.xyz) * att;\n", i);
+ if (settings->localviewer)
+ shader_addline(buffer, "t = dot(normal, normalize(dir - normalize(ec_pos.xyz)));\n");
+ else
+ shader_addline(buffer, "t = dot(normal, normalize(dir + vec3(0.0, 0.0, 1.0)));\n");
+ shader_addline(buffer, "if (t > 0.0) specular += (pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular) * att;\n", i);
+ break;
+
+ case WINED3D_LIGHT_DIRECTIONAL:
+ shader_addline(buffer, "ambient += gl_LightSource[%u].ambient.xyz;\n", i);
+ if (!settings->normal)
+ break;
+ shader_addline(buffer, "dir = normalize(gl_LightSource[%u].position.xyz);\n", i);
+ shader_addline(buffer, "diffuse += max(0.0, dot(dir, normal)) * gl_LightSource[%u].diffuse.xyz;\n", i);
+ shader_addline(buffer, "t = dot(normal, gl_LightSource[%u].halfVector.xyz);\n", i);
+ shader_addline(buffer, "if (t > 0.0) specular += pow(t, gl_FrontMaterial.shininess)"
+ " * gl_LightSource[%u].specular;\n", i);
+ break;
+
+ default:
+ if (light_type)
+ FIXME("Unhandled light type %#x.\n", light_type);
+ continue;
+ }
+ }
+
+ shader_addline(buffer, "gl_FrontColor.xyz = %s.xyz * ambient + %s.xyz * diffuse + %s.xyz;\n",
+ ambient, diffuse, emission);
+ shader_addline(buffer, "gl_FrontColor.w = %s.w;\n", diffuse);
+ shader_addline(buffer, "gl_FrontSecondaryColor = %s * specular;\n", specular);
+}
+
+/* Context activation is done by the caller. */
+static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffer *buffer,
+ const struct wined3d_ffp_vs_settings *settings, const struct wined3d_gl_info *gl_info)
+{
+ GLhandleARB shader_obj;
+ unsigned int i;
+
+ shader_buffer_clear(buffer);
+
+ shader_addline(buffer, "#version 120\n");
+ shader_addline(buffer, "\n");
+ shader_addline(buffer, "void main()\n{\n");
+ shader_addline(buffer, "float m;\n");
+ shader_addline(buffer, "vec3 r;\n");
+
+ shader_addline(buffer, "vec4 ec_pos = gl_ModelViewMatrix * gl_Vertex;\n");
+ shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
+ 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");
+ else if (settings->normalize)
+ shader_addline(buffer, "vec3 normal = normalize(gl_NormalMatrix * gl_Normal);\n");
+ else
+ shader_addline(buffer, "vec3 normal = gl_NormalMatrix * gl_Normal;\n");
+
+ shader_glsl_ffp_vertex_lighting(buffer, settings, gl_info);
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ switch (settings->texgen[i] << WINED3D_FFP_TCI_SHIFT)
+ {
+ case WINED3DTSS_TCI_PASSTHRU:
+ if (settings->texcoords & (1 << i))
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * gl_MultiTexCoord%d;\n",
+ i, i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACENORMAL:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * vec4(normal, 1.0);\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEPOSITION:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * ec_pos;\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]"
+ " * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i);
+ break;
+
+ case WINED3DTSS_TCI_SPHEREMAP:
+ shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n");
+ shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n");
+ shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]"
+ " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);", i, i);
+ break;
+
+ default:
+ ERR("Unhandled texgen %#x.\n", settings->texgen[i]);
+ break;
+ }
+ }
+
+ switch (settings->fog_mode)
+ {
+ case WINED3D_FFP_VS_FOG_OFF:
+ break;
+
+ case WINED3D_FFP_VS_FOG_FOGCOORD:
+ shader_addline(buffer, "gl_FogFragCoord = gl_SecondaryColor.w * 255.0;\n");
+ break;
+
+ case WINED3D_FFP_VS_FOG_RANGE:
+ shader_addline(buffer, "gl_FogFragCoord = length(ec_pos.xyz);\n");
+ break;
+
+ case WINED3D_FFP_VS_FOG_DEPTH:
+ shader_addline(buffer, "gl_FogFragCoord = ec_pos.z;\n");
+ break;
+
+ default:
+ ERR("Unhandled fog mode %#x.\n", settings->fog_mode);
+ break;
+ }
+
+ shader_addline(buffer, "gl_PointSize = gl_Point.size / sqrt(gl_Point.distanceConstantAttenuation"
+ " + gl_Point.distanceLinearAttenuation * length(ec_pos.xyz)"
+ " + gl_Point.distanceQuadraticAttenuation * dot(ec_pos.xyz, ec_pos.xyz));\n");
+ shader_addline(buffer, "gl_PointSize = clamp(gl_PointSize, gl_Point.sizeMin, gl_Point.sizeMax);\n");
+
+ shader_addline(buffer, "}\n");
+
+ shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+ shader_glsl_compile(gl_info, shader_obj, buffer->buffer);
+
+ return shader_obj;
+}
+
static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_shader_buffer *buffer,
DWORD argnum, unsigned int stage, DWORD arg)
{
@@ -5399,6 +5630,27 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
return shader_obj;
}
+static struct glsl_ffp_vertex_shader *shader_glsl_find_ffp_vertex_shader(struct shader_glsl_priv *priv,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_ffp_vs_settings *settings)
+{
+ struct glsl_ffp_vertex_shader *shader;
+ const struct wine_rb_entry *entry;
+
+ if ((entry = wine_rb_get(&priv->ffp_vertex_shaders, settings)))
+ return WINE_RB_ENTRY_VALUE(entry, struct glsl_ffp_vertex_shader, desc.entry);
+
+ if (!(shader = HeapAlloc(GetProcessHeap(), 0, sizeof(*shader))))
+ return NULL;
+
+ shader->desc.settings = *settings;
+ shader->id = shader_glsl_generate_ffp_vertex_shader(&priv->shader_buffer, settings, gl_info);
+ list_init(&shader->linked_programs);
+ if (wine_rb_put(&priv->ffp_vertex_shaders, &shader->desc.settings, &shader->desc.entry) == -1)
+ ERR("Failed to insert ffp vertex shader.\n");
+
+ return shader;
+}
+
static struct glsl_ffp_fragment_shader *shader_glsl_find_ffp_fragment_shader(struct shader_glsl_priv *priv,
const struct wined3d_gl_info *gl_info, const struct ffp_frag_settings *args)
{
@@ -5495,7 +5747,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
struct ps_compile_args ps_compile_args;
struct vs_compile_args vs_compile_args;
GLhandleARB vs_id, gs_id, ps_id;
- struct list *ps_list;
+ struct list *ps_list, *vs_list;
struct wined3d_device *device = context->swapchain->device;
if (use_vs(state))
@@ -5503,12 +5755,25 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
vshader = state->vertex_shader;
find_vs_compile_args(state, vshader, &vs_compile_args);
vs_id = find_glsl_vshader(context, &priv->shader_buffer, vshader, &vs_compile_args);
+ vs_list = &vshader->linked_programs;
if ((gshader = state->geometry_shader))
gs_id = find_glsl_geometry_shader(context, &priv->shader_buffer, gshader);
else
gs_id = 0;
}
+ else if (priv->vertex_pipe == &glsl_vertex_pipe)
+ {
+ struct glsl_ffp_vertex_shader *ffp_shader;
+ struct wined3d_ffp_vs_settings settings;
+
+ wined3d_ffp_get_vs_settings(state, &device->stream_info, &settings);
+ ffp_shader = shader_glsl_find_ffp_vertex_shader(priv, gl_info, &settings);
+ vs_id = ffp_shader->id;
+ vs_list = &ffp_shader->linked_programs;
+
+ gs_id = 0;
+ }
else
{
vs_id = 0;
@@ -5563,6 +5828,15 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
priv->glsl_program = entry;
/* Attach GLSL vshader */
+ if (vs_id)
+ {
+ TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, programId);
+ GL_EXTCALL(glAttachObjectARB(programId, vs_id));
+ checkGLcall("glAttachObjectARB");
+
+ list_add_head(vs_list, &entry->vs.shader_entry);
+ }
+
if (vshader)
{
WORD map = vshader->reg_maps.input_registers;
@@ -5577,10 +5851,6 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
*/
GL_EXTCALL(glDeleteObjectARB(reorder_shader_id));
- TRACE("Attaching GLSL shader object %u to program %u.\n", vs_id, programId);
- GL_EXTCALL(glAttachObjectARB(programId, vs_id));
- checkGLcall("glAttachObjectARB");
-
/* Bind vertex attributes to a corresponding index number to match
* the same index numbers as ARB_vertex_programs (makes loading
* vertex attributes simpler). With this method, we can use the
@@ -5598,8 +5868,6 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
GL_EXTCALL(glBindAttribLocationARB(programId, i, tmp_name));
}
checkGLcall("glBindAttribLocationARB");
-
- list_add_head(&vshader->linked_programs, &entry->vs.shader_entry);
}
if (gshader)
@@ -6376,6 +6644,259 @@ const struct wined3d_shader_backend_ops glsl_shader_backend =
shader_glsl_has_ffp_proj_control,
};
+static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
+{
+ if (enable)
+ gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
+ else
+ gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
+ checkGLcall("GL_VERTEX_PROGRAM_POINT_SIZE_ARB");
+}
+
+static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
+{
+ caps->max_active_lights = gl_info->limits.lights;
+ caps->max_vertex_blend_matrices = 0;
+ caps->max_vertex_blend_matrix_index = 0;
+ caps->vertex_processing_caps = WINED3DVTXPCAPS_TEXGEN
+ | WINED3DVTXPCAPS_MATERIALSOURCE7
+ | WINED3DVTXPCAPS_VERTEXFOG
+ | WINED3DVTXPCAPS_DIRECTIONALLIGHTS
+ | WINED3DVTXPCAPS_POSITIONALLIGHTS
+ | WINED3DVTXPCAPS_LOCALVIEWER
+ | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP;
+ caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 8; /* 8 texture coordinates. */
+ caps->max_user_clip_planes = gl_info->limits.clipplanes;
+ caps->raster_caps = WINED3DPRASTERCAPS_FOGRANGE;
+}
+
+static void *glsl_vertex_pipe_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
+{
+ struct shader_glsl_priv *priv;
+
+ if (shader_backend == &glsl_shader_backend)
+ {
+ priv = shader_priv;
+
+ if (wine_rb_init(&priv->ffp_vertex_shaders, &wined3d_ffp_vertex_program_rb_functions) == -1)
+ {
+ ERR("Failed to initialize rbtree.\n");
+ return NULL;
+ }
+
+ return priv;
+ }
+
+ FIXME("GLSL vertex pipe without GLSL shader backend not implemented.\n");
+
+ return NULL;
+}
+
+static void shader_glsl_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *context)
+{
+ struct glsl_ffp_vertex_shader *shader = WINE_RB_ENTRY_VALUE(entry,
+ struct glsl_ffp_vertex_shader, desc.entry);
+ struct glsl_shader_prog_link *program, *program2;
+ struct glsl_ffp_destroy_ctx *ctx = context;
+
+ LIST_FOR_EACH_ENTRY_SAFE(program, program2, &shader->linked_programs,
+ struct glsl_shader_prog_link, vs.shader_entry)
+ {
+ delete_glsl_program_entry(ctx->priv, ctx->gl_info, program);
+ }
+ ctx->gl_info->gl_ops.ext.p_glDeleteObjectARB(shader->id);
+ HeapFree(GetProcessHeap(), 0, shader);
+}
+
+/* Context activation is done by the caller. */
+static void glsl_vertex_pipe_vp_free(struct wined3d_device *device)
+{
+ struct shader_glsl_priv *priv = device->vertex_priv;
+ struct glsl_ffp_destroy_ctx ctx;
+
+ ctx.priv = priv;
+ ctx.gl_info = &device->adapter->gl_info;
+ wine_rb_destroy(&priv->ffp_vertex_shaders, shader_glsl_free_ffp_vertex_shader, &ctx);
+}
+
+static void glsl_vertex_pipe_shader(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ context->select_shader = 1;
+}
+
+static void glsl_vertex_pipe_light(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id)
+{
+ light(context, state, state_id);
+ context->select_shader = 1;
+}
+
+static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] =
+{
+ {STATE_VDECL, {STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
+ {STATE_VSHADER, {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_MATERIAL, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable }, WINED3D_GL_EXT_NONE },
+ /* Clip planes */
+ {STATE_CLIPPLANE(0), {STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(1), {STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(2), {STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(3), {STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(4), {STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(5), {STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(6), {STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(7), {STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(8), {STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(9), {STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(10), {STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(11), {STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(12), {STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(13), {STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(14), {STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(15), {STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(16), {STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(17), {STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(18), {STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(19), {STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(20), {STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(21), {STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(22), {STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(23), {STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(24), {STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(25), {STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(26), {STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(27), {STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(28), {STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(29), {STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(30), {STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
+ {STATE_CLIPPLANE(31), {STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
+ /* Lights */
+ {STATE_ACTIVELIGHT(0), {STATE_ACTIVELIGHT(0), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(1), {STATE_ACTIVELIGHT(1), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(2), {STATE_ACTIVELIGHT(2), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(3), {STATE_ACTIVELIGHT(3), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(4), {STATE_ACTIVELIGHT(4), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(5), {STATE_ACTIVELIGHT(5), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(6), {STATE_ACTIVELIGHT(6), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ {STATE_ACTIVELIGHT(7), {STATE_ACTIVELIGHT(7), glsl_vertex_pipe_light }, WINED3D_GL_EXT_NONE },
+ /* Viewport */
+ {STATE_VIEWPORT, {STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
+ /* Transform states */
+ {STATE_TRANSFORM(WINED3D_TS_VIEW), {STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_PROJECTION), {STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE0), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE1), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE2), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE3), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE4), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE5), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE6), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_TEXTURE7), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), transform_world }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ /* Fog */
+ {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), glsl_vertex_pipe_shader}, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_AMBIENT), {STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
+ {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
+ {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_TWEENFACTOR), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), {STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
+ /* Samplers for NP2 texture matrix adjustions. They are not needed if
+ * GL_ARB_texture_non_power_of_two is supported, so register a NULL state
+ * handler in that case to get the vertex part of sampler() skipped (VTF
+ * is handled in the misc states). Otherwise, register
+ * sampler_texmatrix(), which takes care of updating the texture matrix. */
+ {STATE_SAMPLER(0), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(0), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(0), {STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(1), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(1), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(1), {STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(2), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(2), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(2), {STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(3), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(3), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(3), {STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(4), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(4), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(4), {STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(5), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(5), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(5), {STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(6), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(6), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(6), {STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {STATE_SAMPLER(7), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
+ {STATE_SAMPLER(7), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT},
+ {STATE_SAMPLER(7), {STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
+ {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE },
+};
+
+/* TODO:
+ * - This currently depends on GL fixed function functions to set things
+ * like light parameters. Ideally we'd use regular uniforms for that.
+ * - In part because of the previous point, much of this is modelled after
+ * GL fixed function, and has much of the same limitations. For example,
+ * D3D spot lights are slightly different from GL spot lights.
+ * - We can now implement drawing transformed vertices using the GLSL pipe,
+ * instead of using the immediate mode fallback.
+ * - Similarly, we don't need the fallback for certain combinations of
+ * material sources anymore.
+ * - Implement vertex blending and vertex tweening.
+ * - Handle WINED3D_TSS_TEXCOORD_INDEX in the shader, instead of duplicating
+ * attribute arrays in load_tex_coords().
+ * - Per-vertex point sizes. */
+const struct wined3d_vertex_pipe_ops glsl_vertex_pipe =
+{
+ glsl_vertex_pipe_vp_enable,
+ glsl_vertex_pipe_vp_get_caps,
+ glsl_vertex_pipe_vp_alloc,
+ glsl_vertex_pipe_vp_free,
+ glsl_vertex_pipe_vp_states,
+};
+
static void glsl_fragment_pipe_enable(const struct wined3d_gl_info *gl_info, BOOL enable)
{
/* Nothing to do. */
@@ -6437,12 +6958,6 @@ static void *glsl_fragment_pipe_alloc(const struct wined3d_shader_backend_ops *s
return NULL;
}
-struct glsl_ffp_destroy_ctx
-{
- struct shader_glsl_priv *priv;
- const struct wined3d_gl_info *gl_info;
-};
-
static void shader_glsl_free_ffp_fragment_shader(struct wine_rb_entry *entry, void *context)
{
struct glsl_ffp_fragment_shader *shader = WINE_RB_ENTRY_VALUE(entry,
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 05c49a5..eddff66 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -271,7 +271,7 @@ static void state_zfunc(struct wined3d_context *context, const struct wined3d_st
checkGLcall("glDepthFunc");
}
-static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
float col[4];
@@ -587,7 +587,7 @@ static void shaderconstant(struct wined3d_context *context, const struct wined3d
context->load_constants = 1;
}
-static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
DWORD enable = 0xffffffff;
@@ -654,7 +654,7 @@ static void state_clipping(struct wined3d_context *context, const struct wined3d
checkGLcall("clip plane disable");
}
-static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
/* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
@@ -950,7 +950,7 @@ static void state_stencilwrite(struct wined3d_context *context, const struct win
checkGLcall("glStencilMask");
}
-static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -1431,7 +1431,7 @@ static void state_normalize(struct wined3d_context *context, const struct wined3
}
}
-static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
union {
DWORD d;
@@ -1451,7 +1451,7 @@ static void state_psizemin_w(struct wined3d_context *context, const struct wined
}
-static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
union
@@ -1474,7 +1474,7 @@ static void state_psizemin_ext(struct wined3d_context *context, const struct win
checkGLcall("glPointParameterfEXT(...)");
}
-static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
union
@@ -1497,7 +1497,7 @@ static void state_psizemin_arb(struct wined3d_context *context, const struct win
checkGLcall("glPointParameterfARB(...)");
}
-static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
/* TODO: Group this with the viewport */
@@ -1672,7 +1672,7 @@ static void state_lastpixel(struct wined3d_context *context, const struct wined3
}
}
-static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
static BOOL warned;
@@ -1685,7 +1685,7 @@ static void state_pointsprite_w(struct wined3d_context *context, const struct wi
}
}
-static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -3295,7 +3295,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st
}
}
-static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
const struct wined3d_device *device = context->swapchain->device;
@@ -3599,7 +3599,7 @@ static void tex_bumpenvlscale(struct wined3d_context *context, const struct wine
context->load_constants = 1;
}
-static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const DWORD sampler = state_id - STATE_SAMPLER(0);
const struct wined3d_texture *texture = state->textures[sampler];
@@ -3763,7 +3763,7 @@ static void shader_bumpenvmat(struct wined3d_context *context, const struct wine
context->load_constants = 1;
}
-static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -3791,7 +3791,7 @@ static void transform_world(struct wined3d_context *context, const struct wined3
}
}
-static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
UINT index = state_id - STATE_CLIPPLANE(0);
@@ -3919,7 +3919,7 @@ static void state_vertexblend(struct wined3d_context *context, const struct wine
}
}
-static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_light_info *light = NULL;
@@ -3978,7 +3978,7 @@ static void transform_view(struct wined3d_context *context, const struct wined3d
}
}
-static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -4536,7 +4536,7 @@ static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d
streamsrc(context, state, STATE_STREAMSRC);
}
-static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_device *device = context->swapchain->device;
const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -4698,10 +4698,13 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
vp.width, vp.height);
}
+ if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
+ state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
+
checkGLcall("glViewport");
}
-static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
@@ -4711,7 +4714,7 @@ static void viewport_vertexpart(struct wined3d_context *context, const struct wi
context->load_constants = 1;
}
-static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
UINT Index = state_id - STATE_ACTIVELIGHT(0);
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 004ee00..59b91ec 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3521,6 +3521,102 @@ const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
ffp_frag_program_key_compare,
};
+void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
+ struct wined3d_ffp_vs_settings *settings)
+{
+ unsigned int coord_idx, i;
+
+ if (si->position_transformed)
+ {
+ memset(settings, 0, sizeof(*settings));
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
+ else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+ else
+ settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
+
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1 << i;
+ settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK;
+ }
+ return;
+ }
+
+ settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
+ settings->normalize = settings->normal && state->render_states[WINED3D_RS_NORMALIZENORMALS];
+ settings->lighting = !!state->render_states[WINED3D_RS_LIGHTING];
+ settings->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER];
+
+ if (state->render_states[WINED3D_RS_COLORVERTEX] && (si->use_map & (1 << WINED3D_FFP_DIFFUSE)))
+ {
+ settings->diffuse_source = state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE];
+ settings->emission_source = state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE];
+ settings->ambient_source = state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE];
+ settings->specular_source = state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE];
+ }
+ else
+ {
+ settings->diffuse_source = WINED3D_MCS_MATERIAL;
+ settings->emission_source = WINED3D_MCS_MATERIAL;
+ settings->ambient_source = WINED3D_MCS_MATERIAL;
+ settings->specular_source = WINED3D_MCS_MATERIAL;
+ }
+
+ settings->texcoords = 0;
+ for (i = 0; i < MAX_TEXTURES; ++i)
+ {
+ coord_idx = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
+ if (coord_idx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coord_idx))))
+ settings->texcoords |= 1 << i;
+ settings->texgen[i] = (state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX] >> WINED3D_FFP_TCI_SHIFT)
+ & WINED3D_FFP_TCI_MASK;
+ }
+
+ settings->light_type = 0;
+ for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i)
+ {
+ if (state->lights[i])
+ settings->light_type |= (state->lights[i]->OriginalParms.type
+ & WINED3D_FFP_LIGHT_TYPE_MASK) << WINED3D_FFP_LIGHT_TYPE_SHIFT(i);
+ }
+
+ if (!state->render_states[WINED3D_RS_FOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
+ else if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+ else if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE)
+ settings->fog_mode = WINED3D_FFP_VS_FOG_FOGCOORD;
+ else if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
+ settings->fog_mode = WINED3D_FFP_VS_FOG_RANGE;
+ else
+ settings->fog_mode = WINED3D_FFP_VS_FOG_DEPTH;
+
+ settings->padding = 0;
+}
+
+static int wined3d_ffp_vertex_program_key_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const struct wined3d_ffp_vs_settings *ka = key;
+ const struct wined3d_ffp_vs_settings *kb = &WINE_RB_ENTRY_VALUE(entry,
+ const struct wined3d_ffp_vs_desc, entry)->settings;
+
+ return memcmp(ka, kb, sizeof(*ka));
+}
+
+const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions =
+{
+ wined3d_rb_alloc,
+ wined3d_rb_realloc,
+ wined3d_rb_free,
+ wined3d_ffp_vertex_program_key_compare,
+};
+
UINT wined3d_log2i(UINT32 x)
{
static const UINT l[] =
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8d6f845..5cbd63a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1214,6 +1214,7 @@ extern const struct fragment_pipeline glsl_fragment_pipe DECLSPEC_HIDDEN;
extern const struct wined3d_vertex_pipe_ops none_vertex_pipe DECLSPEC_HIDDEN;
extern const struct wined3d_vertex_pipe_ops ffp_vertex_pipe DECLSPEC_HIDDEN;
+extern const struct wined3d_vertex_pipe_ops glsl_vertex_pipe DECLSPEC_HIDDEN;
/* "Base" state table */
HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
@@ -1680,6 +1681,7 @@ struct ffp_frag_desc
};
extern const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions DECLSPEC_HIDDEN;
+extern const struct wine_rb_functions wined3d_ffp_vertex_program_rb_functions DECLSPEC_HIDDEN;
extern const struct wined3d_parent_ops wined3d_null_parent_ops DECLSPEC_HIDDEN;
void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d_state *state,
@@ -1689,6 +1691,48 @@ const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *frag
void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc) DECLSPEC_HIDDEN;
void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect) DECLSPEC_HIDDEN;
+enum wined3d_ffp_vs_fog_mode
+{
+ WINED3D_FFP_VS_FOG_OFF = 0,
+ WINED3D_FFP_VS_FOG_FOGCOORD = 1,
+ WINED3D_FFP_VS_FOG_DEPTH = 2,
+ WINED3D_FFP_VS_FOG_RANGE = 3,
+};
+
+#define WINED3D_FFP_TCI_SHIFT 16
+#define WINED3D_FFP_TCI_MASK 0xff
+
+#define WINED3D_FFP_LIGHT_TYPE_SHIFT(idx) (3 * (idx))
+#define WINED3D_FFP_LIGHT_TYPE_MASK 0x7
+
+struct wined3d_ffp_vs_settings
+{
+ DWORD light_type : 24; /* MAX_ACTIVE_LIGHTS, 8 * 3 */
+ DWORD diffuse_source : 2;
+ DWORD emission_source : 2;
+ DWORD ambient_source : 2;
+ DWORD specular_source : 2;
+
+ DWORD normal : 1;
+ DWORD normalize : 1;
+ DWORD lighting : 1;
+ DWORD localviewer : 1;
+ DWORD fog_mode : 2;
+ DWORD texcoords : 8; /* MAX_TEXTURES */
+ DWORD padding : 18;
+
+ BYTE texgen[MAX_TEXTURES];
+};
+
+struct wined3d_ffp_vs_desc
+{
+ struct wine_rb_entry entry;
+ struct wined3d_ffp_vs_settings settings;
+};
+
+void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
+ struct wined3d_ffp_vs_settings *settings) DECLSPEC_HIDDEN;
+
struct wined3d
{
LONG ref;
@@ -2567,6 +2611,45 @@ void state_fog_fragpart(struct wined3d_context *context,
void state_srgbwrite(struct wined3d_context *context,
const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void sampler_texmatrix(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_specularenable(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_world(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_view(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_projection(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void transform_texture(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_ambient(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void viewport_vertexpart(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_clipping(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void light(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_fog_vertexpart(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void vertexdeclaration(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void clipplane(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_w(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_ext(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_psizemin_arb(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pointsprite_w(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pointsprite(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+void state_pscale(struct wined3d_context *context,
+ const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN;
+
BOOL getColorBits(const struct wined3d_format *format,
BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize) DECLSPEC_HIDDEN;
BOOL getDepthStencilBits(const struct wined3d_format *format,
--
1.8.1.5
More information about the wine-patches
mailing list