Stefan Dösinger : d3d: Limit d3d8 and d3d9 vshader constants to 256.

Alexandre Julliard julliard at winehq.org
Mon Apr 27 08:04:07 CDT 2009


Module: wine
Branch: master
Commit: 9f1731edb6b20be5bbad527148c9a8f588e28b33
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9f1731edb6b20be5bbad527148c9a8f588e28b33

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sat Apr 25 15:02:42 2009 +0200

d3d: Limit d3d8 and d3d9 vshader constants to 256.

DX10 cards support 512(ATI) or 1024(Nvidia) vertex shader constants in
GL. The dx9 DXCapsViewer shows that dx10 windows drivers only claim
256 constants on Windows, so we can and should do the same.

---

 dlls/d3d8/d3d8_private.h    |    2 ++
 dlls/d3d8/device.c          |   13 +++++++++++++
 dlls/d3d8/directx.c         |    1 +
 dlls/d3d9/d3d9_private.h    |    2 ++
 dlls/d3d9/directx.c         |    2 ++
 dlls/d3d9/vertexshader.c    |   12 ++++++++++++
 dlls/wined3d/vertexshader.c |   17 +++++++++++++----
 7 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index c9afe17..c38d8cc 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -601,6 +601,8 @@ struct IDirect3DVertexShader8Impl {
   IWineD3DVertexShader             *wineD3DVertexShader;
 };
 
+#define D3D8_MAX_VERTEX_SHADER_CONSTANTF 256
+
 
 /* ------------------------ */
 /* IDirect3DPixelShaderImpl */
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index a33bdbc..f5ab8b3 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -359,6 +359,7 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetDeviceCaps(LPDIRECT3DDEVICE8 iface
     if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
         pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
     }
+    pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
 
     TRACE("Returning %p %p\n", This, pCaps);
     return hrc;
