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);
}
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,
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;
-
- 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;
- }
+ if (state->rs_advertised[State] == Value)
+ return D3D_OK;
- 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];
+ state->rs_advertised[State] = Value;
+ nine_context_set_render_state(This, State, Value);
return D3D_OK;
}
}
}
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;
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;
}
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,
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;
}
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,
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;
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,
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;
}
const void *pVertexStreamZeroData,
UINT VertexStreamZeroStride )
{
- struct pipe_draw_info info;
struct pipe_vertex_buffer vbuf;
struct pipe_index_buffer ibuf;
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;
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,
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,
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);
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;
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;
(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;
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 */
}
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;
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.
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;
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;
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;
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
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;
}
}
- 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
#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"
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];
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;
}
}
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;
}
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;
}
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;
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");
}
}
-boolean
+static void
nine_update_state(struct NineDevice9 *device)
{
struct pipe_context *pipe = device->pipe;
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);
}
(NINE_STATE_FF | NINE_STATE_VS_CONST | NINE_STATE_PS_CONST);
DBG("finished\n");
+}
+
+#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')
+
- return TRUE;
+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
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;
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);
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] =
/* 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,
/* 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.
*/
{
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;
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 */
uint8_t rt_mask;
+ DWORD rs[NINED3DRS_COUNT];
+
uint8_t bound_samplers_mask_vs;
uint16_t bound_samplers_mask_ps;
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);
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;
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;
}
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 */
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];
}
}
}
/* 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));
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);
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;
struct NineDevice9 *device )
{
struct nine_state *state = &(device->state);
+ struct nine_context *context = &(device->context);
uint8_t samplers_shadow;
uint64_t key;
BOOL res;
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;