diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
index c29d2665b134ea75edfbd305c21f82ea71423edb..ace7694a59e50449ce2cb875ef4250a7d4e76b3e 100644
--- a/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -1517,6 +1517,7 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
         case HLSL_CLASS_STRING:
         case HLSL_CLASS_TEXTURE:
             return D3DXPC_OBJECT;
+        case HLSL_CLASS_UAV:
         case HLSL_CLASS_VOID:
             break;
     }
@@ -1613,6 +1614,7 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
         case HLSL_CLASS_STRING:
             return D3DXPT_STRING;
 
+        case HLSL_CLASS_UAV:
         case HLSL_CLASS_VOID:
             break;
     }
diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c
index 0b32f4abbc58ad9feb8788f117811431ff234f1c..984437975430d21f06e08732a1937d89058b08a8 100644
--- a/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d-shader/fx.c
@@ -383,7 +383,7 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
     if (type->class == HLSL_CLASS_TEXTURE)
         return texture_type_names[type->sampler_dim];
 
-    if (type->base_type == HLSL_TYPE_UAV)
+    if (type->class == HLSL_CLASS_UAV)
         return uav_type_names[type->sampler_dim];
 
     switch (type->base_type)
@@ -428,6 +428,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
 
         case HLSL_CLASS_OBJECT:
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
             put_u32_unaligned(buffer, 2);
             break;
 
@@ -494,15 +495,8 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
 
         put_u32_unaligned(buffer, texture_type[type->sampler_dim]);
     }
-    else if (type->class == HLSL_CLASS_OBJECT)
+    else if (type->class == HLSL_CLASS_UAV)
     {
-        static const uint32_t object_type[] =
-        {
-            [HLSL_TYPE_PIXELSHADER]      = 5,
-            [HLSL_TYPE_VERTEXSHADER]     = 6,
-            [HLSL_TYPE_RENDERTARGETVIEW] = 19,
-            [HLSL_TYPE_DEPTHSTENCILVIEW] = 20,
-        };
         static const uint32_t uav_type[] =
         {
             [HLSL_SAMPLER_DIM_1D]                = 31,
@@ -514,6 +508,18 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
             [HLSL_SAMPLER_DIM_STRUCTURED_BUFFER] = 40,
         };
 
+        put_u32_unaligned(buffer, uav_type[type->sampler_dim]);
+    }
+    else if (type->class == HLSL_CLASS_OBJECT)
+    {
+        static const uint32_t object_type[] =
+        {
+            [HLSL_TYPE_PIXELSHADER]      = 5,
+            [HLSL_TYPE_VERTEXSHADER]     = 6,
+            [HLSL_TYPE_RENDERTARGETVIEW] = 19,
+            [HLSL_TYPE_DEPTHSTENCILVIEW] = 20,
+        };
+
         switch (type->base_type)
         {
             case HLSL_TYPE_DEPTHSTENCILVIEW:
@@ -522,9 +528,6 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
             case HLSL_TYPE_VERTEXSHADER:
                 put_u32_unaligned(buffer, object_type[type->base_type]);
                 break;
-            case HLSL_TYPE_UAV:
-                put_u32_unaligned(buffer, uav_type[type->sampler_dim]);
-                break;
             default:
                 hlsl_fixme(ctx, &ctx->location, "Object type %u is not supported.", type->base_type);
                 return 0;
@@ -828,6 +831,7 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type
             hlsl_fixme(ctx, loc, "Write fx 2.0 parameter class %#x.", type->class);
             return false;
 
+        case HLSL_CLASS_UAV:
         case HLSL_CLASS_VOID:
             return false;
     }
@@ -1008,12 +1012,12 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_
     switch (type->class)
     {
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
             break;
 
         case HLSL_CLASS_OBJECT:
             switch (type->base_type)
             {
-                case HLSL_TYPE_UAV:
                 case HLSL_TYPE_RENDERTARGETVIEW:
                     break;
                 case HLSL_TYPE_PIXELSHADER:
@@ -1116,12 +1120,12 @@ static bool is_object_variable(const struct hlsl_ir_var *var)
     {
         case HLSL_CLASS_SAMPLER:
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
             return true;
 
         case HLSL_CLASS_OBJECT:
             switch (type->base_type)
             {
-                case HLSL_TYPE_UAV:
                 case HLSL_TYPE_PIXELSHADER:
                 case HLSL_TYPE_VERTEXSHADER:
                 case HLSL_TYPE_RENDERTARGETVIEW:
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 55135254f585dce1fec867138a6ccbb76da0a7aa..ad6a443bce87396a1216879c038156d7652e6a9b 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -233,17 +233,9 @@ bool hlsl_type_is_resource(const struct hlsl_type *type)
 
         case HLSL_CLASS_SAMPLER:
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
             return true;
 
-        case HLSL_CLASS_OBJECT:
-            switch (type->base_type)
-            {
-                case HLSL_TYPE_UAV:
-                    return true;
-                default:
-                    return false;
-            }
-
         default:
             return false;
     }
@@ -269,15 +261,8 @@ static enum hlsl_regset type_get_regset(const struct hlsl_type *type)
         case HLSL_CLASS_TEXTURE:
             return HLSL_REGSET_TEXTURES;
 
-        case HLSL_CLASS_OBJECT:
-            switch (type->base_type)
-            {
-                case HLSL_TYPE_UAV:
-                    return HLSL_REGSET_UAVS;
-
-                default:
-                    vkd3d_unreachable();
-            }
+        case HLSL_CLASS_UAV:
+            return HLSL_REGSET_UAVS;
 
         default:
             break;
@@ -366,17 +351,6 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
             break;
         }
 
-        case HLSL_CLASS_OBJECT:
-        {
-            if (hlsl_type_is_resource(type))
-            {
-                enum hlsl_regset regset = type_get_regset(type);
-
-                type->reg_size[regset] = 1;
-            }
-            break;
-        }
-
         case HLSL_CLASS_SAMPLER:
             type->reg_size[HLSL_REGSET_SAMPLERS] = 1;
             break;
@@ -385,6 +359,11 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
             type->reg_size[HLSL_REGSET_TEXTURES] = 1;
             break;
 
+        case HLSL_CLASS_UAV:
+            type->reg_size[HLSL_REGSET_UAVS] = 1;
+            break;
+
+        case HLSL_CLASS_OBJECT:
         case HLSL_CLASS_STRING:
         case HLSL_CLASS_VOID:
             break;
@@ -451,6 +430,7 @@ static bool type_is_single_component(const struct hlsl_type *type)
         case HLSL_CLASS_SAMPLER:
         case HLSL_CLASS_STRING:
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
             return true;
 
         case HLSL_CLASS_VECTOR:
@@ -585,6 +565,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
             case HLSL_CLASS_SAMPLER:
             case HLSL_CLASS_STRING:
             case HLSL_CLASS_TEXTURE:
+            case HLSL_CLASS_UAV:
                 assert(idx == 0);
                 break;
 
@@ -851,8 +832,7 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim
 
     if (!(type = hlsl_alloc(ctx, sizeof(*type))))
         return NULL;
-    type->class = HLSL_CLASS_OBJECT;
-    type->base_type = HLSL_TYPE_UAV;
+    type->class = HLSL_CLASS_UAV;
     type->dimx = format->dimx;
     type->dimy = 1;
     type->sampler_dim = dim;
@@ -958,6 +938,7 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
         case HLSL_CLASS_SAMPLER:
         case HLSL_CLASS_STRING:
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
             return 1;
 
         case HLSL_CLASS_VOID:
@@ -976,16 +957,15 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
         return false;
     if (t1->base_type != t2->base_type)
         return false;
-    if (t1->class == HLSL_CLASS_SAMPLER || t1->class == HLSL_CLASS_TEXTURE
-            || t1->base_type == HLSL_TYPE_UAV)
+    if (t1->class == HLSL_CLASS_SAMPLER || t1->class == HLSL_CLASS_TEXTURE || t1->class == HLSL_CLASS_UAV)
     {
         if (t1->sampler_dim != t2->sampler_dim)
             return false;
-        if ((t1->class == HLSL_CLASS_TEXTURE || t1->base_type == HLSL_TYPE_UAV)
+        if ((t1->class == HLSL_CLASS_TEXTURE || t1->class == HLSL_CLASS_UAV)
                 && t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC
                 && !hlsl_types_are_equal(t1->e.resource.format, t2->e.resource.format))
             return false;
-        if (t1->base_type == HLSL_TYPE_UAV && t1->e.resource.rasteriser_ordered != t2->e.resource.rasteriser_ordered)
+        if (t1->class == HLSL_CLASS_UAV && t1->e.resource.rasteriser_ordered != t2->e.resource.rasteriser_ordered)
             return false;
     }
     if ((t1->modifiers & HLSL_MODIFIER_ROW_MAJOR)
@@ -1102,6 +1082,9 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
             break;
         }
 
+        case HLSL_CLASS_UAV:
+            type->e.resource.rasteriser_ordered = old->e.resource.rasteriser_ordered;
+            /* fall through */
         case HLSL_CLASS_TEXTURE:
             type->e.resource.format = old->e.resource.format;
             break;
@@ -1109,11 +1092,6 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
         case HLSL_CLASS_OBJECT:
             if (type->base_type == HLSL_TYPE_TECHNIQUE)
                 type->e.version = old->e.version;
-            if (old->base_type == HLSL_TYPE_UAV)
-            {
-                type->e.resource.format = old->e.resource.format;
-                type->e.resource.rasteriser_ordered = old->e.resource.rasteriser_ordered;
-            }
             break;
 
         default:
@@ -1688,7 +1666,7 @@ bool hlsl_index_is_resource_access(struct hlsl_ir_index *index)
 {
     const struct hlsl_type *type = index->val.node->data_type;
 
-    return type->class == HLSL_CLASS_TEXTURE || (type->class == HLSL_CLASS_OBJECT && type->base_type == HLSL_TYPE_UAV);
+    return type->class == HLSL_CLASS_TEXTURE || type->class == HLSL_CLASS_UAV;
 }
 
 bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index)
@@ -1709,7 +1687,7 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v
     if (!(index = hlsl_alloc(ctx, sizeof(*index))))
         return NULL;
 
-    if (type->class == HLSL_CLASS_TEXTURE || type->class == HLSL_CLASS_OBJECT)
+    if (type->class == HLSL_CLASS_TEXTURE || type->class == HLSL_CLASS_UAV)
         type = type->e.resource.format;
     else if (type->class == HLSL_CLASS_MATRIX)
         type = hlsl_get_vector_type(ctx, type->base_type, type->dimx);
@@ -2363,29 +2341,21 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
             }
             return string;
 
-        case HLSL_CLASS_OBJECT:
-        {
-            switch (type->base_type)
+        case HLSL_CLASS_UAV:
+            if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER)
+                vkd3d_string_buffer_printf(string, "RWBuffer");
+            else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+                vkd3d_string_buffer_printf(string, "RWStructuredBuffer");
+            else
+                vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]);
+            if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format)))
             {
-                case HLSL_TYPE_UAV:
-                    if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER)
-                        vkd3d_string_buffer_printf(string, "RWBuffer");
-                    else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
-                        vkd3d_string_buffer_printf(string, "RWStructuredBuffer");
-                    else
-                        vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]);
-                    if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format)))
-                    {
-                        vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer);
-                        hlsl_release_string_buffer(ctx, inner_string);
-                    }
-                    return string;
-
-                default:
-                    break;
+                vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer);
+                hlsl_release_string_buffer(ctx, inner_string);
             }
