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 template<typename Base = ID3D11DeviceChild> 28 struct GalliumD3D11DeviceChild : public GalliumPrivateDataComObject<Base, dual_refcnt_t> 29 { 30 GalliumD3D11Screen* device; // must not be null 31 32 33 // if this is called, the subclass constructor must set device itself GalliumD3D11DeviceChildGalliumD3D11DeviceChild34 GalliumD3D11DeviceChild() 35 : device(0) 36 {} 37 GalliumD3D11DeviceChildGalliumD3D11DeviceChild38 GalliumD3D11DeviceChild(GalliumD3D11Screen* p_device) 39 { 40 // we store the reference count minus one in refcnt 41 device = p_device; 42 device->AddRef(); 43 } 44 ~GalliumD3D11DeviceChildGalliumD3D11DeviceChild45 virtual ~GalliumD3D11DeviceChild() 46 { 47 if(device) 48 device->Release(); 49 } 50 51 /* The purpose of this is to avoid cyclic garbage, since this won't hold 52 * a pointer to the device if it is only held by a pipeline binding in the immediate context 53 * 54 * TODO: we could only manipulate the device refcnt when atomic_refcnt == 0 changes, 55 * but this requires more complex atomic ops 56 */ add_refGalliumD3D11DeviceChild57 inline ULONG add_ref() 58 { 59 return GalliumPrivateDataComObject<Base, dual_refcnt_t>::add_ref(); 60 } 61 releaseGalliumD3D11DeviceChild62 inline ULONG release() 63 { 64 return GalliumPrivateDataComObject<Base, dual_refcnt_t>::release(); 65 } 66 AddRefGalliumD3D11DeviceChild67 virtual ULONG STDMETHODCALLTYPE AddRef() 68 { 69 return add_ref(); 70 } 71 ReleaseGalliumD3D11DeviceChild72 virtual ULONG STDMETHODCALLTYPE Release() 73 { 74 return release(); 75 } 76 GetDeviceGalliumD3D11DeviceChild77 virtual void STDMETHODCALLTYPE GetDevice( 78 ID3D11Device **out_device 79 ) 80 { 81 device->AddRef(); 82 *out_device = device; 83 } 84 }; 85 86 template<typename Base = ID3D11DeviceChild, typename Object = void> 87 struct GalliumD3D11Object : public GalliumD3D11DeviceChild<Base> 88 { 89 Object* object; GalliumD3D11ObjectGalliumD3D11Object90 GalliumD3D11Object(GalliumD3D11Screen* device, Object* object) 91 : GalliumD3D11DeviceChild<Base>(device), object(object) 92 {} 93 94 virtual ~GalliumD3D11Object(); 95 }; 96 97 #define IMPLEMENT_OBJECT_DTOR(name, gallium) \ 98 template<> \ 99 GalliumD3D11Object<ID3D11##name, void>::~GalliumD3D11Object() \ 100 { \ 101 DX10_ONLY(device->Unbind##name(this)); \ 102 device->immediate_pipe->delete_##gallium##_state(device->immediate_pipe, object); \ 103 } 104 105 #define IMPLEMENT_VIEW_DTOR(name, gallium) \ 106 template<> \ 107 GalliumD3D11Object<ID3D11##name, struct pipe_##gallium>::~GalliumD3D11Object() \ 108 { \ 109 DX10_ONLY(device->Unbind##name(this)); \ 110 pipe_##gallium##_reference(&object, 0); \ 111 } 112 113 IMPLEMENT_OBJECT_DTOR(InputLayout, vertex_elements) 114 IMPLEMENT_OBJECT_DTOR(DepthStencilState, depth_stencil_alpha) 115 IMPLEMENT_OBJECT_DTOR(RasterizerState, rasterizer) 116 IMPLEMENT_OBJECT_DTOR(SamplerState, sampler) 117 IMPLEMENT_OBJECT_DTOR(BlendState, blend) 118 IMPLEMENT_OBJECT_DTOR(VertexShader, vs) 119 IMPLEMENT_OBJECT_DTOR(PixelShader, fs) 120 IMPLEMENT_OBJECT_DTOR(GeometryShader, gs) 121 122 IMPLEMENT_VIEW_DTOR(ShaderResourceView, sampler_view) 123 IMPLEMENT_VIEW_DTOR(RenderTargetView, surface) 124 IMPLEMENT_VIEW_DTOR(DepthStencilView, surface) 125 126 #if API >= 11 127 // IMPLEMENT_VIEW_DTOR(UnorderedAccessView, surface); 128 // IMPLEMENT_OBJECT_DTOR(HullShader, tcs); 129 // IMPLEMENT_OBJECT_DTOR(DomainShader, tes); 130 // IMPLEMENT_OBJECT_DTOR(ComputeShader, cs); 131 #else 132 IMPLEMENT_OBJECT_DTOR(BlendState1, blend) 133 IMPLEMENT_VIEW_DTOR(ShaderResourceView1, sampler_view) 134 #endif 135 136 template<typename Base, typename Desc, typename Object = void> 137 struct GalliumD3D11DescribedObject : public GalliumD3D11Object<Base, Object> 138 { 139 Desc desc; GalliumD3D11DescribedObjectGalliumD3D11DescribedObject140 GalliumD3D11DescribedObject(GalliumD3D11Screen* device, Object* object, const Desc& desc) 141 : GalliumD3D11Object<Base, Object>(device, object), desc(desc) 142 {} 143 GetDescGalliumD3D11DescribedObject144 virtual void STDMETHODCALLTYPE GetDesc(Desc *out_desc) 145 { 146 memcpy(out_desc, &desc, sizeof(desc)); 147 } 148 }; 149 150 typedef GalliumD3D11Object<ID3D11InputLayout> GalliumD3D11InputLayout; 151 typedef GalliumD3D11DescribedObject<ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC> GalliumD3D11DepthStencilState; 152 typedef GalliumD3D11DescribedObject<ID3D11RasterizerState, D3D11_RASTERIZER_DESC> GalliumD3D11RasterizerStateBase; 153 typedef GalliumD3D11DescribedObject<ID3D11SamplerState, D3D11_SAMPLER_DESC> GalliumD3D11SamplerState; 154 155 #if API >= 11 156 typedef GalliumD3D11DescribedObject<ID3D11BlendState, D3D11_BLEND_DESC> GalliumD3D11BlendState; 157 #else 158 typedef GalliumD3D10DescribedObject<ID3D10BlendState1, D3D10_BLEND_DESC> GalliumD3D10BlendStateBase; 159 160 struct GalliumD3D10BlendState : public GalliumD3D10BlendStateBase 161 { convert_to_d3d10GalliumD3D10BlendState162 static D3D10_BLEND_DESC convert_to_d3d10(const D3D10_BLEND_DESC1& desc1) 163 { 164 D3D10_BLEND_DESC desc; 165 desc.AlphaToCoverageEnable = desc1.AlphaToCoverageEnable; 166 desc.SrcBlend = desc1.RenderTarget[0].SrcBlend; 167 desc.DestBlend = desc1.RenderTarget[0].DestBlend; 168 desc.BlendOp = desc1.RenderTarget[0].BlendOp; 169 desc.SrcBlendAlpha = desc1.RenderTarget[0].SrcBlendAlpha; 170 desc.DestBlendAlpha = desc1.RenderTarget[0].DestBlendAlpha; 171 desc.BlendOpAlpha = desc1.RenderTarget[0].BlendOpAlpha; 172 for(unsigned i = 0; i < 8; ++i) 173 { 174 desc.BlendEnable[i] = desc1.RenderTarget[i].BlendEnable; 175 desc.RenderTargetWriteMask[i] = desc1.RenderTarget[i].RenderTargetWriteMask; 176 } 177 return desc; 178 } 179 180 D3D10_BLEND_DESC1 desc1; 181 GalliumD3D10BlendStateGalliumD3D10BlendState182 GalliumD3D10BlendState(GalliumD3D10Screen* device, void* object, const D3D10_BLEND_DESC& desc) 183 : GalliumD3D10BlendStateBase(device, object, desc) 184 { 185 memset(&desc1, 0, sizeof(desc1)); 186 desc1.AlphaToCoverageEnable = desc.AlphaToCoverageEnable; 187 desc1.RenderTarget[0].SrcBlend = desc.SrcBlend; 188 desc1.RenderTarget[0].DestBlend = desc.DestBlend; 189 desc1.RenderTarget[0].BlendOp = desc.BlendOp; 190 desc1.RenderTarget[0].SrcBlendAlpha = desc.SrcBlendAlpha; 191 desc1.RenderTarget[0].DestBlendAlpha = desc.DestBlendAlpha; 192 desc1.RenderTarget[0].BlendOpAlpha = desc.BlendOpAlpha; 193 for(unsigned i = 0; i < 8; ++i) 194 { 195 desc1.RenderTarget[i].BlendEnable = desc.BlendEnable[i]; 196 desc1.RenderTarget[i].RenderTargetWriteMask = desc.RenderTargetWriteMask[i]; 197 } 198 } 199 GalliumD3D10BlendStateGalliumD3D10BlendState200 GalliumD3D10BlendState(GalliumD3D10Screen* device, void* object, const D3D10_BLEND_DESC1& desc) 201 : GalliumD3D10BlendStateBase(device, object, convert_to_d3d10(desc)), desc1(desc1) 202 {} 203 GetDesc1GalliumD3D10BlendState204 virtual void STDMETHODCALLTYPE GetDesc1(D3D10_BLEND_DESC1 *out_desc) 205 { 206 memcpy(out_desc, &desc1, sizeof(desc1)); 207 } 208 }; 209 #endif 210 211 struct GalliumD3D11RasterizerState : public GalliumD3D11RasterizerStateBase 212 { GalliumD3D11RasterizerStateGalliumD3D11RasterizerState213 GalliumD3D11RasterizerState(GalliumD3D11Screen* device, void* object, const D3D11_RASTERIZER_DESC& desc) 214 : GalliumD3D11RasterizerStateBase(device, object, desc) 215 {} 216 }; 217 218 template<typename Base = ID3D11DeviceChild> 219 struct GalliumD3D11Shader : public GalliumD3D11Object<Base> 220 { GalliumD3D11ShaderGalliumD3D11Shader221 GalliumD3D11Shader(GalliumD3D11Screen* device, void* object) 222 : GalliumD3D11Object<Base>(device, object) 223 {} 224 }; 225 226 typedef GalliumD3D11Shader<ID3D11VertexShader> GalliumD3D11VertexShader; 227 typedef GalliumD3D11Shader<ID3D11GeometryShader> GalliumD3D11GeometryShader; 228 typedef GalliumD3D11Shader<ID3D11PixelShader> GalliumD3D11PixelShader; 229 230 #if API >= 11 231 /* 232 typedef GalliumD3D11Shader<ID3D11HullShader> GalliumD3D11HullShader; 233 typedef GalliumD3D11Shader<ID3D11DomainShader> GalliumD3D11DomainShader; 234 typedef GalliumD3D11Shader<ID3D11ComputeShader> GalliumD3D11ComputeShader; 235 */ 236 #endif 237 238 template<typename Base = ID3D11Resource> 239 struct GalliumD3D11ResourceBase : public GalliumD3D11DeviceChild<Base> 240 { 241 unsigned eviction_priority; 242 SetEvictionPriorityGalliumD3D11ResourceBase243 virtual void STDMETHODCALLTYPE SetEvictionPriority( 244 unsigned new_eviction_priority 245 ) 246 { 247 eviction_priority = new_eviction_priority; 248 } 249 GetEvictionPriorityGalliumD3D11ResourceBase250 virtual unsigned STDMETHODCALLTYPE GetEvictionPriority() 251 { 252 return eviction_priority; 253 } 254 }; 255 256 template<typename Real> 257 struct GalliumDXGIResource : public IDXGIResource 258 { SetEvictionPriorityGalliumDXGIResource259 virtual HRESULT STDMETHODCALLTYPE SetEvictionPriority( 260 unsigned new_eviction_priority 261 ) 262 { 263 static_cast<Real*>(this)->eviction_priority = new_eviction_priority; 264 return S_OK; 265 } 266 GetEvictionPriorityGalliumDXGIResource267 virtual HRESULT STDMETHODCALLTYPE GetEvictionPriority(unsigned* out_eviction_priority) 268 { 269 *out_eviction_priority = static_cast<Real*>(this)->eviction_priority; 270 return S_OK; 271 } 272 GetDeviceGalliumDXGIResource273 virtual HRESULT STDMETHODCALLTYPE GetDevice( 274 REFIID riid, 275 void **out_parent) 276 { 277 if(!static_cast<Real*>(this)->device) 278 return E_NOINTERFACE; 279 return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent); 280 } 281 GetParentGalliumDXGIResource282 virtual HRESULT STDMETHODCALLTYPE GetParent( 283 REFIID riid, 284 void **out_parent) 285 { 286 if(!static_cast<Real*>(this)->device) 287 return E_NOINTERFACE; 288 return static_cast<Real*>(this)->device->QueryInterface(riid, out_parent); 289 } 290 }; 291 292 template<typename T> 293 struct com_traits<GalliumDXGIResource<T> > : public com_traits<IDXGIResource> 294 {}; 295 296 template<typename Base = ID3D11Resource> 297 struct GalliumD3D11Resource 298 : public GalliumMultiComObject< 299 GalliumMultiPrivateDataComObject< 300 GalliumD3D11ResourceBase<Base>, 301 GalliumDXGIResource<GalliumD3D11Resource<Base> > 302 >, 303 IGalliumResource 304 > 305 { 306 struct pipe_resource* resource; 307 std::unordered_map<unsigned, pipe_transfer*> transfers; 308 float min_lod; 309 DXGI_USAGE dxgi_usage; 310 311 GalliumD3D11Resource(GalliumD3D11Screen* device = 0, struct pipe_resource* resource = 0, unsigned dxgi_usage = 0) 312 : resource(resource), min_lod(0), dxgi_usage(dxgi_usage) 313 { 314 this->device = device; 315 if(device) 316 device->AddRef(); 317 this->eviction_priority = 0; 318 } 319 320 ~GalliumD3D11Resource() 321 { 322 pipe_resource_reference(&resource, 0); 323 } 324 325 virtual HRESULT STDMETHODCALLTYPE GetUsage( 326 DXGI_USAGE *out_usage 327 ) 328 { 329 *out_usage = this->dxgi_usage; 330 return S_OK; 331 } 332 333 virtual HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE *out_shared_handle) 334 { 335 return E_NOTIMPL; 336 } 337 338 virtual struct pipe_resource* STDMETHODCALLTYPE GetGalliumResource() 339 { 340 return resource; 341 } 342 }; 343 344 template<typename Base, typename Desc, D3D11_RESOURCE_DIMENSION Dim> 345 struct GalliumD3D11TypedResource : public GalliumD3D11Resource<Base> 346 { 347 Desc desc; 348 GalliumD3D11TypedResource() {} 349 GalliumD3D11TypedResource(GalliumD3D11Screen* device, struct pipe_resource* resource, const Desc& desc, unsigned dxgi_usage) 350 : GalliumD3D11Resource<Base>(device, resource, dxgi_usage), desc(desc) 351 {} 352 virtual void STDMETHODCALLTYPE GetType( 353 D3D11_RESOURCE_DIMENSION *out_resource_dimension) 354 { 355 *out_resource_dimension = Dim; 356 } 357 virtual void STDMETHODCALLTYPE GetDesc(Desc *out_desc) 358 { 359 memcpy(out_desc, &desc, sizeof(desc)); 360 } 361 }; 362 363 typedef GalliumD3D11TypedResource<ID3D11Texture1D, D3D11_TEXTURE1D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE1D> GalliumD3D11Texture1DBase; 364 typedef GalliumD3D11TypedResource<ID3D11Texture2D, D3D11_TEXTURE2D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE2D> GalliumD3D11Texture2DBase; 365 typedef GalliumD3D11TypedResource<ID3D11Texture3D, D3D11_TEXTURE3D_DESC, D3D11_RESOURCE_DIMENSION_TEXTURE3D> GalliumD3D11Texture3DBase; 366 typedef GalliumD3D11TypedResource<ID3D11Buffer, D3D11_BUFFER_DESC, D3D11_RESOURCE_DIMENSION_BUFFER> GalliumD3D11BufferBase; 367 368 #if API >= 11 369 typedef GalliumD3D11Texture1DBase GalliumD3D11Texture1D; 370 typedef GalliumD3D11Texture2DBase GalliumD3D11Texture2D; 371 typedef GalliumD3D11Texture3DBase GalliumD3D11Texture3D; 372 373 struct GalliumD3D11Buffer : public GalliumD3D11BufferBase 374 { 375 struct pipe_stream_output_target* so_target; 376 377 GalliumD3D11Buffer(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_BUFFER_DESC& desc, unsigned dxgi_usage) 378 : GalliumD3D11BufferBase(device, resource, desc, dxgi_usage), so_target(0) 379 { 380 } 381 382 ~GalliumD3D11Buffer() 383 { 384 if(so_target) 385 pipe_so_target_reference(&so_target, NULL); 386 } 387 }; 388 #else 389 struct GalliumD3D10Buffer : public GalliumD3D10BufferBase 390 { 391 struct pipe_stream_output_target *so_target; 392 393 GalliumD3D10Buffer(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_BUFFER_DESC& desc, unsigned dxgi_usage) 394 : GalliumD3D10BufferBase(device, resource, desc, dxgi_usage) 395 { 396 } 397 398 ~GalliumD3D10Buffer() 399 { 400 if(so_target) 401 pipe_so_target_reference(&so_target, NULL); 402 403 device->UnbindBuffer(this); 404 } 405 406 virtual HRESULT STDMETHODCALLTYPE Map( 407 D3D10_MAP map_type, 408 unsigned map_flags, 409 void **out_data) 410 { 411 D3D10_MAPPED_SUBRESOURCE msr; 412 HRESULT hr = device->Map(this, 0, map_type, map_flags, &msr); 413 if(!SUCCEEDED(hr)) 414 return hr; 415 *out_data = msr.pData; 416 return S_OK; 417 } 418 419 virtual void STDMETHODCALLTYPE Unmap() 420 { 421 device->Unmap(this, 0); 422 } 423 }; 424 425 struct GalliumD3D10Texture1D : public GalliumD3D10Texture1DBase 426 { 427 GalliumD3D10Texture1D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE1D_DESC& desc, unsigned dxgi_usage) 428 : GalliumD3D10Texture1DBase(device, resource, desc, dxgi_usage) 429 {} 430 431 virtual HRESULT STDMETHODCALLTYPE Map( 432 unsigned subresource, 433 D3D10_MAP map_type, 434 unsigned map_flags, 435 void **out_data) 436 { 437 D3D10_MAPPED_SUBRESOURCE msr; 438 HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr); 439 if(!SUCCEEDED(hr)) 440 return hr; 441 *out_data = msr.pData; 442 return S_OK; 443 } 444 445 virtual void STDMETHODCALLTYPE Unmap( 446 unsigned subresource 447 ) 448 { 449 device->Unmap(this, subresource); 450 } 451 }; 452 453 struct GalliumD3D10Texture2D : public GalliumD3D10Texture2DBase 454 { 455 GalliumD3D10Texture2D() {} 456 GalliumD3D10Texture2D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE2D_DESC& desc, unsigned dxgi_usage) 457 : GalliumD3D10Texture2DBase(device, resource, desc, dxgi_usage) 458 {} 459 460 virtual HRESULT STDMETHODCALLTYPE Map( 461 unsigned subresource, 462 D3D10_MAP map_type, 463 unsigned map_flags, 464 D3D10_MAPPED_TEXTURE2D *out_mapped_subresource) 465 { 466 D3D10_MAPPED_SUBRESOURCE msr; 467 HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr); 468 if(!SUCCEEDED(hr)) 469 return hr; 470 out_mapped_subresource->pData = msr.pData; 471 out_mapped_subresource->RowPitch = msr.RowPitch; 472 return S_OK; 473 } 474 475 virtual void STDMETHODCALLTYPE Unmap( 476 unsigned subresource 477 ) 478 { 479 device->Unmap(this, subresource); 480 } 481 }; 482 483 484 struct GalliumD3D10Texture3D : public GalliumD3D10Texture3DBase 485 { 486 GalliumD3D10Texture3D(GalliumD3D10Screen* device, struct pipe_resource* resource, const D3D10_TEXTURE3D_DESC& desc, unsigned dxgi_usage) 487 : GalliumD3D10Texture3DBase(device, resource, desc, dxgi_usage) 488 {} 489 490 virtual HRESULT STDMETHODCALLTYPE Map( 491 unsigned subresource, 492 D3D10_MAP map_type, 493 unsigned map_flags, 494 D3D10_MAPPED_TEXTURE3D *out_mapped_subresource) 495 { 496 D3D10_MAPPED_SUBRESOURCE msr; 497 HRESULT hr = device->Map(this, subresource, map_type, map_flags, &msr); 498 if(!SUCCEEDED(hr)) 499 return hr; 500 out_mapped_subresource->pData = msr.pData; 501 out_mapped_subresource->RowPitch = msr.RowPitch; 502 out_mapped_subresource->DepthPitch = msr.DepthPitch; 503 return S_OK; 504 } 505 506 virtual void STDMETHODCALLTYPE Unmap( 507 unsigned subresource 508 ) 509 { 510 device->Unmap(this, subresource); 511 } 512 }; 513 #endif 514 515 struct GalliumD3D11Surface : public GalliumMultiPrivateDataComObject<GalliumD3D11Texture2D, IDXGISurface1> 516 { 517 GalliumD3D11Surface(GalliumD3D11Screen* device, struct pipe_resource* resource, const D3D11_TEXTURE2D_DESC& desc, unsigned dxgi_usage) 518 { 519 this->device = device; 520 this->device->AddRef(); 521 this->resource = resource; 522 this->desc = desc; 523 this->dxgi_usage = dxgi_usage; 524 } 525 526 virtual HRESULT STDMETHODCALLTYPE GetDesc( 527 DXGI_SURFACE_DESC *out_desc) 528 { 529 out_desc->Format = this->desc.Format; 530 out_desc->Width = this->desc.Width; 531 out_desc->Height = this->desc.Height; 532 out_desc->SampleDesc = this->desc.SampleDesc; 533 return S_OK; 534 } 535 536 virtual HRESULT STDMETHODCALLTYPE GetParent( 537 REFIID riid, 538 void **out_parent) 539 { 540 if(!device) 541 return E_NOINTERFACE; 542 return device->QueryInterface(riid, out_parent); 543 } 544 545 /* TODO: somehow implement these */ 546 virtual HRESULT STDMETHODCALLTYPE GetDC( 547 BOOL discard, 548 HDC *out_hdc) 549 { 550 *out_hdc = 0; 551 return E_NOTIMPL; 552 } 553 554 virtual HRESULT STDMETHODCALLTYPE ReleaseDC( 555 RECT *out_dirty_rect) 556 { 557 return E_NOTIMPL; 558 } 559 560 virtual HRESULT STDMETHODCALLTYPE Map( 561 DXGI_MAPPED_RECT *out_locked_rect, 562 unsigned map_flags) 563 { 564 D3D11_MAP d3d_map; 565 if(map_flags & DXGI_MAP_DISCARD) 566 d3d_map = D3D11_MAP_WRITE_DISCARD; 567 else 568 { 569 if(map_flags & DXGI_MAP_READ) 570 { 571 if(map_flags & DXGI_MAP_WRITE) 572 d3d_map = D3D11_MAP_READ_WRITE; 573 else 574 d3d_map = D3D11_MAP_READ; 575 } 576 else 577 d3d_map = D3D11_MAP_WRITE; 578 } 579 D3D11_MAPPED_SUBRESOURCE d3d_mapped; 580 HRESULT hres = this->device->get_immediate_context()->Map(this, 0, d3d_map, 0, &d3d_mapped); 581 out_locked_rect->pBits = (uint8_t*)d3d_mapped.pData; 582 out_locked_rect->Pitch = d3d_mapped.RowPitch; 583 return hres; 584 } 585 586 virtual HRESULT STDMETHODCALLTYPE Unmap(void) 587 { 588 this->device->get_immediate_context()->Unmap(this, 0); 589 return S_OK; 590 } 591 592 virtual HRESULT STDMETHODCALLTYPE GetDevice( 593 REFIID riid, 594 void **out_parent) 595 { 596 if(!device) 597 return E_NOINTERFACE; 598 return device->QueryInterface(riid, out_parent); 599 } 600 }; 601 602 template<typename Base, typename Desc, typename Object> 603 struct GalliumD3D11View : public GalliumD3D11DescribedObject<Base, Desc, Object> 604 { 605 GalliumD3D11Resource<>* resource; 606 GalliumD3D11View(GalliumD3D11Screen* device, GalliumD3D11Resource<>* resource, Object* object, const Desc& desc) 607 : GalliumD3D11DescribedObject<Base, Desc, Object>(device, object, desc), resource(resource) 608 { 609 resource->AddRef(); 610 } 611 612 ~GalliumD3D11View() 613 { 614 resource->Release(); 615 } 616 617 virtual void STDMETHODCALLTYPE GetResource(ID3D11Resource** out_resource) 618 { 619 resource->AddRef(); 620 *out_resource = resource; 621 } 622 }; 623 624 typedef GalliumD3D11View<ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, struct pipe_surface> GalliumD3D11DepthStencilView; 625 typedef GalliumD3D11View<ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, struct pipe_surface> GalliumD3D11RenderTargetView; 626 627 #if API >= 11 628 typedef GalliumD3D11View<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, struct pipe_sampler_view> GalliumD3D11ShaderResourceView; 629 #else 630 typedef GalliumD3D10View<ID3D10ShaderResourceView1, D3D10_SHADER_RESOURCE_VIEW_DESC1, struct pipe_sampler_view> GalliumD3D10ShaderResourceViewBase; 631 632 struct GalliumD3D10ShaderResourceView : public GalliumD3D10ShaderResourceViewBase 633 { 634 GalliumD3D10ShaderResourceView(GalliumD3D10Screen* device, GalliumD3D10Resource<>* resource, struct pipe_sampler_view* view, const D3D10_SHADER_RESOURCE_VIEW_DESC1& desc) 635 : GalliumD3D10ShaderResourceViewBase(device, resource, view, desc) 636 {} 637 638 virtual void STDMETHODCALLTYPE GetDesc1(D3D10_SHADER_RESOURCE_VIEW_DESC1 *out_desc) 639 { 640 memcpy(out_desc, &desc, sizeof(*out_desc)); 641 } 642 643 virtual void STDMETHODCALLTYPE GetDesc(D3D10_SHADER_RESOURCE_VIEW_DESC *out_desc) 644 { 645 memcpy(out_desc, &desc, sizeof(*out_desc)); 646 } 647 }; 648 #endif 649 650 template<typename Base = ID3D11Asynchronous> 651 struct GalliumD3D11Asynchronous : public GalliumD3D11DeviceChild<Base> 652 { 653 struct pipe_query* query; 654 unsigned data_size; 655 656 GalliumD3D11Asynchronous(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size) 657 : GalliumD3D11DeviceChild<Base>(device), query(query), data_size(data_size) 658 {} 659 660 ~GalliumD3D11Asynchronous() 661 { 662 this->device->immediate_pipe->destroy_query(this->device->immediate_pipe, query); 663 } 664 665 virtual unsigned STDMETHODCALLTYPE GetDataSize() 666 { 667 return data_size; 668 } 669 670 #if API < 11 671 virtual void STDMETHODCALLTYPE Begin() 672 { 673 this->device->Begin(this); 674 } 675 676 virtual void STDMETHODCALLTYPE End() 677 { 678 this->device->End(this); 679 } 680 681 virtual HRESULT STDMETHODCALLTYPE GetData( 682 void * out_data, 683 unsigned data_size, 684 unsigned get_data_flags) 685 { 686 return this->device->GetData(this, out_data, data_size, get_data_flags); 687 } 688 #endif 689 }; 690 691 template<typename Base = ID3D11Asynchronous> 692 struct GalliumD3D11QueryOrPredicate : public GalliumD3D11Asynchronous<Base> 693 { 694 D3D11_QUERY_DESC desc; 695 GalliumD3D11QueryOrPredicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc) 696 : GalliumD3D11Asynchronous<Base>(device, query, data_size), desc(desc) 697 {} 698 699 virtual void STDMETHODCALLTYPE GetDesc( 700 D3D11_QUERY_DESC *out_desc) 701 { 702 *out_desc = desc; 703 } 704 }; 705 706 struct GalliumD3D11Query : public GalliumD3D11QueryOrPredicate<ID3D11Query> 707 { 708 GalliumD3D11Query(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc) 709 : GalliumD3D11QueryOrPredicate<ID3D11Query>(device, query, data_size, desc) 710 {} 711 }; 712 713 struct GalliumD3D11Predicate : public GalliumD3D11QueryOrPredicate<ID3D11Predicate> 714 { 715 GalliumD3D11Predicate(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_QUERY_DESC& desc) 716 : GalliumD3D11QueryOrPredicate<ID3D11Predicate>(device, query, data_size, desc) 717 {} 718 719 ~GalliumD3D11Predicate() 720 { 721 DX10_ONLY(device->UnbindPredicate(this)); 722 } 723 }; 724 725 struct GalliumD3D11Counter : public GalliumD3D11Asynchronous<ID3D11Counter> 726 { 727 D3D11_COUNTER_DESC desc; 728 GalliumD3D11Counter(GalliumD3D11Screen* device, struct pipe_query* query, unsigned data_size, const D3D11_COUNTER_DESC& desc) 729 : GalliumD3D11Asynchronous<ID3D11Counter>(device, query, data_size), desc(desc) 730 {} 731 732 virtual void STDMETHODCALLTYPE GetDesc( 733 D3D11_COUNTER_DESC *out_desc) 734 { 735 *out_desc = desc; 736 } 737 }; 738