diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c index 3caa08f4f16..32031e4e4c4 100644 --- a/dlls/d3d9/tests/visual.c +++ b/dlls/d3d9/tests/visual.c @@ -8324,7 +8324,7 @@ static void pointsize_test(IDirect3DDevice9 *device) D3DCAPS9 caps; D3DMATRIX matrix; D3DMATRIX identity; - float ptsize, ptsize_orig; + float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig; DWORD color; const float vertices[] = { @@ -8333,7 +8333,10 @@ static void pointsize_test(IDirect3DDevice9 *device) 192, 64, 0.1, 256, 64, 0.1, 320, 64, 0.1, - 384, 64, 0.1 + 384, 64, 0.1, + 448, 64, 0.1, + 512, 64, 0.1, + 576, 64, 0.1, }; /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to [0.0;0.0]x[640.0;480.0]. Z is untouched */ @@ -8405,6 +8408,51 @@ static void pointsize_test(IDirect3DDevice9 *device) hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3); ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr); + hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig)); + ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr); + hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemin_orig)); + ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr); + + /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */ + ptsize = 16.0; + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + ptsize = 1.0; + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr); + + /* What happens if POINTSIZE_MAX < POINTSIZE_MIN? + * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0 + */ + ptsize = 4.0; + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + ptsize = 16.0; + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr); + + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + + /* pointsize < pointsize_min < pointsize_max? + * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0) + */ + ptsize = 1.0; + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + ptsize = 16.0; + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3); + ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr); + + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig))); + ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr); + hr = IDirect3DDevice9_EndScene(device); ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr); } @@ -8483,6 +8531,26 @@ static void pointsize_test(IDirect3DDevice9 *device) color = getPixelColor(device, 320+1, 64+1); ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color); + /* ptsize = 16, ptsize_max = 1 --> point has size 1 */ + color = getPixelColor(device, 448-4, 64-4); + ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color); + color = getPixelColor(device, 448+4, 64+4); + ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color); + + /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */ + color = getPixelColor(device, 512-4, 64-4); + ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color); + color = getPixelColor(device, 512+4, 64+4); + ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color); + + /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16 + * Don't be overly picky - just show that the point is bigger than 1 pixel + */ + color = getPixelColor(device, 576-4, 64-4); + ok(color == 0x00ffffff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color); + color = getPixelColor(device, 576+4, 64+4); + ok(color == 0x00ffffff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color); + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig))); ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr); hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity); diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 573c23c1743..b9d28d4720c 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1410,16 +1410,30 @@ static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi if(tmpvalue.f != 1.0) { FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f); } + tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; + if(tmpvalue.f != 64.0) { + FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f); + } + } static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { union { DWORD d; float f; - } tmpvalue; + } min, max; - tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN]; - GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f); + min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN]; + max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; + + /* Max point size trumps min point size */ + if(min.f > max.f) { + min.f = max.f; + } + + GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f); + checkGLcall("glPointParameterfEXT(...)"); + GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f); checkGLcall("glPointParameterfEXT(...)"); } @@ -1427,45 +1441,20 @@ static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, union { DWORD d; float f; - } tmpvalue; + } min, max; - tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN]; - GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f); - checkGLcall("glPointParameterfARB(...)"); -} + min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN]; + max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; -static void state_psizemax_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { - union { - DWORD d; - float f; - } tmpvalue; - - tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; - GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f); - checkGLcall("glPointParameterfARB(...)"); -} - -static void state_psizemax_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { - union { - DWORD d; - float f; - } tmpvalue; - - tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; - GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f); - checkGLcall("glPointParameterfEXT(...)"); -} - -static void state_psizemax_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { - union { - DWORD d; - float f; - } tmpvalue; - - tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX]; - if(tmpvalue.f != 64.0) { - FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f); + /* Max point size trumps min point size */ + if(min.f > max.f) { + min.f = max.f; } + + GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f); + checkGLcall("glPointParameterfARB(...)"); + GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f); + checkGLcall("glPointParameterfARB(...)"); } static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { @@ -5320,9 +5309,9 @@ const struct StateEntryTemplate ffp_vertexstate_template[] = { { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, 0 }, { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, 0 }, { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, 0 }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax_arb }, ARB_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax_ext }, EXT_POINT_PARAMETERS }, - { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax_w }, 0 }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS }, + { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, 0 }, /* pixel shaders need a different fog input */ { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pshader_fog }, 0 }, /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,