wined3d: Add support for GLSL based fixed function vertex shaders.

This commit is contained in:
Henri Verbeet 2013-05-29 09:45:35 +02:00 committed by Alexandre Julliard
parent 5137fa71ed
commit 2014141a25
5 changed files with 738 additions and 33 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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[] =

View File

@ -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,