mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
wined3d: Issue texture barrier before using a texture attached to FBO.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45978 Signed-off-by: Paul Gofman <gofmanp@gmail.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b9d0cec5f2
commit
a5551040f2
5 changed files with 222 additions and 2 deletions
|
@ -33,7 +33,7 @@
|
|||
|
||||
#define COBJMACROS
|
||||
#include <d3d9.h>
|
||||
#include "wine/test.h"
|
||||
#include "utils.h"
|
||||
#include "wine/heap.h"
|
||||
|
||||
struct vec2
|
||||
|
@ -26263,6 +26263,166 @@ static void test_draw_mapped_buffer(void)
|
|||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
static void test_sample_attached_rendertarget(void)
|
||||
{
|
||||
D3DADAPTER_IDENTIFIER9 identifier;
|
||||
IDirect3DQuery9 *event_query;
|
||||
IDirect3DTexture9 *texture;
|
||||
IDirect3DVertexBuffer9 *vb;
|
||||
IDirect3DPixelShader9 *ps;
|
||||
IDirect3DDevice9 *device;
|
||||
IDirect3DSurface9 *rt;
|
||||
IDirect3D9 *d3d;
|
||||
unsigned int i;
|
||||
ULONG refcount;
|
||||
D3DCOLOR color;
|
||||
BOOL is_warp;
|
||||
HWND window;
|
||||
HRESULT hr;
|
||||
void *data;
|
||||
|
||||
static const struct
|
||||
{
|
||||
struct vec3 posistion;
|
||||
struct vec2 texcoord;
|
||||
}
|
||||
quad[] =
|
||||
{
|
||||
{{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f}},
|
||||
{{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f}},
|
||||
{{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
|
||||
{{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}},
|
||||
};
|
||||
|
||||
static const DWORD pixel_shader_code[] =
|
||||
{
|
||||
0xffff0200, /* ps_2_0 */
|
||||
0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000,
|
||||
/* def c0, 0.25, 0.25, 0.25, 0.25 */
|
||||
0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
|
||||
0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
|
||||
0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
|
||||
0x03000002, 0x800f0000, 0x80e40000, 0xa0e40000, /* add r0, r0, c0 */
|
||||
0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
|
||||
0x0000ffff
|
||||
};
|
||||
|
||||
window = create_window();
|
||||
ok(!!window, "Failed to create a window.\n");
|
||||
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
ok(!!d3d, "Failed to create a D3D object.\n");
|
||||
|
||||
hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
is_warp = adapter_is_warp(&identifier);
|
||||
|
||||
if (!(device = create_device(d3d, window, window, TRUE)))
|
||||
{
|
||||
skip("Failed to create a D3D device, skipping tests.\n");
|
||||
IDirect3D9_Release(d3d);
|
||||
DestroyWindow(window);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, NULL);
|
||||
if (hr == D3DERR_NOTAVAILABLE)
|
||||
{
|
||||
/* Without synchronization native d3d seems to show race condition on
|
||||
* render target update, similar to opengl without using texture barrier. */
|
||||
skip("Event queries are not supported, skipping test.\n");
|
||||
IDirect3DDevice9_Release(device);
|
||||
IDirect3D9_Release(d3d);
|
||||
DestroyWindow(window);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &event_query);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DQuery9_Issue(event_query, D3DISSUE_END);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), D3DUSAGE_DYNAMIC,
|
||||
D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &vb, NULL);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, 0);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
memcpy(data, quad, sizeof(quad));
|
||||
hr = IDirect3DVertexBuffer9_Unlock(vb);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
|
||||
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x01010101, 0.0, 0);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
check_rt_color(rt, 0x00010101);
|
||||
|
||||
hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_BeginScene(device);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_SetPixelShader(device, ps);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
wait_query(event_query);
|
||||
|
||||
hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
IDirect3DQuery9_Issue(event_query, D3DISSUE_END);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
hr = IDirect3DDevice9_EndScene(device);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
|
||||
ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
|
||||
|
||||
color = getPixelColor(device, 0, 0);
|
||||
if (is_warp || color == 0x00010101)
|
||||
skip("Sampling attached render targets is not supported.\n");
|
||||
else
|
||||
check_rt_color(rt, 0x00c1c1c1);
|
||||
|
||||
IDirect3DQuery9_Release(event_query);
|
||||
|
||||
IDirect3DVertexBuffer9_Release(vb);
|
||||
|
||||
IDirect3DPixelShader9_Release(ps);
|
||||
IDirect3DSurface9_Release(rt);
|
||||
IDirect3DTexture9_Release(texture);
|
||||
|
||||
refcount = IDirect3DDevice9_Release(device);
|
||||
ok(!refcount, "Device has %u references left.\n", refcount);
|
||||
|
||||
IDirect3D9_Release(d3d);
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
START_TEST(visual)
|
||||
{
|
||||
|
@ -26409,4 +26569,5 @@ START_TEST(visual)
|
|||
test_desktop_window();
|
||||
test_mismatched_sample_types();
|
||||
test_draw_mapped_buffer();
|
||||
test_sample_attached_rendertarget();
|
||||
}
|
||||
|
|
|
@ -159,6 +159,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
|
|||
{"GL_ARB_vertex_shader", ARB_VERTEX_SHADER },
|
||||
{"GL_ARB_vertex_type_2_10_10_10_rev", ARB_VERTEX_TYPE_2_10_10_10_REV},
|
||||
{"GL_ARB_viewport_array", ARB_VIEWPORT_ARRAY },
|
||||
{"GL_ARB_texture_barrier", ARB_TEXTURE_BARRIER },
|
||||
|
||||
/* ATI */
|
||||
{"GL_ATI_fragment_shader", ATI_FRAGMENT_SHADER },
|
||||
|
@ -228,6 +229,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
|
|||
{"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 },
|
||||
{"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION },
|
||||
{"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 },
|
||||
{"GL_NV_texture_barrier", NV_TEXTURE_BARRIER },
|
||||
};
|
||||
|
||||
static const struct wined3d_extension_map wgl_extension_map[] =
|
||||
|
@ -2454,6 +2456,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
|
|||
USE_GL_FUNC(glViewportArrayv)
|
||||
USE_GL_FUNC(glViewportIndexedf)
|
||||
USE_GL_FUNC(glViewportIndexedfv)
|
||||
/* GL_ARB_texture_barrier */
|
||||
USE_GL_FUNC(glTextureBarrier);
|
||||
/* GL_ATI_fragment_shader */
|
||||
USE_GL_FUNC(glAlphaFragmentOp1ATI)
|
||||
USE_GL_FUNC(glAlphaFragmentOp2ATI)
|
||||
|
@ -2644,6 +2648,8 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
|
|||
USE_GL_FUNC(glCombinerParameteriNV)
|
||||
USE_GL_FUNC(glCombinerParameterivNV)
|
||||
USE_GL_FUNC(glFinalCombinerInputNV)
|
||||
/* GL_NV_texture_barrier */
|
||||
USE_GL_FUNC(glTextureBarrierNV);
|
||||
/* WGL extensions */
|
||||
USE_GL_FUNC(wglChoosePixelFormatARB)
|
||||
USE_GL_FUNC(wglGetExtensionsStringARB)
|
||||
|
@ -3406,6 +3412,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
|
|||
{ARB_CULL_DISTANCE, MAKEDWORD_VERSION(4, 5)},
|
||||
{ARB_DERIVATIVE_CONTROL, MAKEDWORD_VERSION(4, 5)},
|
||||
{ARB_SHADER_TEXTURE_IMAGE_SAMPLES, MAKEDWORD_VERSION(4, 5)},
|
||||
{ARB_TEXTURE_BARRIER, MAKEDWORD_VERSION(4, 5)},
|
||||
|
||||
{ARB_PIPELINE_STATISTICS_QUERY, MAKEDWORD_VERSION(4, 6)},
|
||||
{ARB_POLYGON_OFFSET_CLAMP, MAKEDWORD_VERSION(4, 6)},
|
||||
|
|
|
@ -3696,6 +3696,9 @@ static void context_preload_texture(struct wined3d_context *context,
|
|||
if (!(texture = state->textures[idx]))
|
||||
return;
|
||||
|
||||
if (wined3d_resource_check_fbo_attached(state, &texture->resource))
|
||||
context->uses_fbo_attached_resources = 1;
|
||||
|
||||
wined3d_texture_load(texture, context, is_srgb_enabled(state->sampler_states[idx]));
|
||||
}
|
||||
|
||||
|
@ -3929,6 +3932,8 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
|
|||
unsigned int i, base;
|
||||
WORD map;
|
||||
|
||||
context->uses_fbo_attached_resources = 0;
|
||||
|
||||
if (!have_framebuffer_attachment(gl_info->limits.buffers, fb->render_targets, fb->depth_stencil))
|
||||
{
|
||||
if (!gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS])
|
||||
|
@ -4984,6 +4989,30 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
|
|||
checkGLcall("glPatchParameteri");
|
||||
}
|
||||
|
||||
if (context->uses_fbo_attached_resources)
|
||||
{
|
||||
static unsigned int fixme_once;
|
||||
|
||||
if (gl_info->supported[ARB_TEXTURE_BARRIER])
|
||||
{
|
||||
GL_EXTCALL(glTextureBarrier());
|
||||
}
|
||||
else if (gl_info->supported[NV_TEXTURE_BARRIER])
|
||||
{
|
||||
GL_EXTCALL(glTextureBarrierNV());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fixme_once++)
|
||||
FIXME("Sampling attached render targets is not supported.\n");
|
||||
|
||||
WARN("Sampling attached render targets is not supported, skipping draw.\n");
|
||||
context_release(context);
|
||||
return;
|
||||
}
|
||||
checkGLcall("glTextureBarrier");
|
||||
}
|
||||
|
||||
if (parameters->indirect)
|
||||
{
|
||||
if (!context->use_immediate_mode_draw && !emulation)
|
||||
|
|
|
@ -142,6 +142,7 @@ enum wined3d_gl_extension
|
|||
ARB_VERTEX_SHADER,
|
||||
ARB_VERTEX_TYPE_2_10_10_10_REV,
|
||||
ARB_VIEWPORT_ARRAY,
|
||||
ARB_TEXTURE_BARRIER,
|
||||
/* ATI */
|
||||
ATI_FRAGMENT_SHADER,
|
||||
ATI_SEPARATE_STENCIL,
|
||||
|
@ -204,6 +205,7 @@ enum wined3d_gl_extension
|
|||
NV_VERTEX_PROGRAM2,
|
||||
NV_VERTEX_PROGRAM2_OPTION,
|
||||
NV_VERTEX_PROGRAM3,
|
||||
NV_TEXTURE_BARRIER,
|
||||
/* WGL extensions */
|
||||
WGL_ARB_PIXEL_FORMAT,
|
||||
WGL_EXT_SWAP_CONTROL,
|
||||
|
|
|
@ -1961,6 +1961,7 @@ struct wined3d_context
|
|||
|
||||
DWORD use_immediate_mode_draw : 1;
|
||||
DWORD uses_uavs : 1;
|
||||
DWORD uses_fbo_attached_resources : 1;
|
||||
DWORD transform_feedback_active : 1;
|
||||
DWORD transform_feedback_paused : 1;
|
||||
DWORD fog_coord : 1;
|
||||
|
@ -1969,7 +1970,7 @@ struct wined3d_context
|
|||
DWORD destroyed : 1;
|
||||
DWORD destroy_delayed : 1;
|
||||
DWORD clip_distance_mask : 8; /* WINED3D_MAX_CLIP_DISTANCES, 8 */
|
||||
DWORD padding : 15;
|
||||
DWORD padding : 14;
|
||||
|
||||
DWORD constant_update_mask;
|
||||
DWORD numbered_array_mask;
|
||||
|
@ -5279,6 +5280,26 @@ static inline void wined3d_context_copy_bo_address(struct wined3d_context *conte
|
|||
dst, dst_bind_flags, src, src_bind_flags, size);
|
||||
}
|
||||
|
||||
static inline BOOL wined3d_resource_check_fbo_attached(const struct wined3d_state *state,
|
||||
const struct wined3d_resource *resource)
|
||||
{
|
||||
struct wined3d_rendertarget_view * const *rts = &state->fb->render_targets[0];
|
||||
unsigned int i;
|
||||
|
||||
if ((resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL)
|
||||
&& state->fb->depth_stencil && state->fb->depth_stencil->resource == resource)
|
||||
return TRUE;
|
||||
|
||||
if (!(resource->bind_flags & WINED3D_BIND_RENDER_TARGET))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < MAX_RENDER_TARGET_VIEWS; ++i)
|
||||
if (rts[i] && rts[i]->resource == resource)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
|
||||
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
|
||||
|
||||
|
|
Loading…
Reference in a new issue