This is another step towards getting render states out of wined3d_state.
The idea here is similar to the "push constant buffers" used for d3d8/9 flat constants, and reuses the same infrastructure. That is, we pack all of the constants directly into a wined3d_buffer which is bound directly to the wined3d_state as a normal constant buffer. For SPIR-V this buffer is placed in the GPU, and the shader can simply access it directly, with no renderer-specific changes needed other than to determine the buffer's location.
Currently this buffer is still stored on the CPU for GLSL, and the contents are pulled back from the sysmem resource pointer, instead of being pulled from state->render_states.
Eventually, at least for Vulkan, the idea will be to write a FFP replacement shader which takes structured data (which, given the constraints of SPIR-V, is broadly necessary; we cannot simply upload individual named uniforms as we can with GLSL). In fact this will take the form of an HLSL shader compiled to Shader Model 2 bytecode. This allows us to, once again, reuse pretty much all of the existing infrastructure and avoid writing more backend-specific code, and has the effect that this FFP replacement works not only with SPIR-V but also with GLSL, allowing us to eventually remove the existing GLSL FFP pipeline, and enabling me to develop the HLSL FFP pipeline mainly using the GL renderer [which is useful since the Vulkan renderer is still missing a few other features].
The full branch is available at [1], and passes all tests when using the GL renderer.
From: Elizabeth Figura zfigura@codeweavers.com
So that wined3d_device_process_vertices() can just read the stateblock directly. --- dlls/wined3d/stateblock.c | 114 ++++++++++++++++----------------- dlls/wined3d/wined3d_private.h | 2 - 2 files changed, 57 insertions(+), 59 deletions(-)
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 6c44733c8bb..217ebda743f 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -655,7 +655,7 @@ static void set_light_changed(struct wined3d_stateblock *stateblock, struct wine stateblock->changed.lights = 1; }
-HRESULT wined3d_light_state_set_light(struct wined3d_light_state *state, DWORD light_idx, +static HRESULT wined3d_light_state_set_light(struct wined3d_light_state *state, unsigned int light_idx, const struct wined3d_light *params, struct wined3d_light_info **light_info) { struct wined3d_light_info *object; @@ -676,6 +676,62 @@ HRESULT wined3d_light_state_set_light(struct wined3d_light_state *state, DWORD l
object->OriginalParms = *params;
+ /* Initialize the object. */ + TRACE("Light %u setting to type %#x, diffuse %s, specular %s, ambient %s, " + "position {%.8e, %.8e, %.8e}, direction {%.8e, %.8e, %.8e}, " + "range %.8e, falloff %.8e, theta %.8e, phi %.8e.\n", + light_idx, params->type, debug_color(¶ms->diffuse), + debug_color(¶ms->specular), debug_color(¶ms->ambient), + params->position.x, params->position.y, params->position.z, + params->direction.x, params->direction.y, params->direction.z, + params->range, params->falloff, params->theta, params->phi); + + switch (params->type) + { + case WINED3D_LIGHT_POINT: + /* Position */ + object->position.x = params->position.x; + object->position.y = params->position.y; + object->position.z = params->position.z; + object->position.w = 1.0f; + /* FIXME: Range */ + break; + + case WINED3D_LIGHT_DIRECTIONAL: + /* Direction */ + object->direction.x = -params->direction.x; + object->direction.y = -params->direction.y; + object->direction.z = -params->direction.z; + object->direction.w = 0.0f; + break; + + case WINED3D_LIGHT_SPOT: + /* Position */ + object->position.x = params->position.x; + object->position.y = params->position.y; + object->position.z = params->position.z; + object->position.w = 1.0f; + + /* Direction */ + object->direction.x = params->direction.x; + object->direction.y = params->direction.y; + object->direction.z = params->direction.z; + object->direction.w = 0.0f; + + /* FIXME: Range */ + break; + + case WINED3D_LIGHT_PARALLELPOINT: + object->position.x = params->position.x; + object->position.y = params->position.y; + object->position.z = params->position.z; + object->position.w = 1.0f; + break; + + default: + FIXME("Unrecognized params type %#x.\n", params->type); + } + *light_info = object; return WINED3D_OK; } @@ -2329,62 +2385,6 @@ static void wined3d_device_context_set_light(struct wined3d_device_context *cont if (FAILED(wined3d_light_state_set_light(&context->state->light_state, light_idx, light, &object))) return;
- /* Initialize the object. */ - TRACE("Light %u setting to type %#x, diffuse %s, specular %s, ambient %s, " - "position {%.8e, %.8e, %.8e}, direction {%.8e, %.8e, %.8e}, " - "range %.8e, falloff %.8e, theta %.8e, phi %.8e.\n", - light_idx, light->type, debug_color(&light->diffuse), - debug_color(&light->specular), debug_color(&light->ambient), - light->position.x, light->position.y, light->position.z, - light->direction.x, light->direction.y, light->direction.z, - light->range, light->falloff, light->theta, light->phi); - - switch (light->type) - { - case WINED3D_LIGHT_POINT: - /* Position */ - object->position.x = light->position.x; - object->position.y = light->position.y; - object->position.z = light->position.z; - object->position.w = 1.0f; - /* FIXME: Range */ - break; - - case WINED3D_LIGHT_DIRECTIONAL: - /* Direction */ - object->direction.x = -light->direction.x; - object->direction.y = -light->direction.y; - object->direction.z = -light->direction.z; - object->direction.w = 0.0f; - break; - - case WINED3D_LIGHT_SPOT: - /* Position */ - object->position.x = light->position.x; - object->position.y = light->position.y; - object->position.z = light->position.z; - object->position.w = 1.0f; - - /* Direction */ - object->direction.x = light->direction.x; - object->direction.y = light->direction.y; - object->direction.z = light->direction.z; - object->direction.w = 0.0f; - - /* FIXME: Range */ - break; - - case WINED3D_LIGHT_PARALLELPOINT: - object->position.x = light->position.x; - object->position.y = light->position.y; - object->position.z = light->position.z; - object->position.w = 1.0f; - break; - - default: - FIXME("Unrecognized light type %#x.\n", light->type); - } - wined3d_device_context_emit_set_light(context, object); }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f49a604422d..8c36a033f6e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3503,8 +3503,6 @@ bool wined3d_light_state_enable_light(struct wined3d_light_state *state, const s struct wined3d_light_info *light_info, BOOL enable); struct wined3d_light_info *wined3d_light_state_get_light(const struct wined3d_light_state *state, unsigned int idx); -HRESULT wined3d_light_state_set_light(struct wined3d_light_state *state, DWORD light_idx, - const struct wined3d_light *params, struct wined3d_light_info **light_info);
enum wined3d_cs_queue_id {
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3d8/device.c | 3 +-- dlls/d3d9/device.c | 3 +-- dlls/ddraw/executebuffer.c | 5 ++--- dlls/ddraw/vertexbuffer.c | 3 +-- dlls/wined3d/device.c | 4 +++- dlls/wined3d/wined3d.spec | 2 +- include/wine/wined3d.h | 2 +- 7 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c index 401677e8261..e9cdfa9b4ff 100644 --- a/dlls/d3d8/device.c +++ b/dlls/d3d8/device.c @@ -2798,8 +2798,7 @@ static HRESULT WINAPI d3d8_device_ProcessVertices(IDirect3DDevice8 *iface, UINT ERR("Failed to set stream source.\n"); }
- wined3d_device_apply_stateblock(device->wined3d_device, device->state); - hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, + hr = wined3d_device_process_vertices(device->wined3d_device, device->state, src_start_idx, dst_idx, vertex_count, dst->wined3d_buffer, NULL, flags, dst->fvf);
map = device->sysmem_vb; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index c3cecc4e27f..408dace48ad 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -3391,8 +3391,7 @@ static HRESULT WINAPI d3d9_device_ProcessVertices(IDirect3DDevice9Ex *iface, ERR("Failed to set stream source.\n"); }
- wined3d_device_apply_stateblock(device->wined3d_device, device->state); - hr = wined3d_device_process_vertices(device->wined3d_device, src_start_idx, dst_idx, vertex_count, + hr = wined3d_device_process_vertices(device->wined3d_device, device->state, src_start_idx, dst_idx, vertex_count, dst_impl->wined3d_buffer, decl_impl ? decl_impl->wined3d_declaration : NULL, flags, dst_impl->fvf);
diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 0cf0bf121f3..b0d60c6fb65 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -311,10 +311,9 @@ HRESULT d3d_execute_buffer_execute(struct d3d_execute_buffer *buffer, struct d3d wined3d_stateblock_set_vertex_declaration(device->state, ddraw_find_decl(device->ddraw, op == D3DPROCESSVERTICES_TRANSFORMLIGHT ? D3DFVF_VERTEX : D3DFVF_LVERTEX)); - wined3d_device_apply_stateblock(device->wined3d_device, device->state); d3d_device_sync_surfaces(device); - wined3d_device_process_vertices(device->wined3d_device, ci->wStart, ci->wDest, - ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX); + wined3d_device_process_vertices(device->wined3d_device, device->state, ci->wStart, + ci->wDest, ci->dwCount, buffer->dst_vertex_buffer, NULL, 0, D3DFVF_TLVERTEX); break;
case D3DPROCESSVERTICES_COPY: diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index c02d7e6e354..ccfa0c2e752 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -304,8 +304,7 @@ static HRESULT WINAPI d3d_vertex_buffer7_ProcessVertices(IDirect3DVertexBuffer7 wined3d_stateblock_set_stream_source(device_impl->state, 0, src_buffer_impl->wined3d_buffer, 0, get_flexible_vertex_size(src_buffer_impl->fvf)); wined3d_stateblock_set_vertex_declaration(device_impl->state, src_buffer_impl->wined3d_declaration); - wined3d_device_apply_stateblock(device_impl->wined3d_device, device_impl->state); - hr = wined3d_device_process_vertices(device_impl->wined3d_device, src_idx, dst_idx, + hr = wined3d_device_process_vertices(device_impl->wined3d_device, device_impl->state, src_idx, dst_idx, count, dst_buffer_impl->wined3d_buffer, NULL, flags, dst_buffer_impl->fvf);
/* Restore the states if needed */ diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c0648f2aace..5cfd4040d8e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3610,7 +3610,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO } #undef copy_and_next
-HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, +HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, struct wined3d_stateblock *stateblock, UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer, const struct wined3d_vertex_declaration *declaration, uint32_t flags, uint32_t dst_fvf) { @@ -3631,6 +3631,8 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, if (declaration) FIXME("Output vertex declaration not implemented yet.\n");
+ wined3d_device_apply_stateblock(device, stateblock); + vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; wined3d_stream_info_from_declaration(&stream_info, state, &device->adapter->d3d_info); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index fee5ed0dd7a..3bfe6d2b200 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -73,7 +73,7 @@ @ cdecl wined3d_device_get_swapchain_count(ptr) @ cdecl wined3d_device_get_wined3d(ptr) @ cdecl wined3d_device_incref(ptr) -@ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long) +@ cdecl wined3d_device_process_vertices(ptr ptr long long long ptr ptr long long) @ cdecl wined3d_device_release_focus_window(ptr) @ cdecl wined3d_device_reset(ptr ptr ptr ptr long) @ cdecl wined3d_device_set_clip_status(ptr ptr) diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index b3c1b2f8152..2d2d097497e 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2401,7 +2401,7 @@ struct wined3d_swapchain * __cdecl wined3d_device_get_swapchain(const struct win UINT __cdecl wined3d_device_get_swapchain_count(const struct wined3d_device *device); struct wined3d * __cdecl wined3d_device_get_wined3d(const struct wined3d_device *device); ULONG __cdecl wined3d_device_incref(struct wined3d_device *device); -HRESULT __cdecl wined3d_device_process_vertices(struct wined3d_device *device, +HRESULT __cdecl wined3d_device_process_vertices(struct wined3d_device *device, struct wined3d_stateblock *stateblock, UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer, const struct wined3d_vertex_declaration *declaration, uint32_t flags, uint32_t dst_fvf); void __cdecl wined3d_device_release_focus_window(struct wined3d_device *device);
From: Elizabeth Figura zfigura@codeweavers.com
We eventually want to get things like render states out of wined3d_state, keeping them only in wined3d_stateblock. wined3d_device_process_vertices(), as a d3d < 9 function, is largely better suited to deal in wined3d_stateblock directly at this point. --- dlls/wined3d/device.c | 93 ++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 49 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 5cfd4040d8e..acc70256462 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1819,14 +1819,6 @@ HRESULT CDECL wined3d_device_context_get_stream_source(const struct wined3d_devi return WINED3D_OK; }
-static void wined3d_device_get_transform(const struct wined3d_device *device, - enum wined3d_transform_state state, struct wined3d_matrix *matrix) -{ - TRACE("device %p, state %s, matrix %p.\n", device, debug_d3dtstype(state), matrix); - - *matrix = device->cs->c.state->transforms[state]; -} - HRESULT CDECL wined3d_device_set_clip_status(struct wined3d_device *device, const struct wined3d_clip_status *clip_status) { @@ -2930,7 +2922,7 @@ static void wined3d_color_rgb_mul_add(struct wined3d_color *dst, const struct wi }
static void init_transformed_lights(struct lights_settings *ls, - const struct wined3d_state *state, BOOL legacy_lighting, BOOL compute_lighting) + const struct wined3d_stateblock_state *state, BOOL legacy_lighting, BOOL compute_lighting) { const struct wined3d_light_info *lights[WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS]; const struct wined3d_light_info *light_info; @@ -2943,12 +2935,12 @@ static void init_transformed_lights(struct lights_settings *ls, memset(ls, 0, sizeof(*ls));
ls->lighting = !!compute_lighting; - ls->fog_mode = state->render_states[WINED3D_RS_FOGVERTEXMODE]; - ls->fog_coord_mode = state->render_states[WINED3D_RS_RANGEFOGENABLE] + ls->fog_mode = state->rs[WINED3D_RS_FOGVERTEXMODE]; + ls->fog_coord_mode = state->rs[WINED3D_RS_RANGEFOGENABLE] ? WINED3D_FFP_VS_FOG_RANGE : WINED3D_FFP_VS_FOG_DEPTH; - ls->fog_start = wined3d_get_float_state(state, WINED3D_RS_FOGSTART); - ls->fog_end = wined3d_get_float_state(state, WINED3D_RS_FOGEND); - ls->fog_density = wined3d_get_float_state(state, WINED3D_RS_FOGDENSITY); + ls->fog_start = int_to_float(state->rs[WINED3D_RS_FOGSTART]); + ls->fog_end = int_to_float(state->rs[WINED3D_RS_FOGEND]); + ls->fog_density = int_to_float(state->rs[WINED3D_RS_FOGDENSITY]);
if (ls->fog_mode == WINED3D_FOG_NONE && !compute_lighting) return; @@ -2961,13 +2953,13 @@ static void init_transformed_lights(struct lights_settings *ls,
compute_normal_matrix(&ls->normal_matrix._11, legacy_lighting, &ls->modelview_matrix);
- wined3d_color_from_d3dcolor(&ls->ambient_light, state->render_states[WINED3D_RS_AMBIENT]); + wined3d_color_from_d3dcolor(&ls->ambient_light, state->rs[WINED3D_RS_AMBIENT]); ls->legacy_lighting = !!legacy_lighting; - ls->normalise = !!state->render_states[WINED3D_RS_NORMALIZENORMALS]; - ls->localviewer = !!state->render_states[WINED3D_RS_LOCALVIEWER]; + ls->normalise = !!state->rs[WINED3D_RS_NORMALIZENORMALS]; + ls->localviewer = !!state->rs[WINED3D_RS_LOCALVIEWER];
index = 0; - RB_FOR_EACH_ENTRY(light_iter, &state->light_state.lights_tree, struct wined3d_light_info, entry) + RB_FOR_EACH_ENTRY(light_iter, &state->light_state->lights_tree, struct wined3d_light_info, entry) { if (!light_iter->enabled) continue; @@ -3290,13 +3282,14 @@ static void update_fog_factor(float *fog_factor, struct lights_settings *ls)
/* Context activation is done by the caller. */ #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) -static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD dwDestIndex, DWORD dwCount, +static HRESULT process_vertices_strided(const struct wined3d_device *device, + const struct wined3d_stateblock_state *state, DWORD dwDestIndex, DWORD dwCount, const struct wined3d_stream_info *stream_info, struct wined3d_buffer *dest, uint32_t flags, uint32_t dst_fvf) { enum wined3d_material_color_source diffuse_source, specular_source, ambient_source, emissive_source; + const struct wined3d_state *device_state = device->cs->c.state; + const struct wined3d_matrix *proj_mat, *view_mat, *world_mat; const struct wined3d_color *material_specular_state_colour; - struct wined3d_matrix mat, proj_mat, view_mat, world_mat; - const struct wined3d_state *state = device->cs->c.state; const struct wined3d_format *output_colour_format; static const struct wined3d_color black; struct wined3d_map_desc map_desc; @@ -3304,6 +3297,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO struct wined3d_viewport vp; unsigned int texture_count; struct lights_settings ls; + struct wined3d_matrix mat; unsigned int vertex_size; BOOL do_clip, lighting; float min_z, max_z; @@ -3317,7 +3311,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO return WINED3DERR_INVALIDCALL; }
- if (state->render_states[WINED3D_RS_CLIPPING]) + if (state->rs[WINED3D_RS_CLIPPING]) { static BOOL warned = FALSE; /* @@ -3348,44 +3342,44 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO } dest_ptr = map_desc.data;
- wined3d_device_get_transform(device, WINED3D_TS_VIEW, &view_mat); - wined3d_device_get_transform(device, WINED3D_TS_PROJECTION, &proj_mat); - wined3d_device_get_transform(device, WINED3D_TS_WORLD_MATRIX(0), &world_mat); + view_mat = &state->transforms[WINED3D_TS_VIEW]; + proj_mat = &state->transforms[WINED3D_TS_PROJECTION]; + world_mat = &state->transforms[WINED3D_TS_WORLD];
TRACE("View mat:\n"); - TRACE("%.8e %.8e %.8e %.8e\n", view_mat._11, view_mat._12, view_mat._13, view_mat._14); - TRACE("%.8e %.8e %.8e %.8e\n", view_mat._21, view_mat._22, view_mat._23, view_mat._24); - TRACE("%.8e %.8e %.8e %.8e\n", view_mat._31, view_mat._32, view_mat._33, view_mat._34); - TRACE("%.8e %.8e %.8e %.8e\n", view_mat._41, view_mat._42, view_mat._43, view_mat._44); + TRACE("%.8e %.8e %.8e %.8e\n", view_mat->_11, view_mat->_12, view_mat->_13, view_mat->_14); + TRACE("%.8e %.8e %.8e %.8e\n", view_mat->_21, view_mat->_22, view_mat->_23, view_mat->_24); + TRACE("%.8e %.8e %.8e %.8e\n", view_mat->_31, view_mat->_32, view_mat->_33, view_mat->_34); + TRACE("%.8e %.8e %.8e %.8e\n", view_mat->_41, view_mat->_42, view_mat->_43, view_mat->_44);
TRACE("Proj mat:\n"); - TRACE("%.8e %.8e %.8e %.8e\n", proj_mat._11, proj_mat._12, proj_mat._13, proj_mat._14); - TRACE("%.8e %.8e %.8e %.8e\n", proj_mat._21, proj_mat._22, proj_mat._23, proj_mat._24); - TRACE("%.8e %.8e %.8e %.8e\n", proj_mat._31, proj_mat._32, proj_mat._33, proj_mat._34); - TRACE("%.8e %.8e %.8e %.8e\n", proj_mat._41, proj_mat._42, proj_mat._43, proj_mat._44); + TRACE("%.8e %.8e %.8e %.8e\n", proj_mat->_11, proj_mat->_12, proj_mat->_13, proj_mat->_14); + TRACE("%.8e %.8e %.8e %.8e\n", proj_mat->_21, proj_mat->_22, proj_mat->_23, proj_mat->_24); + TRACE("%.8e %.8e %.8e %.8e\n", proj_mat->_31, proj_mat->_32, proj_mat->_33, proj_mat->_34); + TRACE("%.8e %.8e %.8e %.8e\n", proj_mat->_41, proj_mat->_42, proj_mat->_43, proj_mat->_44);
TRACE("World mat:\n"); - TRACE("%.8e %.8e %.8e %.8e\n", world_mat._11, world_mat._12, world_mat._13, world_mat._14); - TRACE("%.8e %.8e %.8e %.8e\n", world_mat._21, world_mat._22, world_mat._23, world_mat._24); - TRACE("%.8e %.8e %.8e %.8e\n", world_mat._31, world_mat._32, world_mat._33, world_mat._34); - TRACE("%.8e %.8e %.8e %.8e\n", world_mat._41, world_mat._42, world_mat._43, world_mat._44); + TRACE("%.8e %.8e %.8e %.8e\n", world_mat->_11, world_mat->_12, world_mat->_13, world_mat->_14); + TRACE("%.8e %.8e %.8e %.8e\n", world_mat->_21, world_mat->_22, world_mat->_23, world_mat->_24); + TRACE("%.8e %.8e %.8e %.8e\n", world_mat->_31, world_mat->_32, world_mat->_33, world_mat->_34); + TRACE("%.8e %.8e %.8e %.8e\n", world_mat->_41, world_mat->_42, world_mat->_43, world_mat->_44);
/* Get the viewport */ wined3d_device_context_get_viewports(&device->cs->c, NULL, &vp); TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n", vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z);
- multiply_matrix(&mat,&view_mat,&world_mat); - multiply_matrix(&mat,&proj_mat,&mat); + multiply_matrix(&mat, view_mat, world_mat); + multiply_matrix(&mat, proj_mat, &mat);
texture_count = (dst_fvf & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
- lighting = state->render_states[WINED3D_RS_LIGHTING] + lighting = state->rs[WINED3D_RS_LIGHTING] && (dst_fvf & (WINED3DFVF_DIFFUSE | WINED3DFVF_SPECULAR)); wined3d_get_material_colour_source(&diffuse_source, &emissive_source, - &ambient_source, &specular_source, state); + &ambient_source, &specular_source, device_state); output_colour_format = wined3d_get_format(device->adapter, WINED3DFMT_B8G8R8A8_UNORM, 0); - material_specular_state_colour = state->render_states[WINED3D_RS_SPECULARENABLE] + material_specular_state_colour = state->rs[WINED3D_RS_SPECULARENABLE] ? &state->material.specular : &black; init_transformed_lights(&ls, state, device->adapter->d3d_info.wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING, lighting); @@ -3530,7 +3524,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO normal = NULL; } compute_light(&ambient, &diffuse, &specular, &ls, normal, - state->render_states[WINED3D_RS_SPECULARENABLE] ? state->material.power : 0.0f); + state->rs[WINED3D_RS_SPECULARENABLE] ? state->material.power : 0.0f); }
if (dst_fvf & WINED3DFVF_DIFFUSE) @@ -3614,7 +3608,8 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, str UINT src_start_idx, UINT dst_idx, UINT vertex_count, struct wined3d_buffer *dst_buffer, const struct wined3d_vertex_declaration *declaration, uint32_t flags, uint32_t dst_fvf) { - struct wined3d_state *state = device->cs->c.state; + const struct wined3d_stateblock_state *state = wined3d_stateblock_get_state(stateblock); + struct wined3d_state *device_state = device->cs->c.state; struct wined3d_stream_info stream_info; struct wined3d_resource *resource; struct wined3d_box box = {0}; @@ -3633,10 +3628,10 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, str
wined3d_device_apply_stateblock(device, stateblock);
- vs = state->shader[WINED3D_SHADER_TYPE_VERTEX]; - state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; - wined3d_stream_info_from_declaration(&stream_info, state, &device->adapter->d3d_info); - state->shader[WINED3D_SHADER_TYPE_VERTEX] = vs; + vs = device_state->shader[WINED3D_SHADER_TYPE_VERTEX]; + device_state->shader[WINED3D_SHADER_TYPE_VERTEX] = NULL; + wined3d_stream_info_from_declaration(&stream_info, device_state, &device->adapter->d3d_info); + device_state->shader[WINED3D_SHADER_TYPE_VERTEX] = vs;
/* We can't convert FROM a VBO, and vertex buffers used to source into * process_vertices() are unlikely to ever be used for drawing. Release @@ -3675,7 +3670,7 @@ HRESULT CDECL wined3d_device_process_vertices(struct wined3d_device *device, str e->data.addr += (ULONG_PTR)map_desc.data; }
- hr = process_vertices_strided(device, dst_idx, vertex_count, + hr = process_vertices_strided(device, state, dst_idx, vertex_count, &stream_info, dst_buffer, flags, dst_fvf);
map = stream_info.use_map;
From: Elizabeth Figura zfigura@codeweavers.com
We will want to pass multiple constants in the same buffer (e.g. FFP_MODELVIEW, FFP_PROJ) covered by different update flags. --- dlls/wined3d/cs.c | 23 ++++++++++++----------- dlls/wined3d/stateblock.c | 18 ++++++++++++------ dlls/wined3d/wined3d_private.h | 2 +- 3 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 958c23d76a7..3cf0cb6c5b1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -414,6 +414,7 @@ struct wined3d_cs_push_constants enum wined3d_push_constants type; unsigned int start_idx; unsigned int count; + uint32_t update_mask; };
struct wined3d_cs_reset_state @@ -2140,18 +2141,17 @@ static const struct push_constant_info { size_t size; unsigned int max_count; - DWORD mask; enum wined3d_shader_type shader_type; enum vkd3d_shader_d3dbc_constant_register shader_binding; } wined3d_cs_push_constant_info[] = { - [WINED3D_PUSH_CONSTANTS_VS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_VS_CONSTS_F, WINED3D_SHADER_CONST_VS_F, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_PS_CONSTS_F, WINED3D_SHADER_CONST_PS_F, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_VS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_CONST_VS_I, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_CONST_PS_I, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_VS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_CONST_VS_B, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_CONST_PS_B, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_VS_CONSTS_F, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_PS_CONSTS_F, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, };
static bool prepare_push_constant_buffer(struct wined3d_device_context *context, enum wined3d_push_constants type) @@ -2206,11 +2206,11 @@ static void wined3d_cs_exec_push_constants(struct wined3d_cs *cs, const void *da device->shader_backend->shader_update_float_pixel_constants(device, op->start_idx, op->count);
for (i = 0, context_count = device->context_count; i < context_count; ++i) - device->contexts[i]->constant_update_mask |= wined3d_cs_push_constant_info[op->type].mask; + device->contexts[i]->constant_update_mask |= op->update_mask; }
static void wined3d_device_context_emit_push_constants(struct wined3d_device_context *context, - enum wined3d_push_constants type, unsigned int start_idx, unsigned int count) + enum wined3d_push_constants type, uint32_t update_mask, unsigned int start_idx, unsigned int count) { struct wined3d_cs *cs = wined3d_cs_from_context(context); struct wined3d_cs_push_constants *op; @@ -2218,6 +2218,7 @@ static void wined3d_device_context_emit_push_constants(struct wined3d_device_con op = wined3d_device_context_require_space(&cs->c, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_PUSH_CONSTANTS; op->type = type; + op->update_mask = update_mask; op->start_idx = start_idx; op->count = count;
@@ -2225,7 +2226,7 @@ static void wined3d_device_context_emit_push_constants(struct wined3d_device_con }
void wined3d_device_context_push_constants(struct wined3d_device_context *context, - enum wined3d_push_constants type, unsigned int start_idx, + enum wined3d_push_constants type, uint32_t update_mask, unsigned int start_idx, unsigned int count, const void *constants) { const struct push_constant_info *info = &wined3d_cs_push_constant_info[type]; @@ -2239,7 +2240,7 @@ void wined3d_device_context_push_constants(struct wined3d_device_context *contex wined3d_box_set(&box, byte_offset, 0, byte_offset + byte_size, 1, 0, 1); wined3d_device_context_emit_update_sub_resource(context, &context->device->push_constants[type]->resource, 0, &box, constants, byte_size, byte_size); - wined3d_device_context_emit_push_constants(context, type, start_idx, count); + wined3d_device_context_emit_push_constants(context, type, update_mask, start_idx, count); }
static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 217ebda743f..9d597e293a3 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -2287,7 +2287,8 @@ static void wined3d_device_set_vs_consts_b(struct wined3d_device *device, TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); }
- wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_VS_B, start_idx, count, constants); + wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_VS_B, + WINED3D_SHADER_CONST_VS_B, start_idx, count, constants); }
static void wined3d_device_set_vs_consts_i(struct wined3d_device *device, @@ -2303,7 +2304,8 @@ static void wined3d_device_set_vs_consts_i(struct wined3d_device *device, TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); }
- wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_VS_I, start_idx, count, constants); + wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_VS_I, + WINED3D_SHADER_CONST_VS_I, start_idx, count, constants); }
static void wined3d_device_set_vs_consts_f(struct wined3d_device *device, @@ -2319,7 +2321,8 @@ static void wined3d_device_set_vs_consts_f(struct wined3d_device *device, TRACE("Set vec4 constant %u to %s.\n", start_idx + i, debug_vec4(&constants[i])); }
- wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_VS_F, start_idx, count, constants); + wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_VS_F, + WINED3D_SHADER_CONST_VS_F, start_idx, count, constants); }
static void wined3d_device_set_ps_consts_b(struct wined3d_device *device, @@ -2335,7 +2338,8 @@ static void wined3d_device_set_ps_consts_b(struct wined3d_device *device, TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); }
- wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_PS_B, start_idx, count, constants); + wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_PS_B, + WINED3D_SHADER_CONST_PS_B, start_idx, count, constants); }
static void wined3d_device_set_ps_consts_i(struct wined3d_device *device, @@ -2351,7 +2355,8 @@ static void wined3d_device_set_ps_consts_i(struct wined3d_device *device, TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); }
- wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_PS_I, start_idx, count, constants); + wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_PS_I, + WINED3D_SHADER_CONST_PS_I, start_idx, count, constants); }
static void wined3d_device_set_ps_consts_f(struct wined3d_device *device, @@ -2367,7 +2372,8 @@ static void wined3d_device_set_ps_consts_f(struct wined3d_device *device, TRACE("Set vec4 constant %u to %s.\n", start_idx + i, debug_vec4(&constants[i])); }
- wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_PS_F, start_idx, count, constants); + wined3d_device_context_push_constants(&device->cs->c, WINED3D_PUSH_CONSTANTS_PS_F, + WINED3D_SHADER_CONST_PS_F, start_idx, count, constants); }
/* Note lights are real special cases. Although the device caps state only diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 8c36a033f6e..178911dd08f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3705,7 +3705,7 @@ void wined3d_device_context_emit_update_sub_resource(struct wined3d_device_conte HRESULT wined3d_device_context_emit_unmap(struct wined3d_device_context *context, struct wined3d_resource *resource, unsigned int sub_resource_idx); void wined3d_device_context_push_constants(struct wined3d_device_context *context, - enum wined3d_push_constants type, unsigned int start_idx, + enum wined3d_push_constants type, uint32_t update_mask, unsigned int start_idx, unsigned int count, const void *constants);
static inline void wined3d_resource_reference(struct wined3d_resource *resource)
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/cs.c | 13 ++++++------ dlls/wined3d/glsl_shader.c | 15 +++++--------- dlls/wined3d/stateblock.c | 36 +++++++++++++++++++++++++++++++--- dlls/wined3d/wined3d_private.h | 18 +++++++++++++++++ 4 files changed, 63 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 3cf0cb6c5b1..81a66ab3cf7 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2146,12 +2146,13 @@ static const struct push_constant_info } wined3d_cs_push_constant_info[] = { - [WINED3D_PUSH_CONSTANTS_VS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_VS_CONSTS_F, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_PS_CONSTS_F, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_VS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_VS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, - [WINED3D_PUSH_CONSTANTS_PS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_VS_CONSTS_F, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_F] = {sizeof(struct wined3d_vec4), WINED3D_MAX_PS_CONSTS_F, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_I] = {sizeof(struct wined3d_ivec4), WINED3D_MAX_CONSTS_I, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_VS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_VERTEX, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_B] = {sizeof(BOOL), WINED3D_MAX_CONSTS_B, WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + [WINED3D_PUSH_CONSTANTS_PS_FFP] = {1, sizeof(struct wined3d_ffp_ps_constants), WINED3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, };
static bool prepare_push_constant_buffer(struct wined3d_device_context *context, enum wined3d_push_constants type) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b45494b9f12..3f7199de87d 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1893,8 +1893,12 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv,
if (update_mask & WINED3D_SHADER_CONST_FFP_PS) { + const struct wined3d_ffp_ps_constants *constants; struct wined3d_color color;
+ constants = wined3d_buffer_load_sysmem( + context_gl->c.device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], &context_gl->c); + if (prog->ps.tex_factor_location != -1) { wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); @@ -1911,8 +1915,7 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, if (prog->ps.tss_constant_location[i] == -1) continue;
- wined3d_color_from_d3dcolor(&color, state->texture_states[i][WINED3D_TSS_CONSTANT]); - GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, &color.r)); + GL_EXTCALL(glUniform4fv(prog->ps.tss_constant_location[i], 1, &constants->texture_constants[i].r)); }
checkGLcall("fixed function uniforms"); @@ -12453,14 +12456,6 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, glsl_fragment_pipe_shader }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), glsl_fragment_pipe_shademode }, WINED3D_GLSL_130 }, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 9d597e293a3..267da31ff19 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -30,6 +30,8 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag);
struct wined3d_saved_states { + struct list changed_lights; + uint32_t vs_consts_f[WINED3D_BITMAP_SIZE(WINED3D_MAX_VS_CONSTS_F)]; uint16_t vertexShaderConstantsI; /* WINED3D_MAX_CONSTS_I, 16 */ uint16_t vertexShaderConstantsB; /* WINED3D_MAX_CONSTS_B, 16 */ @@ -55,9 +57,10 @@ struct wined3d_saved_states uint32_t alpha_to_coverage : 1; uint32_t lights : 1; uint32_t transforms : 1; - uint32_t padding : 1;
- struct list changed_lights; + /* Flags only consumed by wined3d_device_apply_stateblock(), concerned with + * translation from stateblock formats to wined3d_state formats. */ + uint32_t ffp_ps_constants : 1; };
struct stage_state @@ -1574,6 +1577,9 @@ void CDECL wined3d_stateblock_set_texture_stage_state(struct wined3d_stateblock
stateblock->stateblock_state.texture_states[stage][state] = value; stateblock->changed.textureState[stage] |= 1u << state; + + if (state == WINED3D_TSS_CONSTANT) + stateblock->changed.ffp_ps_constants = 1; }
void CDECL wined3d_stateblock_set_texture(struct wined3d_stateblock *stateblock, @@ -2190,6 +2196,10 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru stateblock->changed.store_stream_offset = 1; list_init(&stateblock->changed.changed_lights);
+ /* FFP push constant buffers need to be set if used; the backend does not + * have a default state for them. */ + stateblock->changed.ffp_ps_constants = 1; + if (type == WINED3D_SBT_RECORDED || type == WINED3D_SBT_PRIMARY) return WINED3D_OK;
@@ -2651,6 +2661,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, struct wined3d_stateblock *stateblock) { bool set_blend_state = false, set_depth_stencil_state = false, set_rasterizer_state = false; + const struct wined3d_stateblock_state *state = &stateblock->stateblock_state; const struct wined3d_saved_states *changed = &stateblock->changed; const unsigned int word_bit_count = sizeof(DWORD) * CHAR_BIT; @@ -3193,7 +3204,15 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, while (map) { j = wined3d_bit_scan(&map); - wined3d_device_set_texture_stage_state(device, i, j, state->texture_states[i][j]); + + switch (j) + { + case WINED3D_TSS_CONSTANT: + break; + + default: + wined3d_device_set_texture_stage_state(device, i, j, state->texture_states[i][j]); + } } }
@@ -3286,6 +3305,17 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, wined3d_device_set_clip_plane(device, i, &state->clip_planes[i]); }
+ if (changed->ffp_ps_constants) + { + struct wined3d_ffp_ps_constants constants; + + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) + wined3d_color_from_d3dcolor(&constants.texture_constants[i], state->texture_states[i][WINED3D_TSS_CONSTANT]); + + wined3d_device_context_push_constants(context, WINED3D_PUSH_CONSTANTS_PS_FFP, + WINED3D_SHADER_CONST_FFP_PS, 0, sizeof(constants), &constants); + } + assert(list_empty(&stateblock->changed.changed_lights)); memset(&stateblock->changed, 0, sizeof(stateblock->changed)); list_init(&stateblock->changed.changed_lights); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 178911dd08f..f0e1d3ed615 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2755,6 +2755,23 @@ void wined3d_unregister_window(HWND window);
BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size);
+/* Direct3D 1-9 shader constants are submitted by internally feeding them into + * wined3d_buffer objects, which are updated with + * wined3d_device_context_emit_update_sub_resource(). + * This allows Vulkan backend shaders to read from the buffers as they would + * any other uniform buffer, with no extra code needed to set up the descriptor + * set and bind buffers. Other renderers simply map the buffers as CPU buffers + * and read from them directly. + * + * The "FFP" buffer contains constants that are part of the D3D1-9 FFP pipe, + * i.e. only used when shaders are disabled. + */ + +struct wined3d_ffp_ps_constants +{ + struct wined3d_color texture_constants[WINED3D_MAX_FFP_TEXTURES]; +}; + enum wined3d_push_constants { WINED3D_PUSH_CONSTANTS_VS_F, @@ -2763,6 +2780,7 @@ enum wined3d_push_constants WINED3D_PUSH_CONSTANTS_PS_I, WINED3D_PUSH_CONSTANTS_VS_B, WINED3D_PUSH_CONSTANTS_PS_B, + WINED3D_PUSH_CONSTANTS_PS_FFP, WINED3D_PUSH_CONSTANTS_COUNT, };
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/ffp_gl.c | 3 +-- dlls/wined3d/glsl_shader.c | 7 +------ dlls/wined3d/shader_spirv.c | 1 - dlls/wined3d/stateblock.c | 22 ++++++++++++++++++---- dlls/wined3d/wined3d_private.h | 1 + 5 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index b1a3c56a097..bab0f752df8 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -1678,8 +1678,7 @@ static void validate_state_table(struct wined3d_state_entry *state_table) { 30, 33}, { 39, 40}, { 42, 47}, - { 49, 59}, - { 61, 135}, + { 49, 135}, {138, 138}, {144, 144}, {149, 150}, diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 3f7199de87d..41e6949b7af 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1894,16 +1894,12 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, if (update_mask & WINED3D_SHADER_CONST_FFP_PS) { const struct wined3d_ffp_ps_constants *constants; - struct wined3d_color color;
constants = wined3d_buffer_load_sysmem( context_gl->c.device->push_constants[WINED3D_PUSH_CONSTANTS_PS_FFP], &context_gl->c);
if (prog->ps.tex_factor_location != -1) - { - wined3d_color_from_d3dcolor(&color, state->render_states[WINED3D_RS_TEXTUREFACTOR]); - GL_EXTCALL(glUniform4fv(prog->ps.tex_factor_location, 1, &color.r)); - } + GL_EXTCALL(glUniform4fv(prog->ps.tex_factor_location, 1, &constants->texture_factor.r));
if (state->render_states[WINED3D_RS_SPECULARENABLE]) GL_EXTCALL(glUniform4f(prog->ps.specular_enable_location, 1.0f, 1.0f, 1.0f, 0.0f)); @@ -12355,7 +12351,6 @@ static const struct wined3d_state_entry_template glsl_fragment_pipe_state_templa { {STATE_VDECL, {STATE_VDECL, glsl_fragment_pipe_vdecl }, WINED3D_GL_EXT_NONE }, {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), glsl_fragment_pipe_vs }, WINED3D_GL_EXT_NONE }, - {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 110fdfeff39..b4ef9f61f43 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -1260,7 +1260,6 @@ static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_state {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGEND), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_nop}}, {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop}}, - {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_nop}}, {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}}, {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}}, {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}}, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 267da31ff19..28aa2a46f08 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1532,11 +1532,22 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb stateblock->stateblock_state.rs[state] = value; stateblock->changed.renderState[state >> 5] |= 1u << (state & 0x1f);
- if (state == WINED3D_RS_POINTSIZE - && (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE || value == WINED3D_ALPHA_TO_COVERAGE_DISABLE)) + switch (state) { - stateblock->changed.alpha_to_coverage = 1; - stateblock->stateblock_state.alpha_to_coverage = (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE); + case WINED3D_RS_POINTSIZE: + if (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE || value == WINED3D_ALPHA_TO_COVERAGE_DISABLE) + { + stateblock->changed.alpha_to_coverage = 1; + stateblock->stateblock_state.alpha_to_coverage = (value == WINED3D_ALPHA_TO_COVERAGE_ENABLE); + } + break; + + case WINED3D_RS_TEXTUREFACTOR: + stateblock->changed.ffp_ps_constants = 1; + break; + + default: + break; } }
@@ -2805,6 +2816,7 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, break;
case WINED3D_RS_ADAPTIVETESS_Y: + case WINED3D_RS_TEXTUREFACTOR: break;
case WINED3D_RS_ANTIALIAS: @@ -3312,6 +3324,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) wined3d_color_from_d3dcolor(&constants.texture_constants[i], state->texture_states[i][WINED3D_TSS_CONSTANT]);
+ wined3d_color_from_d3dcolor(&constants.texture_factor, state->rs[WINED3D_RS_TEXTUREFACTOR]); + wined3d_device_context_push_constants(context, WINED3D_PUSH_CONSTANTS_PS_FFP, WINED3D_SHADER_CONST_FFP_PS, 0, sizeof(constants), &constants); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f0e1d3ed615..46cc0ec30ce 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2770,6 +2770,7 @@ BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size); struct wined3d_ffp_ps_constants { struct wined3d_color texture_constants[WINED3D_MAX_FFP_TEXTURES]; + struct wined3d_color texture_factor; };
enum wined3d_push_constants
This merge request was approved by Jan Sikorski.