[PATCH 5/5] d3d10: Implement d3d10_stateblock_Capture().

Henri Verbeet hverbeet at codeweavers.com
Mon Sep 1 05:42:59 CDT 2014


---
 dlls/d3d10/stateblock.c |  297 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 295 insertions(+), 2 deletions(-)

diff --git a/dlls/d3d10/stateblock.c b/dlls/d3d10/stateblock.c
index ef6fe3f..11ebbdf 100644
--- a/dlls/d3d10/stateblock.c
+++ b/dlls/d3d10/stateblock.c
@@ -28,6 +28,43 @@ struct d3d10_stateblock
 {
     ID3D10StateBlock ID3D10StateBlock_iface;
     LONG refcount;
+
+    ID3D10Device *device;
+    D3D10_STATE_BLOCK_MASK mask;
+
+    ID3D10VertexShader *vs;
+    ID3D10SamplerState *vs_samplers[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
+    ID3D10ShaderResourceView *vs_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
+    ID3D10Buffer *vs_cbs[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
+    ID3D10GeometryShader *gs;
+    ID3D10SamplerState *gs_samplers[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
+    ID3D10ShaderResourceView *gs_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
+    ID3D10Buffer *gs_cbs[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
+    ID3D10PixelShader *ps;
+    ID3D10SamplerState *ps_samplers[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
+    ID3D10ShaderResourceView *ps_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
+    ID3D10Buffer *ps_cbs[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
+    ID3D10Buffer *vbs[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
+    UINT vb_strides[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
+    UINT vb_offsets[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
+    ID3D10Buffer *ib;
+    DXGI_FORMAT ib_format;
+    UINT ib_offset;
+    ID3D10InputLayout *il;
+    D3D10_PRIMITIVE_TOPOLOGY topology;
+    ID3D10RenderTargetView *rtvs[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
+    ID3D10DepthStencilView *dsv;
+    ID3D10DepthStencilState *dss;
+    ID3D10BlendState *bs;
+    float blend_factor[4];
+    UINT sample_mask;
+    D3D10_VIEWPORT vps[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
+    D3D10_RECT scissor_rects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
+    ID3D10RasterizerState *rs;
+    ID3D10Buffer *so_buffers[D3D10_SO_BUFFER_SLOT_COUNT];
+    UINT so_offsets[D3D10_SO_BUFFER_SLOT_COUNT];
+    ID3D10Predicate *predicate;
+    BOOL predicate_value;
 };
 
 static inline struct d3d10_stateblock *impl_from_ID3D10StateBlock(ID3D10StateBlock *iface)
@@ -35,6 +72,160 @@ static inline struct d3d10_stateblock *impl_from_ID3D10StateBlock(ID3D10StateBlo
     return CONTAINING_RECORD(iface, struct d3d10_stateblock, ID3D10StateBlock_iface);
 }
 
+static void stateblock_cleanup(struct d3d10_stateblock *stateblock)
+{
+    unsigned int i;
+
+    if (stateblock->vs)
+    {
+        ID3D10VertexShader_Release(stateblock->vs);
+        stateblock->vs = NULL;
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+    {
+        if (stateblock->vs_samplers[i])
+        {
+            ID3D10SamplerState_Release(stateblock->vs_samplers[i]);
+            stateblock->vs_samplers[i] = NULL;
+        }
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->vs_resources[i])
+        {
+            ID3D10ShaderResourceView_Release(stateblock->vs_resources[i]);
+            stateblock->vs_resources[i] = NULL;
+        }
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i)
+    {
+        if (stateblock->vs_cbs[i])
+        {
+            ID3D10Buffer_Release(stateblock->vs_cbs[i]);
+            stateblock->vs_cbs[i] = NULL;
+        }
+    }
+
+    if (stateblock->gs)
+    {
+        ID3D10GeometryShader_Release(stateblock->gs);
+        stateblock->gs = NULL;
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+    {
+        if (stateblock->gs_samplers[i])
+        {
+            ID3D10SamplerState_Release(stateblock->gs_samplers[i]);
+            stateblock->gs_samplers[i] = NULL;
+        }
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->gs_resources[i])
+        {
+            ID3D10ShaderResourceView_Release(stateblock->gs_resources[i]);
+            stateblock->gs_resources[i] = NULL;
+        }
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i)
+    {
+        if (stateblock->gs_cbs[i])
+        {
+            ID3D10Buffer_Release(stateblock->gs_cbs[i]);
+            stateblock->gs_cbs[i] = NULL;
+        }
+    }
+
+    if (stateblock->ps)
+    {
+        ID3D10PixelShader_Release(stateblock->ps);
+        stateblock->ps = NULL;
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+    {
+        if (stateblock->ps_samplers[i])
+        {
+            ID3D10SamplerState_Release(stateblock->ps_samplers[i]);
+            stateblock->ps_samplers[i] = NULL;
+        }
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->ps_resources[i])
+        {
+            ID3D10ShaderResourceView_Release(stateblock->ps_resources[i]);
+            stateblock->ps_resources[i] = NULL;
+        }
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i)
+    {
+        if (stateblock->ps_cbs[i])
+        {
+            ID3D10Buffer_Release(stateblock->ps_cbs[i]);
+            stateblock->ps_cbs[i] = NULL;
+        }
+    }
+
+    for (i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->vbs[i])
+        {
+            ID3D10Buffer_Release(stateblock->vbs[i]);
+            stateblock->vbs[i] = NULL;
+        }
+    }
+    if (stateblock->ib)
+    {
+        ID3D10Buffer_Release(stateblock->ib);
+        stateblock->ib = NULL;
+    }
+    if (stateblock->il)
+    {
+        ID3D10InputLayout_Release(stateblock->il);
+        stateblock->il = NULL;
+    }
+
+    for (i = 0; i < D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
+    {
+        if (stateblock->rtvs[i])
+        {
+            ID3D10RenderTargetView_Release(stateblock->rtvs[i]);
+            stateblock->rtvs[i] = NULL;
+        }
+    }
+    if (stateblock->dsv)
+    {
+        ID3D10DepthStencilView_Release(stateblock->dsv);
+        stateblock->dsv = NULL;
+    }
+    if (stateblock->bs)
+    {
+        ID3D10BlendState_Release(stateblock->bs);
+        stateblock->bs = NULL;
+    }
+
+    if (stateblock->rs)
+    {
+        ID3D10RasterizerState_Release(stateblock->rs);
+        stateblock->rs = NULL;
+    }
+
+    for (i = 0; i < D3D10_SO_BUFFER_SLOT_COUNT; ++i)
+    {
+        if (stateblock->so_buffers[i])
+        {
+            ID3D10Buffer_Release(stateblock->so_buffers[i]);
+            stateblock->so_buffers[i] = NULL;
+        }
+    }
+
+    if (stateblock->predicate)
+    {
+        ID3D10Predicate_Release(stateblock->predicate);
+        stateblock->predicate = NULL;
+    }
+}
+
 static HRESULT STDMETHODCALLTYPE d3d10_stateblock_QueryInterface(ID3D10StateBlock *iface, REFIID iid, void **object)
 {
     struct d3d10_stateblock *stateblock;
@@ -75,16 +266,114 @@ static ULONG STDMETHODCALLTYPE d3d10_stateblock_Release(ID3D10StateBlock *iface)
     TRACE("%p decreasing refcount to %u.\n", stateblock, refcount);
 
     if (!refcount)
+    {
+        stateblock_cleanup(stateblock);
         HeapFree(GetProcessHeap(), 0, stateblock);
+    }
 
     return refcount;
 }
 
 static HRESULT STDMETHODCALLTYPE d3d10_stateblock_Capture(ID3D10StateBlock *iface)
 {
-    FIXME("iface %p stub!\n", iface);
+    unsigned int vp_count = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
+    struct d3d10_stateblock *stateblock = impl_from_ID3D10StateBlock(iface);
+    unsigned int i;
 
-    return E_NOTIMPL;
+    TRACE("iface %p.\n", iface);
+
+    stateblock_cleanup(stateblock);
+
+    if (stateblock->mask.VS)
+        ID3D10Device_VSGetShader(stateblock->device, &stateblock->vs);
+    for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.VSSamplers[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_VSGetSamplers(stateblock->device, i, 1, &stateblock->vs_samplers[i]);
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.VSShaderResources[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_VSGetShaderResources(stateblock->device, i, 1, &stateblock->vs_resources[i]);
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.VSConstantBuffers[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_VSGetConstantBuffers(stateblock->device, i, 1, &stateblock->vs_cbs[i]);
+    }
+
+    if (stateblock->mask.GS)
+        ID3D10Device_GSGetShader(stateblock->device, &stateblock->gs);
+    for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.GSSamplers[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_GSGetSamplers(stateblock->device, i, 1, &stateblock->gs_samplers[i]);
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.GSShaderResources[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_GSGetShaderResources(stateblock->device, i, 1, &stateblock->gs_resources[i]);
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.GSConstantBuffers[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_GSGetConstantBuffers(stateblock->device, i, 1, &stateblock->gs_cbs[i]);
+    }
+
+    if (stateblock->mask.PS)
+        ID3D10Device_PSGetShader(stateblock->device, &stateblock->ps);
+    for (i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.PSSamplers[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_PSGetSamplers(stateblock->device, i, 1, &stateblock->ps_samplers[i]);
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.PSShaderResources[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_PSGetShaderResources(stateblock->device, i, 1, &stateblock->ps_resources[i]);
+    }
+    for (i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.PSConstantBuffers[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_PSGetConstantBuffers(stateblock->device, i, 1, &stateblock->ps_cbs[i]);
+    }
+
+    for (i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; ++i)
+    {
+        if (stateblock->mask.IAVertexBuffers[i >> 3] & (1 << (i & 7)))
+            ID3D10Device_IAGetVertexBuffers(stateblock->device, i, 1, &stateblock->vbs[i],
+                    &stateblock->vb_strides[i], &stateblock->vb_offsets[i]);
+    }
+    if (stateblock->mask.IAIndexBuffer)
+        ID3D10Device_IAGetIndexBuffer(stateblock->device, &stateblock->ib,
+                &stateblock->ib_format, &stateblock->ib_offset);
+    if (stateblock->mask.IAInputLayout)
+        ID3D10Device_IAGetInputLayout(stateblock->device, &stateblock->il);
+    if (stateblock->mask.IAPrimitiveTopology)
+        ID3D10Device_IAGetPrimitiveTopology(stateblock->device, &stateblock->topology);
+
+    if (stateblock->mask.OMRenderTargets)
+        ID3D10Device_OMGetRenderTargets(stateblock->device, D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT,
+                stateblock->rtvs, &stateblock->dsv);
+    if (stateblock->mask.OMBlendState)
+        ID3D10Device_OMGetBlendState(stateblock->device, &stateblock->bs,
+                stateblock->blend_factor, &stateblock->sample_mask);
+
+    if (stateblock->mask.RSViewports)
+        ID3D10Device_RSGetViewports(stateblock->device, &vp_count, stateblock->vps);
+    if (stateblock->mask.RSScissorRects)
+        ID3D10Device_RSGetScissorRects(stateblock->device, &vp_count, stateblock->scissor_rects);
+    if (stateblock->mask.RSRasterizerState)
+        ID3D10Device_RSGetState(stateblock->device, &stateblock->rs);
+
+    if (stateblock->mask.SOBuffers)
+        ID3D10Device_SOGetTargets(stateblock->device, D3D10_SO_BUFFER_SLOT_COUNT,
+                stateblock->so_buffers, stateblock->so_offsets);
+
+    if (stateblock->mask.Predication)
+        ID3D10Device_GetPredication(stateblock->device, &stateblock->predicate, &stateblock->predicate_value);
+
+    return S_OK;
 }
 
 static HRESULT STDMETHODCALLTYPE d3d10_stateblock_Apply(ID3D10StateBlock *iface)
@@ -138,6 +427,10 @@ HRESULT WINAPI D3D10CreateStateBlock(ID3D10Device *device,
     object->ID3D10StateBlock_iface.lpVtbl = &d3d10_stateblock_vtbl;
     object->refcount = 1;
 
+    object->device = device;
+    ID3D10Device_AddRef(object->device);
+    object->mask = *mask;
+
     TRACE("Created stateblock %p.\n", object);
     *stateblock = &object->ID3D10StateBlock_iface;
 
-- 
1.7.10.4




More information about the wine-patches mailing list