wined3d: texkill ignores the .w only in ps 1.x.

This commit is contained in:
Stefan Dösinger 2007-08-30 23:35:50 +02:00 committed by Alexandre Julliard
parent 8656713366
commit 422e0ba1cc
5 changed files with 189 additions and 3 deletions

View File

@ -2571,6 +2571,155 @@ static void texdepth_test(IDirect3DDevice9 *device)
ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
}
static void texkill_test(IDirect3DDevice9 *device)
{
IDirect3DPixelShader9 *shader;
HRESULT hr;
DWORD color;
const float vertex[] = {
/* bottom top right left */
-1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
-1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
};
DWORD shader_code_11[] = {
0xffff0101, /* ps_1_1 */
0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
0x00000041, 0xb00f0000, /* texkill t0 */
0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
0x0000ffff /* end */
};
DWORD shader_code_20[] = {
0xffff0200, /* ps_2_0 */
0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
0x01000041, 0xb00f0000, /* texkill t0 */
0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
0x0000ffff /* end */
};
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_SetPixelShader(device, shader);
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_BeginScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
hr = IDirect3DDevice9_EndScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
}
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
color = getPixelColor(device, 63, 46);
ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 66, 46);
ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 63, 49);
ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 66, 49);
ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 578, 46);
ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 575, 46);
ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 578, 49);
ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 575, 49);
ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 63, 430);
ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 63, 433);
ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 66, 433);
ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 66, 430);
ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 578, 430);
ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 578, 433);
ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
color = getPixelColor(device, 575, 433);
ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
color = getPixelColor(device, 575, 430);
ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
hr = IDirect3DDevice9_SetPixelShader(device, NULL);
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
IDirect3DPixelShader9_Release(shader);
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
if(FAILED(hr)) {
skip("Failed to create 2.0 test shader, most likely not supported\n");
return;
}
hr = IDirect3DDevice9_SetPixelShader(device, shader);
ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
hr = IDirect3DDevice9_BeginScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
if(SUCCEEDED(hr))
{
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
hr = IDirect3DDevice9_EndScene(device);
ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
}
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
color = getPixelColor(device, 63, 46);
ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 66, 46);
ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 63, 49);
ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 66, 49);
ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
color = getPixelColor(device, 578, 46);
ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 575, 46);
ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 578, 49);
ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 575, 49);
ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
color = getPixelColor(device, 63, 430);
ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 63, 433);
ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 66, 433);
ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 66, 430);
ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
color = getPixelColor(device, 578, 430);
ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 578, 433);
ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 575, 433);
ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
color = getPixelColor(device, 575, 430);
ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
}
START_TEST(visual)
{
IDirect3DDevice9 *device_ptr;
@ -2666,6 +2815,7 @@ START_TEST(visual)
{
texbem_test(device_ptr);
texdepth_test(device_ptr);
texkill_test(device_ptr);
}
else skip("No ps_1_1 support\n");

View File

@ -652,8 +652,31 @@ void pshader_hw_map2gl(SHADER_OPCODE_ARG* arg) {
}
}
void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
void pshader_hw_texkill(SHADER_OPCODE_ARG* arg) {
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
DWORD hex_version = This->baseShader.hex_version;
SHADER_BUFFER* buffer = arg->buffer;
char reg_dest[40];
/* No swizzles are allowed in d3d's texkill. PS 1.x ignores the 4th component as documented,
* but >= 2.0 honors it(undocumented, but tested by the d3d9 testsuit)
*/
pshader_get_register_name(arg->dst, reg_dest);
if(hex_version >= WINED3DPS_VERSION(2,0)) {
/* The arb backend doesn't claim ps 2.0 support, but try to eat what the app feeds to us */
shader_addline(buffer, "KIL %s;\n", reg_dest);
} else {
/* ARB fp doesn't like swizzles on the parameter of the KIL instruction. To mask the 4th component,
* copy the register into our general purpose TMP variable, overwrite .w and pass TMP to KIL
*/
shader_addline(buffer, "MOV TMP, %s;\n", reg_dest);
shader_addline(buffer, "MOV TMP.w, one.w;\n", reg_dest);
shader_addline(buffer, "KIL TMP;\n", reg_dest);
}
}
void pshader_hw_tex(SHADER_OPCODE_ARG* arg) {
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
DWORD dst = arg->dst;

View File

@ -2037,10 +2037,22 @@ void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) {
/** Process the WINED3DSIO_TEXKILL instruction in GLSL.
* If any of the first 3 components are < 0, discard this pixel */
void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) {
IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
DWORD hex_version = This->baseShader.hex_version;
glsl_dst_param_t dst_param;
/* The argument is a destination parameter, and no writemasks are allowed */
shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param);
shader_addline(arg->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
if((hex_version >= WINED3DPS_VERSION(2,0))) {
/* 2.0 shaders compare all 4 components in texkill */
shader_addline(arg->buffer, "if (any(lessThan(%s.xyzw, vec4(0.0)))) discard;\n", dst_param.reg_name);
} else {
/* 1.X shaders only compare the first 3 components, propably due to the nature of the texkill
* instruction as a tex* instruction, and phase, which kills all a / w components. Even if all
* 4 components are defined, only the first 3 are used
*/
shader_addline(arg->buffer, "if (any(lessThan(%s.xyz, vec3(0.0)))) discard;\n", dst_param.reg_name);
}
}
/** Process the WINED3DSIO_DP2ADD instruction in GLSL.

View File

@ -218,7 +218,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
/* Texture */
{WINED3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, pshader_hw_texcoord, pshader_glsl_texcoord, 0, WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXCOORD, "texcrd", "undefined", 1, 2, pshader_hw_texcoord, pshader_glsl_texcoord, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_TEXKILL, "texkill", "KIL", 1, 1, pshader_hw_map2gl, pshader_glsl_texkill, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
{WINED3DSIO_TEXKILL, "texkill", "KIL", 1, 1, pshader_hw_texkill, pshader_glsl_texkill, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(3,0)},
{WINED3DSIO_TEX, "tex", "undefined", 1, 1, pshader_hw_tex, pshader_glsl_tex, 0, WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEX, "texld", "undefined", 1, 2, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_TEX, "texld", "undefined", 1, 3, pshader_hw_tex, pshader_glsl_tex, WINED3DPS_VERSION(2,0), -1},

View File

@ -1786,6 +1786,7 @@ extern void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texkill(SHADER_OPCODE_ARG* arg);
/* ARB vertex shader prototypes */
extern void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg);