wined3d: rsq and rcp use the .w component if no swizzle is given.

This commit is contained in:
Stefan Dösinger 2007-07-02 22:40:06 +02:00 committed by Alexandre Julliard
parent ac82f20b36
commit a1f83aae8e
6 changed files with 153 additions and 6 deletions

View file

@ -495,11 +495,127 @@ static void present_test(IDirect3DDevice8 *device)
ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
}
static void test_rcp_rsq(IDirect3DDevice8 *device)
{
HRESULT hr;
DWORD shader;
DWORD color;
unsigned char c1, c2, c3;
float constant[4] = {1.0, 1.0, 1.0, 2.0};
static const float quad[][3] = {
{-1.0f, -1.0f, 0.0f},
{-1.0f, 1.0f, 0.0f},
{ 1.0f, -1.0f, 0.0f},
{ 1.0f, 1.0f, 0.0f},
};
const DWORD rcp_test[] = {
0xfffe0101, /* vs.1.1 */
0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
0x00303030, /* enough to make windows happy */
0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
0x0000ffff /* END */
};
const DWORD rsq_test[] = {
0xfffe0101, /* vs.1.1 */
0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually D3DX8's*/
0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
0x00303030, /* enough to make windows happy */
0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
0x0000ffff /* END */
};
DWORD decl[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* D3DVSDE_POSITION, Register v0 */
D3DVSD_END()
};
hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff800080, 0.0, 0);
ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %08x\n", hr);
hr = IDirect3DDevice8_CreateVertexShader(device, decl, rcp_test, &shader, 0);
ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %08x\n", hr);
IDirect3DDevice8_SetVertexShader(device, shader);
ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %08x\n", hr);
IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
hr = IDirect3DDevice8_BeginScene(device);
ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
if(SUCCEEDED(hr))
{
hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
hr = IDirect3DDevice8_EndScene(device);
ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
}
hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
color = getPixelColor(device, 320, 240);
c1 = (color & 0x00ff0000 )>> 16;
c2 = (color & 0x0000ff00 )>> 8;
c3 = (color & 0x000000ff )>> 0;
ok(c1 == c2 && c2 == c3, "Color components differ: c1 = %02x, c2 = %02x, c3 = %02x\n",
c1, c2, c3);
ok(c1 >= 0x7c && c1 <= 0x84, "Color component value is %02x\n", c1);
IDirect3DDevice8_SetVertexShader(device, 0);
IDirect3DDevice8_DeleteVertexShader(device, shader);
hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff800080, 0.0, 0);
ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %08x\n", hr);
hr = IDirect3DDevice8_CreateVertexShader(device, decl, rsq_test, &shader, 0);
ok(hr == D3D_OK, "IDirect3DDevice8_CreateVertexShader returned with %08x\n", hr);
IDirect3DDevice8_SetVertexShader(device, shader);
ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %08x\n", hr);
IDirect3DDevice8_SetVertexShaderConstant(device, 0, constant, 1);
hr = IDirect3DDevice8_BeginScene(device);
ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
if(SUCCEEDED(hr))
{
hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
hr = IDirect3DDevice8_EndScene(device);
ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
}
hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
color = getPixelColor(device, 320, 240);
c1 = (color & 0x00ff0000 )>> 16;
c2 = (color & 0x0000ff00 )>> 8;
c3 = (color & 0x000000ff )>> 0;
ok(c1 == c2 && c2 == c3, "Color components differ: c1 = %02x, c2 = %02x, c3 = %02x\n",
c1, c2, c3);
ok(c1 >= 0xb0 && c1 <= 0xb8, "Color component value is %02x\n", c1);
IDirect3DDevice8_SetVertexShader(device, 0);
IDirect3DDevice8_DeleteVertexShader(device, shader);
}
START_TEST(visual)
{
IDirect3DDevice8 *device_ptr;
HRESULT hr;
DWORD color;
D3DCAPS8 caps;
d3d8_handle = LoadLibraryA("d3d8.dll");
if (!d3d8_handle)
@ -511,6 +627,8 @@ START_TEST(visual)
device_ptr = init_d3d8();
if (!device_ptr) return;
IDirect3DDevice8_GetDeviceCaps(device_ptr, &caps);
/* Check for the reliability of the returned data */
hr = IDirect3DDevice8_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
if(FAILED(hr))
@ -548,6 +666,15 @@ START_TEST(visual)
fog_test(device_ptr);
present_test(device_ptr);
if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
{
test_rcp_rsq(device_ptr);
}
else
{
skip("No vs.1.1 support\n");
}
cleanup:
if(device_ptr) IDirect3DDevice8_Release(device_ptr);
}

View file