-        }
+            return string;
 
+        case HLSL_CLASS_OBJECT:
         case HLSL_CLASS_SAMPLER:
         case HLSL_CLASS_STRING:
         case HLSL_CLASS_VOID:
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index be9748c6edfdd1c7efef1a2a0fde8a2d19f96dfd..aff3c59fa6346d7ec8dc8d7abc44082f8b3e2864 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -82,6 +82,7 @@ enum hlsl_type_class
     HLSL_CLASS_SAMPLER,
     HLSL_CLASS_STRING,
     HLSL_CLASS_TEXTURE,
+    HLSL_CLASS_UAV,
     HLSL_CLASS_VOID,
 };
 
@@ -94,7 +95,6 @@ enum hlsl_base_type
     HLSL_TYPE_UINT,
     HLSL_TYPE_BOOL,
     HLSL_TYPE_LAST_SCALAR = HLSL_TYPE_BOOL,
-    HLSL_TYPE_UAV,
     HLSL_TYPE_PIXELSHADER,
     HLSL_TYPE_VERTEXSHADER,
     HLSL_TYPE_PASS,
@@ -153,7 +153,7 @@ struct hlsl_type
     /* If class is HLSL_CLASS_SAMPLER, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_SAMPLER.
      * If class is HLSL_CLASS_TEXTURE, then sampler_dim can be any value of the enum except
      *   HLSL_SAMPLER_DIM_GENERIC and HLSL_SAMPLER_DIM_COMPARISON.
-     * If base_type is HLSL_TYPE_UAV, then sampler_dim must be one of HLSL_SAMPLER_DIM_1D,
+     * If class is HLSL_CLASS_UAV, then sampler_dim must be one of HLSL_SAMPLER_DIM_1D,
      *   HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, HLSL_SAMPLER_DIM_2DARRAY,
      *   HLSL_SAMPLER_DIM_BUFFER, or HLSL_SAMPLER_DIM_STRUCTURED_BUFFER.
      * Otherwise, sampler_dim is not used */
@@ -171,8 +171,6 @@ struct hlsl_type
      * If type is HLSL_CLASS_MATRIX, then dimx is the number of columns, and dimy the number of rows.
      * If type is HLSL_CLASS_ARRAY, then dimx and dimy have the same value as in the type of the array elements.
      * If type is HLSL_CLASS_STRUCT, then dimx is the sum of (dimx * dimy) of every component, and dimy = 1.
-     * If type is HLSL_CLASS_OBJECT, dimx and dimy depend on the base_type:
-     *   If base_type is HLSL_TYPE_UAV, then dimx is the dimx of e.resource_format, and dimy = 1.
      */
     unsigned int dimx;
     unsigned int dimy;
@@ -194,8 +192,8 @@ struct hlsl_type
             /* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */
             unsigned int elements_count;
         } array;
-        /* Additional information if the base_type is HLSL_TYPE_TEXTURE or
-         * HLSL_TYPE_UAV. */
+        /* Additional information if the class is HLSL_CLASS_TEXTURE or
+         * HLSL_CLASS_UAV. */
         struct
         {
             /* Format of the data contained within the type. */
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 71522e054581273d418e5c649bf97b20dc8c58d2..0c196b77595c97e2e2a2396ccd1db61d75662492 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -833,8 +833,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str
     const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type;
     struct hlsl_ir_node *return_index, *cast;
 
-    if ((expr_type->class == HLSL_CLASS_TEXTURE
-            || (expr_type->class == HLSL_CLASS_OBJECT && expr_type->base_type == HLSL_TYPE_UAV))
+    if ((expr_type->class == HLSL_CLASS_TEXTURE || expr_type->class == HLSL_CLASS_UAV)
             && expr_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)
     {
         unsigned int dim_count = hlsl_sampler_dim_count(expr_type->sampler_dim);
@@ -1941,10 +1940,9 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
             return NULL;
 
         resource_type = hlsl_deref_get_type(ctx, &resource_deref);
-        assert(resource_type->class == HLSL_CLASS_TEXTURE
-                || (resource_type->class == HLSL_CLASS_OBJECT && resource_type->base_type == HLSL_TYPE_UAV));
+        assert(resource_type->class == HLSL_CLASS_TEXTURE || resource_type->class == HLSL_CLASS_UAV);
 
-        if (resource_type->base_type != HLSL_TYPE_UAV)
+        if (resource_type->class != HLSL_CLASS_UAV)
             hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
                     "Read-only resources cannot be stored to.");
 
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index e6c8dab9c4b87825009259f20197fdfe5ad49ff4..f6cccfe8bea4544db7c26322d89c8b3ee18b682a 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -1627,6 +1627,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
         case HLSL_CLASS_VECTOR:
         case HLSL_CLASS_SAMPLER:
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
         case HLSL_CLASS_OBJECT:
             break;
 
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c
index db4e5e2fb52e9ec4691eb81d4b01f0c539f8acf3..6ee06c02d7409e3fbf9b4d599fcfee5676958405 100644
--- a/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d-shader/tpf.c
@@ -3011,6 +3011,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
         case HLSL_CLASS_SAMPLER:
         case HLSL_CLASS_STRING:
         case HLSL_CLASS_TEXTURE:
+        case HLSL_CLASS_UAV:
         case HLSL_CLASS_VOID:
             break;
     }
@@ -3119,15 +3120,8 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type)
             return D3D_SIT_SAMPLER;
         case HLSL_CLASS_TEXTURE:
             return D3D_SIT_TEXTURE;
-        case HLSL_CLASS_OBJECT:
-            switch (type->base_type)
-            {
-                case HLSL_TYPE_UAV:
-                    return D3D_SIT_UAV_RWTYPED;
-                default:
-                    break;
-            }
-
+        case HLSL_CLASS_UAV:
+            return D3D_SIT_UAV_RWTYPED;
         default:
             break;
     }