diff --git a/hw/xbox/nv2a/pgraph/glsl/psh.c b/hw/xbox/nv2a/pgraph/glsl/psh.c
index 243aee04ed..ffb387d997 100644
--- a/hw/xbox/nv2a/pgraph/glsl/psh.c
+++ b/hw/xbox/nv2a/pgraph/glsl/psh.c
@@ -562,6 +562,24 @@ static void add_final_stage_code(struct PixelShader *ps, struct FCInputInfo fina
     ps->varE = ps->varF = NULL;
 }
 
+static enum PS_TEXTUREMODES correct_texture_mode_for_dimensionality(enum PS_TEXTUREMODES mode, const PshState *state, int i)
+{
+    int dim = state->dim_tex[i];
+
+    switch (mode) {
+    case PS_TEXTUREMODES_PROJECT2D:
+        return dim == 2 ? PS_TEXTUREMODES_PROJECT2D :
+               dim == 3 ? PS_TEXTUREMODES_PROJECT3D :
+                          mode;
+    case PS_TEXTUREMODES_PROJECT3D:
+        return dim == 2 ? PS_TEXTUREMODES_PROJECT2D : mode;
+    case PS_TEXTUREMODES_DOT_STR_3D:
+        return dim == 2 ? PS_TEXTUREMODES_DOT_ST : mode;
+    default:
+        return mode;
+    }
+}
+
 static const char sampler2D[] = "sampler2D";
 static const char sampler3D[] = "sampler3D";
 static const char samplerCube[] = "samplerCube";
@@ -575,6 +593,7 @@ static const char* get_sampler_type(enum PS_TEXTUREMODES mode, const PshState *s
         return NULL;
 
     case PS_TEXTUREMODES_PROJECT2D:
+        assert(state->dim_tex[i] == 2);
         return (state->rect_tex[i] && !state->vulkan) ? sampler2DRect : sampler2D;
 
     case PS_TEXTUREMODES_BUMPENVMAP:
@@ -584,6 +603,7 @@ static const char* get_sampler_type(enum PS_TEXTUREMODES mode, const PshState *s
             fprintf(stderr, "Shadow map support not implemented for mode %d\n", mode);
             assert(!"Shadow map support not implemented for this mode");
         }
+        assert(state->dim_tex[i] == 2);
         return (state->rect_tex[i] && !state->vulkan) ? sampler2DRect : sampler2D;
 
     case PS_TEXTUREMODES_PROJECT3D:
@@ -594,6 +614,7 @@ static const char* get_sampler_type(enum PS_TEXTUREMODES mode, const PshState *s
         if (state->shadow_map[i]) {
             return (state->rect_tex[i] && !state->vulkan) ? sampler2DRect : sampler2D;
         }
+        assert(state->dim_tex[i] == 3);
         return sampler3D;
 
     case PS_TEXTUREMODES_CUBEMAP:
@@ -604,6 +625,7 @@ static const char* get_sampler_type(enum PS_TEXTUREMODES mode, const PshState *s
             fprintf(stderr, "Shadow map support not implemented for mode %d\n", mode);
             assert(!"Shadow map support not implemented for this mode");
         }
+        assert(state->dim_tex[i] == 2);
         return samplerCube;
 
     case PS_TEXTUREMODES_DPNDNT_AR:
@@ -612,6 +634,7 @@ static const char* get_sampler_type(enum PS_TEXTUREMODES mode, const PshState *s
             fprintf(stderr, "Shadow map support not implemented for mode %d\n", mode);
             assert(!"Shadow map support not implemented for this mode");
         }
+        assert(state->dim_tex[i] == 2);
         return sampler2D;
     }
 }
@@ -1245,6 +1268,7 @@ MString *pgraph_gen_psh_glsl(const PshState state)
     ps.flags = state.combiner_control >> 8;
     for (i = 0; i < 4; i++) {
         ps.tex_modes[i] = (state.shader_stage_program >> (i * 5)) & 0x1F;
+        ps.tex_modes[i] = correct_texture_mode_for_dimensionality(ps.tex_modes[i], &state, i);
     }
 
     ps.dot_map[0] = 0;
diff --git a/hw/xbox/nv2a/pgraph/psh.h b/hw/xbox/nv2a/pgraph/psh.h
index 6232a2834a..1366045707 100644
--- a/hw/xbox/nv2a/pgraph/psh.h
+++ b/hw/xbox/nv2a/pgraph/psh.h
@@ -71,6 +71,7 @@ typedef struct PshState {
     bool alphakill[4];
     enum ConvolutionFilter conv_tex[4];
     bool tex_x8y24[4];
+    int dim_tex[4];
 
     float border_logical_size[4][3];
     float border_inv_real_size[4][3];
diff --git a/hw/xbox/nv2a/pgraph/shaders.c b/hw/xbox/nv2a/pgraph/shaders.c
index 285d24f439..8d2c77a535 100644
--- a/hw/xbox/nv2a/pgraph/shaders.c
+++ b/hw/xbox/nv2a/pgraph/shaders.c
@@ -204,6 +204,8 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
         state.psh.alphakill[i] = ctl_0 & NV_PGRAPH_TEXCTL0_0_ALPHAKILLEN;
 
         uint32_t tex_fmt = pgraph_reg_r(pg, NV_PGRAPH_TEXFMT0 + i * 4);
+        state.psh.dim_tex[i] = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_DIMENSIONALITY);
+
         unsigned int color_format = GET_MASK(tex_fmt, NV_PGRAPH_TEXFMT0_COLOR);
         BasicColorFormatInfo f = kelvin_color_format_info_map[color_format];
         state.psh.rect_tex[i] = f.linear;