diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index bbae5add951..a3ea6484ba1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -54,6 +54,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_CLIP_PLANE, WINED3D_CS_OP_SET_COLOR_KEY, WINED3D_CS_OP_SET_MATERIAL, + WINED3D_CS_OP_SET_LIGHT, WINED3D_CS_OP_RESET_STATE, WINED3D_CS_OP_CALLBACK, WINED3D_CS_OP_QUERY_ISSUE, @@ -278,6 +279,12 @@ struct wined3d_cs_set_material struct wined3d_material material; }; +struct wined3d_cs_set_light +{ + enum wined3d_cs_op opcode; + struct wined3d_light_info light; +}; + struct wined3d_cs_reset_state { enum wined3d_cs_op opcode; @@ -1369,6 +1376,47 @@ void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_ma cs->ops->submit(cs); } +static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_light *op = data; + struct wined3d_light_info *light_info; + unsigned int light_idx, hash_idx; + + light_idx = op->light.OriginalIndex; + + if (!(light_info = wined3d_state_get_light(&cs->state, light_idx))) + { + TRACE("Adding new light.\n"); + if (!(light_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*light_info)))) + { + ERR("Failed to allocate light info.\n"); + return; + } + + hash_idx = LIGHTMAP_HASHFUNC(light_idx); + list_add_head(&cs->state.light_map[hash_idx], &light_info->entry); + light_info->glIndex = -1; + light_info->OriginalIndex = light_idx; + } + + light_info->OriginalParms = op->light.OriginalParms; + light_info->position = op->light.position; + light_info->direction = op->light.direction; + light_info->exponent = op->light.exponent; + light_info->cutoff = op->light.cutoff; +} + +void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) +{ + struct wined3d_cs_set_light *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_LIGHT; + op->light = *light; + + cs->ops->submit(cs); +} + static void wined3d_cs_exec_reset_state(struct wined3d_cs *cs, const void *data) { struct wined3d_adapter *adapter = cs->device->adapter; @@ -1565,6 +1613,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_CLIP_PLANE */ wined3d_cs_exec_set_clip_plane, /* WINED3D_CS_OP_SET_COLOR_KEY */ wined3d_cs_exec_set_color_key, /* WINED3D_CS_OP_SET_MATERIAL */ wined3d_cs_exec_set_material, + /* WINED3D_CS_OP_SET_LIGHT */ wined3d_cs_exec_set_light, /* WINED3D_CS_OP_RESET_STATE */ wined3d_cs_exec_reset_state, /* WINED3D_CS_OP_CALLBACK */ wined3d_cs_exec_callback, /* WINED3D_CS_OP_QUERY_ISSUE */ wined3d_cs_exec_query_issue, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 2c8da309f4f..4c10f9912cb 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1655,6 +1655,9 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, FIXME("Unrecognized light type %#x.\n", light->type); } + if (!device->recording) + wined3d_cs_emit_set_light(device->cs, object); + return WINED3D_OK; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4c70c970bc5..23f15dfb561 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3203,6 +3203,7 @@ void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs, struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, enum wined3d_format_id format_id, unsigned int offset) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_light(struct wined3d_cs *cs, const struct wined3d_light_info *light) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_material(struct wined3d_cs *cs, const struct wined3d_material *material) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_predication(struct wined3d_cs *cs, struct wined3d_query *predicate, BOOL value) DECLSPEC_HIDDEN;