Module: wine Branch: master Commit: bc0f990b44893f531720c041e7cc5a7bd4fa8bb2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=bc0f990b44893f531720c041e7...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Mon Sep 30 09:40:39 2013 +0200
wined3d: Send viewport updates through the command stream.
---
dlls/wined3d/cs.c | 47 +++++++++++++++++++++++++++++++++++++++- dlls/wined3d/device.c | 10 ++++---- dlls/wined3d/stateblock.c | 8 ++++-- dlls/wined3d/wined3d_private.h | 8 ++++++- 4 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index cdd7794..a03e608 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -28,6 +28,7 @@ enum wined3d_cs_op WINED3D_CS_OP_PRESENT, WINED3D_CS_OP_CLEAR, WINED3D_CS_OP_DRAW, + WINED3D_CS_OP_SET_VIEWPORT, };
struct wined3d_cs_present @@ -62,6 +63,12 @@ struct wined3d_cs_draw BOOL indexed; };
+struct wined3d_cs_set_viewport +{ + enum wined3d_cs_op opcode; + const struct wined3d_viewport *viewport; +}; + static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_present *op = data; @@ -146,11 +153,31 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun cs->ops->submit(cs); }
+static void wined3d_cs_exec_set_viewport(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_viewport *op = data; + + cs->state.viewport = *op->viewport; + device_invalidate_state(cs->device, STATE_VIEWPORT); +} + +void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) +{ + struct wined3d_cs_set_viewport *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_VIEWPORT; + op->viewport = viewport; + + cs->ops->submit(cs); +} + static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = { /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, /* WINED3D_CS_OP_CLEAR */ wined3d_cs_exec_clear, /* WINED3D_CS_OP_DRAW */ wined3d_cs_exec_draw, + /* WINED3D_CS_OP_SET_VIEWPORT */ wined3d_cs_exec_set_viewport, };
static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) @@ -184,10 +211,26 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops =
struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device) { + const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct wined3d_cs *cs;
- if (!(cs = HeapAlloc(GetProcessHeap(), 0, sizeof(*cs)))) + if (!(cs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*cs)))) + return NULL; + + if (!(cs->fb.render_targets = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(*cs->fb.render_targets) * gl_info->limits.buffers))) + { + HeapFree(GetProcessHeap(), 0, cs); + return NULL; + } + + if (FAILED(state_init(&cs->state, &cs->fb, &device->adapter->d3d_info, WINED3D_STATE_NO_REF))) + { + HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); + HeapFree(GetProcessHeap(), 0, cs); return NULL; + } + state_init_default(&cs->state, gl_info);
cs->ops = &wined3d_cs_st_ops; cs->device = device; @@ -204,5 +247,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
void wined3d_cs_destroy(struct wined3d_cs *cs) { + state_cleanup(&cs->state); + HeapFree(GetProcessHeap(), 0, cs->fb.render_targets); HeapFree(GetProcessHeap(), 0, cs); } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 6d5f913..391e876 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1922,7 +1922,7 @@ void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const stru return; }
- device_invalidate_state(device, STATE_VIEWPORT); + wined3d_cs_emit_set_viewport(device->cs, viewport); }
void CDECL wined3d_device_get_viewport(const struct wined3d_device *device, struct wined3d_viewport *viewport) @@ -4015,7 +4015,7 @@ HRESULT CDECL wined3d_device_set_render_target(struct wined3d_device *device, state->viewport.height = render_target->resource.height; state->viewport.min_z = 0.0f; state->viewport.max_z = 1.0f; - device_invalidate_state(device, STATE_VIEWPORT); + wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
state->scissor_rect.top = 0; state->scissor_rect.left = 0; @@ -4705,7 +4705,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, if (device->d3d_initialized) delete_opengl_contexts(device, swapchain);
- if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->d3d_info))) + if (FAILED(hr = state_init(&device->state, &device->fb, &device->adapter->d3d_info, 0))) ERR("Failed to initialize device state, hr %#x.\n", hr); state_init_default(&device->state, &device->adapter->gl_info); device->update_state = &device->state; @@ -4722,7 +4722,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, state->viewport.y = 0; state->viewport.width = rt->resource.width; state->viewport.height = rt->resource.height; - device_invalidate_state(device, STATE_VIEWPORT); + wined3d_cs_emit_set_viewport(device->cs, &state->viewport);
state->scissor_rect.top = 0; state->scissor_rect.left = 0; @@ -4969,7 +4969,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
device->blitter = adapter->blitter;
- if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->d3d_info))) + if (FAILED(hr = state_init(&device->state, &device->fb, &adapter->d3d_info, 0))) { ERR("Failed to initialize device state, hr %#x.\n", hr); goto err; diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index c990e7d..c0d37f0 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -581,7 +581,8 @@ void state_cleanup(struct wined3d_state *state) { unsigned int counter;
- state_unbind_resources(state); + if (!(state->flags & WINED3D_STATE_NO_REF)) + state_unbind_resources(state);
for (counter = 0; counter < LIGHTMAP_SIZE; ++counter) { @@ -599,10 +600,11 @@ void state_cleanup(struct wined3d_state *state) }
HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - const struct wined3d_d3d_info *d3d_info) + const struct wined3d_d3d_info *d3d_info, DWORD flags) { unsigned int i;
+ state->flags = flags; state->fb = fb;
for (i = 0; i < LIGHTMAP_SIZE; i++) @@ -1386,7 +1388,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, stateblock->ref = 1; stateblock->device = device;
- if (FAILED(hr = state_init(&stateblock->state, NULL, d3d_info))) + if (FAILED(hr = state_init(&stateblock->state, NULL, d3d_info, 0))) return hr;
if (FAILED(hr = stateblock_allocate_shader_constants(stateblock))) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 3ffa4da..6d6b3a9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1804,8 +1804,11 @@ struct wined3d_stream_state UINT flags; };
+#define WINED3D_STATE_NO_REF 0x00000001 + struct wined3d_state { + DWORD flags; const struct wined3d_fb_state *fb;
struct wined3d_vertex_declaration *vertex_declaration; @@ -2451,7 +2454,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DEC
void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; HRESULT state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, - const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN; + const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; void state_init_default(struct wined3d_state *state, const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN;
@@ -2465,6 +2468,8 @@ struct wined3d_cs { const struct wined3d_cs_ops *ops; struct wined3d_device *device; + struct wined3d_fb_state fb; + struct wined3d_state state;
size_t data_size; void *data; @@ -2480,6 +2485,7 @@ void wined3d_cs_emit_draw(struct wined3d_cs *cs, UINT start_idx, UINT index_coun void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_viewport(struct wined3d_cs *cs, const struct wined3d_viewport *viewport) DECLSPEC_HIDDEN;
/* Direct3D terminology with little modifications. We do not have an issued state * because only the driver knows about it, but we have a created state because d3d