st/nine: Move draw calls to nine_state

Part of the refactor to move all gallium calls to
nine_state.c, and have all internal states required
for those calls in nine_context.

v2: Release buffers for Draw*Up functions in device9.c,
instead of nine_context. This prevents a leak with csmt
where the wrong pointers were released.

Signed-off-by: Axel Davy <axel.davy@ens.fr>
This commit is contained in:
Axel Davy 2016-10-16 11:34:35 +02:00
parent f72d8719eb
commit 64e232bd60
9 changed files with 389 additions and 252 deletions

View file

@ -106,10 +106,10 @@ NineDevice9_SetDefaultState( struct NineDevice9 *This, boolean is_reset )
This->state.scissor.maxy = refSurf->desc.Height;
if (This->nswapchains && This->swapchains[0]->params.EnableAutoDepthStencil) {
This->state.rs[D3DRS_ZENABLE] = TRUE;
nine_context_set_render_state(This, D3DRS_ZENABLE, TRUE);
This->state.rs_advertised[D3DRS_ZENABLE] = TRUE;
}
if (This->state.rs[D3DRS_ZENABLE])
if (This->state.rs_advertised[D3DRS_ZENABLE])
NineDevice9_SetDepthStencilSurface(
This, (IDirect3DSurface9 *)This->swapchains[0]->zsbuf);
}
@ -2221,64 +2221,6 @@ 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);
memset(&blit, 0, sizeof(blit));
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;
}
#define ALPHA_TO_COVERAGE_ENABLE MAKEFOURCC('A', '2', 'M', '1')
#define ALPHA_TO_COVERAGE_DISABLE MAKEFOURCC('A', '2', 'M', '0')
HRESULT NINE_WINAPI
NineDevice9_SetRenderState( struct NineDevice9 *This,
D3DRENDERSTATETYPE State,
@ -2291,43 +2233,19 @@ NineDevice9_SetRenderState( struct NineDevice9 *This,
user_assert(State < D3DRS_COUNT, D3DERR_INVALIDCALL);
if (state->rs_advertised[State] == Value && likely(!This->is_recording))
if (unlikely(This->is_recording)) {
state->rs_advertised[State] = Value;
/* only need to record changed render states for stateblocks */
state->changed.rs[State / 32] |= 1 << (State % 32);
state->changed.group |= nine_render_state_group[State];
return D3D_OK;
}
if (state->rs_advertised[State] == Value)
return D3D_OK;
state->rs_advertised[State] = Value;
/* Amd hacks (equivalent to GL extensions) */
if (unlikely(State == D3DRS_POINTSIZE)) {
if (Value == RESZ_CODE)
return NineDevice9_ResolveZ(This);
if (Value == ALPHA_TO_COVERAGE_ENABLE ||
Value == ALPHA_TO_COVERAGE_DISABLE) {
state->rs[NINED3DRS_ALPHACOVERAGE] = (Value == ALPHA_TO_COVERAGE_ENABLE);
state->changed.group |= NINE_STATE_BLEND;
return D3D_OK;
}
}
/* NV hack */
if (unlikely(State == D3DRS_ADAPTIVETESS_Y)) {
if (Value == D3DFMT_ATOC || (Value == D3DFMT_UNKNOWN && state->rs[NINED3DRS_ALPHACOVERAGE])) {
state->rs[NINED3DRS_ALPHACOVERAGE] = (Value == D3DFMT_ATOC) ? 3 : 0;
state->rs[NINED3DRS_ALPHACOVERAGE] &= state->rs[D3DRS_ALPHATESTENABLE] ? 3 : 2;
state->changed.group |= NINE_STATE_BLEND;
return D3D_OK;
}
}
if (unlikely(State == D3DRS_ALPHATESTENABLE && (state->rs[NINED3DRS_ALPHACOVERAGE] & 2))) {
DWORD alphacoverage_prev = state->rs[NINED3DRS_ALPHACOVERAGE];
state->rs[NINED3DRS_ALPHACOVERAGE] = (Value ? 3 : 2);
if (state->rs[NINED3DRS_ALPHACOVERAGE] != alphacoverage_prev)
state->changed.group |= NINE_STATE_BLEND;
}
state->rs[State] = nine_fix_render_state_value(State, Value);
state->changed.rs[State / 32] |= 1 << (State % 32);
state->changed.group |= nine_render_state_group[State];
nine_context_set_render_state(This, State, Value);
return D3D_OK;
}
@ -2717,7 +2635,7 @@ NineDevice9_ValidateDevice( struct NineDevice9 *This,
}
}
if (state->ds &&
(state->rs[D3DRS_ZENABLE] || state->rs[D3DRS_STENCILENABLE])) {
(state->rs_advertised[D3DRS_ZENABLE] || state->rs_advertised[D3DRS_STENCILENABLE])) {
if (w != 0 &&
(state->ds->desc.Width != w || state->ds->desc.Height != h))
return D3DERR_CONFLICTINGRENDERSTATE;
@ -2821,44 +2739,16 @@ NineDevice9_GetNPatchMode( struct NineDevice9 *This )
STUB(0);
}
static inline void
init_draw_info(struct pipe_draw_info *info,
struct NineDevice9 *dev, D3DPRIMITIVETYPE type, UINT count)
{
info->mode = d3dprimitivetype_to_pipe_prim(type);
info->count = prim_count_to_vertex_count(type, count);
info->start_instance = 0;
info->instance_count = 1;
if (dev->state.stream_instancedata_mask & dev->state.stream_usage_mask)
info->instance_count = MAX2(dev->state.stream_freq[0] & 0x7FFFFF, 1);
info->primitive_restart = FALSE;
info->restart_index = 0;
info->count_from_stream_output = NULL;
info->indirect = NULL;
info->indirect_params = NULL;
}
HRESULT NINE_WINAPI
NineDevice9_DrawPrimitive( struct NineDevice9 *This,
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex,
UINT PrimitiveCount )
{
struct pipe_draw_info info;
DBG("iface %p, PrimitiveType %u, StartVertex %u, PrimitiveCount %u\n",
This, PrimitiveType, StartVertex, PrimitiveCount);
nine_update_state(This);
init_draw_info(&info, This, PrimitiveType, PrimitiveCount);
info.indexed = FALSE;
info.start = StartVertex;
info.index_bias = 0;
info.min_index = info.start;
info.max_index = info.count - 1;
This->pipe->draw_vbo(This->pipe, &info);
nine_context_draw_primitive(This, PrimitiveType, StartVertex, PrimitiveCount);
return D3D_OK;
}
@ -2872,8 +2762,6 @@ NineDevice9_DrawIndexedPrimitive( struct NineDevice9 *This,
UINT StartIndex,
UINT PrimitiveCount )
{
struct pipe_draw_info info;
DBG("iface %p, PrimitiveType %u, BaseVertexIndex %u, MinVertexIndex %u "
"NumVertices %u, StartIndex %u, PrimitiveCount %u\n",
This, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices,
@ -2882,17 +2770,9 @@ NineDevice9_DrawIndexedPrimitive( struct NineDevice9 *This,
user_assert(This->state.idxbuf, D3DERR_INVALIDCALL);
user_assert(This->state.vdecl, D3DERR_INVALIDCALL);
nine_update_state(This);
init_draw_info(&info, This, PrimitiveType, PrimitiveCount);
info.indexed = TRUE;
info.start = StartIndex;
info.index_bias = BaseVertexIndex;
/* These don't include index bias: */
info.min_index = MinVertexIndex;
info.max_index = MinVertexIndex + NumVertices - 1;
This->pipe->draw_vbo(This->pipe, &info);
nine_context_draw_indexed_primitive(This, PrimitiveType, BaseVertexIndex,
MinVertexIndex, NumVertices, StartIndex,
PrimitiveCount);
return D3D_OK;
}
@ -2905,7 +2785,6 @@ NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This,
UINT VertexStreamZeroStride )
{
struct pipe_vertex_buffer vtxbuf;
struct pipe_draw_info info;
DBG("iface %p, PrimitiveType %u, PrimitiveCount %u, data %p, stride %u\n",
This, PrimitiveType, PrimitiveCount,
@ -2915,15 +2794,6 @@ NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This,
D3DERR_INVALIDCALL);
user_assert(PrimitiveCount, D3D_OK);
nine_update_state(This);
init_draw_info(&info, This, PrimitiveType, PrimitiveCount);
info.indexed = FALSE;
info.start = 0;
info.index_bias = 0;
info.min_index = 0;
info.max_index = info.count - 1;
vtxbuf.stride = VertexStreamZeroStride;
vtxbuf.buffer_offset = 0;
vtxbuf.buffer = NULL;
@ -2932,7 +2802,7 @@ NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This,
if (!This->driver_caps.user_vbufs) {
u_upload_data(This->vertex_uploader,
0,
(info.max_index + 1) * VertexStreamZeroStride, /* XXX */
(prim_count_to_vertex_count(PrimitiveType, PrimitiveCount)) * VertexStreamZeroStride, /* XXX */
4,
vtxbuf.user_buffer,
&vtxbuf.buffer_offset,
@ -2941,16 +2811,14 @@ NineDevice9_DrawPrimitiveUP( struct NineDevice9 *This,
vtxbuf.user_buffer = NULL;
}
This->pipe->set_vertex_buffers(This->pipe, 0, 1, &vtxbuf);
nine_context_draw_primitive_from_vtxbuf(This, PrimitiveType, PrimitiveCount, &vtxbuf);
This->pipe->draw_vbo(This->pipe, &info);
pipe_resource_reference(&vtxbuf.buffer, NULL);
NineDevice9_PauseRecording(This);
NineDevice9_SetStreamSource(This, 0, NULL, 0, 0);
NineDevice9_ResumeRecording(This);
pipe_resource_reference(&vtxbuf.buffer, NULL);
return D3D_OK;
}
@ -2965,7 +2833,6 @@ NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This,
const void *pVertexStreamZeroData,
UINT VertexStreamZeroStride )
{
struct pipe_draw_info info;
struct pipe_vertex_buffer vbuf;
struct pipe_index_buffer ibuf;
@ -2982,15 +2849,6 @@ NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This,
IndexDataFormat == D3DFMT_INDEX32, D3DERR_INVALIDCALL);
user_assert(PrimitiveCount, D3D_OK);
nine_update_state(This);
init_draw_info(&info, This, PrimitiveType, PrimitiveCount);
info.indexed = TRUE;
info.start = 0;
info.index_bias = 0;
info.min_index = MinVertexIndex;
info.max_index = MinVertexIndex + NumVertices - 1;
vbuf.stride = VertexStreamZeroStride;
vbuf.buffer_offset = 0;
vbuf.buffer = NULL;
@ -3002,11 +2860,10 @@ NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This,
ibuf.user_buffer = pIndexData;
if (!This->driver_caps.user_vbufs) {
const unsigned base = info.min_index * VertexStreamZeroStride;
const unsigned base = MinVertexIndex * VertexStreamZeroStride;
u_upload_data(This->vertex_uploader,
base,
(info.max_index -
info.min_index + 1) * VertexStreamZeroStride, /* XXX */
NumVertices * VertexStreamZeroStride, /* XXX */
4,
(const uint8_t *)vbuf.user_buffer + base,
&vbuf.buffer_offset,
@ -3019,7 +2876,7 @@ NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This,
if (!This->driver_caps.user_ibufs) {
u_upload_data(This->index_uploader,
0,
info.count * ibuf.index_size,
(prim_count_to_vertex_count(PrimitiveType, PrimitiveCount)) * ibuf.index_size,
4,
ibuf.user_buffer,
&ibuf.offset,
@ -3028,10 +2885,12 @@ NineDevice9_DrawIndexedPrimitiveUP( struct NineDevice9 *This,
ibuf.user_buffer = NULL;
}
This->pipe->set_vertex_buffers(This->pipe, 0, 1, &vbuf);
This->pipe->set_index_buffer(This->pipe, &ibuf);
This->pipe->draw_vbo(This->pipe, &info);
nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf(This, PrimitiveType,
MinVertexIndex,
NumVertices,
PrimitiveCount,
&vbuf,
&ibuf);
pipe_resource_reference(&vbuf.buffer, NULL);
pipe_resource_reference(&ibuf.buffer, NULL);
@ -3139,7 +2998,14 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
return D3DERR_DRIVERINTERNALERROR;
}
init_draw_info(&draw, This, D3DPT_POINTLIST, VertexCount);
draw.mode = PIPE_PRIM_POINTS;
draw.count = VertexCount;
draw.start_instance = 0;
draw.primitive_restart = FALSE;
draw.restart_index = 0;
draw.count_from_stream_output = NULL;
draw.indirect = NULL;
draw.indirect_params = NULL;
draw.instance_count = 1;
draw.indexed = FALSE;
draw.start = 0;

View file

@ -1559,6 +1559,7 @@ static struct NineVertexShader9 *
nine_ff_get_vs(struct NineDevice9 *device)
{
const struct nine_state *state = &device->state;
const struct nine_context *context = &device->context;
struct NineVertexShader9 *vs;
enum pipe_error err;
struct vs_build_ctx bld;
@ -1616,34 +1617,34 @@ nine_ff_get_vs(struct NineDevice9 *device)
(1 << NINE_DECLUSAGE_TESSFACTOR) | (1 << NINE_DECLUSAGE_SAMPLE));
if (!key.position_t)
key.passthrough = 0;
key.pointscale = !!state->rs[D3DRS_POINTSCALEENABLE];
key.pointscale = !!context->rs[D3DRS_POINTSCALEENABLE];
key.lighting = !!state->rs[D3DRS_LIGHTING] && state->ff.num_lights_active;
key.darkness = !!state->rs[D3DRS_LIGHTING] && !state->ff.num_lights_active;
key.lighting = !!context->rs[D3DRS_LIGHTING] && state->ff.num_lights_active;
key.darkness = !!context->rs[D3DRS_LIGHTING] && !state->ff.num_lights_active;
if (key.position_t) {
key.darkness = 0; /* |= key.lighting; */ /* XXX ? */
key.lighting = 0;
}
if ((key.lighting | key.darkness) && state->rs[D3DRS_COLORVERTEX]) {
if ((key.lighting | key.darkness) && context->rs[D3DRS_COLORVERTEX]) {
uint32_t mask = (key.color0in_one ? 0 : 1) | (key.color1in_zero ? 0 : 2);
key.mtl_diffuse = state->rs[D3DRS_DIFFUSEMATERIALSOURCE] & mask;
key.mtl_ambient = state->rs[D3DRS_AMBIENTMATERIALSOURCE] & mask;
key.mtl_specular = state->rs[D3DRS_SPECULARMATERIALSOURCE] & mask;
key.mtl_emissive = state->rs[D3DRS_EMISSIVEMATERIALSOURCE] & mask;
key.mtl_diffuse = context->rs[D3DRS_DIFFUSEMATERIALSOURCE] & mask;
key.mtl_ambient = context->rs[D3DRS_AMBIENTMATERIALSOURCE] & mask;
key.mtl_specular = context->rs[D3DRS_SPECULARMATERIALSOURCE] & mask;
key.mtl_emissive = context->rs[D3DRS_EMISSIVEMATERIALSOURCE] & mask;
}
key.fog = !!state->rs[D3DRS_FOGENABLE];
key.fog_mode = (!key.position_t && state->rs[D3DRS_FOGENABLE]) ? state->rs[D3DRS_FOGVERTEXMODE] : 0;
key.fog = !!context->rs[D3DRS_FOGENABLE];
key.fog_mode = (!key.position_t && context->rs[D3DRS_FOGENABLE]) ? context->rs[D3DRS_FOGVERTEXMODE] : 0;
if (key.fog_mode)
key.fog_range = state->rs[D3DRS_RANGEFOGENABLE];
key.fog_range = context->rs[D3DRS_RANGEFOGENABLE];
key.localviewer = !!state->rs[D3DRS_LOCALVIEWER];
key.normalizenormals = !!state->rs[D3DRS_NORMALIZENORMALS];
key.ucp = !!state->rs[D3DRS_CLIPPLANEENABLE];
key.localviewer = !!context->rs[D3DRS_LOCALVIEWER];
key.normalizenormals = !!context->rs[D3DRS_NORMALIZENORMALS];
key.ucp = !!context->rs[D3DRS_CLIPPLANEENABLE];
if (state->rs[D3DRS_VERTEXBLEND] != D3DVBF_DISABLE) {
key.vertexblend_indexed = !!state->rs[D3DRS_INDEXEDVERTEXBLENDENABLE] && has_indexes;
if (context->rs[D3DRS_VERTEXBLEND] != D3DVBF_DISABLE) {
key.vertexblend_indexed = !!context->rs[D3DRS_INDEXEDVERTEXBLENDENABLE] && has_indexes;
switch (state->rs[D3DRS_VERTEXBLEND]) {
switch (context->rs[D3DRS_VERTEXBLEND]) {
case D3DVBF_0WEIGHTS: key.vertexblend = key.vertexblend_indexed; break;
case D3DVBF_1WEIGHTS: key.vertexblend = 2; break;
case D3DVBF_2WEIGHTS: key.vertexblend = 3; break;
@ -1653,7 +1654,7 @@ nine_ff_get_vs(struct NineDevice9 *device)
assert(!"invalid D3DVBF");
break;
}
if (!has_weights && state->rs[D3DRS_VERTEXBLEND] != D3DVBF_0WEIGHTS)
if (!has_weights && context->rs[D3DRS_VERTEXBLEND] != D3DVBF_0WEIGHTS)
key.vertexblend = 0; /* TODO: if key.vertexblend_indexed, perhaps it should use 1.0 as weight, or revert to D3DVBF_0WEIGHTS */
}
@ -1714,6 +1715,7 @@ static struct NinePixelShader9 *
nine_ff_get_ps(struct NineDevice9 *device)
{
struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
D3DMATRIX *projection_matrix = GET_D3DTS(PROJECTION);
struct NinePixelShader9 *ps;
enum pipe_error err;
@ -1817,13 +1819,13 @@ nine_ff_get_ps(struct NineDevice9 *device)
key.ts[s-1].resultarg = 0;
key.projected = nine_ff_get_projected_key(state);
key.specular = !!state->rs[D3DRS_SPECULARENABLE];
key.specular = !!context->rs[D3DRS_SPECULARENABLE];
for (; s < 8; ++s)
key.ts[s].colorop = key.ts[s].alphaop = D3DTOP_DISABLE;
if (state->rs[D3DRS_FOGENABLE])
key.fog_mode = state->rs[D3DRS_FOGTABLEMODE];
key.fog = !!state->rs[D3DRS_FOGENABLE];
if (context->rs[D3DRS_FOGENABLE])
key.fog_mode = context->rs[D3DRS_FOGTABLEMODE];
key.fog = !!context->rs[D3DRS_FOGENABLE];
/* Pixel fog (with WFOG advertised): source is either Z or W.
* W is the source if vs ff is used, and the
* projection matrix is not orthogonal.
@ -1859,6 +1861,7 @@ static void
nine_ff_load_vs_transforms(struct NineDevice9 *device)
{
struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
D3DMATRIX T;
D3DMATRIX *M = (D3DMATRIX *)device->ff.vs_const;
unsigned i;
@ -1885,20 +1888,21 @@ nine_ff_load_vs_transforms(struct NineDevice9 *device)
M[40] = M[1];
}
if (state->rs[D3DRS_VERTEXBLEND] != D3DVBF_DISABLE) {
if (context->rs[D3DRS_VERTEXBLEND] != D3DVBF_DISABLE) {
/* load other world matrices */
for (i = 1; i <= 8; ++i) {
nine_d3d_matrix_matrix_mul(&M[40 + i], GET_D3DTS(WORLDMATRIX(i)), GET_D3DTS(VIEW));
}
}
device->ff.vs_const[30 * 4] = asfloat(state->rs[D3DRS_TWEENFACTOR]);
device->ff.vs_const[30 * 4] = asfloat(context->rs[D3DRS_TWEENFACTOR]);
}
static void
nine_ff_load_lights(struct NineDevice9 *device)
{
struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
struct fvec4 *dst = (struct fvec4 *)device->ff.vs_const;
unsigned l;
@ -1910,7 +1914,7 @@ nine_ff_load_lights(struct NineDevice9 *device)
memcpy(&dst[22], &mtl->Specular, 4 * sizeof(float));
dst[23].x = mtl->Power;
memcpy(&dst[24], &mtl->Emissive, 4 * sizeof(float));
d3dcolor_to_rgba(&dst[25].x, state->rs[D3DRS_AMBIENT]);
d3dcolor_to_rgba(&dst[25].x, context->rs[D3DRS_AMBIENT]);
dst[19].x = dst[25].x * mtl->Ambient.r + mtl->Emissive.r;
dst[19].y = dst[25].y * mtl->Ambient.g + mtl->Emissive.g;
dst[19].z = dst[25].z * mtl->Ambient.b + mtl->Emissive.b;
@ -1944,21 +1948,22 @@ static void
nine_ff_load_point_and_fog_params(struct NineDevice9 *device)
{
const struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
struct fvec4 *dst = (struct fvec4 *)device->ff.vs_const;
if (!(state->changed.group & NINE_STATE_FF_OTHER))
return;
dst[26].x = asfloat(state->rs[D3DRS_POINTSIZE_MIN]);
dst[26].y = asfloat(state->rs[D3DRS_POINTSIZE_MAX]);
dst[26].z = asfloat(state->rs[D3DRS_POINTSIZE]);
dst[26].w = asfloat(state->rs[D3DRS_POINTSCALE_A]);
dst[27].x = asfloat(state->rs[D3DRS_POINTSCALE_B]);
dst[27].y = asfloat(state->rs[D3DRS_POINTSCALE_C]);
dst[28].x = asfloat(state->rs[D3DRS_FOGEND]);
dst[28].y = 1.0f / (asfloat(state->rs[D3DRS_FOGEND]) - asfloat(state->rs[D3DRS_FOGSTART]));
dst[26].x = asfloat(context->rs[D3DRS_POINTSIZE_MIN]);
dst[26].y = asfloat(context->rs[D3DRS_POINTSIZE_MAX]);
dst[26].z = asfloat(context->rs[D3DRS_POINTSIZE]);
dst[26].w = asfloat(context->rs[D3DRS_POINTSCALE_A]);
dst[27].x = asfloat(context->rs[D3DRS_POINTSCALE_B]);
dst[27].y = asfloat(context->rs[D3DRS_POINTSCALE_C]);
dst[28].x = asfloat(context->rs[D3DRS_FOGEND]);
dst[28].y = 1.0f / (asfloat(context->rs[D3DRS_FOGEND]) - asfloat(context->rs[D3DRS_FOGSTART]));
if (isinf(dst[28].y))
dst[28].y = 0.0f;
dst[28].z = asfloat(state->rs[D3DRS_FOGDENSITY]);
dst[28].z = asfloat(context->rs[D3DRS_FOGDENSITY]);
}
static void
@ -1980,6 +1985,7 @@ static void
nine_ff_load_ps_params(struct NineDevice9 *device)
{
const struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
struct fvec4 *dst = (struct fvec4 *)device->ff.ps_const;
unsigned s;
@ -2003,11 +2009,11 @@ nine_ff_load_ps_params(struct NineDevice9 *device)
}
}
d3dcolor_to_rgba(&dst[20].x, state->rs[D3DRS_TEXTUREFACTOR]);
d3dcolor_to_rgba(&dst[21].x, state->rs[D3DRS_FOGCOLOR]);
dst[22].x = asfloat(state->rs[D3DRS_FOGEND]);
dst[22].y = 1.0f / (asfloat(state->rs[D3DRS_FOGEND]) - asfloat(state->rs[D3DRS_FOGSTART]));
dst[22].z = asfloat(state->rs[D3DRS_FOGDENSITY]);
d3dcolor_to_rgba(&dst[20].x, context->rs[D3DRS_TEXTUREFACTOR]);
d3dcolor_to_rgba(&dst[21].x, context->rs[D3DRS_FOGCOLOR]);
dst[22].x = asfloat(context->rs[D3DRS_FOGEND]);
dst[22].y = 1.0f / (asfloat(context->rs[D3DRS_FOGEND]) - asfloat(context->rs[D3DRS_FOGSTART]));
dst[22].z = asfloat(context->rs[D3DRS_FOGDENSITY]);
}
static void

View file

@ -32,6 +32,7 @@
#include "pixelshader9.h"
#include "nine_pipe.h"
#include "nine_ff.h"
#include "nine_limits.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "cso_cache/cso_context.h"
@ -47,7 +48,7 @@
static inline DWORD
check_multisample(struct NineDevice9 *device)
{
DWORD *rs = device->state.rs;
DWORD *rs = device->context.rs;
DWORD new_value = (rs[D3DRS_ZENABLE] || rs[D3DRS_STENCILENABLE]) &&
device->state.rt[0]->desc.MultiSampleType >= 1 &&
rs[D3DRS_MULTISAMPLEANTIALIAS];
@ -63,21 +64,21 @@ check_multisample(struct NineDevice9 *device)
static inline void
prepare_blend(struct NineDevice9 *device)
{
nine_convert_blend_state(&device->context.pipe.blend, device->state.rs);
nine_convert_blend_state(&device->context.pipe.blend, device->context.rs);
device->context.commit |= NINE_STATE_COMMIT_BLEND;
}
static inline void
prepare_dsa(struct NineDevice9 *device)
{
nine_convert_dsa_state(&device->context.pipe.dsa, device->state.rs);
nine_convert_dsa_state(&device->context.pipe.dsa, device->context.rs);
device->context.commit |= NINE_STATE_COMMIT_DSA;
}
static inline void
prepare_rasterizer(struct NineDevice9 *device)
{
nine_convert_rasterizer_state(device, &device->context.pipe.rast, device->state.rs);
nine_convert_rasterizer_state(device, &device->context.pipe.rast, device->context.rs);
device->context.commit |= NINE_STATE_COMMIT_RASTERIZER;
}
@ -350,19 +351,19 @@ prepare_ps_constants_userbuf(struct NineDevice9 *device)
}
if (state->ps->byte_code.version < 0x30 &&
state->rs[D3DRS_FOGENABLE]) {
context->rs[D3DRS_FOGENABLE]) {
float *dst = &state->ps_lconstf_temp[4 * 32];
if (cb.user_buffer != state->ps_lconstf_temp) {
memcpy(state->ps_lconstf_temp, cb.user_buffer, cb.buffer_size);
cb.user_buffer = state->ps_lconstf_temp;
}
d3dcolor_to_rgba(dst, state->rs[D3DRS_FOGCOLOR]);
if (state->rs[D3DRS_FOGTABLEMODE] == D3DFOG_LINEAR) {
dst[4] = asfloat(state->rs[D3DRS_FOGEND]);
dst[5] = 1.0f / (asfloat(state->rs[D3DRS_FOGEND]) - asfloat(state->rs[D3DRS_FOGSTART]));
} else if (state->rs[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
dst[4] = asfloat(state->rs[D3DRS_FOGDENSITY]);
d3dcolor_to_rgba(dst, context->rs[D3DRS_FOGCOLOR]);
if (context->rs[D3DRS_FOGTABLEMODE] == D3DFOG_LINEAR) {
dst[4] = asfloat(context->rs[D3DRS_FOGEND]);
dst[5] = 1.0f / (asfloat(context->rs[D3DRS_FOGEND]) - asfloat(context->rs[D3DRS_FOGSTART]));
} else if (context->rs[D3DRS_FOGTABLEMODE] != D3DFOG_NONE) {
dst[4] = asfloat(context->rs[D3DRS_FOGDENSITY]);
}
cb.buffer_size = 4 * 4 * 34;
}
@ -419,8 +420,8 @@ prepare_vs(struct NineDevice9 *device, uint8_t shader_changed)
context->cso.vs = vs->ff_cso;
}
if (state->rs[NINED3DRS_VSPOINTSIZE] != vs->point_size) {
state->rs[NINED3DRS_VSPOINTSIZE] = vs->point_size;
if (context->rs[NINED3DRS_VSPOINTSIZE] != vs->point_size) {
context->rs[NINED3DRS_VSPOINTSIZE] = vs->point_size;
changed_group |= NINE_STATE_RASTERIZER;
}
@ -442,7 +443,7 @@ prepare_ps(struct NineDevice9 *device, uint8_t shader_changed)
int has_key_changed = 0;
if (likely(ps))
has_key_changed = NinePixelShader9_UpdateKey(ps, state);
has_key_changed = NinePixelShader9_UpdateKey(ps, state, context);
if (!shader_changed && !has_key_changed)
return 0;
@ -480,7 +481,7 @@ update_framebuffer(struct NineDevice9 *device, bool is_clear)
unsigned nr_samples = rt0->base.info.nr_samples;
unsigned ps_mask = state->ps ? state->ps->rt_mask : 1;
unsigned mask = is_clear ? 0xf : ps_mask;
const int sRGB = state->rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
const int sRGB = context->rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
DBG("\n");
@ -1006,7 +1007,7 @@ update_managed_buffers(struct NineDevice9 *device)
}
}
boolean
static void
nine_update_state(struct NineDevice9 *device)
{
struct pipe_context *pipe = device->pipe;
@ -1095,19 +1096,19 @@ nine_update_state(struct NineDevice9 *device)
commit_scissor(device);
if (group & NINE_STATE_BLEND_COLOR) {
struct pipe_blend_color color;
d3dcolor_to_rgba(&color.color[0], state->rs[D3DRS_BLENDFACTOR]);
d3dcolor_to_rgba(&color.color[0], context->rs[D3DRS_BLENDFACTOR]);
pipe->set_blend_color(pipe, &color);
}
if (group & NINE_STATE_SAMPLE_MASK) {
if (state->rt[0]->desc.MultiSampleType <= D3DMULTISAMPLE_NONMASKABLE) {
pipe->set_sample_mask(pipe, ~0);
} else {
pipe->set_sample_mask(pipe, state->rs[D3DRS_MULTISAMPLEMASK]);
pipe->set_sample_mask(pipe, context->rs[D3DRS_MULTISAMPLEMASK]);
}
}
if (group & NINE_STATE_STENCIL_REF) {
struct pipe_stencil_ref ref;
ref.ref_value[0] = state->rs[D3DRS_STENCILREF];
ref.ref_value[0] = context->rs[D3DRS_STENCILREF];
ref.ref_value[1] = ref.ref_value[0];
pipe->set_stencil_ref(pipe, &ref);
}
@ -1117,8 +1118,126 @@ nine_update_state(struct NineDevice9 *device)
(NINE_STATE_FF | NINE_STATE_VS_CONST | NINE_STATE_PS_CONST);
DBG("finished\n");
}
return TRUE;
#define RESZ_CODE 0x7fa05000
static void
NineDevice9_ResolveZ( struct NineDevice9 *device )
{
struct nine_state *state = &device->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");
if (!source || !destination ||
destination->base.type != D3DRTYPE_TEXTURE)
return;
src = source->base.resource;
dst = destination->base.resource;
if (!src || !dst)
return;
/* check dst is depth format. we know already for src */
desc = util_format_description(dst->format);
if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
return;
memset(&blit, 0, sizeof(blit));
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;
device->pipe->blit(device->pipe, &blit);
}
#define ALPHA_TO_COVERAGE_ENABLE MAKEFOURCC('A', '2', 'M', '1')
#define ALPHA_TO_COVERAGE_DISABLE MAKEFOURCC('A', '2', 'M', '0')
void
nine_context_set_render_state(struct NineDevice9 *device,
D3DRENDERSTATETYPE State,
DWORD Value)
{
struct nine_state *state = &device->state;
struct nine_context *context = &device->context;
/* Amd hacks (equivalent to GL extensions) */
if (unlikely(State == D3DRS_POINTSIZE)) {
if (Value == RESZ_CODE) {
NineDevice9_ResolveZ(device);
return;
}
if (Value == ALPHA_TO_COVERAGE_ENABLE ||
Value == ALPHA_TO_COVERAGE_DISABLE) {
context->rs[NINED3DRS_ALPHACOVERAGE] = (Value == ALPHA_TO_COVERAGE_ENABLE);
state->changed.group |= NINE_STATE_BLEND;
return;
}
}
/* NV hack */
if (unlikely(State == D3DRS_ADAPTIVETESS_Y)) {
if (Value == D3DFMT_ATOC || (Value == D3DFMT_UNKNOWN && context->rs[NINED3DRS_ALPHACOVERAGE])) {
context->rs[NINED3DRS_ALPHACOVERAGE] = (Value == D3DFMT_ATOC) ? 3 : 0;
context->rs[NINED3DRS_ALPHACOVERAGE] &= context->rs[D3DRS_ALPHATESTENABLE] ? 3 : 2;
state->changed.group |= NINE_STATE_BLEND;
return;
}
}
if (unlikely(State == D3DRS_ALPHATESTENABLE && (context->rs[NINED3DRS_ALPHACOVERAGE] & 2))) {
DWORD alphacoverage_prev = context->rs[NINED3DRS_ALPHACOVERAGE];
context->rs[NINED3DRS_ALPHACOVERAGE] = (Value ? 3 : 2);
if (context->rs[NINED3DRS_ALPHACOVERAGE] != alphacoverage_prev)
state->changed.group |= NINE_STATE_BLEND;
}
context->rs[State] = nine_fix_render_state_value(State, Value);
state->changed.group |= nine_render_state_group[State];
}
void
nine_context_apply_stateblock(struct nine_context *dst,
const struct nine_state *src)
{
int i;
for (i = 0; i < ARRAY_SIZE(src->changed.rs); ++i) {
uint32_t m = src->changed.rs[i];
while (m) {
const int r = ffs(m) - 1;
m &= ~(1 << r);
dst->rs[i * 32 + r] = nine_fix_render_state_value(i * 32 + r, src->rs_advertised[i * 32 + r]);
}
}
}
static void
@ -1142,7 +1261,7 @@ nine_context_clear_fb(struct NineDevice9 *device,
float Z,
DWORD Stencil)
{
const int sRGB = device->state.rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
const int sRGB = device->context.rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
struct pipe_surface *cbuf, *zsbuf;
struct pipe_context *pipe = device->pipe;
struct NineSurface9 *zsbuf_surf = device->state.ds;
@ -1171,7 +1290,7 @@ nine_context_clear_fb(struct NineDevice9 *device,
rect.y2 = device->state.viewport.Height + rect.y1;
/* Both rectangles apply, which is weird, but that's D3D9. */
if (device->state.rs[D3DRS_SCISSORTESTENABLE]) {
if (device->context.rs[D3DRS_SCISSORTESTENABLE]) {
rect.x1 = MAX2(rect.x1, device->state.scissor.minx);
rect.y1 = MAX2(rect.y1, device->state.scissor.miny);
rect.x2 = MIN2(rect.x2, device->state.scissor.maxx);
@ -1276,6 +1395,115 @@ nine_context_clear_fb(struct NineDevice9 *device,
return;
}
static inline void
init_draw_info(struct pipe_draw_info *info,
struct NineDevice9 *dev, D3DPRIMITIVETYPE type, UINT count)
{
info->mode = d3dprimitivetype_to_pipe_prim(type);
info->count = prim_count_to_vertex_count(type, count);
info->start_instance = 0;
info->instance_count = 1;
if (dev->state.stream_instancedata_mask & dev->state.stream_usage_mask)
info->instance_count = MAX2(dev->state.stream_freq[0] & 0x7FFFFF, 1);
info->primitive_restart = FALSE;
info->restart_index = 0;
info->count_from_stream_output = NULL;
info->indirect = NULL;
info->indirect_params = NULL;
}
void
nine_context_draw_primitive(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex,
UINT PrimitiveCount)
{
struct pipe_draw_info info;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
info.indexed = FALSE;
info.start = StartVertex;
info.index_bias = 0;
info.min_index = info.start;
info.max_index = info.count - 1;
device->pipe->draw_vbo(device->pipe, &info);
}
void
nine_context_draw_indexed_primitive(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
INT BaseVertexIndex,
UINT MinVertexIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount)
{
struct pipe_draw_info info;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
info.indexed = TRUE;
info.start = StartIndex;
info.index_bias = BaseVertexIndex;
/* These don't include index bias: */
info.min_index = MinVertexIndex;
info.max_index = MinVertexIndex + NumVertices - 1;
device->pipe->draw_vbo(device->pipe, &info);
}
void
nine_context_draw_primitive_from_vtxbuf(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT PrimitiveCount,
struct pipe_vertex_buffer *vtxbuf)
{
struct pipe_draw_info info;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
info.indexed = FALSE;
info.start = 0;
info.index_bias = 0;
info.min_index = 0;
info.max_index = info.count - 1;
device->pipe->set_vertex_buffers(device->pipe, 0, 1, vtxbuf);
device->pipe->draw_vbo(device->pipe, &info);
}
void
nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT MinVertexIndex,
UINT NumVertices,
UINT PrimitiveCount,
struct pipe_vertex_buffer *vbuf,
struct pipe_index_buffer *ibuf)
{
struct pipe_draw_info info;
nine_update_state(device);
init_draw_info(&info, device, PrimitiveType, PrimitiveCount);
info.indexed = TRUE;
info.start = 0;
info.index_bias = 0;
info.min_index = MinVertexIndex;
info.max_index = MinVertexIndex + NumVertices - 1;
device->pipe->set_vertex_buffers(device->pipe, 0, 1, vbuf);
device->pipe->set_index_buffer(device->pipe, ibuf);
device->pipe->draw_vbo(device->pipe, &info);
}
/* State defaults */
static const DWORD nine_render_state_defaults[NINED3DRS_LAST + 1] =
@ -1456,7 +1684,7 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
/* Initialize defaults.
*/
memcpy(state->rs, nine_render_state_defaults, sizeof(state->rs));
memcpy(context->rs, nine_render_state_defaults, sizeof(context->rs));
for (s = 0; s < ARRAY_SIZE(state->ff.tex_stage); ++s) {
memcpy(&state->ff.tex_stage[s], nine_tex_stage_state_defaults,
@ -1481,9 +1709,9 @@ nine_state_set_defaults(struct NineDevice9 *device, const D3DCAPS9 *caps,
/* Cap dependent initial state:
*/
state->rs[D3DRS_POINTSIZE_MAX] = fui(caps->MaxPointSize);
context->rs[D3DRS_POINTSIZE_MAX] = fui(caps->MaxPointSize);
memcpy(state->rs_advertised, state->rs, sizeof(state->rs));
memcpy(state->rs_advertised, context->rs, sizeof(context->rs));
/* Set changed flags to initialize driver.
*/

View file

@ -135,7 +135,7 @@ struct nine_state
{
struct {
uint32_t group;
uint32_t rs[(NINED3DRS_COUNT + 31) / 32];
uint32_t rs[(NINED3DRS_COUNT + 31) / 32]; /* stateblocks only */
uint32_t vtxbuf;
uint32_t stream_freq;
uint32_t texture;
@ -187,7 +187,6 @@ struct nine_state
struct pipe_clip_state clip;
DWORD rs[NINED3DRS_COUNT];
DWORD rs_advertised[NINED3DRS_COUNT]; /* the ones apps get with GetRenderState */
struct NineBaseTexture9 *texture[NINE_MAX_SAMPLERS]; /* PS, DMAP, VS */
@ -228,6 +227,8 @@ struct nine_context {
uint8_t rt_mask;
DWORD rs[NINED3DRS_COUNT];
uint8_t bound_samplers_mask_vs;
uint16_t bound_samplers_mask_ps;
@ -266,12 +267,46 @@ extern const uint32_t nine_render_states_vertex[(NINED3DRS_COUNT + 31) / 32];
struct NineDevice9;
boolean nine_update_state(struct NineDevice9 *);
void
nine_context_set_render_state(struct NineDevice9 *device,
D3DRENDERSTATETYPE State,
DWORD Value);
void
nine_context_clear_fb(struct NineDevice9 *device, DWORD Count,
const D3DRECT *pRects, DWORD Flags,
D3DCOLOR Color, float Z, DWORD Stencil);
void
nine_context_draw_primitive(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT StartVertex,
UINT PrimitiveCount);
void
nine_context_draw_indexed_primitive(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
INT BaseVertexIndex,
UINT MinVertexIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount);
void
nine_context_draw_primitive_from_vtxbuf(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT PrimitiveCount,
struct pipe_vertex_buffer *vtxbuf);
void
nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf(struct NineDevice9 *device,
D3DPRIMITIVETYPE PrimitiveType,
UINT MinVertexIndex,
UINT NumVertices,
UINT PrimitiveCount,
struct pipe_vertex_buffer *vbuf,
struct pipe_index_buffer *ibuf);
void nine_state_restore_non_cso(struct NineDevice9 *device);
void nine_state_set_defaults(struct NineDevice9 *, const D3DCAPS9 *,
boolean is_reset);

View file

@ -159,8 +159,8 @@ NinePixelShader9_GetVariant( struct NinePixelShader9 *This )
info.byte_code = This->byte_code.tokens;
info.sampler_mask_shadow = key & 0xffff;
info.sampler_ps1xtypes = key;
info.fog_enable = device->state.rs[D3DRS_FOGENABLE];
info.fog_mode = device->state.rs[D3DRS_FOGTABLEMODE];
info.fog_enable = device->context.rs[D3DRS_FOGENABLE];
info.fog_mode = device->context.rs[D3DRS_FOGTABLEMODE];
info.force_color_in_centroid = key >> 34 & 1;
info.projected = (key >> 48) & 0xffff;
info.process_vertices = false;

View file

@ -65,7 +65,8 @@ NinePixelShader9( void *data )
static inline BOOL
NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
struct nine_state *state )
struct nine_state *state,
struct nine_context *context )
{
uint16_t samplers_shadow;
uint32_t samplers_ps1_types;
@ -89,8 +90,8 @@ NinePixelShader9_UpdateKey( struct NinePixelShader9 *ps,
}
if (ps->byte_code.version < 0x30) {
key |= ((uint64_t)state->rs[D3DRS_FOGENABLE]) << 32;
key |= ((uint64_t)state->rs[D3DRS_FOGTABLEMODE]) << 33;
key |= ((uint64_t)context->rs[D3DRS_FOGENABLE]) << 32;
key |= ((uint64_t)context->rs[D3DRS_FOGTABLEMODE]) << 33;
}
/* centroid interpolation automatically used for color ps inputs */

View file

@ -225,8 +225,7 @@ nine_state_copy_common(struct NineDevice9 *device,
while (m) {
const int r = ffs(m) - 1;
m &= ~(1 << r);
dst->rs[i * 32 + r] = src->rs[i * 32 + r];
DBG("State %d %s = %d\n", i * 32 + r, nine_d3drs_to_string(i * 32 + r), (int)src->rs[i * 32 + r]);
DBG("State %d %s = %d\n", i * 32 + r, nine_d3drs_to_string(i * 32 + r), (int)src->rs_advertised[i * 32 + r]);
dst->rs_advertised[i * 32 + r] = src->rs_advertised[i * 32 + r];
}
}
@ -438,7 +437,6 @@ nine_state_copy_common_all(struct NineDevice9 *device,
}
/* Render states. */
memcpy(dst->rs, src->rs, sizeof(dst->rs));
memcpy(dst->rs_advertised, src->rs_advertised, sizeof(dst->rs_advertised));
if (apply)
memcpy(dst->changed.rs, src->changed.rs, sizeof(dst->changed.rs));
@ -572,6 +570,8 @@ NineStateBlock9_Apply( struct NineStateBlock9 *This )
else
nine_state_copy_common(device, dst, src, src, TRUE, pool);
nine_context_apply_stateblock(&device->context, src);
if ((src->changed.group & NINE_STATE_VDECL) && src->vdecl)
NineDevice9_SetVertexDeclaration(This->base.device, (IDirect3DVertexDeclaration9 *)src->vdecl);

View file

@ -186,9 +186,9 @@ NineVertexShader9_GetVariant( struct NineVertexShader9 *This )
info.const_b_base = NINE_CONST_B_BASE(device->max_vs_const_f) / 16;
info.byte_code = This->byte_code.tokens;
info.sampler_mask_shadow = key & 0xf;
info.fog_enable = device->state.rs[D3DRS_FOGENABLE];
info.point_size_min = asfloat(device->state.rs[D3DRS_POINTSIZE_MIN]);
info.point_size_max = asfloat(device->state.rs[D3DRS_POINTSIZE_MAX]);
info.fog_enable = device->context.rs[D3DRS_FOGENABLE];
info.point_size_min = asfloat(device->context.rs[D3DRS_POINTSIZE_MIN]);
info.point_size_max = asfloat(device->context.rs[D3DRS_POINTSIZE_MAX]);
info.swvp_on = device->swvp;
info.process_vertices = false;

View file

@ -81,6 +81,7 @@ NineVertexShader9_UpdateKey( struct NineVertexShader9 *vs,
struct NineDevice9 *device )
{
struct nine_state *state = &(device->state);
struct nine_context *context = &(device->context);
uint8_t samplers_shadow;
uint64_t key;
BOOL res;
@ -90,15 +91,15 @@ NineVertexShader9_UpdateKey( struct NineVertexShader9 *vs,
key = samplers_shadow;
if (vs->byte_code.version < 0x30)
key |= (uint32_t) ((!!state->rs[D3DRS_FOGENABLE]) << 8);
key |= (uint32_t) ((!!context->rs[D3DRS_FOGENABLE]) << 8);
key |= (uint32_t) (device->swvp << 9);
/* We want to use a 64 bits key for performance.
* Use compressed float16 values for the pointsize min/max in the key.
* Shaders do not usually output psize.*/
if (vs->point_size) {
key |= ((uint64_t)util_float_to_half(asfloat(state->rs[D3DRS_POINTSIZE_MIN]))) << 32;
key |= ((uint64_t)util_float_to_half(asfloat(state->rs[D3DRS_POINTSIZE_MAX]))) << 48;
key |= ((uint64_t)util_float_to_half(asfloat(context->rs[D3DRS_POINTSIZE_MIN]))) << 32;
key |= ((uint64_t)util_float_to_half(asfloat(context->rs[D3DRS_POINTSIZE_MAX]))) << 48;
}
res = vs->last_key != key;