[PATCH v2 1/3] wined3d: Introduce a wined3d_bound_range() helper.

Zebediah Figura zfigura at codeweavers.com
Tue Jul 6 20:43:42 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/d3d8/device.c        |  5 ++---
 dlls/d3d9/device.c        |  4 ++--
 dlls/ddraw/device.c       |  4 ++--
 dlls/ddraw/viewport.c     |  8 ++++----
 dlls/wined3d/device.c     |  6 +++---
 dlls/wined3d/palette.c    |  2 +-
 dlls/wined3d/stateblock.c |  6 ++----
 dlls/wined3d/view.c       |  9 +++------
 include/wine/wined3d.h    | 11 +++++++++++
 9 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index b14e6679763..c0fa38e090a 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -3071,7 +3071,7 @@ static HRESULT WINAPI d3d8_device_GetVertexShaderConstant(IDirect3DDevice8 *ifac
     if (!constants)
         return D3DERR_INVALIDCALL;
 
-    if (start_idx >= device->vs_uniform_count || count > device->vs_uniform_count - start_idx)
+    if (!wined3d_bound_range(start_idx, count, device->vs_uniform_count))
     {
         WARN("Trying to access %u constants, but d3d8 only supports %u.\n",
              start_idx + count, device->vs_uniform_count);
@@ -3375,8 +3375,7 @@ static HRESULT WINAPI d3d8_device_GetPixelShaderConstant(IDirect3DDevice8 *iface
 
     TRACE("iface %p, start_idx %u, constants %p, count %u.\n", iface, start_idx, constants, count);
 
-    if (!constants || start_idx >= D3D8_MAX_PIXEL_SHADER_CONSTANTF
-            || count > D3D8_MAX_PIXEL_SHADER_CONSTANTF - start_idx)
+    if (!constants || !wined3d_bound_range(start_idx, count, D3D8_MAX_PIXEL_SHADER_CONSTANTF))
         return WINED3DERR_INVALIDCALL;
 
     wined3d_mutex_lock();
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 932d6d2d814..c8b906a981f 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -3684,7 +3684,7 @@ static HRESULT WINAPI d3d9_device_GetVertexShaderConstantF(IDirect3DDevice9Ex *i
     if (!constants)
         return D3DERR_INVALIDCALL;
 
-    if (start_idx >= device->vs_uniform_count || count > device->vs_uniform_count - start_idx)
+    if (!wined3d_bound_range(start_idx, count, device->vs_uniform_count))
     {
         WARN("Trying to access %u constants, but d3d9 only supports %u\n",
              start_idx + count, device->vs_uniform_count);
@@ -4033,7 +4033,7 @@ static HRESULT WINAPI d3d9_device_GetPixelShaderConstantF(IDirect3DDevice9Ex *if
 
     TRACE("iface %p, start_idx %u, constants %p, count %u.\n", iface, start_idx, constants, count);
 
-    if (!constants || start_idx >= WINED3D_MAX_PS_CONSTS_F || count > WINED3D_MAX_PS_CONSTS_F - start_idx)
+    if (!constants || !wined3d_bound_range(start_idx, count, WINED3D_MAX_PS_CONSTS_F))
         return WINED3DERR_INVALIDCALL;
 
     wined3d_mutex_lock();
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index e9070cfbda6..b66ae7698c8 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -5373,8 +5373,8 @@ static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *vi
     surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
     wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
 
-    if (viewport->dwX > rt_desc.width || viewport->dwWidth > rt_desc.width - viewport->dwX
-            || viewport->dwY > rt_desc.height || viewport->dwHeight > rt_desc.height - viewport->dwY)
+    if (!wined3d_bound_range(viewport->dwX, viewport->dwWidth, rt_desc.width)
+            || !wined3d_bound_range(viewport->dwY, viewport->dwHeight, rt_desc.height))
     {
         WARN("Invalid viewport, returning E_INVALIDARG.\n");
         wined3d_mutex_unlock();
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c
index ada3f1757b7..13a6a147083 100644
--- a/dlls/ddraw/viewport.c
+++ b/dlls/ddraw/viewport.c
@@ -414,8 +414,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
         surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
         wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
 
-        if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX
-            || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY)
+        if (!wined3d_bound_range(vp->dwX, vp->dwWidth, rt_desc.width)
+                || !wined3d_bound_range(vp->dwY, vp->dwHeight, rt_desc.height))
         {
             WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n");
             wined3d_mutex_unlock();
@@ -1043,8 +1043,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport2(IDirect3DViewport3 *iface, D3DVI
         surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
         wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
 
-        if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX
-            || vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY)
+        if (!wined3d_bound_range(vp->dwX, vp->dwWidth, rt_desc.width)
+                || !wined3d_bound_range(vp->dwY, vp->dwHeight, rt_desc.height))
         {
             WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n");
             wined3d_mutex_unlock();
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 175a3b7ed0b..e9d4d0a0677 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1837,7 +1837,7 @@ void CDECL wined3d_device_context_set_constant_buffers(struct wined3d_device_con
 
     TRACE("context %p, type %#x, start_idx %u, count %u, buffers %p.\n", context, type, start_idx, count, buffers);
 
-    if (start_idx >= MAX_CONSTANT_BUFFERS || count > MAX_CONSTANT_BUFFERS - start_idx)
+    if (!wined3d_bound_range(start_idx, count, MAX_CONSTANT_BUFFERS))
     {
         WARN("Invalid constant buffer index %u, count %u.\n", start_idx, count);
         return;
@@ -1988,7 +1988,7 @@ void CDECL wined3d_device_context_set_shader_resource_views(struct wined3d_devic
 
     TRACE("context %p, type %#x, start_idx %u, count %u, views %p.\n", context, type, start_idx, count, views);
 
-    if (start_idx >= MAX_SHADER_RESOURCE_VIEWS || count > MAX_SHADER_RESOURCE_VIEWS - start_idx)
+    if (!wined3d_bound_range(start_idx, count, MAX_SHADER_RESOURCE_VIEWS))
     {
         WARN("Invalid view index %u, count %u.\n", start_idx, count);
         return;
@@ -2040,7 +2040,7 @@ void CDECL wined3d_device_context_set_samplers(struct wined3d_device_context *co
 
     TRACE("context %p, type %#x, start_idx %u, count %u, samplers %p.\n", context, type, start_idx, count, samplers);
 
-    if (start_idx >= MAX_SAMPLER_OBJECTS || count > MAX_SAMPLER_OBJECTS - start_idx)
+    if (!wined3d_bound_range(start_idx, count, MAX_SAMPLER_OBJECTS))
     {
         WARN("Invalid sampler index %u, count %u.\n", start_idx, count);
         return;
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index 615fb00905f..85105d1f8de 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -61,7 +61,7 @@ HRESULT CDECL wined3d_palette_get_entries(const struct wined3d_palette *palette,
 
     if (flags)
         return WINED3DERR_INVALIDCALL; /* unchecked */
-    if (start > palette->size || count > palette->size - start)
+    if (!wined3d_bound_range(start, count, palette->size))
         return WINED3DERR_INVALIDCALL;
 
     if (palette->flags & WINED3D_PALETTE_8BIT_ENTRIES)
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 1f1ba262336..4cf30941d62 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -1204,8 +1204,7 @@ HRESULT CDECL wined3d_stateblock_set_vs_consts_f(struct wined3d_stateblock *stat
     TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n",
             stateblock, start_idx, count, constants);
 
-    if (!constants || start_idx >= d3d_info->limits.vs_uniform_count
-            || count > d3d_info->limits.vs_uniform_count - start_idx)
+    if (!constants || !wined3d_bound_range(start_idx, count, d3d_info->limits.vs_uniform_count))
         return WINED3DERR_INVALIDCALL;
 
     memcpy(&stateblock->stateblock_state.vs_consts_f[start_idx], constants, count * sizeof(*constants));
@@ -1273,8 +1272,7 @@ HRESULT CDECL wined3d_stateblock_set_ps_consts_f(struct wined3d_stateblock *stat
     TRACE("stateblock %p, start_idx %u, count %u, constants %p.\n",
             stateblock, start_idx, count, constants);
 
-    if (!constants || start_idx >= d3d_info->limits.ps_uniform_count
-            || count > d3d_info->limits.ps_uniform_count - start_idx)
+    if (!constants || !wined3d_bound_range(start_idx, count, d3d_info->limits.ps_uniform_count))
         return WINED3DERR_INVALIDCALL;
 
     memcpy(&stateblock->stateblock_state.ps_consts_f[start_idx], constants, count * sizeof(*constants));
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 03d6a4d17b5..55742fb06b6 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -132,8 +132,7 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_
             return NULL;
 
         buffer_size = buffer->resource.size / element_size;
-        if (desc->u.buffer.start_idx >= buffer_size
-                || desc->u.buffer.count > buffer_size - desc->u.buffer.start_idx)
+        if (!wined3d_bound_range(desc->u.buffer.start_idx, desc->u.buffer.count, buffer_size))
             return NULL;
     }
     else
@@ -156,11 +155,9 @@ static const struct wined3d_format *validate_resource_view(const struct wined3d_
 
         if (!desc->u.texture.level_count
                 || (mip_slice && desc->u.texture.level_count != 1)
-                || desc->u.texture.level_idx >= texture->level_count
-                || desc->u.texture.level_count > texture->level_count - desc->u.texture.level_idx
+                || !wined3d_bound_range(desc->u.texture.level_idx, desc->u.texture.level_count, texture->level_count)
                 || !desc->u.texture.layer_count
-                || desc->u.texture.layer_idx >= depth_or_layer_count
-                || desc->u.texture.layer_count > depth_or_layer_count - desc->u.texture.layer_idx)
+                || !wined3d_bound_range(desc->u.texture.layer_idx, desc->u.texture.layer_count, depth_or_layer_count))
             return NULL;
     }
 
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 80a636edc9f..10253cab87d 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2927,6 +2927,17 @@ static inline int wined3d_bit_scan(unsigned int *x)
     return bit_offset;
 }
 
+static inline bool wined3d_bound_range(unsigned int start, unsigned int count, unsigned int limit)
+{
+#if defined(__GNUC__) && __GNUC__ >= 5
+    unsigned int sum;
+
+    return !__builtin_add_overflow(start, count, &sum) && sum <= limit;
+#else
+    return start <= limit && count <= limit - start;
+#endif
+}
+
 static inline void wined3d_box_set(struct wined3d_box *box, unsigned int left, unsigned int top,
         unsigned int right, unsigned int bottom, unsigned int front, unsigned int back)
 {
-- 
2.30.2




More information about the wine-devel mailing list