summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Davy <[email protected]>2015-01-07 18:43:20 +0100
committerAxel Davy <[email protected]>2015-02-06 00:07:18 +0100
commit42ac71a4e20c04a2cd7cd441274e5c527012a03c (patch)
tree80ad4134ee3809b9a06639d61f8f96c515968b73
parent5c61f6344a93e2bddb1984dcc735b8bc587c5db9 (diff)
st/nine: Implement RESZ hack
This D3D hack allows to resolve a multisampled depth buffer into a single sampled one. Note that the implementation is slightly incorrect. When querying the content of D3DRS_POINTSIZE, it should return the resz code if it has been set. This behaviour will be implemented when state changes will be reworked. For now the current behaviour is ok, since apps use the D3DCREATE_PUREDEVICE flag when creating the device, which means they won't read states and in exchange get better performance. Reviewed-by: Tiziano Bacocco <[email protected]> Signed-off-by: Axel Davy <[email protected]>
-rw-r--r--include/D3D9/d3d9types.h1
-rw-r--r--src/gallium/state_trackers/nine/adapter9.c6
-rw-r--r--src/gallium/state_trackers/nine/device9.c57
-rw-r--r--src/gallium/state_trackers/nine/nine_pipe.h1
4 files changed, 65 insertions, 0 deletions
diff --git a/include/D3D9/d3d9types.h b/include/D3D9/d3d9types.h
index 456ae9ffb02..859c2f56dc4 100644
--- a/include/D3D9/d3d9types.h
+++ b/include/D3D9/d3d9types.h
@@ -658,6 +658,7 @@ typedef enum _D3DFORMAT {
D3DFMT_NVDB = MAKEFOURCC('N', 'V', 'D', 'B'),
D3DFMT_NV11 = MAKEFOURCC('N', 'V', '1', '1'),
D3DFMT_NV12 = MAKEFOURCC('N', 'V', '1', '2'),
+ D3DFMT_RESZ = MAKEFOURCC('R', 'E', 'S', 'Z'),
D3DFMT_Y210 = MAKEFOURCC('Y', '2', '1', '0'),
D3DFMT_Y216 = MAKEFOURCC('Y', '2', '1', '6'),
D3DFMT_Y410 = MAKEFOURCC('Y', '4', '1', '0')
diff --git a/src/gallium/state_trackers/nine/adapter9.c b/src/gallium/state_trackers/nine/adapter9.c
index bdf547e78c4..6ff197e1dfe 100644
--- a/src/gallium/state_trackers/nine/adapter9.c
+++ b/src/gallium/state_trackers/nine/adapter9.c
@@ -305,6 +305,12 @@ NineAdapter9_CheckDeviceFormat( struct NineAdapter9 *This,
RType == D3DRTYPE_TEXTURE))
return D3D_OK;
+ /* RESZ hack */
+ if (CheckFormat == D3DFMT_RESZ && bind == PIPE_BIND_RENDER_TARGET &&
+ RType == D3DRTYPE_SURFACE)
+ return screen->get_param(screen, PIPE_CAP_MULTISAMPLE_Z_RESOLVE) ?
+ D3D_OK : D3DERR_NOTAVAILABLE;
+
if (Usage & D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
bind |= PIPE_BIND_BLENDABLE;
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index b7e83a4bab9..0326442f949 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -1991,6 +1991,60 @@ NineDevice9_GetClipPlane( struct NineDevice9 *This,
return D3D_OK;
}
+#define RESZ_CODE 0x7fa05000
+
+static HRESULT
+NineDevice9_ResolveZ( struct NineDevice9 *This )
+{
+ struct nine_state *state = &This->state;
+ const struct util_format_description *desc;
+ struct NineSurface9 *source = state->ds;
+ struct NineBaseTexture9 *destination = state->texture[0];
+ struct pipe_resource *src, *dst;
+ struct pipe_blit_info blit;
+
+ DBG("RESZ resolve\n");
+
+ user_assert(source && destination &&
+ destination->base.type == D3DRTYPE_TEXTURE, D3DERR_INVALIDCALL);
+
+ src = source->base.resource;
+ dst = destination->base.resource;
+
+ user_assert(src && dst, D3DERR_INVALIDCALL);
+
+ /* check dst is depth format. we know already for src */
+ desc = util_format_description(dst->format);
+ user_assert(desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS, D3DERR_INVALIDCALL);
+
+ blit.src.resource = src;
+ blit.src.level = 0;
+ blit.src.format = src->format;
+ blit.src.box.z = 0;
+ blit.src.box.depth = 1;
+ blit.src.box.x = 0;
+ blit.src.box.y = 0;
+ blit.src.box.width = src->width0;
+ blit.src.box.height = src->height0;
+
+ blit.dst.resource = dst;
+ blit.dst.level = 0;
+ blit.dst.format = dst->format;
+ blit.dst.box.z = 0;
+ blit.dst.box.depth = 1;
+ blit.dst.box.x = 0;
+ blit.dst.box.y = 0;
+ blit.dst.box.width = dst->width0;
+ blit.dst.box.height = dst->height0;
+
+ blit.mask = PIPE_MASK_ZS;
+ blit.filter = PIPE_TEX_FILTER_NEAREST;
+ blit.scissor_enable = FALSE;
+
+ This->pipe->blit(This->pipe, &blit);
+ return D3D_OK;
+}
+
HRESULT WINAPI
NineDevice9_SetRenderState( struct NineDevice9 *This,
D3DRENDERSTATETYPE State,
@@ -2001,6 +2055,9 @@ NineDevice9_SetRenderState( struct NineDevice9 *This,
DBG("This=%p State=%u(%s) Value=%08x\n", This,
State, nine_d3drs_to_string(State), Value);
+ if (State == D3DRS_POINTSIZE && Value == RESZ_CODE)
+ return NineDevice9_ResolveZ(This);
+
user_assert(State < Elements(state->rs), D3DERR_INVALIDCALL);
if (likely(state->rs[State] != Value) || unlikely(This->is_recording)) {
diff --git a/src/gallium/state_trackers/nine/nine_pipe.h b/src/gallium/state_trackers/nine/nine_pipe.h
index 41792f09e8c..4fb6fa38ba4 100644
--- a/src/gallium/state_trackers/nine/nine_pipe.h
+++ b/src/gallium/state_trackers/nine/nine_pipe.h
@@ -284,6 +284,7 @@ d3dformat_to_string(D3DFORMAT fmt)
case D3DFMT_DF24: return "D3DFMT_DF24";
case D3DFMT_INTZ: return "D3DFMT_INTZ";
case D3DFMT_NVDB: return "D3DFMT_NVDB";
+ case D3DFMT_RESZ: return "D3DFMT_RESZ";
case D3DFMT_NULL: return "D3DFMT_NULL";
default:
break;