Commit 2014141a authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

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

parent 5137fa71
......@@ -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);
......
......@@ -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);
......
......@@ -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[] =
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment