Henri Verbeet : wined3d: Send viewport updates through the command stream.
Alexandre Julliard
julliard at winehq.org
Mon Sep 30 16:07:55 CDT 2013
Module: wine
Branch: master
Commit: bc0f990b44893f531720c041e7cc5a7bd4fa8bb2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=bc0f990b44893f531720c041e7cc5a7bd4fa8bb2
Author: Henri Verbeet <hverbeet at 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
More information about the wine-cvs
mailing list