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