From a50dd3392b878524bd0e29e33bb336dfea3ae3d4 Mon Sep 17 00:00:00 2001 From: Elizabeth Figura Date: Sun, 9 Jun 2024 12:50:29 -0500 Subject: [PATCH] wined3d: Beginnings of an HLSL FFP vertex shader implementation. --- dlls/wined3d/ffp_hlsl.c | 122 ++++++++++++++++++++++++++++++++- dlls/wined3d/wined3d_private.h | 5 +- 2 files changed, 123 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/ffp_hlsl.c b/dlls/wined3d/ffp_hlsl.c index 8451be71e82..959ecd4195a 100644 --- a/dlls/wined3d/ffp_hlsl.c +++ b/dlls/wined3d/ffp_hlsl.c @@ -1,6 +1,10 @@ /* * Fixed-function pipeline replacement implemented using HLSL shaders * + * Copyright 2006 Jason Green + * Copyright 2006-2007 Henri Verbeet + * Copyright 2007-2009,2013 Stefan Dösinger for CodeWeavers + * Copyright 2009-2011 Henri Verbeet for CodeWeavers * Copyright 2022,2024 Elizabeth Figura for CodeWeavers * * This library is free software; you can redistribute it and/or @@ -24,10 +28,122 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader); static bool ffp_hlsl_generate_vertex_shader(const struct wined3d_ffp_vs_settings *settings, - struct wined3d_string_buffer *string) + struct wined3d_string_buffer *buffer) { - FIXME("Not yet implemented.\n"); - return false; + if (settings->lighting) + FIXME("Ignoring lighting.\n"); + + if (settings->point_size) + FIXME("Ignoring point size.\n"); + + if (settings->transformed) + FIXME("Ignoring pretransformed vertices.\n"); + + if (settings->vertexblends) + FIXME("Ignoring vertex blend.\n"); + + if (settings->normal) + FIXME("Ignoring normals.\n"); + + if (settings->fog_mode != WINED3D_FFP_VS_FOG_OFF) + FIXME("Ignoring fog.\n"); + + /* This must be kept in sync with struct wined3d_ffp_vs_constants. */ + shader_addline(buffer, "uniform struct\n"); + shader_addline(buffer, "{\n"); + shader_addline(buffer, " float4x4 modelview_matrices[%u];\n", MAX_VERTEX_BLENDS); + shader_addline(buffer, " float4x4 projection_matrix;\n"); + shader_addline(buffer, " float4x4 texture_matrices[%u];\n", WINED3D_MAX_FFP_TEXTURES); + shader_addline(buffer, " float4 point_params;\n"); + shader_addline(buffer, " struct\n"); + shader_addline(buffer, " {\n"); + shader_addline(buffer, " float4 diffuse;\n"); + shader_addline(buffer, " float4 ambient;\n"); + shader_addline(buffer, " float4 specular;\n"); + shader_addline(buffer, " float4 emissive;\n"); + shader_addline(buffer, " float power;\n"); + shader_addline(buffer, " } material;\n"); + shader_addline(buffer, " float4 ambient_colour;\n"); + shader_addline(buffer, " struct\n"); + shader_addline(buffer, " {\n"); + shader_addline(buffer, " float4 diffuse, specular, ambient;\n"); + shader_addline(buffer, " float4 position, direction;\n"); + shader_addline(buffer, " float4 packed_params;\n"); + shader_addline(buffer, " float4 attenuation;\n"); + shader_addline(buffer, " } lights[%u];\n", WINED3D_MAX_ACTIVE_LIGHTS); + shader_addline(buffer, "} c;\n"); + + shader_addline(buffer, "struct input\n"); + shader_addline(buffer, "{\n"); + shader_addline(buffer, " float4 pos : POSITION;\n"); + shader_addline(buffer, " float4 blend_weight : BLENDWEIGHT;\n"); + shader_addline(buffer, " uint blend_indices : BLENDINDICES;\n"); + shader_addline(buffer, " float3 normal : NORMAL;\n"); + shader_addline(buffer, " float point_size : PSIZE;\n"); + shader_addline(buffer, " float4 diffuse : COLOR0;\n"); + shader_addline(buffer, " float4 specular : COLOR1;\n"); + shader_addline(buffer, " float4 texcoord[%u] : TEXCOORD;\n", WINED3D_MAX_FFP_TEXTURES); + shader_addline(buffer, "};\n\n"); + + shader_addline(buffer, "struct output\n"); + shader_addline(buffer, "{\n"); + shader_addline(buffer, " float4 pos : POSITION;\n"); + shader_addline(buffer, " float4 diffuse : COLOR0;\n"); + shader_addline(buffer, " float4 specular : COLOR1;\n"); + for (unsigned int i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) + { + if (((settings->texgen[i] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU) || (settings->texcoords & (1u << i))) + shader_addline(buffer, " float4 texcoord%u : TEXCOORD%u;\n", i, i); + } + shader_addline(buffer, "};\n\n"); + + shader_addline(buffer, "void main(in struct input i, out struct output o)\n"); + shader_addline(buffer, "{\n"); + shader_addline(buffer, " float4 ec_pos = 0.0;\n\n"); + + shader_addline(buffer, " ec_pos += mul(c.modelview_matrices[0], float4(i.pos.xyz, 1.0));\n\n"); + + shader_addline(buffer, " o.pos = mul(c.projection_matrix, ec_pos);\n"); + shader_addline(buffer, " ec_pos /= ec_pos.w;\n\n"); + + /* No lighting. */ + if (settings->diffuse) + shader_addline(buffer, " o.diffuse = i.diffuse;\n"); + else + shader_addline(buffer, " o.diffuse = 1.0;\n"); + shader_addline(buffer, " o.specular = i.specular;\n\n"); + + for (unsigned int i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) + { + switch (settings->texgen[i] & 0xffff0000) + { + case WINED3DTSS_TCI_PASSTHRU: + if (settings->texcoords & (1u << i)) + shader_addline(buffer, " o.texcoord%u = mul(c.texture_matrices[%u], i.texcoord[%u]);\n", + i, i, settings->texgen[i] & 0x0000ffff); + else + continue; + break; + + default: + FIXME("Unhandled texgen %#x.\n", settings->texgen[i]); + break; + } + } + + switch (settings->fog_mode) + { + case WINED3D_FFP_VS_FOG_OFF: + break; + + default: + FIXME("Unhandled fog mode %#x.\n", settings->fog_mode); + break; + } + + shader_addline(buffer, "}\n"); + + return true; } static bool ffp_hlsl_generate_pixel_shader(const struct ffp_frag_settings *settings, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 12b61b68bbb..2e0a541cea5 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2050,10 +2050,11 @@ void context_state_fb(struct wined3d_context *context, struct wined3d_light_constants { + /* Padding is needed for the HLSL backend. */ struct wined3d_color diffuse, specular, ambient; struct wined3d_vec4 position, direction; float range, falloff, cos_half_theta, cos_half_phi; - float const_att, linear_att, quad_att; + float const_att, linear_att, quad_att, padding; }; /***************************************************************************** @@ -2783,8 +2784,10 @@ struct wined3d_ffp_vs_constants struct wined3d_ffp_point_constants { float scale_const, scale_linear, scale_quad; + float padding; /* For the HLSL backend. */ } point; struct wined3d_material material; + float padding[3]; /* For the HLSL backend. */ struct wined3d_ffp_light_constants { struct wined3d_color ambient;