@ -948,8 +948,10 @@ void vshader_hw_rsq_rcp(SHADER_OPCODE_ARG* arg) {
strcat(tmpLine, ",");
vshader_program_add_param(arg, src, TRUE, tmpLine);
if ((WINED3DSP_NOSWIZZLE >> WINED3DSP_SWIZZLE_SHIFT) == swizzle) {
/* Dx sdk says .x is used if no swizzle is given */
strcat(tmpLine, ".x");
/* Dx sdk says .x is used if no swizzle is given, but our test shows that
* .w is used
*/
strcat(tmpLine, ".w");
}
shader_addline(buffer, "%s;\n", tmpLine);

View file

@ -1054,7 +1054,6 @@ void shader_glsl_map2gl(SHADER_OPCODE_ARG* arg) {
switch (curOpcode->opcode) {
case WINED3DSIO_MIN: instruction = "min"; break;
case WINED3DSIO_MAX: instruction = "max"; break;
case WINED3DSIO_RSQ: instruction = "inversesqrt"; break;
case WINED3DSIO_ABS: instruction = "abs"; break;
case WINED3DSIO_FRC: instruction = "fract"; break;
case WINED3DSIO_NRM: instruction = "normalize"; break;
@ -1132,7 +1131,7 @@ void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) {
write_mask = shader_glsl_append_dst(arg->buffer, arg);
mask_size = shader_glsl_get_write_mask_size(write_mask);
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src_param);
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &src_param);
if (mask_size > 1) {
shader_addline(arg->buffer, "vec%d(1.0 / %s));\n", mask_size, src_param.param_str);
@ -1141,6 +1140,24 @@ void shader_glsl_rcp(SHADER_OPCODE_ARG* arg) {
}
}
void shader_glsl_rsq(SHADER_OPCODE_ARG* arg) {
SHADER_BUFFER* buffer = arg->buffer;
glsl_src_param_t src_param;
DWORD write_mask;
size_t mask_size;
write_mask = shader_glsl_append_dst(buffer, arg);
mask_size = shader_glsl_get_write_mask_size(write_mask);
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &src_param);
if (mask_size > 1) {
shader_addline(buffer, "vec%d(inversesqrt(%s)));\n", mask_size, src_param.param_str);
} else {
shader_addline(buffer, "inversesqrt(%s));\n", src_param.param_str);
}
}
/** Process signed comparison opcodes in GLSL. */
void shader_glsl_compare(SHADER_OPCODE_ARG* arg) {
glsl_src_param_t src0_param;

View file

@ -166,7 +166,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
{WINED3DSIO_MAD, "mad", "MAD", 1, 4, pshader_hw_map2gl, shader_glsl_mad, 0, 0},
{WINED3DSIO_MUL, "mul", "MUL", 1, 3, pshader_hw_map2gl, shader_glsl_arith, 0, 0},
{WINED3DSIO_RCP, "rcp", "RCP", 1, 2, pshader_hw_map2gl, shader_glsl_rcp, 0, 0},
{WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, pshader_hw_map2gl, shader_glsl_rsq, 0, 0},
{WINED3DSIO_DP3, "dp3", "DP3", 1, 3, pshader_hw_map2gl, shader_glsl_dot, 0, 0},
{WINED3DSIO_DP4, "dp4", "DP4", 1, 3, pshader_hw_map2gl, shader_glsl_dot, 0, 0},
{WINED3DSIO_MIN, "min", "MIN", 1, 3, pshader_hw_map2gl, shader_glsl_map2gl, 0, 0},

View file

@ -92,7 +92,7 @@ CONST SHADER_OPCODE IWineD3DVertexShaderImpl_shader_ins[] = {
{WINED3DSIO_MAD, "mad", "MAD", 1, 4, vshader_hw_map2gl, shader_glsl_mad, 0, 0},
{WINED3DSIO_MUL, "mul", "MUL", 1, 3, vshader_hw_map2gl, shader_glsl_arith, 0, 0},
{WINED3DSIO_RCP, "rcp", "RCP", 1, 2, vshader_hw_rsq_rcp, shader_glsl_rcp, 0, 0},
{WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, vshader_hw_rsq_rcp, shader_glsl_map2gl, 0, 0},
{WINED3DSIO_RSQ, "rsq", "RSQ", 1, 2, vshader_hw_rsq_rcp, shader_glsl_rsq, 0, 0},
{WINED3DSIO_DP3, "dp3", "DP3", 1, 3, vshader_hw_map2gl, shader_glsl_dot, 0, 0},
{WINED3DSIO_DP4, "dp4", "DP4", 1, 3, vshader_hw_map2gl, shader_glsl_dot, 0, 0},
{WINED3DSIO_MIN, "min", "MIN", 1, 3, vshader_hw_map2gl, shader_glsl_map2gl, 0, 0},

View file

@ -1714,6 +1714,7 @@ extern void shader_glsl_mnxn(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_lrp(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_dot(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_rcp(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_rsq(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_cnd(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_compare(SHADER_OPCODE_ARG* arg);
extern void shader_glsl_def(SHADER_OPCODE_ARG* arg);