wined3d: Create stub FFP vertex shaders.

This commit is contained in:
Elizabeth Figura 2024-09-23 18:50:26 -05:00 committed by Alexandre Julliard
parent 484c6f9af1
commit 04450b6e07
Notes: Alexandre Julliard 2024-11-19 23:22:30 +01:00
Approved-by: Jan Sikorski (@jsikorski)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6813
6 changed files with 142 additions and 5 deletions

View file

@ -1667,6 +1667,14 @@ static void device_free_depth_stencil_state(struct wine_rb_entry *entry, void *c
wined3d_depth_stencil_state_decref(state);
}
static void device_free_ffp_vertex_shader(struct wine_rb_entry *entry, void *context)
{
struct wined3d_ffp_vs *vs = WINE_RB_ENTRY_VALUE(entry, struct wined3d_ffp_vs, entry);
wined3d_shader_decref(vs->shader);
free(vs);
}
static void device_free_ffp_pixel_shader(struct wine_rb_entry *entry, void *context)
{
struct wined3d_ffp_ps *ps = WINE_RB_ENTRY_VALUE(entry, struct wined3d_ffp_ps, entry);
@ -1722,6 +1730,7 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
wine_rb_destroy(&device->rasterizer_states, device_free_rasterizer_state, NULL);
wine_rb_destroy(&device->blend_states, device_free_blend_state, NULL);
wine_rb_destroy(&device->depth_stencil_states, device_free_depth_stencil_state, NULL);
wine_rb_destroy(&device->ffp_vertex_shaders, device_free_ffp_vertex_shader, NULL);
wine_rb_destroy(&device->ffp_pixel_shaders, device_free_ffp_pixel_shader, NULL);
LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
@ -5524,6 +5533,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
wine_rb_init(&device->rasterizer_states, wined3d_rasterizer_state_compare);
wine_rb_init(&device->blend_states, wined3d_blend_state_compare);
wine_rb_init(&device->depth_stencil_states, wined3d_depth_stencil_state_compare);
wine_rb_init(&device->ffp_vertex_shaders, wined3d_ffp_vertex_program_key_compare);
wine_rb_init(&device->ffp_pixel_shaders, wined3d_ffp_frag_program_key_compare);
if (vertex_pipeline->vp_states && fragment_pipeline->states
@ -5537,6 +5547,7 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
wine_rb_destroy(&device->blend_states, NULL, NULL);
wine_rb_destroy(&device->depth_stencil_states, NULL, NULL);
wine_rb_destroy(&device->so_descs, NULL, NULL);
wine_rb_destroy(&device->ffp_vertex_shaders, NULL, NULL);
wine_rb_destroy(&device->ffp_pixel_shaders, NULL, NULL);
wined3d_decref(device->wined3d);
return hr;
@ -5565,6 +5576,7 @@ err:
wine_rb_destroy(&device->blend_states, NULL, NULL);
wine_rb_destroy(&device->depth_stencil_states, NULL, NULL);
wine_rb_destroy(&device->so_descs, NULL, NULL);
wine_rb_destroy(&device->ffp_vertex_shaders, NULL, NULL);
wine_rb_destroy(&device->ffp_pixel_shaders, NULL, NULL);
wined3d_decref(device->wined3d);
return hr;

View file

@ -23,6 +23,13 @@
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)
{
FIXME("Not yet implemented.\n");
return false;
}
static bool ffp_hlsl_generate_pixel_shader(const struct ffp_frag_settings *settings,
struct wined3d_string_buffer *string)
{
@ -70,6 +77,32 @@ static bool compile_hlsl_shader(const struct wined3d_string_buffer *hlsl,
return true;
}
bool ffp_hlsl_compile_vs(const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader_desc *shader_desc)
{
struct wined3d_string_buffer string;
struct vkd3d_shader_code sm1;
if (!string_buffer_init(&string))
return false;
if (!ffp_hlsl_generate_vertex_shader(settings, &string))
{
string_buffer_free(&string);
return false;
}
if (!compile_hlsl_shader(&string, &sm1, "vs_2_0"))
{
string_buffer_free(&string);
return false;
}
string_buffer_free(&string);
shader_desc->byte_code = sm1.code;
shader_desc->byte_code_size = ~(size_t)0;
return true;
}
bool ffp_hlsl_compile_ps(const struct ffp_frag_settings *settings, struct wined3d_shader_desc *shader_desc)
{
struct wined3d_string_buffer string;

View file

@ -2436,7 +2436,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const struct w
WARN("Wrong shader type %s.\n", debug_shader_type(reg_maps->shader_version.type));
return WINED3DERR_INVALIDCALL;
}
if (!shader->is_ffp_ps
if (!shader->is_ffp_vs && !shader->is_ffp_ps
&& version->major > shader_max_version_from_feature_level(shader->device->cs->c.state->feature_level))
{
WARN("Shader version %u not supported by this device.\n", version->major);
@ -2550,6 +2550,18 @@ static void wined3d_shader_init_object(void *object)
list_add_head(&device->shaders, &shader->shader_list_entry);
if (shader->is_ffp_vs)
{
struct wined3d_ffp_vs_settings *settings = shader->byte_code;
struct wined3d_shader_desc desc;
if (!ffp_hlsl_compile_vs(settings, &desc))
return;
free(settings);
shader_set_function(shader, &desc, WINED3D_SHADER_TYPE_VERTEX, NULL,
device->adapter->d3d_info.limits.vs_uniform_count);
}
if (shader->is_ffp_ps)
{
struct ffp_frag_settings *settings = shader->byte_code;
@ -3327,6 +3339,31 @@ HRESULT CDECL wined3d_shader_create_vs(struct wined3d_device *device, const stru
return WINED3D_OK;
}
HRESULT wined3d_shader_create_ffp_vs(struct wined3d_device *device,
const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader **shader)
{
struct wined3d_shader *object;
if (!(object = calloc(1, sizeof(*object))))
return E_OUTOFMEMORY;
shader_init(object, device, NULL, &wined3d_null_parent_ops);
object->is_ffp_vs = true;
if (!(object->byte_code = malloc(sizeof(*settings))))
{
free(object);
return E_OUTOFMEMORY;
}
memcpy(object->byte_code, settings, sizeof(*settings));
wined3d_cs_init_object(device->cs, wined3d_shader_init_object, object);
TRACE("Created FFP vertex shader %p.\n", object);
*shader = object;
return WINED3D_OK;
}
HRESULT wined3d_shader_create_ffp_ps(struct wined3d_device *device,
const struct ffp_frag_settings *settings, struct wined3d_shader **shader)
{

View file

@ -1299,6 +1299,7 @@ void CDECL wined3d_stateblock_set_vertex_shader(struct wined3d_stateblock *state
wined3d_shader_decref(stateblock->stateblock_state.vs);
stateblock->stateblock_state.vs = shader;
stateblock->changed.vertexShader = TRUE;
stateblock->changed.ffp_vs_settings = 1;
}
static void wined3d_bitmap_set_bits(uint32_t *bitmap, unsigned int start, unsigned int count)
@ -2393,6 +2394,7 @@ static void wined3d_stateblock_invalidate_initial_states(struct wined3d_stateblo
memset(stateblock->changed.transform, 0xff, sizeof(stateblock->changed.transform));
stateblock->changed.modelview_matrices = 1;
stateblock->changed.point_scale = 1;
stateblock->changed.ffp_vs_settings = 1;
stateblock->changed.ffp_ps_settings = 1;
}
@ -2911,6 +2913,40 @@ void CDECL wined3d_stateblock_apply_clear_state(struct wined3d_stateblock *state
wined3d_device_set_render_state(device, WINED3D_RS_SRGBWRITEENABLE, state->rs[WINED3D_RS_SRGBWRITEENABLE]);
}
static struct wined3d_shader *get_ffp_vertex_shader(struct wined3d_device *device, const struct wined3d_state *state)
{
static const struct wined3d_stream_info dummy_stream_info;
struct wined3d_ffp_vs_settings settings;
const struct wine_rb_entry *entry;
struct wined3d_ffp_vs *vs;
/* XXX: wined3d_ffp_get_vs_settings() only needs the stream info for the
* swizzle map, which the HLSL pipeline doesn't use (it will be computed and
* used later as part of struct vs_compile_args).
*
* This is nevertheless janky, and we'd like to get rid of it. Eventually
* once the HLSL backend is used everywhere, we can get rid of the swizzle
* map from wined3d_ffp_vs_settings. */
wined3d_ffp_get_vs_settings(state, &dummy_stream_info, &device->adapter->d3d_info, &settings);
if ((entry = wine_rb_get(&device->ffp_vertex_shaders, &settings)))
return WINE_RB_ENTRY_VALUE(entry, struct wined3d_ffp_vs, entry.entry)->shader;
if (!(vs = malloc(sizeof(*vs))))
return NULL;
vs->entry.settings = settings;
if (FAILED(wined3d_shader_create_ffp_vs(device, &settings, &vs->shader)))
{
free(vs);
return NULL;
}
if (wine_rb_put(&device->ffp_vertex_shaders, &vs->entry.settings, &vs->entry.entry) == -1)
ERR("Failed to insert FFP vertex shader.\n");
return vs->shader;
}
static struct wined3d_shader *get_ffp_pixel_shader(struct wined3d_device *device, const struct wined3d_state *state)
{
struct ffp_frag_settings settings;
@ -3779,10 +3815,19 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
* those structs and left only in vs_compile_args / ps_compile_args. */
if (changed->ffp_vs_settings && !state->vs)
{
if (device->adapter->d3d_info.ffp_hlsl)
{
struct wined3d_shader *shader = get_ffp_vertex_shader(device, device->cs->c.state);
wined3d_device_context_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, shader);
}
else
{
/* Force invalidation of the vertex shader. */
wined3d_device_context_emit_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, NULL);
}
}
if (changed->ffp_ps_settings && !state->ps)
{

View file

@ -6448,7 +6448,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct
memset(settings, 0, sizeof(*settings));
if (si->position_transformed)
if (vdecl->position_transformed)
{
settings->transformed = 1;
settings->point_size = state->primitive_type == WINED3D_PT_POINTLIST;

View file

@ -2731,6 +2731,12 @@ struct wined3d_ffp_vs_desc
struct wined3d_ffp_vs_settings settings;
};
struct wined3d_ffp_vs
{
struct wined3d_ffp_vs_desc entry;
struct wined3d_shader *shader;
};
void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct wined3d_stream_info *si,
const struct wined3d_d3d_info *d3d_info, struct wined3d_ffp_vs_settings *settings);
@ -2990,7 +2996,7 @@ struct wined3d_device
struct list shaders; /* a linked list to track shaders (pixel and vertex) */
struct wine_rb_tree so_descs;
struct wine_rb_tree samplers, rasterizer_states, blend_states, depth_stencil_states;
struct wine_rb_tree ffp_pixel_shaders;
struct wine_rb_tree ffp_vertex_shaders, ffp_pixel_shaders;
/* Render Target Support */
struct wined3d_rendertarget_view *auto_depth_stencil_view;
@ -4215,6 +4221,7 @@ struct wined3d_shader
void *byte_code;
unsigned int byte_code_size;
bool load_local_constsF;
bool is_ffp_vs;
bool is_ffp_ps;
enum vkd3d_shader_source_type source_type;
const struct wined3d_shader_frontend *frontend;
@ -4253,6 +4260,8 @@ struct wined3d_shader
} u;
};
HRESULT wined3d_shader_create_ffp_vs(struct wined3d_device *device,
const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader **shader);
HRESULT wined3d_shader_create_ffp_ps(struct wined3d_device *device,
const struct ffp_frag_settings *settings, struct wined3d_shader **shader);
@ -4285,6 +4294,7 @@ BOOL shader_match_semantic(const char *semantic_name, enum wined3d_decl_usage us
enum vkd3d_shader_visibility vkd3d_shader_visibility_from_wined3d(enum wined3d_shader_type shader_type);
bool ffp_hlsl_compile_vs(const struct wined3d_ffp_vs_settings *settings, struct wined3d_shader_desc *shader_desc);
bool ffp_hlsl_compile_ps(const struct ffp_frag_settings *settings, struct wined3d_shader_desc *shader_desc);
static inline BOOL shader_is_scalar(const struct wined3d_shader_register *reg)