wined3d: Implement support for per-stage texture stage constants.
This patch is loosely based on an earlier patch by Christian Costa.
This commit is contained in:
parent
ac70dd2c97
commit
23eed88fde
|
@ -16407,6 +16407,146 @@ static void add_dirty_rect_test(void)
|
|||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
static void test_per_stage_constant(void)
|
||||
{
|
||||
IDirect3DDevice9 *device;
|
||||
IDirect3D9 *d3d;
|
||||
D3DCOLOR color;
|
||||
ULONG refcount;
|
||||
D3DCAPS9 caps;
|
||||
HWND window;
|
||||
HRESULT hr;
|
||||
|
||||
static const struct
|
||||
{
|
||||
struct vec3 position;
|
||||
D3DCOLOR diffuse;
|
||||
}
|
||||
quad[] =
|
||||
{
|
||||
{{-1.0f, -1.0f, 0.1f}, 0xffff0000},
|
||||
{{-1.0f, 1.0f, 0.1f}, 0xffff0000},
|
||||
{{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
|
||||
{{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
|
||||
};
|
||||
|
||||
window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||
0, 0, 640, 480, NULL, NULL, NULL, NULL);
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
ok(!!d3d, "Failed to create a D3D object.\n");
|
||||
if (!(device = create_device(d3d, window, window, TRUE)))
|
||||
{
|
||||
skip("Failed to create a D3D device, skipping tests.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
|
||||
ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
|
||||
if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
|
||||
{
|
||||
skip("Per-stage constants not supported, skipping tests.\n");
|
||||
IDirect3DDevice9_Release(device);
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
|
||||
ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
|
||||
ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
|
||||
ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
|
||||
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
|
||||
|
||||
color = getPixelColor(device, 320, 240);
|
||||
ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
|
||||
ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
|
||||
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
|
||||
|
||||
color = getPixelColor(device, 320, 240);
|
||||
ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
|
||||
ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
|
||||
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
|
||||
|
||||
color = getPixelColor(device, 320, 240);
|
||||
ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
|
||||
ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
|
||||
ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
|
||||
|
||||
color = getPixelColor(device, 320, 240);
|
||||
ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
|
||||
|
||||
refcount = IDirect3DDevice9_Release(device);
|
||||
ok(!refcount, "Device has %u references left.\n", refcount);
|
||||
done:
|
||||
IDirect3D9_Release(d3d);
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
START_TEST(visual)
|
||||
{
|
||||
D3DADAPTER_IDENTIFIER9 identifier;
|
||||
|
@ -16513,4 +16653,5 @@ START_TEST(visual)
|
|||
multisampled_depth_buffer_test();
|
||||
resz_test();
|
||||
stencil_cull_test();
|
||||
test_per_stage_constant();
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ struct glsl_ps_program
|
|||
GLint bumpenv_mat_location[MAX_TEXTURES];
|
||||
GLint bumpenv_lum_scale_location[MAX_TEXTURES];
|
||||
GLint bumpenv_lum_offset_location[MAX_TEXTURES];
|
||||
GLint tss_constant_location[MAX_TEXTURES];
|
||||
GLint tex_factor_location;
|
||||
GLint specular_enable_location;
|
||||
GLint ycorrection_location;
|
||||
|
@ -868,6 +869,15 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
|
|||
else
|
||||
GL_EXTCALL(glUniform4fARB(prog->ps.specular_enable_location, 0.0f, 0.0f, 0.0f, 0.0f));
|
||||
|
||||
for (i = 0; i < MAX_TEXTURES; ++i)
|
||||
{
|
||||
if (prog->ps.tss_constant_location[i] == -1)
|
||||
continue;
|
||||
|
||||
D3DCOLORTOGLFLOAT4(state->texture_states[i][WINED3D_TSS_CONSTANT], col);
|
||||
GL_EXTCALL(glUniform4fvARB(prog->ps.tss_constant_location[i], 1, col));
|
||||
}
|
||||
|
||||
checkGLcall("fixed function uniforms");
|
||||
}
|
||||
|
||||
|
@ -5083,17 +5093,16 @@ static const char *shader_glsl_get_ffp_fragment_op_arg(struct wined3d_shader_buf
|
|||
break;
|
||||
|
||||
case WINED3DTA_CONSTANT:
|
||||
FIXME("Per-stage constants not implemented.\n");
|
||||
switch (stage)
|
||||
{
|
||||
case 0: ret = "const0"; break;
|
||||
case 1: ret = "const1"; break;
|
||||
case 2: ret = "const2"; break;
|
||||
case 3: ret = "const3"; break;
|
||||
case 4: ret = "const4"; break;
|
||||
case 5: ret = "const5"; break;
|
||||
case 6: ret = "const6"; break;
|
||||
case 7: ret = "const7"; break;
|
||||
case 0: ret = "tss_const0"; break;
|
||||
case 1: ret = "tss_const1"; break;
|
||||
case 2: ret = "tss_const2"; break;
|
||||
case 3: ret = "tss_const3"; break;
|
||||
case 4: ret = "tss_const4"; break;
|
||||
case 5: ret = "tss_const5"; break;
|
||||
case 6: ret = "tss_const6"; break;
|
||||
case 7: ret = "tss_const7"; break;
|
||||
default:
|
||||
ret = "<invalid constant>";
|
||||
break;
|
||||
|
@ -5284,8 +5293,8 @@ static void shader_glsl_ffp_fragment_op(struct wined3d_shader_buffer *buffer, un
|
|||
static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buffer *buffer,
|
||||
const struct ffp_frag_settings *settings, const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
BYTE lum_map = 0, bump_map = 0, tex_map = 0, tss_const_map = 0;
|
||||
BOOL tempreg_used = FALSE, tfactor_used = FALSE;
|
||||
BYTE lum_map = 0, bump_map = 0, tex_map = 0;
|
||||
const char *final_combiner_src = "ret";
|
||||
UINT lowest_disabled_stage;
|
||||
GLhandleARB shader_obj;
|
||||
|
@ -5312,6 +5321,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
|
|||
tempreg_used = TRUE;
|
||||
if (settings->op[stage].dst == tempreg)
|
||||
tempreg_used = TRUE;
|
||||
if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT)
|
||||
tss_const_map |= 1 << stage;
|
||||
|
||||
switch (settings->op[stage].cop)
|
||||
{
|
||||
|
@ -5347,6 +5358,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
|
|||
tfactor_used = TRUE;
|
||||
if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP)
|
||||
tempreg_used = TRUE;
|
||||
if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT)
|
||||
tss_const_map |= 1 << stage;
|
||||
}
|
||||
lowest_disabled_stage = stage;
|
||||
|
||||
|
@ -5363,6 +5376,9 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct wined3d_shader_buf
|
|||
|
||||
for (stage = 0; stage < MAX_TEXTURES; ++stage)
|
||||
{
|
||||
if (tss_const_map & (1 << stage))
|
||||
shader_addline(buffer, "uniform vec4 tss_const%u;\n", stage);
|
||||
|
||||
if (!(tex_map & (1 << stage)))
|
||||
continue;
|
||||
|
||||
|
@ -5723,6 +5739,8 @@ static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *
|
|||
ps->bumpenv_lum_scale_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
|
||||
snprintf(name, sizeof(name), "bumpenv_lum_offset%u", i);
|
||||
ps->bumpenv_lum_offset_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
|
||||
snprintf(name, sizeof(name), "tss_const%u", i);
|
||||
ps->tss_constant_location[i] = GL_EXTCALL(glGetUniformLocationARB(program_id, name));
|
||||
}
|
||||
|
||||
ps->tex_factor_location = GL_EXTCALL(glGetUniformLocationARB(program_id, "tex_factor"));
|
||||
|
@ -7027,7 +7045,8 @@ static void glsl_fragment_pipe_get_caps(const struct wined3d_gl_info *gl_info, s
|
|||
{
|
||||
caps->wined3d_caps = WINED3D_FRAGMENT_CAP_PROJ_CONTROL
|
||||
| WINED3D_FRAGMENT_CAP_SRGB_WRITE;
|
||||
caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP;
|
||||
caps->PrimitiveMiscCaps = WINED3DPMISCCAPS_TSSARGTEMP
|
||||
| WINED3DPMISCCAPS_PERSTAGECONSTANT;
|
||||
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE
|
||||
| WINED3DTEXOPCAPS_SELECTARG1
|
||||
| WINED3DTEXOPCAPS_SELECTARG2
|
||||
|
@ -7253,6 +7272,14 @@ static const struct StateEntryTemplate glsl_fragment_pipe_state_template[] =
|
|||
{STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_fragment_pipe_tex_transform }, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), glsl_fragment_pipe_invalidate_constants}, WINED3D_GL_EXT_NONE },
|
||||
{0 /* Terminate */, {0, 0 }, WINED3D_GL_EXT_NONE },
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue