738 lines
21 KiB
C++
738 lines
21 KiB
C++
/**************************************************************************
|
|
*
|
|
* Copyright 2010 Luca Barbieri
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial
|
|
* portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
|
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
**************************************************************************/
|
|
|
|
template<typename Base = ID3D11DeviceChild>
|
|
struct GalliumD3D11DeviceChild : public GalliumPrivateDataComObject<Base, dual_refcnt_t>
|
|
{
|
|
GalliumD3D11Screen* device; // must not be null
|
|
|
|
|
|
// if this is called, the subclass constructor must set device itself
|
|
GalliumD3D11DeviceChild()
|
|
: device(0)
|
|
{}
|
|
|
|
GalliumD3D11DeviceChild(GalliumD3D11Screen* p_device)
|
|
{
|
|
// we store the reference count minus one in refcnt
|
|
device = p_device;
|
|
device->AddRef();
|
|
}
|
|
|
|
virtual ~GalliumD3D11DeviceChild()
|
|
{
|
|
if(device)
|
|
device->Release();
|
|
}
|
|
|
|
/* The purpose of this is to avoid cyclic garbage, since this won't hold
|
|
* a pointer to the device if it is only held by a pipeline binding in the immediate context
|
|
*
|
|
* TODO: we could only manipulate the device refcnt when atomic_refcnt == 0 changes,
|
|
* but this requires more complex atomic ops
|
|
*/
|
|
inline ULONG add_ref()
|
|
{
|
|
return GalliumPrivateDataComObject<Base, dual_refcnt_t>::add_ref();
|
|
}
|
|
|
|
inline ULONG release()
|
|
{
|
|
return GalliumPrivateDataComObject<Base, dual_refcnt_t>::release();
|
|
}
|
|
|
|
virtual ULONG STDMETHODCALLTYPE AddRef()
|
|
{
|
|
return add_ref();
|
|
}
|
|
|
|
virtual ULONG STDMETHODCALLTYPE Release()
|
|
{
|
|
return release();
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE GetDevice(
|
|
ID3D11Device **out_device
|
|
)
|
|
{
|
|
device->AddRef();
|
|
*out_device = device;
|
|
}
|
|
};
|
|
|
|
template<typename Base = ID3D11DeviceChild, typename Object = void>
|
|
struct GalliumD3D11Object : public GalliumD3D11DeviceChild<Base>
|
|
{
|
|
Object* object;
|
|
GalliumD3D11Object(GalliumD3D11Screen* device, Object* object)
|
|
: GalliumD3D11DeviceChild<Base>(device), object(object)
|
|
{}
|
|
|
|
virtual ~GalliumD3D11Object();
|
|
};
|
|
|
|
#define IMPLEMENT_OBJECT_DTOR(name, gallium) \
|
|
template<> \
|
|
GalliumD3D11Object<ID3D11##name, void>::~GalliumD3D11Object() \
|
|
{ \
|
|
DX10_ONLY(device->Unbind##name(this)); \
|
|
device->immediate_pipe->delete_##gallium##_state(device->immediate_pipe, object); \
|
|
}
|
|
|
|
#define IMPLEMENT_VIEW_DTOR(name, gallium) \
|
|
template<> \
|
|
GalliumD3D11Object<ID3D11##name, struct pipe_##gallium>::~GalliumD3D11Object() \
|
|
{ \
|
|
DX10_ONLY(device->Unbind##name(this)); \
|
|
pipe_##gallium##_reference(&object, 0); \
|
|
}
|
|
|
|
IMPLEMENT_OBJECT_DTOR(InputLayout, vertex_elements)
|
|
IMPLEMENT_OBJECT_DTOR(DepthStencilState, depth_stencil_alpha)
|
|
IMPLEMENT_OBJECT_DTOR(RasterizerState, rasterizer)
|
|
IMPLEMENT_OBJECT_DTOR(SamplerState, sampler)
|
|
IMPLEMENT_OBJECT_DTOR(BlendState, blend)
|
|
IMPLEMENT_OBJECT_DTOR(VertexShader, vs)
|
|
IMPLEMENT_OBJECT_DTOR(PixelShader, fs)
|
|
IMPLEMENT_OBJECT_DTOR(GeometryShader, gs)
|
|
|
|
IMPLEMENT_VIEW_DTOR(ShaderResourceView, sampler_view)
|
|
IMPLEMENT_VIEW_DTOR(RenderTargetView, surface)
|
|
IMPLEMENT_VIEW_DTOR(DepthStencilView, surface)
|
|
|
|
#if API >= 11
|
|
// IMPLEMENT_VIEW_DTOR(UnorderedAccessView, surface);
|
|
// IMPLEMENT_OBJECT_DTOR(HullShader, tcs);
|
|
// IMPLEMENT_OBJECT_DTOR(DomainShader, tes);
|
|
// IMPLEMENT_OBJECT_DTOR(ComputeShader, cs);
|
|
#else
|
|
IMPLEMENT_OBJECT_DTOR(BlendState1, blend)
|
|
IMPLEMENT_VIEW_DTOR(ShaderResourceView1, sampler_view)
|
|
#endif
|
|
|
|
template<typename Base, typename Desc, typename Object = void>
|
|
struct GalliumD3D11DescribedObject : public GalliumD3D11Object<Base, Object>
|
|
{
|
|
Desc desc;
|
|
GalliumD3D11DescribedObject(GalliumD3D11Screen* device, Object* object, const Desc& desc)
|
|
: GalliumD3D11Object<Base, Object>(device, object), desc(desc)
|
|
{}
|
|
|
|
virtual void STDMETHODCALLTYPE GetDesc(Desc *out_desc)
|
|
{
|
|
memcpy(out_desc, &desc, sizeof(desc));
|
|
}
|
|
};
|
|
|
|
typedef GalliumD3D11Object<ID3D11InputLayout> GalliumD3D11InputLayout;
|
|
typedef GalliumD3D11DescribedObject<ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC> GalliumD3D11DepthStencilState;
|
|
typedef GalliumD3D11DescribedObject<ID3D11RasterizerState, D3D11_RASTERIZER_DESC> GalliumD3D11RasterizerStateBase;
|
|
typedef GalliumD3D11DescribedObject<ID3D11SamplerState, D3D11_SAMPLER_DESC> GalliumD3D11SamplerState;
|
|
|
|
#if API >= 11
|
|
typedef GalliumD3D11DescribedObject<ID3D11BlendState, D3D11_BLEND_DESC> GalliumD3D11BlendState;
|
|
#else
|
|
typedef GalliumD3D10DescribedObject<ID3D10BlendState1, D3D10_BLEND_DESC> GalliumD3D10BlendStateBase;
|
|
|
|
struct GalliumD3D10BlendState : public GalliumD3D10BlendStateBase
|
|
{
|
|
static D3D10_BLEND_DESC convert_to_d3d10(const D3D10_BLEND_DESC1& desc1)
|
|
{
|
|
D3D10_BLEND_DESC desc;
|
|
desc.AlphaToCoverageEnable = desc1.AlphaToCoverageEnable;
|
|
desc.SrcBlend = desc1.RenderTarget[0].SrcBlend;
|
|
desc.DestBlend = desc1.RenderTarget[0].DestBlend;
|
|
desc.BlendOp = desc1.RenderTarget[0].BlendOp;
|
|
desc.SrcBlendAlpha = desc1.RenderTarget[0].SrcBlendAlpha;
|
|
desc.DestBlendAlpha = desc1.RenderTarget[0].DestBlendAlpha;
|
|
desc.BlendOpAlpha = desc1.RenderTarget[0].BlendOpAlpha;
|
|
for(unsigned i = 0; i < 8; ++i)
|
|
{
|
|
desc.BlendEnable[i] = desc1.RenderTarget[i].BlendEnable;
|
|
desc.RenderTargetWriteMask[i] = desc1.RenderTarget[i].RenderTargetWriteMask;
|
|
}
|
|
return desc;
|
|
}
|
|
|
|
D3D10_BLEND_DESC1 desc1;
|
|
|
|
GalliumD3D10BlendState(GalliumD3D10Screen* device, void* object, const D3D10_BLEND_DESC& desc)
|
|
: GalliumD3D10BlendStateBase(device, object, desc)
|
|
{
|
|
memset(&desc1, 0, sizeof(desc1));
|
|
desc1.AlphaToCoverageEnable = desc.AlphaToCoverageEnable;
|
|
desc1.RenderTarget[0].SrcBlend = desc.SrcBlend;
|
|
desc1.RenderTarget[0].DestBlend = desc.DestBlend;
|
|
desc1.RenderTarget[0].BlendOp = desc.BlendOp;
|
|
desc1.RenderTarget[0].SrcBlendAlpha = desc.SrcBlendAlpha;
|
|
desc1.RenderTarget[0].DestBlendAlpha = desc.DestBlendAlpha;
|
|
desc1.RenderTarget[0].BlendOpAlpha = desc.BlendOpAlpha;
|
|
for(unsigned i = 0; i < 8; ++i)
|
|
{
|
|
desc1.RenderTarget[i].BlendEnable = desc.BlendEnable[i];
|
|
desc1.RenderTarget[i].RenderTargetWriteMask = desc.RenderTargetWriteMask[i];
|
|
}
|
|
}
|
|
|
|
GalliumD3D10BlendState(GalliumD3D10Screen* device, void* object, const D3D10_BLEND_DESC1& desc)
|
|
: GalliumD3D10BlendStateBase(device, object, convert_to_d3d10(desc)), desc1(desc1)
|
|
{}
|
|
|
|
virtual void STDMETHODCALLTYPE GetDesc1(D3D10_BLEND_DESC1 *out_desc)
|
|
{
|
|
memcpy(out_desc, &desc1, sizeof(desc1));
|
|
}
|
|
};
|
|
#endif
|
|
|
|
struct GalliumD3D11RasterizerState : public GalliumD3D11RasterizerStateBase
|
|
{
|
|
GalliumD3D11RasterizerState(GalliumD3D11Screen* device, void* object, const D3D11_RASTERIZER_DESC& desc)
|
|
: GalliumD3D11RasterizerStateBase(device, object, desc)
|
|
{}
|
|
};
|
|
|
|
template<typename Base = ID3D11DeviceChild>
|
|
struct GalliumD3D11Shader : public GalliumD3D11Object<Base>
|
|
{
|
|
GalliumD3D11Shader(GalliumD3D11Screen* device, void* object)
|
|
: GalliumD3D11Object<Base>(device, object)
|
|
{}
|
|
};
|
|
|
|
typedef GalliumD3D11Shader<ID3D11VertexShader> GalliumD3D11VertexShader;
|
|
typedef GalliumD3D11Shader<ID3D11GeometryShader> GalliumD3D11GeometryShader;
|
|
typedef GalliumD3D11Shader<ID3D11PixelShader> GalliumD3D11PixelShader;
|
|
|
|
#if API >= 11
|
|
/*
|
|
typedef GalliumD3D11Shader<ID3D11HullShader> GalliumD3D11HullShader;
|
|
typedef GalliumD3D11Shader<ID3D11DomainShader> GalliumD3D11DomainShader;
|
|
typedef GalliumD3D11Shader<ID3D11ComputeShader> GalliumD3D11ComputeShader;
|
|
*/
|
|
#endif
|
|
|
|
template<typename Base = ID3D11Resource>
|
|
struct GalliumD3D11ResourceBase : public GalliumD3D11DeviceChild<Base>
|
|
{
|
|
unsigned eviction_priority;
|
|
|
|
virtual void STDMETHODCALLTYPE SetEvictionPriority(
|
|
unsigned new_eviction_priority
|
|
)
|
|
{
|
|
eviction_priority = new_eviction_priority;
|
|
}
|
|
|
|
virtual unsigned STDMETHODCALLTYPE GetEvictionPriority()
|
|
{
|
|
return eviction_priority;
|
|
}
|
|
};
|
|
|
|
template<typename Real>
|
|
struct GalliumDXGIResource : public IDXGIResource
|
|
{
|
|
virtual HRESULT STDMETHODCALLTYPE SetEvictionPriority(
|
|
unsigned new_eviction_priority
|
|
)
|
|
{
|
|
static_cast<Real*>(this)->eviction_priority = new_eviction_priority;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetEvictionPriority(unsigned* out_eviction_priority)
|
|
{
|
|
*out_eviction_priority = static_cast<Real*>(this)->eviction_priority;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetDevice(
|
|
REFIID riid,
|
|
void **out_parent)
|
|
{
|
|
if(!static_cast<Real*>(this)->device)
|
|
return E_NOINTERFACE;
|
|
return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent);
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetParent(
|
|
REFIID riid,
|
|
void **out_parent)
|
|
{
|
|
if(!static_cast<Real*>(this)->device)
|
|
return E_NOINTERFACE;
|
|
return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent);
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct com_traits<GalliumDXGIResource<T> > : public com_traits<IDXGIResource>
|
|
{};
|
|
|
|
template<typename Base = ID3D11Resource>
|
|
struct GalliumD3D11Resource
|
|
: public GalliumMultiComObject<
|
|
GalliumMultiPrivateDataComObject<
|
|
GalliumD3D11ResourceBase<Base>,
|
|
GalliumDXGIResource<GalliumD3D11Resource<Base> >
|
|
>,
|
|
IGalliumResource
|
|
>
|
|
{
|
|
struct pipe_resource* resource;
|
|
std::unordered_map<unsigned, pipe_transfer*> transfers;
|
|
float min_lod;
|
|
DXGI_USAGE dxgi_usage;
|
|
|
|
GalliumD3D11Resource(GalliumD3D11Screen* device = 0, struct pipe_resource* resource = 0, unsigned dxgi_usage = 0)
|
|
: resource(resource), min_lod(0), dxgi_usage(dxgi_usage)
|
|
{
|
|
this->device = device;
|
|
if(device)
|
|
device->AddRef();
|
|
this->eviction_priority = 0;
|
|
}
|
|
|
|
~GalliumD3D11Resource()
|
|
{
|
|
pipe_resource_reference(&resource, 0);
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetUsage(
|
|
DXGI_USAGE *out_usage
|
|
)
|
|
{
|
|
*out_usage = this->dxgi_usage;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE *out_shared_handle)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual struct pipe_resource* STDMETHODCALLTYPE GetGalliumResource()
|
|
{
|
|
return resource;
|
|
}
|
|
};
|
|
|
|
template<typename Base, typename Desc, D3D11_RESOURCE_DIMENSION Dim>
|
|
struct GalliumD3D11TypedResource : public GalliumD3D11Resource<Base>
|
|
{
|
|
Desc desc;
|
|
GalliumD3D11TypedResource() {}
|
|
GalliumD3D11TypedResource(GalliumD3D11Screen* device, struct pipe_resource* resource, const Desc& desc, unsigned dxgi_usage)
|
|
: GalliumD3D11Resource<Base>(device, resource, dxgi_usage), desc(desc)
|
|
{}
|
|
virtual void STDMETHODCALLTYPE GetType(
|
|
D3D11_RESOURCE_DIMENSION *out_resource_dimension)
|
|
{
|
|
*out_resource_dimension = Dim;
|
|
}
|
|
virtual void STDMETHODCALLTYPE GetDesc(Desc *out_desc)
|
|
{
|
|
memcpy(out_desc, &desc, sizeof(desc));
|
|
}
|
|
};
|
|
|
|
typedef GalliumD3D11TypedResource<ID3D11Texture1D, D3D11_TEXTURE1D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE1D> GalliumD3D11Texture1DBase;
|
|
typedef GalliumD3D11TypedResource<ID3D11Texture2D, D3D11_TEXTURE2D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE2D> GalliumD3D11Texture2DBase;
|
|
typedef GalliumD3D11TypedResource<ID3D11Texture3D, D3D11_TEXTURE3D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE3D> GalliumD3D11Texture3DBase;
|
|
typedef GalliumD3D11TypedResource<ID3D11Buffer, D3D11_BUFFER_DESC, D3D11_RESOURCE_DIMENSION_BUFFER> GalliumD3D11BufferBase;
|
|
|
|
#if API >= 11
|
|
typedef GalliumD3D11Texture1DBase GalliumD3D11Texture1D;
|
|
typedef GalliumD3D11Texture2DBase GalliumD3D11Texture2D;
|
|
typedef GalliumD3D11Texture3DBase GalliumD3D11Texture3D;
|
|
|
|
struct GalliumD3D11Buffer : public GalliumD3D11BufferBase
|
|
{
|
|
struct pipe_stream_output_target* so_target;
|
|
|
|
GalliumD3D11Buffer(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_BUFFER_DESC& desc, unsigned dxgi_usage)
|
|
: GalliumD3D11BufferBase(device, resource, desc, dxgi_usage), so_target(0)
|
|
{
|
|
}
|
|
|
|
~GalliumD3D11Buffer()
|
|
{
|
|
if(so_target)
|
|
pipe_so_target_reference(&so_target, NULL);
|
|
}
|
|
};
|
|
#else
|
|
struct GalliumD3D10Buffer : public GalliumD3D10BufferBase
|
|
{
|
|
struct pipe_stream_output_target *so_target;
|
|
|
|
GalliumD3D10Buffer(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_BUFFER_DESC& desc, unsigned dxgi_usage)
|
|
: GalliumD3D10BufferBase(device, resource, desc, dxgi_usage)
|
|
{
|
|
}
|
|
|
|
~GalliumD3D10Buffer()
|
|
{
|
|
if(so_target)
|
|
pipe_so_target_reference(&so_target, NULL);
|
|
|
|
device->UnbindBuffer(this);
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Map(
|
|
D3D10_MAP map_type,
|
|
unsigned map_flags,
|
|
void **out_data)
|
|
{
|
|
D3D10_MAPPED_SUBRESOURCE msr;
|
|
HRESULT hr = device->Map(this, 0, map_type, map_flags, &msr);
|
|
if(!SUCCEEDED(hr))
|
|
return hr;
|
|
*out_data = msr.pData;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE Unmap()
|
|
{
|
|
device->Unmap(this, 0);
|
|
}
|
|
};
|
|
|
|
struct GalliumD3D10Texture1D : public GalliumD3D10Texture1DBase
|
|
{
|
|
GalliumD3D10Texture1D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE1D_DESC& desc, unsigned dxgi_usage)
|
|
: GalliumD3D10Texture1DBase(device, resource, desc, dxgi_usage)
|
|
{}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Map(
|
|
unsigned subresource,
|
|
D3D10_MAP map_type,
|
|
unsigned map_flags,
|
|
void **out_data)
|
|
{
|
|
D3D10_MAPPED_SUBRESOURCE msr;
|
|
HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
|
|
if(!SUCCEEDED(hr))
|
|
return hr;
|
|
*out_data = msr.pData;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE Unmap(
|
|
unsigned subresource
|
|
)
|
|
{
|
|
device->Unmap(this, subresource);
|
|
}
|
|
};
|
|
|
|
struct GalliumD3D10Texture2D : public GalliumD3D10Texture2DBase
|
|
{
|
|
GalliumD3D10Texture2D() {}
|
|
GalliumD3D10Texture2D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE2D_DESC& desc, unsigned dxgi_usage)
|
|
: GalliumD3D10Texture2DBase(device, resource, desc, dxgi_usage)
|
|
{}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Map(
|
|
unsigned subresource,
|
|
D3D10_MAP map_type,
|
|
unsigned map_flags,
|
|
D3D10_MAPPED_TEXTURE2D *out_mapped_subresource)
|
|
{
|
|
D3D10_MAPPED_SUBRESOURCE msr;
|
|
HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
|
|
if(!SUCCEEDED(hr))
|
|
return hr;
|
|
out_mapped_subresource->pData = msr.pData;
|
|
out_mapped_subresource->RowPitch = msr.RowPitch;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE Unmap(
|
|
unsigned subresource
|
|
)
|
|
{
|
|
device->Unmap(this, subresource);
|
|
}
|
|
};
|
|
|
|
|
|
struct GalliumD3D10Texture3D : public GalliumD3D10Texture3DBase
|
|
{
|
|
GalliumD3D10Texture3D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE3D_DESC& desc, unsigned dxgi_usage)
|
|
: GalliumD3D10Texture3DBase(device, resource, desc, dxgi_usage)
|
|
{}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Map(
|
|
unsigned subresource,
|
|
D3D10_MAP map_type,
|
|
unsigned map_flags,
|
|
D3D10_MAPPED_TEXTURE3D *out_mapped_subresource)
|
|
{
|
|
D3D10_MAPPED_SUBRESOURCE msr;
|
|
HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr);
|
|
if(!SUCCEEDED(hr))
|
|
return hr;
|
|
out_mapped_subresource->pData = msr.pData;
|
|
out_mapped_subresource->RowPitch = msr.RowPitch;
|
|
out_mapped_subresource->DepthPitch = msr.DepthPitch;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE Unmap(
|
|
unsigned subresource
|
|
)
|
|
{
|
|
device->Unmap(this, subresource);
|
|
}
|
|
};
|
|
#endif
|
|
|
|
struct GalliumD3D11Surface : public GalliumMultiPrivateDataComObject<GalliumD3D11Texture2D, IDXGISurface1>
|
|
{
|
|
GalliumD3D11Surface(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_TEXTURE2D_DESC& desc, unsigned dxgi_usage)
|
|
{
|
|
this->device = device;
|
|
this->device->AddRef();
|
|
this->resource = resource;
|
|
this->desc = desc;
|
|
this->dxgi_usage = dxgi_usage;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetDesc(
|
|
DXGI_SURFACE_DESC *out_desc)
|
|
{
|
|
out_desc->Format = this->desc.Format;
|
|
out_desc->Width = this->desc.Width;
|
|
out_desc->Height = this->desc.Height;
|
|
out_desc->SampleDesc = this->desc.SampleDesc;
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetParent(
|
|
REFIID riid,
|
|
void **out_parent)
|
|
{
|
|
if(!device)
|
|
return E_NOINTERFACE;
|
|
return device->QueryInterface(riid, out_parent);
|
|
}
|
|
|
|
/* TODO: somehow implement these */
|
|
virtual HRESULT STDMETHODCALLTYPE GetDC(
|
|
BOOL discard,
|
|
HDC *out_hdc)
|
|
{
|
|
*out_hdc = 0;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE ReleaseDC(
|
|
RECT *out_dirty_rect)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Map(
|
|
DXGI_MAPPED_RECT *out_locked_rect,
|
|
unsigned map_flags)
|
|
{
|
|
D3D11_MAP d3d_map;
|
|
if(map_flags & DXGI_MAP_DISCARD)
|
|
d3d_map = D3D11_MAP_WRITE_DISCARD;
|
|
else
|
|
{
|
|
if(map_flags & DXGI_MAP_READ)
|
|
{
|
|
if(map_flags & DXGI_MAP_WRITE)
|
|
d3d_map = D3D11_MAP_READ_WRITE;
|
|
else
|
|
d3d_map = D3D11_MAP_READ;
|
|
}
|
|
else
|
|
d3d_map = D3D11_MAP_WRITE;
|
|
}
|
|
D3D11_MAPPED_SUBRESOURCE d3d_mapped;
|
|
HRESULT hres = this->device->get_immediate_context()->Map(this, 0, d3d_map, 0, &d3d_mapped);
|
|
out_locked_rect->pBits = (uint8_t*)d3d_mapped.pData;
|
|
out_locked_rect->Pitch = d3d_mapped.RowPitch;
|
|
return hres;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE Unmap(void)
|
|
{
|
|
this->device->get_immediate_context()->Unmap(this, 0);
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetDevice(
|
|
REFIID riid,
|
|
void **out_parent)
|
|
{
|
|
if(!device)
|
|
return E_NOINTERFACE;
|
|
return device->QueryInterface(riid, out_parent);
|
|
}
|
|
};
|
|
|
|
template<typename Base, typename Desc, typename Object>
|
|
struct GalliumD3D11View : public GalliumD3D11DescribedObject<Base, Desc, Object>
|
|
{
|
|
GalliumD3D11Resource<>* resource;
|
|
GalliumD3D11View(GalliumD3D11Screen* device, GalliumD3D11Resource<>* resource, Object* object, const Desc& desc)
|
|
: GalliumD3D11DescribedObject<Base, Desc, Object>(device, object, desc), resource(resource)
|
|
{
|
|
resource->AddRef();
|
|
}
|
|
|
|
~GalliumD3D11View()
|
|
{
|
|
resource->Release();
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE GetResource(ID3D11Resource** out_resource)
|
|
{
|
|
resource->AddRef();
|
|
*out_resource = resource;
|
|
}
|
|
};
|
|
|
|
typedef GalliumD3D11View<ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, struct pipe_surface> GalliumD3D11DepthStencilView;
|
|
typedef GalliumD3D11View<ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, struct pipe_surface> GalliumD3D11RenderTargetView;
|
|
|
|
#if API >= 11
|
|
typedef GalliumD3D11View<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, struct pipe_sampler_view> GalliumD3D11ShaderResourceView;
|
|
#else
|
|
typedef GalliumD3D10View<ID3D10ShaderResourceView1, D3D10_SHADER_RESOURCE_VIEW_DESC1, struct pipe_sampler_view> GalliumD3D10ShaderResourceViewBase;
|
|
|
|
struct GalliumD3D10ShaderResourceView : public GalliumD3D10ShaderResourceViewBase
|
|
{
|
|
GalliumD3D10ShaderResourceView(GalliumD3D10Screen* device, GalliumD3D10Resource<>* resource, struct pipe_sampler_view* view, const D3D10_SHADER_RESOURCE_VIEW_DESC1& desc)
|
|
: GalliumD3D10ShaderResourceViewBase(device, resource, view, desc)
|
|
{}
|
|
|
|
virtual void STDMETHODCALLTYPE GetDesc1(D3D10_SHADER_RESOURCE_VIEW_DESC1 *out_desc)
|
|
{
|
|
memcpy(out_desc, &desc, sizeof(*out_desc));
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE GetDesc(D3D10_SHADER_RESOURCE_VIEW_DESC *out_desc)
|
|
{
|
|
memcpy(out_desc, &desc, sizeof(*out_desc));
|
|
}
|
|
};
|
|
#endif
|
|
|
|
template<typename Base = ID3D11Asynchronous>
|
|
struct GalliumD3D11Asynchronous : public GalliumD3D11DeviceChild<Base>
|
|
{
|
|
struct pipe_query* query;
|
|
unsigned data_size;
|
|
|
|
GalliumD3D11Asynchronous(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size)
|
|
: GalliumD3D11DeviceChild<Base>(device), query(query), data_size(data_size)
|
|
{}
|
|
|
|
~GalliumD3D11Asynchronous()
|
|
{
|
|
this->device->immediate_pipe->destroy_query(this->device->immediate_pipe, query);
|
|
}
|
|
|
|
virtual unsigned STDMETHODCALLTYPE GetDataSize()
|
|
{
|
|
return data_size;
|
|
}
|
|
|
|
#if API < 11
|
|
virtual void STDMETHODCALLTYPE Begin()
|
|
{
|
|
this->device->Begin(this);
|
|
}
|
|
|
|
virtual void STDMETHODCALLTYPE End()
|
|
{
|
|
this->device->End(this);
|
|
}
|
|
|
|
virtual HRESULT STDMETHODCALLTYPE GetData(
|
|
void * out_data,
|
|
unsigned data_size,
|
|
unsigned get_data_flags)
|
|
{
|
|
return this->device->GetData(this, out_data, data_size, get_data_flags);
|
|
}
|
|
#endif
|
|
};
|
|
|
|
template<typename Base = ID3D11Asynchronous>
|
|
struct GalliumD3D11QueryOrPredicate : public GalliumD3D11Asynchronous<Base>
|
|
{
|
|
D3D11_QUERY_DESC desc;
|
|
GalliumD3D11QueryOrPredicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
|
|
: GalliumD3D11Asynchronous<Base>(device, query, data_size), desc(desc)
|
|
{}
|
|
|
|
virtual void STDMETHODCALLTYPE GetDesc(
|
|
D3D11_QUERY_DESC *out_desc)
|
|
{
|
|
*out_desc = desc;
|
|
}
|
|
};
|
|
|
|
struct GalliumD3D11Query : public GalliumD3D11QueryOrPredicate<ID3D11Query>
|
|
{
|
|
GalliumD3D11Query(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
|
|
: GalliumD3D11QueryOrPredicate<ID3D11Query>(device, query, data_size, desc)
|
|
{}
|
|
};
|
|
|
|
struct GalliumD3D11Predicate : public GalliumD3D11QueryOrPredicate<ID3D11Predicate>
|
|
{
|
|
GalliumD3D11Predicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc)
|
|
: GalliumD3D11QueryOrPredicate<ID3D11Predicate>(device, query, data_size, desc)
|
|
{}
|
|
|
|
~GalliumD3D11Predicate()
|
|
{
|
|
DX10_ONLY(device->UnbindPredicate(this));
|
|
}
|
|
};
|
|
|
|
struct GalliumD3D11Counter : public GalliumD3D11Asynchronous<ID3D11Counter>
|
|
{
|
|
D3D11_COUNTER_DESC desc;
|
|
GalliumD3D11Counter(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_COUNTER_DESC& desc)
|
|
: GalliumD3D11Asynchronous<ID3D11Counter>(device, query, data_size), desc(desc)
|
|
{}
|
|
|
|
virtual void STDMETHODCALLTYPE GetDesc(
|
|
D3D11_COUNTER_DESC *out_desc)
|
|
{
|
|
*out_desc = desc;
|
|
}
|
|
};
|