summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Davy <davyaxel0@gmail.com>2021-03-12 13:03:01 +0100
committerMarge Bot <eric+marge@anholt.net>2021-04-14 08:33:13 +0000
commitd9e79bfe4f03eb0412a5535fce2a98c10623f53d (patch)
treebf884b8206993a2d7e9d6d6c0115c676395c2ab8
parent9e5762c387fffc5b6fccee61dc0c65067f7292e9 (diff)
st/nine: Disable fpu exceptions during init
Prevents a crash in wine tests. The crash seems to happen in llvmpipe. Signed-off-by: Axel Davy <davyaxel0@gmail.com> Acked-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10160>
-rw-r--r--src/gallium/frontends/nine/device9.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c
index 26f09944d54..02f6e6e4ed0 100644
--- a/src/gallium/frontends/nine/device9.c
+++ b/src/gallium/frontends/nine/device9.c
@@ -75,6 +75,19 @@ static void nine_setup_fpu()
__asm__ __volatile__ ("fldcw %0" : : "m" (*&c));
}
+static void nine_setup_set_fpu(uint16_t val)
+{
+ __asm__ __volatile__ ("fldcw %0" : : "m" (*&val));
+}
+
+static uint16_t nine_setup_get_fpu()
+{
+ uint16_t c;
+
+ __asm__ __volatile__ ("fnstcw %0" : "=m" (*&c));
+ return c;
+}
+
#else
static void nine_setup_fpu(void)
@@ -82,6 +95,17 @@ static void nine_setup_fpu(void)
WARN_ONCE("FPU setup not supported on non-x86 platforms\n");
}
+static void nine_setup_set_fpu(uint16_t)
+{
+ WARN_ONCE("FPU setup not supported on non-x86 platforms\n");
+}
+
+static uint16_t nine_setup_get_fpu()
+{
+ WARN_ONCE("FPU setup not supported on non-x86 platforms\n");
+ return 0;
+}
+
#endif
struct pipe_resource *
@@ -159,6 +183,7 @@ NineDevice9_ctor( struct NineDevice9 *This,
int minorVersionNum )
{
unsigned i;
+ uint16_t fpu_cw = 0;
HRESULT hr = NineUnknown_ctor(&This->base, pParams);
DBG("This=%p pParams=%p pScreen=%p pCreationParameters=%p pCaps=%p pPresentationParameters=%p "
@@ -188,8 +213,13 @@ NineDevice9_ctor( struct NineDevice9 *This,
IDirect3D9_AddRef(This->d3d9);
ID3DPresentGroup_AddRef(This->present);
- if (!(This->params.BehaviorFlags & D3DCREATE_FPU_PRESERVE))
+ if (!(This->params.BehaviorFlags & D3DCREATE_FPU_PRESERVE)) {
nine_setup_fpu();
+ } else {
+ /* Software renderer initialization needs exceptions masked */
+ fpu_cw = nine_setup_get_fpu();
+ nine_setup_set_fpu(fpu_cw | 0x007f);
+ }
if (This->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) {
DBG("Application asked full Software Vertex Processing.\n");
@@ -544,6 +574,9 @@ NineDevice9_ctor( struct NineDevice9 *This,
nine_context_update_state(This); /* Some drivers needs states to be initialized */
nine_csmt_process(This);
+ if (This->params.BehaviorFlags & D3DCREATE_FPU_PRESERVE)
+ nine_setup_set_fpu(fpu_cw);
+
return D3D_OK;
}
#undef GET_PCAP