summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/nine/device9.c3
-rw-r--r--src/gallium/state_trackers/nine/nine_shader.c59
-rw-r--r--src/gallium/state_trackers/nine/nine_shader.h1
-rw-r--r--src/gallium/state_trackers/nine/nine_state.c5
-rw-r--r--src/gallium/state_trackers/nine/nine_state.h5
-rw-r--r--src/gallium/state_trackers/nine/pixelshader9.c2
-rw-r--r--src/gallium/state_trackers/nine/pixelshader9.h7
7 files changed, 74 insertions, 8 deletions
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 8023f785e10..aa5734b90f3 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -2637,6 +2637,9 @@ NineDevice9_SetTextureStageState( struct NineDevice9 *This,
case D3DTSS_BUMPENVLOFFSET:
bumpmap_index = 4 * 8 + 2 * Stage + 1;
break;
+ case D3DTSS_TEXTURETRANSFORMFLAGS:
+ state->changed.group |= NINE_STATE_PS1X_SHADER;
+ break;
default:
break;
}
diff --git a/src/gallium/state_trackers/nine/nine_shader.c b/src/gallium/state_trackers/nine/nine_shader.c
index 2e35edecaf7..7e76d7d5ba8 100644
--- a/src/gallium/state_trackers/nine/nine_shader.c
+++ b/src/gallium/state_trackers/nine/nine_shader.c
@@ -681,6 +681,54 @@ tx_pred_alloc(struct shader_translator *tx, INT idx)
tx->regs.p = ureg_DECL_predicate(tx->ureg);
}
+/* NOTE: It's not very clear on which ps1.1-ps1.3 instructions
+ * the projection should be applied on the texture. It doesn't
+ * apply on texkill.
+ * The doc is very imprecise here (it says the projection is done
+ * before rasterization, thus in vs, which seems wrong since ps instructions
+ * are affected differently)
+ * For now we only apply to the ps TEX instruction and TEXBEM.
+ * Perhaps some other instructions would need it */
+static inline void
+apply_ps1x_projection(struct shader_translator *tx, struct ureg_dst dst,
+ struct ureg_src src, INT idx)
+{
+ struct ureg_dst tmp;
+ unsigned dim = 1 + ((tx->info->projected >> (2 * idx)) & 3);
+
+ /* no projection */
+ if (dim == 1) {
+ ureg_MOV(tx->ureg, dst, src);
+ } else {
+ tmp = tx_scratch_scalar(tx);
+ ureg_RCP(tx->ureg, tmp, ureg_scalar(src, dim-1));
+ ureg_MUL(tx->ureg, dst, tx_src_scalar(tmp), src);
+ }
+}
+
+static inline void
+TEX_with_ps1x_projection(struct shader_translator *tx, struct ureg_dst dst,
+ unsigned target, struct ureg_src src0,
+ struct ureg_src src1, INT idx)
+{
+ unsigned dim = 1 + ((tx->info->projected >> (2 * idx)) & 3);
+ struct ureg_dst tmp;
+
+ /* dim == 1: no projection
+ * Looks like must be disabled when it makes no
+ * sense according the texture dimensions
+ */
+ if (dim == 1 || dim <= target) {
+ ureg_TEX(tx->ureg, dst, target, src0, src1);
+ } else if (dim == 4) {
+ ureg_TXP(tx->ureg, dst, target, src0, src1);
+ } else {
+ tmp = tx_scratch(tx);
+ apply_ps1x_projection(tx, tmp, src0, idx);
+ ureg_TEX(tx->ureg, dst, target, ureg_src(tmp), src1);
+ }
+}
+
static inline void
tx_texcoord_alloc(struct shader_translator *tx, INT idx)
{
@@ -2155,7 +2203,7 @@ DECL_SPECIAL(TEXBEM)
{
struct ureg_program *ureg = tx->ureg;
struct ureg_dst dst = tx_dst_param(tx, &tx->insn.dst[0]);
- struct ureg_dst tmp, tmp2;
+ struct ureg_dst tmp, tmp2, texcoord;
struct ureg_src sample, m00, m01, m10, m11;
struct ureg_src bumpenvlscale, bumpenvloffset;
const int m = tx->insn.dst[0].idx;
@@ -2170,6 +2218,7 @@ DECL_SPECIAL(TEXBEM)
tmp = tx_scratch(tx);
tmp2 = tx_scratch(tx);
+ texcoord = tx_scratch(tx);
/*
* Bump-env-matrix:
* 00 is X
@@ -2192,9 +2241,11 @@ DECL_SPECIAL(TEXBEM)
bumpenvloffset = NINE_CONSTANT_SRC_SWIZZLE(8 + 8 + m / 2, W);
}
+ apply_ps1x_projection(tx, texcoord, tx->regs.vT[m], m);
+
/* u' = TextureCoordinates(stage m)u + D3DTSS_BUMPENVMAT00(stage m)*t(n)R */
ureg_MAD(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), m00,
- NINE_APPLY_SWIZZLE(ureg_src(tx->regs.tS[n]), X), tx->regs.vT[m]);
+ NINE_APPLY_SWIZZLE(ureg_src(tx->regs.tS[n]), X), ureg_src(texcoord));
/* u' = u' + D3DTSS_BUMPENVMAT10(stage m)*t(n)G */
ureg_MAD(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_X), m10,
NINE_APPLY_SWIZZLE(ureg_src(tx->regs.tS[n]), Y),
@@ -2202,7 +2253,7 @@ DECL_SPECIAL(TEXBEM)
/* v' = TextureCoordinates(stage m)v + D3DTSS_BUMPENVMAT01(stage m)*t(n)R */
ureg_MAD(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), m01,
- NINE_APPLY_SWIZZLE(ureg_src(tx->regs.tS[n]), X), tx->regs.vT[m]);
+ NINE_APPLY_SWIZZLE(ureg_src(tx->regs.tS[n]), X), ureg_src(texcoord));
/* v' = v' + D3DTSS_BUMPENVMAT11(stage m)*t(n)G*/
ureg_MAD(ureg, ureg_writemask(tmp, TGSI_WRITEMASK_Y), m11,
NINE_APPLY_SWIZZLE(ureg_src(tx->regs.tS[n]), Y),
@@ -2600,7 +2651,7 @@ DECL_SPECIAL(TEX)
src[1] = ureg_DECL_sampler(ureg, s);
tx->info->sampler_mask |= 1 << s;
- ureg_TEX(ureg, dst, t, src[0], src[1]);
+ TEX_with_ps1x_projection(tx, dst, t, src[0], src[1], s);
return D3D_OK;
}
diff --git a/src/gallium/state_trackers/nine/nine_shader.h b/src/gallium/state_trackers/nine/nine_shader.h
index 3ba79af47c7..41577ac572b 100644
--- a/src/gallium/state_trackers/nine/nine_shader.h
+++ b/src/gallium/state_trackers/nine/nine_shader.h
@@ -61,6 +61,7 @@ struct nine_shader_info
uint8_t fog_enable;
uint8_t fog_mode;
+ uint16_t projected; /* ps 1.1 to 1.3 */
unsigned const_i_base; /* in vec4 (16 byte) units */
unsigned const_b_base; /* in vec4 (16 byte) units */
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index e185b025134..a4392171f2c 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -961,7 +961,8 @@ commit_ps(struct NineDevice9 *device)
NINE_STATE_BLEND_COLOR | \
NINE_STATE_STENCIL_REF | \
NINE_STATE_SAMPLE_MASK | \
- NINE_STATE_FOG_SHADER)
+ NINE_STATE_FOG_SHADER | \
+ NINE_STATE_PS1X_SHADER)
#define NINE_STATE_FREQ_GROUP_1 ~NINE_STATE_FREQ_GROUP_0
@@ -1032,7 +1033,7 @@ nine_update_state(struct NineDevice9 *device)
if (group & NINE_STATE_RASTERIZER)
prepare_rasterizer(device);
- if (group & (NINE_STATE_PS | NINE_STATE_TEXTURE | NINE_STATE_FOG_SHADER))
+ if (group & (NINE_STATE_PS | NINE_STATE_TEXTURE | NINE_STATE_FOG_SHADER | NINE_STATE_PS1X_SHADER))
group |= prepare_ps(device, (group & NINE_STATE_PS) != 0);
if (group & NINE_STATE_BLEND_COLOR) {
diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h
index f1af49fa137..109c0bb93ca 100644
--- a/src/gallium/state_trackers/nine/nine_state.h
+++ b/src/gallium/state_trackers/nine/nine_state.h
@@ -76,8 +76,9 @@
#define NINE_STATE_FF_PSSTAGES (1 << 22)
#define NINE_STATE_FF_OTHER (1 << 23)
#define NINE_STATE_FOG_SHADER (1 << 24)
-#define NINE_STATE_ALL 0x1ffffff
-#define NINE_STATE_UNHANDLED (1 << 25)
+#define NINE_STATE_PS1X_SHADER (1 << 25)
+#define NINE_STATE_ALL 0x3ffffff
+#define NINE_STATE_UNHANDLED (1 << 26)
#define NINE_STATE_COMMIT_DSA (1 << 0)
#define NINE_STATE_COMMIT_RASTERIZER (1 << 1)
diff --git a/src/gallium/state_trackers/nine/pixelshader9.c b/src/gallium/state_trackers/nine/pixelshader9.c
index 6173b0eea05..42bc349c2cc 100644
--- a/src/gallium/state_trackers/nine/pixelshader9.c
+++ b/src/gallium/state_trackers/nine/pixelshader9.c
@@ -58,6 +58,7 @@ NinePixelShader9_ctor( struct NinePixelShader9 *This,
info.sampler_mask_shadow = 0x0;
info.sampler_ps1xtypes = 0x0;
info.fog_enable = 0;
+ info.projected = 0;
hr = nine_translate_shader(device, &info);
if (FAILED(hr))
@@ -159,6 +160,7 @@ NinePixelShader9_GetVariant( struct NinePixelShader9 *This )
info.sampler_ps1xtypes = key;
info.fog_enable = device->state.rs[D3DRS_FOGENABLE];
info.fog_mode = device->state.rs[D3DRS_FOGTABLEMODE];
+ info.projected = (key >> 48) & 0xffff;
hr = nine_translate_shader(This->base.device, &info);
if (FAILED(hr))
diff --git a/src/gallium/state_trackers/nine/pixelshader9.h b/src/gallium/state_trackers/nine/pixelshader9.h
index 5d1f5041c47..e09009f6621 100644
--- a/src/gallium/state_trackers/nine/pixelshader9.h
+++ b/src/gallium/state_trackers/nine/pixelshader9.h
@@ -27,6 +27,7 @@
#include "nine_shader.h"
#include "nine_state.h"
#include "basetexture9.h"
+#include "nine_ff.h"
struct nine_lconstf;
@@ -67,6 +68,7 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
{
uint16_t samplers_shadow;
uint32_t samplers_ps1_types;
+ uint16_t projected;
uint64_t key;
BOOL res;
@@ -90,6 +92,11 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
key |= ((uint64_t)state->rs[D3DRS_FOGTABLEMODE]) << 33;
}
+ if (unlikely(ps->byte_code.version < 0x14)) {
+ projected = nine_ff_get_projected_key(state);
+ key |= ((uint64_t) projected) << 48;
+ }
+
res = ps->last_key != key;
if (res)
ps->next_key = key;