2 * Copyright 2011 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/port.h"
23 #include "d3d10_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d10
);
27 struct d3d10_stateblock
29 ID3D10StateBlock ID3D10StateBlock_iface
;
33 D3D10_STATE_BLOCK_MASK mask
;
35 ID3D10VertexShader
*vs
;
36 ID3D10SamplerState
*vs_samplers
[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
];
37 ID3D10ShaderResourceView
*vs_resources
[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
];
38 ID3D10Buffer
*vs_cbs
[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
];
39 ID3D10GeometryShader
*gs
;
40 ID3D10SamplerState
*gs_samplers
[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
];
41 ID3D10ShaderResourceView
*gs_resources
[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
];
42 ID3D10Buffer
*gs_cbs
[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
];
43 ID3D10PixelShader
*ps
;
44 ID3D10SamplerState
*ps_samplers
[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
];
45 ID3D10ShaderResourceView
*ps_resources
[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
];
46 ID3D10Buffer
*ps_cbs
[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
];
47 ID3D10Buffer
*vbs
[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
];
48 UINT vb_strides
[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
];
49 UINT vb_offsets
[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
];
51 DXGI_FORMAT ib_format
;
53 ID3D10InputLayout
*il
;
54 D3D10_PRIMITIVE_TOPOLOGY topology
;
55 ID3D10RenderTargetView
*rtvs
[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
];
56 ID3D10DepthStencilView
*dsv
;
57 ID3D10DepthStencilState
*dss
;
60 float blend_factor
[4];
62 D3D10_VIEWPORT vps
[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE
];
63 D3D10_RECT scissor_rects
[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE
];
64 ID3D10RasterizerState
*rs
;
65 ID3D10Buffer
*so_buffers
[D3D10_SO_BUFFER_SLOT_COUNT
];
66 UINT so_offsets
[D3D10_SO_BUFFER_SLOT_COUNT
];
67 ID3D10Predicate
*predicate
;
71 static inline struct d3d10_stateblock
*impl_from_ID3D10StateBlock(ID3D10StateBlock
*iface
)
73 return CONTAINING_RECORD(iface
, struct d3d10_stateblock
, ID3D10StateBlock_iface
);
76 static void stateblock_cleanup(struct d3d10_stateblock
*stateblock
)
82 ID3D10VertexShader_Release(stateblock
->vs
);
83 stateblock
->vs
= NULL
;
85 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
87 if (stateblock
->vs_samplers
[i
])
89 ID3D10SamplerState_Release(stateblock
->vs_samplers
[i
]);
90 stateblock
->vs_samplers
[i
] = NULL
;
93 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
95 if (stateblock
->vs_resources
[i
])
97 ID3D10ShaderResourceView_Release(stateblock
->vs_resources
[i
]);
98 stateblock
->vs_resources
[i
] = NULL
;
101 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
103 if (stateblock
->vs_cbs
[i
])
105 ID3D10Buffer_Release(stateblock
->vs_cbs
[i
]);
106 stateblock
->vs_cbs
[i
] = NULL
;
112 ID3D10GeometryShader_Release(stateblock
->gs
);
113 stateblock
->gs
= NULL
;
115 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
117 if (stateblock
->gs_samplers
[i
])
119 ID3D10SamplerState_Release(stateblock
->gs_samplers
[i
]);
120 stateblock
->gs_samplers
[i
] = NULL
;
123 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
125 if (stateblock
->gs_resources
[i
])
127 ID3D10ShaderResourceView_Release(stateblock
->gs_resources
[i
]);
128 stateblock
->gs_resources
[i
] = NULL
;
131 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
133 if (stateblock
->gs_cbs
[i
])
135 ID3D10Buffer_Release(stateblock
->gs_cbs
[i
]);
136 stateblock
->gs_cbs
[i
] = NULL
;
142 ID3D10PixelShader_Release(stateblock
->ps
);
143 stateblock
->ps
= NULL
;
145 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
147 if (stateblock
->ps_samplers
[i
])
149 ID3D10SamplerState_Release(stateblock
->ps_samplers
[i
]);
150 stateblock
->ps_samplers
[i
] = NULL
;
153 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
155 if (stateblock
->ps_resources
[i
])
157 ID3D10ShaderResourceView_Release(stateblock
->ps_resources
[i
]);
158 stateblock
->ps_resources
[i
] = NULL
;
161 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
163 if (stateblock
->ps_cbs
[i
])
165 ID3D10Buffer_Release(stateblock
->ps_cbs
[i
]);
166 stateblock
->ps_cbs
[i
] = NULL
;
170 for (i
= 0; i
< D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
172 if (stateblock
->vbs
[i
])
174 ID3D10Buffer_Release(stateblock
->vbs
[i
]);
175 stateblock
->vbs
[i
] = NULL
;
180 ID3D10Buffer_Release(stateblock
->ib
);
181 stateblock
->ib
= NULL
;
185 ID3D10InputLayout_Release(stateblock
->il
);
186 stateblock
->il
= NULL
;
189 for (i
= 0; i
< D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
191 if (stateblock
->rtvs
[i
])
193 ID3D10RenderTargetView_Release(stateblock
->rtvs
[i
]);
194 stateblock
->rtvs
[i
] = NULL
;
199 ID3D10DepthStencilView_Release(stateblock
->dsv
);
200 stateblock
->dsv
= NULL
;
204 ID3D10DepthStencilState_Release(stateblock
->dss
);
205 stateblock
->dss
= NULL
;
209 ID3D10BlendState_Release(stateblock
->bs
);
210 stateblock
->bs
= NULL
;
215 ID3D10RasterizerState_Release(stateblock
->rs
);
216 stateblock
->rs
= NULL
;
219 for (i
= 0; i
< D3D10_SO_BUFFER_SLOT_COUNT
; ++i
)
221 if (stateblock
->so_buffers
[i
])
223 ID3D10Buffer_Release(stateblock
->so_buffers
[i
]);
224 stateblock
->so_buffers
[i
] = NULL
;
228 if (stateblock
->predicate
)
230 ID3D10Predicate_Release(stateblock
->predicate
);
231 stateblock
->predicate
= NULL
;
235 static HRESULT STDMETHODCALLTYPE
d3d10_stateblock_QueryInterface(ID3D10StateBlock
*iface
, REFIID iid
, void **object
)
237 struct d3d10_stateblock
*stateblock
;
239 TRACE("iface %p, iid %s, object %p.\n", iface
, debugstr_guid(iid
), object
);
241 stateblock
= impl_from_ID3D10StateBlock(iface
);
243 if (IsEqualGUID(iid
, &IID_ID3D10StateBlock
)
244 || IsEqualGUID(iid
, &IID_IUnknown
))
246 IUnknown_AddRef(&stateblock
->ID3D10StateBlock_iface
);
247 *object
= &stateblock
->ID3D10StateBlock_iface
;
251 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
254 return E_NOINTERFACE
;
257 static ULONG STDMETHODCALLTYPE
d3d10_stateblock_AddRef(ID3D10StateBlock
*iface
)
259 struct d3d10_stateblock
*stateblock
= impl_from_ID3D10StateBlock(iface
);
260 ULONG refcount
= InterlockedIncrement(&stateblock
->refcount
);
262 TRACE("%p increasing refcount to %u.\n", stateblock
, refcount
);
267 static ULONG STDMETHODCALLTYPE
d3d10_stateblock_Release(ID3D10StateBlock
*iface
)
269 struct d3d10_stateblock
*stateblock
= impl_from_ID3D10StateBlock(iface
);
270 ULONG refcount
= InterlockedDecrement(&stateblock
->refcount
);
272 TRACE("%p decreasing refcount to %u.\n", stateblock
, refcount
);
276 stateblock_cleanup(stateblock
);
277 ID3D10Device_Release(stateblock
->device
);
278 heap_free(stateblock
);
284 static HRESULT STDMETHODCALLTYPE
d3d10_stateblock_Capture(ID3D10StateBlock
*iface
)
286 unsigned int vp_count
= D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE
;
287 struct d3d10_stateblock
*stateblock
= impl_from_ID3D10StateBlock(iface
);
290 TRACE("iface %p.\n", iface
);
292 stateblock_cleanup(stateblock
);
294 if (stateblock
->mask
.VS
)
295 ID3D10Device_VSGetShader(stateblock
->device
, &stateblock
->vs
);
296 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
298 if (stateblock
->mask
.VSSamplers
[i
>> 3] & (1 << (i
& 7)))
299 ID3D10Device_VSGetSamplers(stateblock
->device
, i
, 1, &stateblock
->vs_samplers
[i
]);
301 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
303 if (stateblock
->mask
.VSShaderResources
[i
>> 3] & (1 << (i
& 7)))
304 ID3D10Device_VSGetShaderResources(stateblock
->device
, i
, 1, &stateblock
->vs_resources
[i
]);
306 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
308 if (stateblock
->mask
.VSConstantBuffers
[i
>> 3] & (1 << (i
& 7)))
309 ID3D10Device_VSGetConstantBuffers(stateblock
->device
, i
, 1, &stateblock
->vs_cbs
[i
]);
312 if (stateblock
->mask
.GS
)
313 ID3D10Device_GSGetShader(stateblock
->device
, &stateblock
->gs
);
314 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
316 if (stateblock
->mask
.GSSamplers
[i
>> 3] & (1 << (i
& 7)))
317 ID3D10Device_GSGetSamplers(stateblock
->device
, i
, 1, &stateblock
->gs_samplers
[i
]);
319 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
321 if (stateblock
->mask
.GSShaderResources
[i
>> 3] & (1 << (i
& 7)))
322 ID3D10Device_GSGetShaderResources(stateblock
->device
, i
, 1, &stateblock
->gs_resources
[i
]);
324 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
326 if (stateblock
->mask
.GSConstantBuffers
[i
>> 3] & (1 << (i
& 7)))
327 ID3D10Device_GSGetConstantBuffers(stateblock
->device
, i
, 1, &stateblock
->gs_cbs
[i
]);
330 if (stateblock
->mask
.PS
)
331 ID3D10Device_PSGetShader(stateblock
->device
, &stateblock
->ps
);
332 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
334 if (stateblock
->mask
.PSSamplers
[i
>> 3] & (1 << (i
& 7)))
335 ID3D10Device_PSGetSamplers(stateblock
->device
, i
, 1, &stateblock
->ps_samplers
[i
]);
337 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
339 if (stateblock
->mask
.PSShaderResources
[i
>> 3] & (1 << (i
& 7)))
340 ID3D10Device_PSGetShaderResources(stateblock
->device
, i
, 1, &stateblock
->ps_resources
[i
]);
342 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
344 if (stateblock
->mask
.PSConstantBuffers
[i
>> 3] & (1 << (i
& 7)))
345 ID3D10Device_PSGetConstantBuffers(stateblock
->device
, i
, 1, &stateblock
->ps_cbs
[i
]);
348 for (i
= 0; i
< D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
350 if (stateblock
->mask
.IAVertexBuffers
[i
>> 3] & (1 << (i
& 7)))
351 ID3D10Device_IAGetVertexBuffers(stateblock
->device
, i
, 1, &stateblock
->vbs
[i
],
352 &stateblock
->vb_strides
[i
], &stateblock
->vb_offsets
[i
]);
354 if (stateblock
->mask
.IAIndexBuffer
)
355 ID3D10Device_IAGetIndexBuffer(stateblock
->device
, &stateblock
->ib
,
356 &stateblock
->ib_format
, &stateblock
->ib_offset
);
357 if (stateblock
->mask
.IAInputLayout
)
358 ID3D10Device_IAGetInputLayout(stateblock
->device
, &stateblock
->il
);
359 if (stateblock
->mask
.IAPrimitiveTopology
)
360 ID3D10Device_IAGetPrimitiveTopology(stateblock
->device
, &stateblock
->topology
);
362 if (stateblock
->mask
.OMRenderTargets
)
363 ID3D10Device_OMGetRenderTargets(stateblock
->device
, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
,
364 stateblock
->rtvs
, &stateblock
->dsv
);
365 if (stateblock
->mask
.OMDepthStencilState
)
366 ID3D10Device_OMGetDepthStencilState(stateblock
->device
, &stateblock
->dss
, &stateblock
->stencil_ref
);
367 if (stateblock
->mask
.OMBlendState
)
368 ID3D10Device_OMGetBlendState(stateblock
->device
, &stateblock
->bs
,
369 stateblock
->blend_factor
, &stateblock
->sample_mask
);
371 if (stateblock
->mask
.RSViewports
)
372 ID3D10Device_RSGetViewports(stateblock
->device
, &vp_count
, stateblock
->vps
);
373 if (stateblock
->mask
.RSScissorRects
)
374 ID3D10Device_RSGetScissorRects(stateblock
->device
, &vp_count
, stateblock
->scissor_rects
);
375 if (stateblock
->mask
.RSRasterizerState
)
376 ID3D10Device_RSGetState(stateblock
->device
, &stateblock
->rs
);
378 if (stateblock
->mask
.SOBuffers
)
379 ID3D10Device_SOGetTargets(stateblock
->device
, D3D10_SO_BUFFER_SLOT_COUNT
,
380 stateblock
->so_buffers
, stateblock
->so_offsets
);
382 if (stateblock
->mask
.Predication
)
383 ID3D10Device_GetPredication(stateblock
->device
, &stateblock
->predicate
, &stateblock
->predicate_value
);
388 static HRESULT STDMETHODCALLTYPE
d3d10_stateblock_Apply(ID3D10StateBlock
*iface
)
390 struct d3d10_stateblock
*stateblock
= impl_from_ID3D10StateBlock(iface
);
393 TRACE("iface %p.\n", iface
);
395 if (stateblock
->mask
.VS
)
396 ID3D10Device_VSSetShader(stateblock
->device
, stateblock
->vs
);
397 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
399 if (stateblock
->mask
.VSSamplers
[i
>> 3] & (1 << (i
& 7)))
400 ID3D10Device_VSSetSamplers(stateblock
->device
, i
, 1, &stateblock
->vs_samplers
[i
]);
402 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
404 if (stateblock
->mask
.VSShaderResources
[i
>> 3] & (1 << (i
& 7)))
405 ID3D10Device_VSSetShaderResources(stateblock
->device
, i
, 1, &stateblock
->vs_resources
[i
]);
407 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
409 if (stateblock
->mask
.VSConstantBuffers
[i
>> 3] & (1 << (i
& 7)))
410 ID3D10Device_VSSetConstantBuffers(stateblock
->device
, i
, 1, &stateblock
->vs_cbs
[i
]);
413 if (stateblock
->mask
.GS
)
414 ID3D10Device_GSSetShader(stateblock
->device
, stateblock
->gs
);
415 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
417 if (stateblock
->mask
.GSSamplers
[i
>> 3] & (1 << (i
& 7)))
418 ID3D10Device_GSSetSamplers(stateblock
->device
, i
, 1, &stateblock
->gs_samplers
[i
]);
420 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
422 if (stateblock
->mask
.GSShaderResources
[i
>> 3] & (1 << (i
& 7)))
423 ID3D10Device_GSSetShaderResources(stateblock
->device
, i
, 1, &stateblock
->gs_resources
[i
]);
425 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
427 if (stateblock
->mask
.GSConstantBuffers
[i
>> 3] & (1 << (i
& 7)))
428 ID3D10Device_GSSetConstantBuffers(stateblock
->device
, i
, 1, &stateblock
->gs_cbs
[i
]);
431 if (stateblock
->mask
.PS
)
432 ID3D10Device_PSSetShader(stateblock
->device
, stateblock
->ps
);
433 for (i
= 0; i
< D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
; ++i
)
435 if (stateblock
->mask
.PSSamplers
[i
>> 3] & (1 << (i
& 7)))
436 ID3D10Device_PSSetSamplers(stateblock
->device
, i
, 1, &stateblock
->ps_samplers
[i
]);
438 for (i
= 0; i
< D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
440 if (stateblock
->mask
.PSShaderResources
[i
>> 3] & (1 << (i
& 7)))
441 ID3D10Device_PSSetShaderResources(stateblock
->device
, i
, 1, &stateblock
->ps_resources
[i
]);
443 for (i
= 0; i
< D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
; ++i
)
445 if (stateblock
->mask
.PSConstantBuffers
[i
>> 3] & (1 << (i
& 7)))
446 ID3D10Device_PSSetConstantBuffers(stateblock
->device
, i
, 1, &stateblock
->ps_cbs
[i
]);
449 for (i
= 0; i
< D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
; ++i
)
451 if (stateblock
->mask
.IAVertexBuffers
[i
>> 3] & (1 << (i
& 7)))
452 ID3D10Device_IASetVertexBuffers(stateblock
->device
, i
, 1, &stateblock
->vbs
[i
],
453 &stateblock
->vb_strides
[i
], &stateblock
->vb_offsets
[i
]);
455 if (stateblock
->mask
.IAIndexBuffer
)
456 ID3D10Device_IASetIndexBuffer(stateblock
->device
, stateblock
->ib
,
457 stateblock
->ib_format
, stateblock
->ib_offset
);
458 if (stateblock
->mask
.IAInputLayout
)
459 ID3D10Device_IASetInputLayout(stateblock
->device
, stateblock
->il
);
460 if (stateblock
->mask
.IAPrimitiveTopology
)
461 ID3D10Device_IASetPrimitiveTopology(stateblock
->device
, stateblock
->topology
);
463 if (stateblock
->mask
.OMRenderTargets
)
464 ID3D10Device_OMSetRenderTargets(stateblock
->device
, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
,
465 stateblock
->rtvs
, stateblock
->dsv
);
466 if (stateblock
->mask
.OMDepthStencilState
)
467 ID3D10Device_OMSetDepthStencilState(stateblock
->device
, stateblock
->dss
, stateblock
->stencil_ref
);
468 if (stateblock
->mask
.OMBlendState
)
469 ID3D10Device_OMSetBlendState(stateblock
->device
, stateblock
->bs
,
470 stateblock
->blend_factor
, stateblock
->sample_mask
);
472 if (stateblock
->mask
.RSViewports
)
473 ID3D10Device_RSSetViewports(stateblock
->device
, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE
,
475 if (stateblock
->mask
.RSScissorRects
)
476 ID3D10Device_RSSetScissorRects(stateblock
->device
, D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE
,
477 stateblock
->scissor_rects
);
478 if (stateblock
->mask
.RSRasterizerState
)
479 ID3D10Device_RSSetState(stateblock
->device
, stateblock
->rs
);
481 if (stateblock
->mask
.SOBuffers
)
482 ID3D10Device_SOSetTargets(stateblock
->device
, D3D10_SO_BUFFER_SLOT_COUNT
,
483 stateblock
->so_buffers
, stateblock
->so_offsets
);
485 if (stateblock
->mask
.Predication
)
486 ID3D10Device_SetPredication(stateblock
->device
, stateblock
->predicate
, stateblock
->predicate_value
);
491 static HRESULT STDMETHODCALLTYPE
d3d10_stateblock_ReleaseAllDeviceObjects(ID3D10StateBlock
*iface
)
493 FIXME("iface %p stub!\n", iface
);
498 static HRESULT STDMETHODCALLTYPE
d3d10_stateblock_GetDevice(ID3D10StateBlock
*iface
, ID3D10Device
**device
)
500 FIXME("iface %p, device %p stub!\n", iface
, device
);
505 static const struct ID3D10StateBlockVtbl d3d10_stateblock_vtbl
=
507 /* IUnknown methods */
508 d3d10_stateblock_QueryInterface
,
509 d3d10_stateblock_AddRef
,
510 d3d10_stateblock_Release
,
511 /* ID3D10StateBlock methods */
512 d3d10_stateblock_Capture
,
513 d3d10_stateblock_Apply
,
514 d3d10_stateblock_ReleaseAllDeviceObjects
,
515 d3d10_stateblock_GetDevice
,
518 HRESULT WINAPI
D3D10CreateStateBlock(ID3D10Device
*device
,
519 D3D10_STATE_BLOCK_MASK
*mask
, ID3D10StateBlock
**stateblock
)
521 struct d3d10_stateblock
*object
;
523 TRACE("device %p, mask %p, stateblock %p.\n", device
, mask
, stateblock
);
525 if (!(object
= heap_alloc_zero(sizeof(*object
))))
527 ERR("Failed to allocate D3D10 stateblock object memory.\n");
528 return E_OUTOFMEMORY
;
531 object
->ID3D10StateBlock_iface
.lpVtbl
= &d3d10_stateblock_vtbl
;
532 object
->refcount
= 1;
534 object
->device
= device
;
535 ID3D10Device_AddRef(object
->device
);
536 object
->mask
= *mask
;
538 TRACE("Created stateblock %p.\n", object
);
539 *stateblock
= &object
->ID3D10StateBlock_iface
;
544 static BOOL
stateblock_mask_get_bit(BYTE
*field
, UINT field_size
, UINT idx
)
546 if (idx
>= field_size
)
549 return field
[idx
>> 3] & (1 << (idx
& 7));
552 static HRESULT
stateblock_mask_set_bits(BYTE
*field
, UINT field_size
, UINT start_bit
, UINT count
)
554 UINT end_bit
= start_bit
+ count
;
555 BYTE start_mask
= 0xff << (start_bit
& 7);
556 BYTE end_mask
= 0x7f >> (~end_bit
& 7);
557 UINT start_idx
= start_bit
>> 3;
558 UINT end_idx
= end_bit
>> 3;
560 if (start_bit
>= field_size
|| field_size
- start_bit
< count
)
563 if (start_idx
== end_idx
)
565 field
[start_idx
] |= start_mask
& end_mask
;
571 field
[start_idx
] |= start_mask
;
575 memset(&field
[start_idx
], 0xff, end_idx
- start_idx
);
578 field
[end_idx
] |= end_mask
;
583 static HRESULT
stateblock_mask_clear_bits(BYTE
*field
, UINT field_size
, UINT start_bit
, UINT count
)
585 UINT end_bit
= start_bit
+ count
;
586 BYTE start_mask
= 0x7f >> (~start_bit
& 7);
587 BYTE end_mask
= 0xff << (end_bit
& 7);
588 UINT start_idx
= start_bit
>> 3;
589 UINT end_idx
= end_bit
>> 3;
591 if (start_bit
>= field_size
|| field_size
- start_bit
< count
)
594 if (start_idx
== end_idx
)
596 field
[start_idx
] &= start_mask
| end_mask
;
602 field
[start_idx
] &= start_mask
;
606 memset(&field
[start_idx
], 0, end_idx
- start_idx
);
609 field
[end_idx
] &= end_mask
;
614 HRESULT WINAPI
D3D10StateBlockMaskDifference(D3D10_STATE_BLOCK_MASK
*mask_x
,
615 D3D10_STATE_BLOCK_MASK
*mask_y
, D3D10_STATE_BLOCK_MASK
*result
)
617 UINT count
= sizeof(*result
) / sizeof(DWORD
);
620 TRACE("mask_x %p, mask_y %p, result %p.\n", mask_x
, mask_y
, result
);
622 if (!mask_x
|| !mask_y
|| !result
)
625 for (i
= 0; i
< count
; ++i
)
627 ((DWORD
*)result
)[i
] = ((DWORD
*)mask_x
)[i
] ^ ((DWORD
*)mask_y
)[i
];
629 for (i
= count
* sizeof(DWORD
); i
< sizeof(*result
); ++i
)
631 ((BYTE
*)result
)[i
] = ((BYTE
*)mask_x
)[i
] ^ ((BYTE
*)mask_y
)[i
];
637 HRESULT WINAPI
D3D10StateBlockMaskDisableAll(D3D10_STATE_BLOCK_MASK
*mask
)
639 TRACE("mask %p.\n", mask
);
644 memset(mask
, 0, sizeof(*mask
));
649 HRESULT WINAPI
D3D10StateBlockMaskDisableCapture(D3D10_STATE_BLOCK_MASK
*mask
,
650 D3D10_DEVICE_STATE_TYPES state_type
, UINT start_idx
, UINT count
)
652 TRACE("mask %p state_type %s, start_idx %u, count %u.\n",
653 mask
, debug_d3d10_device_state_types(state_type
), start_idx
, count
);
660 case D3D10_DST_SO_BUFFERS
:
661 return stateblock_mask_clear_bits(&mask
->SOBuffers
, 1, start_idx
, count
);
662 case D3D10_DST_OM_RENDER_TARGETS
:
663 return stateblock_mask_clear_bits(&mask
->OMRenderTargets
, 1, start_idx
, count
);
664 case D3D10_DST_DEPTH_STENCIL_STATE
:
665 return stateblock_mask_clear_bits(&mask
->OMDepthStencilState
, 1, start_idx
, count
);
666 case D3D10_DST_BLEND_STATE
:
667 return stateblock_mask_clear_bits(&mask
->OMBlendState
, 1, start_idx
, count
);
669 return stateblock_mask_clear_bits(&mask
->VS
, 1, start_idx
, count
);
670 case D3D10_DST_VS_SAMPLERS
:
671 return stateblock_mask_clear_bits(mask
->VSSamplers
,
672 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, start_idx
, count
);
673 case D3D10_DST_VS_SHADER_RESOURCES
:
674 return stateblock_mask_clear_bits(mask
->VSShaderResources
,
675 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
676 case D3D10_DST_VS_CONSTANT_BUFFERS
:
677 return stateblock_mask_clear_bits(mask
->VSConstantBuffers
,
678 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, start_idx
, count
);
680 return stateblock_mask_clear_bits(&mask
->GS
, 1, start_idx
, count
);
681 case D3D10_DST_GS_SAMPLERS
:
682 return stateblock_mask_clear_bits(mask
->GSSamplers
,
683 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, start_idx
, count
);
684 case D3D10_DST_GS_SHADER_RESOURCES
:
685 return stateblock_mask_clear_bits(mask
->GSShaderResources
,
686 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
687 case D3D10_DST_GS_CONSTANT_BUFFERS
:
688 return stateblock_mask_clear_bits(mask
->GSConstantBuffers
,
689 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, start_idx
, count
);
691 return stateblock_mask_clear_bits(&mask
->PS
, 1, start_idx
, count
);
692 case D3D10_DST_PS_SAMPLERS
:
693 return stateblock_mask_clear_bits(mask
->PSSamplers
,
694 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, start_idx
, count
);
695 case D3D10_DST_PS_SHADER_RESOURCES
:
696 return stateblock_mask_clear_bits(mask
->PSShaderResources
,
697 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
698 case D3D10_DST_PS_CONSTANT_BUFFERS
:
699 return stateblock_mask_clear_bits(mask
->PSConstantBuffers
,
700 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, start_idx
, count
);
701 case D3D10_DST_IA_VERTEX_BUFFERS
:
702 return stateblock_mask_clear_bits(mask
->IAVertexBuffers
,
703 D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
704 case D3D10_DST_IA_INDEX_BUFFER
:
705 return stateblock_mask_clear_bits(&mask
->IAIndexBuffer
, 1, start_idx
, count
);
706 case D3D10_DST_IA_INPUT_LAYOUT
:
707 return stateblock_mask_clear_bits(&mask
->IAInputLayout
, 1, start_idx
, count
);
708 case D3D10_DST_IA_PRIMITIVE_TOPOLOGY
:
709 return stateblock_mask_clear_bits(&mask
->IAPrimitiveTopology
, 1, start_idx
, count
);
710 case D3D10_DST_RS_VIEWPORTS
:
711 return stateblock_mask_clear_bits(&mask
->RSViewports
, 1, start_idx
, count
);
712 case D3D10_DST_RS_SCISSOR_RECTS
:
713 return stateblock_mask_clear_bits(&mask
->RSScissorRects
, 1, start_idx
, count
);
714 case D3D10_DST_RS_RASTERIZER_STATE
:
715 return stateblock_mask_clear_bits(&mask
->RSRasterizerState
, 1, start_idx
, count
);
716 case D3D10_DST_PREDICATION
:
717 return stateblock_mask_clear_bits(&mask
->Predication
, 1, start_idx
, count
);
719 FIXME("Unhandled state_type %#x.\n", state_type
);
724 HRESULT WINAPI
D3D10StateBlockMaskEnableAll(D3D10_STATE_BLOCK_MASK
*mask
)
726 TRACE("mask %p.\n", mask
);
731 memset(mask
, 0xff, sizeof(*mask
));
736 HRESULT WINAPI
D3D10StateBlockMaskEnableCapture(D3D10_STATE_BLOCK_MASK
*mask
,
737 D3D10_DEVICE_STATE_TYPES state_type
, UINT start_idx
, UINT count
)
739 TRACE("mask %p state_type %s, start_idx %u, count %u.\n",
740 mask
, debug_d3d10_device_state_types(state_type
), start_idx
, count
);
747 case D3D10_DST_SO_BUFFERS
:
748 return stateblock_mask_set_bits(&mask
->SOBuffers
, 1, start_idx
, count
);
749 case D3D10_DST_OM_RENDER_TARGETS
:
750 return stateblock_mask_set_bits(&mask
->OMRenderTargets
, 1, start_idx
, count
);
751 case D3D10_DST_DEPTH_STENCIL_STATE
:
752 return stateblock_mask_set_bits(&mask
->OMDepthStencilState
, 1, start_idx
, count
);
753 case D3D10_DST_BLEND_STATE
:
754 return stateblock_mask_set_bits(&mask
->OMBlendState
, 1, start_idx
, count
);
756 return stateblock_mask_set_bits(&mask
->VS
, 1, start_idx
, count
);
757 case D3D10_DST_VS_SAMPLERS
:
758 return stateblock_mask_set_bits(mask
->VSSamplers
,
759 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, start_idx
, count
);
760 case D3D10_DST_VS_SHADER_RESOURCES
:
761 return stateblock_mask_set_bits(mask
->VSShaderResources
,
762 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
763 case D3D10_DST_VS_CONSTANT_BUFFERS
:
764 return stateblock_mask_set_bits(mask
->VSConstantBuffers
,
765 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, start_idx
, count
);
767 return stateblock_mask_set_bits(&mask
->GS
, 1, start_idx
, count
);
768 case D3D10_DST_GS_SAMPLERS
:
769 return stateblock_mask_set_bits(mask
->GSSamplers
,
770 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, start_idx
, count
);
771 case D3D10_DST_GS_SHADER_RESOURCES
:
772 return stateblock_mask_set_bits(mask
->GSShaderResources
,
773 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
774 case D3D10_DST_GS_CONSTANT_BUFFERS
:
775 return stateblock_mask_set_bits(mask
->GSConstantBuffers
,
776 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, start_idx
, count
);
778 return stateblock_mask_set_bits(&mask
->PS
, 1, start_idx
, count
);
779 case D3D10_DST_PS_SAMPLERS
:
780 return stateblock_mask_set_bits(mask
->PSSamplers
,
781 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, start_idx
, count
);
782 case D3D10_DST_PS_SHADER_RESOURCES
:
783 return stateblock_mask_set_bits(mask
->PSShaderResources
,
784 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
785 case D3D10_DST_PS_CONSTANT_BUFFERS
:
786 return stateblock_mask_set_bits(mask
->PSConstantBuffers
,
787 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, start_idx
, count
);
788 case D3D10_DST_IA_VERTEX_BUFFERS
:
789 return stateblock_mask_set_bits(mask
->IAVertexBuffers
,
790 D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
, start_idx
, count
);
791 case D3D10_DST_IA_INDEX_BUFFER
:
792 return stateblock_mask_set_bits(&mask
->IAIndexBuffer
, 1, start_idx
, count
);
793 case D3D10_DST_IA_INPUT_LAYOUT
:
794 return stateblock_mask_set_bits(&mask
->IAInputLayout
, 1, start_idx
, count
);
795 case D3D10_DST_IA_PRIMITIVE_TOPOLOGY
:
796 return stateblock_mask_set_bits(&mask
->IAPrimitiveTopology
, 1, start_idx
, count
);
797 case D3D10_DST_RS_VIEWPORTS
:
798 return stateblock_mask_set_bits(&mask
->RSViewports
, 1, start_idx
, count
);
799 case D3D10_DST_RS_SCISSOR_RECTS
:
800 return stateblock_mask_set_bits(&mask
->RSScissorRects
, 1, start_idx
, count
);
801 case D3D10_DST_RS_RASTERIZER_STATE
:
802 return stateblock_mask_set_bits(&mask
->RSRasterizerState
, 1, start_idx
, count
);
803 case D3D10_DST_PREDICATION
:
804 return stateblock_mask_set_bits(&mask
->Predication
, 1, start_idx
, count
);
806 FIXME("Unhandled state_type %#x.\n", state_type
);
811 BOOL WINAPI
D3D10StateBlockMaskGetSetting(D3D10_STATE_BLOCK_MASK
*mask
,
812 D3D10_DEVICE_STATE_TYPES state_type
, UINT idx
)
814 TRACE("mask %p state_type %s, idx %u.\n",
815 mask
, debug_d3d10_device_state_types(state_type
), idx
);
822 case D3D10_DST_SO_BUFFERS
:
823 return stateblock_mask_get_bit(&mask
->SOBuffers
, 1, idx
);
824 case D3D10_DST_OM_RENDER_TARGETS
:
825 return stateblock_mask_get_bit(&mask
->OMRenderTargets
, 1, idx
);
826 case D3D10_DST_DEPTH_STENCIL_STATE
:
827 return stateblock_mask_get_bit(&mask
->OMDepthStencilState
, 1, idx
);
828 case D3D10_DST_BLEND_STATE
:
829 return stateblock_mask_get_bit(&mask
->OMBlendState
, 1, idx
);
831 return stateblock_mask_get_bit(&mask
->VS
, 1, idx
);
832 case D3D10_DST_VS_SAMPLERS
:
833 return stateblock_mask_get_bit(mask
->VSSamplers
,
834 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, idx
);
835 case D3D10_DST_VS_SHADER_RESOURCES
:
836 return stateblock_mask_get_bit(mask
->VSShaderResources
,
837 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, idx
);
838 case D3D10_DST_VS_CONSTANT_BUFFERS
:
839 return stateblock_mask_get_bit(mask
->VSConstantBuffers
,
840 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, idx
);
842 return stateblock_mask_get_bit(&mask
->GS
, 1, idx
);
843 case D3D10_DST_GS_SAMPLERS
:
844 return stateblock_mask_get_bit(mask
->GSSamplers
,
845 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, idx
);
846 case D3D10_DST_GS_SHADER_RESOURCES
:
847 return stateblock_mask_get_bit(mask
->GSShaderResources
,
848 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, idx
);
849 case D3D10_DST_GS_CONSTANT_BUFFERS
:
850 return stateblock_mask_get_bit(mask
->GSConstantBuffers
,
851 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, idx
);
853 return stateblock_mask_get_bit(&mask
->PS
, 1, idx
);
854 case D3D10_DST_PS_SAMPLERS
:
855 return stateblock_mask_get_bit(mask
->PSSamplers
,
856 D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT
, idx
);
857 case D3D10_DST_PS_SHADER_RESOURCES
:
858 return stateblock_mask_get_bit(mask
->PSShaderResources
,
859 D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT
, idx
);
860 case D3D10_DST_PS_CONSTANT_BUFFERS
:
861 return stateblock_mask_get_bit(mask
->PSConstantBuffers
,
862 D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT
, idx
);
863 case D3D10_DST_IA_VERTEX_BUFFERS
:
864 return stateblock_mask_get_bit(mask
->IAVertexBuffers
,
865 D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
, idx
);
866 case D3D10_DST_IA_INDEX_BUFFER
:
867 return stateblock_mask_get_bit(&mask
->IAIndexBuffer
, 1, idx
);
868 case D3D10_DST_IA_INPUT_LAYOUT
:
869 return stateblock_mask_get_bit(&mask
->IAInputLayout
, 1, idx
);
870 case D3D10_DST_IA_PRIMITIVE_TOPOLOGY
:
871 return stateblock_mask_get_bit(&mask
->IAPrimitiveTopology
, 1, idx
);
872 case D3D10_DST_RS_VIEWPORTS
:
873 return stateblock_mask_get_bit(&mask
->RSViewports
, 1, idx
);
874 case D3D10_DST_RS_SCISSOR_RECTS
:
875 return stateblock_mask_get_bit(&mask
->RSScissorRects
, 1, idx
);
876 case D3D10_DST_RS_RASTERIZER_STATE
:
877 return stateblock_mask_get_bit(&mask
->RSRasterizerState
, 1, idx
);
878 case D3D10_DST_PREDICATION
:
879 return stateblock_mask_get_bit(&mask
->Predication
, 1, idx
);
881 FIXME("Unhandled state_type %#x.\n", state_type
);
886 HRESULT WINAPI
D3D10StateBlockMaskIntersect(D3D10_STATE_BLOCK_MASK
*mask_x
,
887 D3D10_STATE_BLOCK_MASK
*mask_y
, D3D10_STATE_BLOCK_MASK
*result
)
889 UINT count
= sizeof(*result
) / sizeof(DWORD
);
892 TRACE("mask_x %p, mask_y %p, result %p.\n", mask_x
, mask_y
, result
);
894 if (!mask_x
|| !mask_y
|| !result
)
897 for (i
= 0; i
< count
; ++i
)
899 ((DWORD
*)result
)[i
] = ((DWORD
*)mask_x
)[i
] & ((DWORD
*)mask_y
)[i
];
901 for (i
= count
* sizeof(DWORD
); i
< sizeof(*result
); ++i
)
903 ((BYTE
*)result
)[i
] = ((BYTE
*)mask_x
)[i
] & ((BYTE
*)mask_y
)[i
];
909 HRESULT WINAPI
D3D10StateBlockMaskUnion(D3D10_STATE_BLOCK_MASK
*mask_x
,
910 D3D10_STATE_BLOCK_MASK
*mask_y
, D3D10_STATE_BLOCK_MASK
*result
)
912 UINT count
= sizeof(*result
) / sizeof(DWORD
);
915 TRACE("mask_x %p, mask_y %p, result %p.\n", mask_x
, mask_y
, result
);
917 if (!mask_x
|| !mask_y
|| !result
)
920 for (i
= 0; i
< count
; ++i
)
922 ((DWORD
*)result
)[i
] = ((DWORD
*)mask_x
)[i
] | ((DWORD
*)mask_y
)[i
];
924 for (i
= count
* sizeof(DWORD
); i
< sizeof(*result
); ++i
)
926 ((BYTE
*)result
)[i
] = ((BYTE
*)mask_x
)[i
] | ((BYTE
*)mask_y
)[i
];