diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index eafc06e2ea599b2d479a7969b7f126b147697b0f..2e10aa55e00c394c8e2190f2c27e2a392ed428b5 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -2952,6 +2952,46 @@ static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *va
         buffer->used_size = max(buffer->used_size, var->buffer_offset + var_reg_size);
 }
 
+static void validate_buffer_offsets(struct hlsl_ctx *ctx)
+{
+    struct hlsl_ir_var *var1, *var2;
+    struct hlsl_buffer *buffer;
+
+    LIST_FOR_EACH_ENTRY(var1, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+    {
+        if (!var1->is_uniform || var1->data_type->class == HLSL_CLASS_OBJECT)
+            continue;
+
+        buffer = var1->buffer;
+        if (!buffer->used_size)
+            continue;
+
+        LIST_FOR_EACH_ENTRY(var2, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+        {
+            unsigned int var1_reg_size, var2_reg_size;
+
+            if (!var2->is_uniform || var2->data_type->class == HLSL_CLASS_OBJECT)
+                continue;
+
+            if (var1 == var2 || var1->buffer != var2->buffer)
+                continue;
+
+            /* This is to avoid reporting the error twice for the same pair of overlapping variables. */
+            if (strcmp(var1->name, var2->name) >= 0)
+                continue;
+
+            var1_reg_size = var1->data_type->reg_size[HLSL_REGSET_NUMERIC];
+            var2_reg_size = var2->data_type->reg_size[HLSL_REGSET_NUMERIC];
+
+            if (var1->buffer_offset < var2->buffer_offset + var2_reg_size
+                    && var2->buffer_offset < var1->buffer_offset + var1_reg_size)
+                hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+                        "Invalid packoffset() reservation: Variables %s and %s overlap.",
+                        var1->name, var2->name);
+        }
+    }
+}
+
 static void allocate_buffers(struct hlsl_ctx *ctx)
 {
     struct hlsl_buffer *buffer;
@@ -2969,6 +3009,8 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
         }
     }
 
+    validate_buffer_offsets(ctx);
+
     LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry)
     {
         if (!buffer->used_size)
diff --git a/tests/cbuffer.shader_test b/tests/cbuffer.shader_test
index bf71162900848816c6cb9d6c647deaa198132ea0..d8cfc351ee6841df78a741bb7ee02972c5ede5e0 100644
--- a/tests/cbuffer.shader_test
+++ b/tests/cbuffer.shader_test
@@ -106,7 +106,7 @@ draw quad
 probe all rgba (0.0, 4.0, 5.0, 6.0)
 
 
-[pixel shader fail todo]
+[pixel shader fail]
 // Elements cannot overlap if buffer is used.
 cbuffer buffer
 {