@@ -1998,6 +1999,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_SetVertexShaderConstant(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
+    if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+             Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     LeaveCriticalSection(&d3d8_cs);
@@ -2009,6 +2016,12 @@ static HRESULT WINAPI IDirect3DDevice8Impl_GetVertexShaderConstant(LPDIRECT3DDEV
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
+    if(Register + ConstantCount > D3D8_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d8 only supports %u\n",
+             Register + ConstantCount, D3D8_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     EnterCriticalSection(&d3d8_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, ConstantCount);
     LeaveCriticalSection(&d3d8_cs);
diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index 64fc360..d39d3d6 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -265,6 +265,7 @@ static HRESULT  WINAPI  IDirect3D8Impl_GetDeviceCaps(LPDIRECT3D8 iface, UINT Ada
     if(pCaps->VertexShaderVersion > D3DVS_VERSION(1,1)){
         pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
     }
+    pCaps->MaxVertexShaderConst = min(D3D8_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
 
     TRACE("(%p) returning %p\n", This, pCaps);
     return hrc;
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 25b6ae2..7e43974 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -497,6 +497,8 @@ typedef struct IDirect3DVertexShader9Impl {
   LPDIRECT3DDEVICE9EX parentDevice;
 } IDirect3DVertexShader9Impl;
 
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256
+
 /* --------------------- */
 /* IDirect3DPixelShader9 */
 /* --------------------- */
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index 229368a..e9547a7 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -311,6 +311,8 @@ void filter_caps(D3DCAPS9* pCaps)
         D3DPTEXTURECAPS_PROJECTED      | D3DPTEXTURECAPS_CUBEMAP       | D3DPTEXTURECAPS_VOLUMEMAP       |
         D3DPTEXTURECAPS_MIPMAP         | D3DPTEXTURECAPS_MIPVOLUMEMAP  | D3DPTEXTURECAPS_MIPCUBEMAP      |
         D3DPTEXTURECAPS_CUBEMAP_POW2   | D3DPTEXTURECAPS_VOLUMEMAP_POW2| D3DPTEXTURECAPS_NOPROJECTEDBUMPENV;
+
+    pCaps->MaxVertexShaderConst = min(D3D9_MAX_VERTEX_SHADER_CONSTANTF, pCaps->MaxVertexShaderConst);
 }
 
 static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9EX iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) {
diff --git a/dlls/d3d9/vertexshader.c b/dlls/d3d9/vertexshader.c
index 6478b68..fd2837d 100644
--- a/dlls/d3d9/vertexshader.c
+++ b/dlls/d3d9/vertexshader.c
@@ -192,6 +192,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
     HRESULT hr;
     TRACE("(%p) : Relay\n", This);
 
+    if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+             Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_SetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
     LeaveCriticalSection(&d3d9_cs);
@@ -202,6 +208,12 @@ HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(LPDIRECT3DDEVICE9EX
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
     HRESULT hr;
 
+    if(Register + Vector4fCount > D3D9_MAX_VERTEX_SHADER_CONSTANTF) {
+        WARN("Trying to access %u constants, but d3d9 only supports %u\n",
+             Register + Vector4fCount, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
+        return D3DERR_INVALIDCALL;
+    }
+
     TRACE("(%p) : Relay\n", This);
     EnterCriticalSection(&d3d9_cs);
     hr = IWineD3DDevice_GetVertexShaderConstantF(This->WineD3DDevice, Register, pConstantData, Vector4fCount);
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index fab0dca..7f1dd92 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -115,9 +115,6 @@ static void vshader_set_limits(
       This->baseShader.limits.attributes = 16;
       This->baseShader.limits.packed_input = 0;
 
-      /* Must match D3DCAPS9.MaxVertexShaderConst: at least 256 for vs_2_0 */
-      This->baseShader.limits.constant_float = GL_LIMITS(vshader_constantsF);
-
       switch (This->baseShader.reg_maps.shader_version)
       {
           case WINED3DVS_VERSION(1,0):
@@ -129,8 +126,12 @@ static void vshader_set_limits(
                    This->baseShader.limits.packed_output = 0;
                    This->baseShader.limits.sampler = 0;
                    This->baseShader.limits.label = 0;
+                   /* TODO: vs_1_1 has a minimum of 96 constants. What happens if a vs_1_1 shader is used
+                    * on a vs_3_0 capable card that has 256 constants?
+                    */
+                   This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
                    break;
-      
+
           case WINED3DVS_VERSION(2,0):
           case WINED3DVS_VERSION(2,1):
                    This->baseShader.limits.temporary = 12;
@@ -140,6 +141,7 @@ static void vshader_set_limits(
                    This->baseShader.limits.packed_output = 0;
                    This->baseShader.limits.sampler = 0;
                    This->baseShader.limits.label = 16;
+                   This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
                    break;
 
           case WINED3DVS_VERSION(3,0):
@@ -150,6 +152,12 @@ static void vshader_set_limits(
                    This->baseShader.limits.packed_output = 12;
                    This->baseShader.limits.sampler = 4;
                    This->baseShader.limits.label = 16; /* FIXME: 2048 */
+                   /* DX10 cards on Windows advertise a d3d9 constant limit of 256 even though they are capable
+                    * of supporting much more(GL drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
+                    * wined3d-advertised maximum. Clamp the constant limit for <= 3.0 shaders to 256.s
+                    * use constant buffers
+                    */
+                   This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
                    break;
 
           default: This->baseShader.limits.temporary = 12;
@@ -159,6 +167,7 @@ static void vshader_set_limits(
                    This->baseShader.limits.packed_output = 0;
                    This->baseShader.limits.sampler = 0;
                    This->baseShader.limits.label = 16;
+                   This->baseShader.limits.constant_float = min(256, GL_LIMITS(vshader_constantsF));
                    FIXME("Unrecognized vertex shader version %#x\n",
                            This->baseShader.reg_maps.shader_version);
       }




More information about the wine-cvs mailing list