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