[PATCH 1/7] wined3d: Add a new structure for for d3d limits and other info

Stefan Dösinger stefan at codeweavers.com
Thu Apr 25 08:20:24 CDT 2013


Applies on top of Henri's patches.

The problem this and the following patches address is that in general we
can't access the device without synchronization. This is no problem for
cached limit information because it never changes once the device is
initialized. However, this is not obvious from reading the code.

Beyond this, the adapter already decides which shader implementation to
use and thus already sets this limit.
---
 dlls/wined3d/arb_program_shader.c | 12 ++++++++----
 dlls/wined3d/context.c            |  1 +
 dlls/wined3d/device.c             |  1 -
 dlls/wined3d/directx.c            |  4 ++++
 dlls/wined3d/state.c              | 12 +++++++-----
 dlls/wined3d/utils.c              |  3 ++-
 dlls/wined3d/wined3d_private.h    |  8 +++++++-
 7 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 967a057..5054b7c 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -4293,6 +4293,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
 {
     struct wined3d_device *device = shader->device;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
     UINT i;
     DWORD new_size;
     struct arb_ps_compiled_shader *new_array;
@@ -4315,7 +4316,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(struct wined3d_shader *sh
 
         TRACE("Shader got assigned input signature index %u\n", shader_data->input_signature_idx);
 
-        if (!device->vs_clipping)
+        if (!d3d_info->vs_clipping)
             shader_data->clipplane_emulation = shader_find_free_input_register(&shader->reg_maps,
                     gl_info->limits.texture_stages - 1);
         else
@@ -4475,6 +4476,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state,
 {
     struct wined3d_device *device = shader->device;
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
     int i;
     WORD int_skip;
 
@@ -4493,7 +4495,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state,
      * is quite expensive because it forces the driver to disable early Z discards. It is cheaper to
      * duplicate the shader than have a no-op KIL instruction in every shader
      */
-    if (!device->vs_clipping && use_vs(state)
+    if (!d3d_info->vs_clipping && use_vs(state)
             && state->render_states[WINED3D_RS_CLIPPING]
             && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
         args->clip = 1;
@@ -4529,7 +4531,9 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
         const struct wined3d_shader *shader, struct arb_vs_compile_args *args)
 {
     struct wined3d_device *device = shader->device;
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_adapter *adapter = device->adapter;
+    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
     int i;
     WORD int_skip;
 
@@ -4547,7 +4551,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
     else
     {
         args->ps_signature = ~0;
-        if (!device->vs_clipping && device->adapter->fragment_pipe == &arbfp_fragment_pipeline)
+        if (!d3d_info->vs_clipping && adapter->fragment_pipe == &arbfp_fragment_pipeline)
         {
             args->clip.boolclip.clip_texcoord = ffp_clip_emul(state) ? gl_info->limits.texture_stages : 0;
         }
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 4ee5bd4..6a4f766 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1449,6 +1449,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
     }
 
     ret->gl_info = gl_info;
+    ret->d3d_info = &device->adapter->d3d_info;
     ret->state_table = device->StateTable;
 
     /* Mark all states dirty to force a proper initialization of the states
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 3eb7852..b15d4c2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5435,7 +5435,6 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d,
     device->ps_version = shader_caps.ps_version;
     device->d3d_vshader_constantF = shader_caps.vs_uniform_count;
     device->d3d_pshader_constantF = shader_caps.ps_uniform_count;
-    device->vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
 
     vertex_pipeline = adapter->vertex_pipe;
 
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 3743968..cd96ac7 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2625,6 +2625,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     struct wined3d_gl_info *gl_info = &adapter->gl_info;
     enum wined3d_pci_vendor card_vendor;
     struct fragment_caps fragment_caps;
+    struct shader_caps shader_caps;
     const char *WGL_Extensions = NULL;
     const char *GL_Extensions = NULL;
     enum wined3d_gl_vendor gl_vendor;
@@ -2843,6 +2844,9 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
     adapter->blitter = select_blit_implementation(gl_info, adapter->shader_backend);
 
+    adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
+    adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
+
     adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
     gl_info->limits.texture_stages = fragment_caps.MaxTextureBlendStages;
     TRACE("Max texture stages: %u.\n", gl_info->limits.texture_stages);
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 84e8b72..5de7f43 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -610,9 +610,7 @@ static void state_clipping(struct wined3d_context *context, const struct wined3d
 
     if (use_vs(state))
     {
-        const struct wined3d_device *device = context->swapchain->device;
-
-        if (!device->vs_clipping)
+        if (!context->d3d_info->vs_clipping)
         {
             /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
              * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
@@ -4603,8 +4601,11 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
         {
             updateFog = TRUE;
 
-            if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
+            if (!context->d3d_info->vs_clipping
+                    && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
+            {
                 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
+            }
 
             for (i = 0; i < gl_info->limits.clipplanes; ++i)
             {
@@ -4618,7 +4619,8 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
     {
         if(!context->last_was_vshader) {
             static BOOL warned = FALSE;
-            if(!device->vs_clipping) {
+            if (!context->d3d_info->vs_clipping)
+            {
                 /* Disable all clip planes to get defined results on all drivers. See comment in the
                  * state_clipping state handler
                  */
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 4a4289c..0e5ff2b 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3131,6 +3131,7 @@ void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_s
     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
     const struct wined3d_surface *rt = state->fb->render_targets[0];
     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_d3d_info *d3d_info = &device->adapter->d3d_info;
 
     for (i = 0; i < gl_info->limits.texture_stages; ++i)
     {
@@ -3350,7 +3351,7 @@ void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_s
     } else {
         settings->sRGB_write = 0;
     }
-    if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
+    if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
             || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
     {
         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f836485..b3d1eb7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1059,6 +1059,7 @@ BOOL wined3d_event_query_supported(const struct wined3d_gl_info *gl_info) DECLSP
 struct wined3d_context
 {
     const struct wined3d_gl_info *gl_info;
+    const struct wined3d_d3d_info *d3d_info;
     const struct StateEntry *state_table;
     /* State dirtification
      * dirtyArray is an array that contains markers for dirty states. numDirtyEntries states are dirty, their numbers are in indices
@@ -1586,6 +1587,11 @@ struct wined3d_driver_info
     DWORD version_low;
 };
 
+struct wined3d_d3d_info
+{
+    BOOL vs_clipping;
+};
+
 /* The adapter structure */
 struct wined3d_adapter
 {
@@ -1594,6 +1600,7 @@ struct wined3d_adapter
     enum wined3d_format_id screen_format;
 
     struct wined3d_gl_info  gl_info;
+    struct wined3d_d3d_info d3d_info;
     struct wined3d_driver_info driver_info;
     WCHAR                   DeviceName[CCHDEVICENAME]; /* DeviceName for use with e.g. ChangeDisplaySettings */
     unsigned int cfg_count;
@@ -1724,7 +1731,6 @@ struct wined3d_device
     unsigned int max_ffp_textures;
     UINT vs_version, gs_version, ps_version;
     DWORD d3d_vshader_constantF, d3d_pshader_constantF; /* Advertised d3d caps, not GL ones */
-    DWORD vs_clipping;
     UINT instance_count;
 
     WORD vertexBlendUsed : 1;           /* To avoid needless setting of the blend matrices */
-- 
1.8.1.5




More information about the wine-patches mailing list