Home | History | Annotate | Download | only in gd3d11
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 Luca Barbieri
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining
      6  * a copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sublicense, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial
     15  * portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     20  * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  *
     25  **************************************************************************/
     26 
     27 #include "d3d1x_private.h"
     28 
     29 extern "C"
     30 {
     31 #include "util/u_gen_mipmap.h"
     32 #include "tgsi/tgsi_ureg.h"
     33 #include "tgsi/tgsi_dump.h"
     34 #include "cso_cache/cso_context.h"
     35 }
     36 
     37 
     38 // the perl script will change this to 10 for d3d10, and also do s/D3D11/D3D10 in the whole file
     39 #define API 11
     40 
     41 #if API >= 11
     42 #define DX10_ONLY(x)
     43 #else
     44 #define DX10_ONLY(x) x
     45 #endif
     46 
     47 typedef D3D10_MAPPED_TEXTURE3D D3D10_MAPPED_SUBRESOURCE;
     48 
     49 // used to make QueryInterface know the IIDs of the interface and its ancestors
     50 COM_INTERFACE(ID3D11DeviceChild, IUnknown)
     51 COM_INTERFACE(ID3D11InputLayout, ID3D11DeviceChild)
     52 COM_INTERFACE(ID3D11DepthStencilState, ID3D11DeviceChild)
     53 COM_INTERFACE(ID3D11BlendState, ID3D11DeviceChild)
     54 COM_INTERFACE(ID3D11RasterizerState, ID3D11DeviceChild)
     55 COM_INTERFACE(ID3D11SamplerState, ID3D11DeviceChild)
     56 COM_INTERFACE(ID3D11Resource, ID3D11DeviceChild)
     57 COM_INTERFACE(ID3D11Buffer, ID3D11Resource)
     58 COM_INTERFACE(ID3D11Texture1D, ID3D11Resource)
     59 COM_INTERFACE(ID3D11Texture2D, ID3D11Resource)
     60 COM_INTERFACE(ID3D11Texture3D, ID3D11Resource)
     61 COM_INTERFACE(ID3D11View, ID3D11DeviceChild)
     62 COM_INTERFACE(ID3D11ShaderResourceView, ID3D11View)
     63 COM_INTERFACE(ID3D11RenderTargetView, ID3D11View)
     64 COM_INTERFACE(ID3D11DepthStencilView, ID3D11View)
     65 COM_INTERFACE(ID3D11VertexShader, ID3D11DeviceChild)
     66 COM_INTERFACE(ID3D11GeometryShader, ID3D11DeviceChild)
     67 COM_INTERFACE(ID3D11PixelShader, ID3D11DeviceChild)
     68 COM_INTERFACE(ID3D11Asynchronous, ID3D11DeviceChild)
     69 COM_INTERFACE(ID3D11Query, ID3D11Asynchronous)
     70 COM_INTERFACE(ID3D11Predicate, ID3D11Query)
     71 COM_INTERFACE(ID3D11Counter, ID3D11Asynchronous)
     72 COM_INTERFACE(ID3D11Device, IUnknown)
     73 
     74 #if API >= 11
     75 COM_INTERFACE(ID3D11UnorderedAccessView, ID3D11View)
     76 COM_INTERFACE(ID3D11HullShader, ID3D11DeviceChild)
     77 COM_INTERFACE(ID3D11DomainShader, ID3D11DeviceChild)
     78 COM_INTERFACE(ID3D11ComputeShader, ID3D11DeviceChild)
     79 COM_INTERFACE(ID3D11ClassInstance, ID3D11DeviceChild)
     80 COM_INTERFACE(ID3D11ClassLinkage, ID3D11DeviceChild)
     81 COM_INTERFACE(ID3D11CommandList, ID3D11DeviceChild)
     82 COM_INTERFACE(ID3D11DeviceContext, ID3D11DeviceChild)
     83 #else
     84 COM_INTERFACE(ID3D10BlendState1, ID3D10BlendState)
     85 COM_INTERFACE(ID3D10ShaderResourceView1, ID3D10ShaderResourceView)
     86 COM_INTERFACE(ID3D10Device1, ID3D10Device)
     87 #endif
     88 
     89 struct GalliumD3D11Screen;
     90 
     91 #if API >= 11
     92 static ID3D11DeviceContext* GalliumD3D11ImmediateDeviceContext_Create(GalliumD3D11Screen* device, struct pipe_context* pipe, bool owns_pipe);
     93 static void GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(ID3D11DeviceContext* context);
     94 static void GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(ID3D11DeviceContext* context);
     95 static void GalliumD3D11ImmediateDeviceContext_Destroy(ID3D11DeviceContext* device);
     96 #endif
     97 
     98 static inline pipe_box d3d11_to_pipe_box(struct pipe_resource* resource, unsigned level, const D3D11_BOX* pBox)
     99 {
    100 	pipe_box box;
    101 	if(pBox)
    102 	{
    103 		box.x = pBox->left;
    104 		box.y = pBox->top;
    105 		box.z = pBox->front;
    106 		box.width = pBox->right - pBox->left;
    107 		box.height = pBox->bottom - pBox->top;
    108 		box.depth = pBox->back - pBox->front;
    109 	}
    110 	else
    111 	{
    112 		box.x = box.y = box.z = 0;
    113 		box.width = u_minify(resource->width0, level);
    114 		box.height = u_minify(resource->height0, level);
    115 		box.depth = u_minify(resource->depth0, level);
    116 	}
    117 	return box;
    118 }
    119 
    120 struct GalliumD3D11Caps
    121 {
    122 	bool so;
    123 	bool gs;
    124 	bool queries;
    125 	bool render_condition;
    126 	unsigned constant_buffers[D3D11_STAGES];
    127 	unsigned stages;
    128 	unsigned stages_with_sampling;
    129 };
    130 
    131 typedef GalliumDXGIDevice<
    132 	GalliumMultiComObject<
    133 #if API >= 11
    134 		GalliumPrivateDataComObject<ID3D11Device>,
    135 #else
    136 		GalliumPrivateDataComObject<ID3D10Device1>,
    137 #endif
    138 		IGalliumDevice
    139 	>
    140 > GalliumD3D11ScreenBase;
    141 
    142 // used to avoid needing to have forward declarations of functions
    143 // this is called "screen" because in the D3D10 case it's only part of the device
    144 struct GalliumD3D11Screen : public GalliumD3D11ScreenBase
    145 {
    146 
    147 	pipe_screen* screen;
    148 	pipe_context* immediate_pipe;
    149 	GalliumD3D11Caps screen_caps;
    150 
    151 #if API >= 11
    152 	ID3D11DeviceContext* immediate_context;
    153 	ID3D11DeviceContext* get_immediate_context()
    154 	{
    155 		return immediate_context;
    156 	}
    157 #else
    158 	GalliumD3D11Screen* get_immediate_context()
    159 	{
    160 		return this;
    161 	}
    162 #endif
    163 
    164 
    165 	GalliumD3D11Screen(pipe_screen* screen, struct pipe_context* immediate_pipe, IDXGIAdapter* adapter)
    166 	: GalliumD3D11ScreenBase(adapter), screen(screen), immediate_pipe(immediate_pipe)
    167 	{
    168 	}
    169 
    170 #if API < 11
    171 	// we use a D3D11-like API internally
    172 	virtual HRESULT STDMETHODCALLTYPE Map(
    173 			ID3D11Resource *pResource,
    174 			unsigned Subresource,
    175 			D3D11_MAP MapType,
    176 			unsigned MapFlags,
    177 			D3D11_MAPPED_SUBRESOURCE *pMappedResource) = 0;
    178 	virtual void STDMETHODCALLTYPE Unmap(
    179 			ID3D11Resource *pResource,
    180 			unsigned Subresource) = 0;
    181 	virtual void STDMETHODCALLTYPE Begin(
    182 		ID3D11Asynchronous *pAsync) = 0;
    183 	virtual void STDMETHODCALLTYPE End(
    184 		ID3D11Asynchronous *pAsync) = 0;
    185 	virtual HRESULT STDMETHODCALLTYPE GetData(
    186 		ID3D11Asynchronous *pAsync,
    187 		void *pData,
    188 		unsigned DataSize,
    189 		unsigned GetDataFlags) = 0;
    190 
    191 	// TODO: maybe we should use function overloading, but that might risk silent errors,
    192 	// and cannot be exported to a C interface
    193 	virtual void UnbindBlendState(ID3D11BlendState* state) = 0;
    194 	virtual void UnbindRasterizerState(ID3D11RasterizerState* state) = 0;
    195 	virtual void UnbindDepthStencilState(ID3D11DepthStencilState* state) = 0;
    196 	virtual void UnbindInputLayout(ID3D11InputLayout* state) = 0;
    197 	virtual void UnbindPixelShader(ID3D11PixelShader* state) = 0;
    198 	virtual void UnbindVertexShader(ID3D11VertexShader* state) = 0;
    199 	virtual void UnbindGeometryShader(ID3D11GeometryShader* state) = 0;
    200 	virtual void UnbindPredicate(ID3D11Predicate* predicate) = 0;
    201 	virtual void UnbindSamplerState(ID3D11SamplerState* state) = 0;
    202 	virtual void UnbindBuffer(ID3D11Buffer* buffer) = 0;
    203 	virtual void UnbindDepthStencilView(ID3D11DepthStencilView* view) = 0;
    204 	virtual void UnbindRenderTargetView(ID3D11RenderTargetView* view) = 0;
    205 	virtual void UnbindShaderResourceView(ID3D11ShaderResourceView* view) = 0;
    206 
    207 	void UnbindBlendState1(ID3D11BlendState1* state)
    208 	{
    209 		UnbindBlendState(state);
    210 	}
    211 	void UnbindShaderResourceView1(ID3D11ShaderResourceView1* view)
    212 	{
    213 		UnbindShaderResourceView(view);
    214 	}
    215 #endif
    216 };
    217 
    218 #include "d3d11_objects.h"
    219 #include "d3d11_screen.h"
    220 #include "d3d11_context.h"
    221 #include "d3d11_misc.h"
    222 
    223 #if API >= 11
    224 HRESULT STDMETHODCALLTYPE GalliumD3D11DeviceCreate(struct pipe_screen* screen, struct pipe_context* context, BOOL owns_context, unsigned creation_flags, IDXGIAdapter* adapter, ID3D11Device** ppDevice)
    225 {
    226 	if(creation_flags & D3D11_CREATE_DEVICE_SINGLETHREADED)
    227 		*ppDevice = new GalliumD3D11ScreenImpl<false>(screen, context, owns_context, creation_flags, adapter);
    228 	else
    229 		*ppDevice = new GalliumD3D11ScreenImpl<true>(screen, context, owns_context, creation_flags, adapter);
    230 	return S_OK;
    231 }
    232 #else
    233 HRESULT STDMETHODCALLTYPE GalliumD3D10DeviceCreate1(struct pipe_screen* screen, struct pipe_context* context, BOOL owns_context, unsigned creation_flags, IDXGIAdapter* adapter, ID3D10Device1** ppDevice)
    234 {
    235 	if(creation_flags & D3D10_CREATE_DEVICE_SINGLETHREADED)
    236 		*ppDevice = new GalliumD3D10Device<false>(screen, context, owns_context, creation_flags, adapter);
    237 	else
    238 		*ppDevice = new GalliumD3D10Device<true>(screen, context, owns_context, creation_flags, adapter);
    239 	return S_OK;
    240 }
    241 #endif
    242