1 /**************************************************************************
3 * Copyright 2010 Luca Barbieri
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:
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.
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.
25 **************************************************************************/
27 /* These cap sets are much more correct than the ones in u_caps.c */
28 /* TODO: it seems cube levels should be the same as 2D levels */
31 static unsigned caps_dx_9_1
[] = {
32 UTIL_CHECK_INT(MAX_RENDER_TARGETS
, 1),
33 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS
, 12), /* 2048 */
34 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS
, 8), /* 256 */
35 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS
, 10), /* 512 */
40 static unsigned caps_dx_9_2
[] = {
41 UTIL_CHECK_CAP(OCCLUSION_QUERY
),
42 UTIL_CHECK_CAP(TWO_SIDED_STENCIL
),
43 UTIL_CHECK_CAP(TEXTURE_MIRROR_CLAMP
),
44 UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE
),
45 UTIL_CHECK_INT(MAX_RENDER_TARGETS
, 1),
46 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS
, 12), /* 2048 */
47 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS
, 9), /* 256 */
48 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS
, 10), /* 512 */
53 static unsigned caps_dx_9_3
[] = {
54 UTIL_CHECK_CAP(OCCLUSION_QUERY
),
55 UTIL_CHECK_CAP(TWO_SIDED_STENCIL
),
56 UTIL_CHECK_CAP(TEXTURE_MIRROR_CLAMP
),
57 UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE
),
59 //UTIL_CHECK_CAP(INSTANCING),
60 UTIL_CHECK_CAP(OCCLUSION_QUERY
),
61 UTIL_CHECK_INT(MAX_RENDER_TARGETS
, 4),
62 UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS
, 13), /* 4096 */
63 UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS
, 9), /* 256 */
64 UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS
, 10), /* 512 */
69 // this is called "screen" because in the D3D10 case it's only part of the device
70 template<bool threadsafe
>
71 struct GalliumD3D11ScreenImpl
: public GalliumD3D11Screen
73 D3D_FEATURE_LEVEL feature_level
;
74 int format_support
[PIPE_FORMAT_COUNT
];
75 unsigned creation_flags
;
76 unsigned exception_mode
;
77 maybe_mutex_t
<threadsafe
> mutex
;
79 /* TODO: Direct3D 11 specifies that fine-grained locking should be used if the driver supports it.
80 * Right now, I don't trust Gallium drivers to get this right.
82 #define SYNCHRONIZED lock_t<maybe_mutex_t<threadsafe> > lock_(mutex)
84 GalliumD3D11ScreenImpl(struct pipe_screen
* screen
, struct pipe_context
* immediate_pipe
, BOOL owns_immediate_pipe
,unsigned creation_flags
, IDXGIAdapter
* adapter
)
85 : GalliumD3D11Screen(screen
, immediate_pipe
, adapter
), creation_flags(creation_flags
)
87 memset(&screen_caps
, 0, sizeof(screen_caps
));
88 screen_caps
.gs
= screen
->get_shader_param(screen
, PIPE_SHADER_GEOMETRY
, PIPE_SHADER_CAP_MAX_INSTRUCTIONS
) > 0;
89 screen_caps
.so
= !!screen
->get_param(screen
, PIPE_CAP_STREAM_OUTPUT
);
90 screen_caps
.queries
= screen
->get_param(screen
, PIPE_CAP_OCCLUSION_QUERY
);
91 screen_caps
.render_condition
= screen_caps
.queries
;
92 for(unsigned i
= 0; i
< PIPE_SHADER_TYPES
; ++i
)
93 screen_caps
.constant_buffers
[i
] = screen
->get_shader_param(screen
, i
, PIPE_SHADER_CAP_MAX_CONST_BUFFERS
);
94 screen_caps
.stages
= 0;
95 for(unsigned i
= 0; i
< PIPE_SHADER_TYPES
; ++i
)
97 if(!screen
->get_shader_param(screen
, i
, PIPE_SHADER_CAP_MAX_INSTRUCTIONS
))
99 screen_caps
.stages
= i
+ 1;
102 memset(format_support
, 0xff, sizeof(format_support
));
105 /* don't even attempt to autodetect D3D10 level support, since it's just not fully implemented yet */
106 if(util_check_caps(screen
, caps_dx_9_3
))
108 else if(util_check_caps(screen
, caps_dx_9_2
))
110 else if(util_check_caps(screen
, caps_dx_9_1
))
114 _debug_printf("Warning: driver does not even meet D3D_FEATURE_LEVEL_9_1 features, advertising it anyway!\n");
118 char default_level_name
[64];
119 sprintf(default_level_name
, "%.1f", default_level
);
120 float feature_level_number
= atof(debug_get_option("D3D11_FEATURE_LEVEL", default_level_name
));
121 if(!feature_level_number
)
122 feature_level_number
= default_level
;
125 if(feature_level_number
>= 11.0f
)
126 feature_level
= D3D_FEATURE_LEVEL_11_0
;
129 if(feature_level_number
>= 10.1f
)
130 feature_level
= D3D_FEATURE_LEVEL_10_1
;
131 else if(feature_level_number
>= 10.0f
)
132 feature_level
= D3D_FEATURE_LEVEL_10_0
;
133 else if(feature_level_number
>= 9.3f
)
134 feature_level
= D3D_FEATURE_LEVEL_9_3
;
135 else if(feature_level_number
>= 9.2f
)
136 feature_level
= D3D_FEATURE_LEVEL_9_2
;
138 feature_level
= D3D_FEATURE_LEVEL_9_1
;
141 immediate_context
= GalliumD3D11ImmediateDeviceContext_Create(this, immediate_pipe
, owns_immediate_pipe
);
145 ~GalliumD3D11ScreenImpl()
148 GalliumD3D11ImmediateDeviceContext_Destroy(immediate_context
);
152 virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE
GetFeatureLevel(void)
154 return feature_level
;
157 virtual unsigned STDMETHODCALLTYPE
GetCreationFlags(void)
159 return creation_flags
;
162 virtual HRESULT STDMETHODCALLTYPE
GetDeviceRemovedReason(void)
168 virtual void STDMETHODCALLTYPE
GetImmediateContext(
169 ID3D11DeviceContext
**ppImmediateContext
)
171 immediate_context
->AddRef();
172 *ppImmediateContext
= immediate_context
;
176 virtual HRESULT STDMETHODCALLTYPE
SetExceptionMode(unsigned RaiseFlags
)
178 exception_mode
= RaiseFlags
;
182 virtual unsigned STDMETHODCALLTYPE
GetExceptionMode(void)
184 return exception_mode
;
187 virtual HRESULT STDMETHODCALLTYPE
CheckCounter(
188 const D3D11_COUNTER_DESC
*pDesc
,
189 D3D11_COUNTER_TYPE
*pType
,
190 unsigned *pActiveCounters
,
192 unsigned *pNameLength
,
194 unsigned *pUnitsLength
,
196 unsigned *pDescriptionLength
)
201 virtual void STDMETHODCALLTYPE
CheckCounterInfo(
202 D3D11_COUNTER_INFO
*pCounterInfo
)
204 /* none supported at the moment */
205 pCounterInfo
->LastDeviceDependentCounter
= (D3D11_COUNTER
)0;
206 pCounterInfo
->NumSimultaneousCounters
= 0;
207 pCounterInfo
->NumDetectableParallelUnits
= 1;
211 virtual HRESULT STDMETHODCALLTYPE
CheckFeatureSupport(
212 D3D11_FEATURE Feature
,
213 void *pFeatureSupportData
,
214 unsigned FeatureSupportDataSize
)
220 case D3D11_FEATURE_THREADING
:
222 D3D11_FEATURE_DATA_THREADING
* data
= (D3D11_FEATURE_DATA_THREADING
*)pFeatureSupportData
;
223 if(FeatureSupportDataSize
!= sizeof(*data
))
226 data
->DriverCommandLists
= FALSE
;
227 data
->DriverConcurrentCreates
= FALSE
;
230 case D3D11_FEATURE_DOUBLES
:
232 D3D11_FEATURE_DATA_DOUBLES
* data
= (D3D11_FEATURE_DATA_DOUBLES
*)pFeatureSupportData
;
233 if(FeatureSupportDataSize
!= sizeof(*data
))
236 data
->DoublePrecisionFloatShaderOps
= FALSE
;
239 case D3D11_FEATURE_FORMAT_SUPPORT
:
241 D3D11_FEATURE_DATA_FORMAT_SUPPORT
* data
= (D3D11_FEATURE_DATA_FORMAT_SUPPORT
*)pFeatureSupportData
;
242 if(FeatureSupportDataSize
!= sizeof(*data
))
245 return this->CheckFormatSupport(data
->InFormat
, &data
->OutFormatSupport
);
247 case D3D11_FEATURE_FORMAT_SUPPORT2
:
249 D3D11_FEATURE_DATA_FORMAT_SUPPORT
* data
= (D3D11_FEATURE_DATA_FORMAT_SUPPORT
*)pFeatureSupportData
;
250 if(FeatureSupportDataSize
!= sizeof(*data
))
253 data
->OutFormatSupport
= 0;
254 /* TODO: should this be S_OK? */
257 case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS
:
259 D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS
* data
= (D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS
*)pFeatureSupportData
;
260 if(FeatureSupportDataSize
!= sizeof(*data
))
263 data
->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x
= FALSE
;
272 virtual HRESULT STDMETHODCALLTYPE
CheckFormatSupport(
274 unsigned *pFormatSupport
279 /* TODO: MSAA, advanced features */
280 pipe_format format
= dxgi_to_pipe_format
[Format
];
284 int support
= format_support
[format
];
288 unsigned buffer
= D3D11_FORMAT_SUPPORT_BUFFER
| D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER
| D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER
;
289 unsigned sampler_view
= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE
| D3D11_FORMAT_SUPPORT_MIP
| D3D11_FORMAT_SUPPORT_MIP_AUTOGEN
;
290 if(util_format_is_depth_or_stencil(format
))
291 sampler_view
|= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON
;
293 /* TODO: do this properly when Gallium drivers actually support index/vertex format queries */
294 if(screen
->is_format_supported(screen
, format
, PIPE_BUFFER
, 0, PIPE_BIND_VERTEX_BUFFER
, 0)
295 || (screen
->is_format_supported(screen
, format
, PIPE_BUFFER
, 0, PIPE_BIND_INDEX_BUFFER
, 0)
296 || format
== PIPE_FORMAT_R8_UNORM
))
298 if(screen
->is_format_supported(screen
, format
, PIPE_BUFFER
, 0, PIPE_BIND_STREAM_OUTPUT
, 0))
299 support
|= buffer
| D3D11_FORMAT_SUPPORT_SO_BUFFER
;
300 if(screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_1D
, 0, PIPE_BIND_SAMPLER_VIEW
, 0))
301 support
|= D3D11_FORMAT_SUPPORT_TEXTURE1D
| sampler_view
;
302 if(screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_2D
, 0, PIPE_BIND_SAMPLER_VIEW
, 0))
303 support
|= D3D11_FORMAT_SUPPORT_TEXTURE2D
| sampler_view
;
304 if(screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_CUBE
, 0, PIPE_BIND_SAMPLER_VIEW
, 0))
305 support
|= D3D11_FORMAT_SUPPORT_TEXTURE2D
| sampler_view
;
306 if(screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_3D
, 0, PIPE_BIND_SAMPLER_VIEW
, 0))
307 support
|= D3D11_FORMAT_SUPPORT_TEXTURE3D
| sampler_view
;
308 if(screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_2D
, 0, PIPE_BIND_RENDER_TARGET
, 0))
309 support
|= D3D11_FORMAT_SUPPORT_TEXTURE2D
| D3D11_FORMAT_SUPPORT_RENDER_TARGET
| D3D11_FORMAT_SUPPORT_BLENDABLE
;
310 if(screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_2D
, 0, PIPE_BIND_DEPTH_STENCIL
, 0))
311 support
|= D3D11_FORMAT_SUPPORT_TEXTURE2D
| D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
;
312 if(screen
->is_format_supported(screen
, format
, PIPE_TEXTURE_2D
, 0, PIPE_BIND_DISPLAY_TARGET
, 0))
313 support
|= D3D11_FORMAT_SUPPORT_DISPLAY
;
314 format_support
[format
] = support
;
316 *pFormatSupport
= support
;
320 virtual HRESULT STDMETHODCALLTYPE
CheckMultisampleQualityLevels(
322 unsigned SampleCount
,
323 unsigned *pNumQualityLevels
328 *pNumQualityLevels
= 0;
332 template<typename T
, typename U
>
333 bool convert_blend_state(T
& to
, const U
& from
, unsigned BlendEnable
, unsigned RenderTargetWriteMask
)
336 || from
.SrcBlend
>= D3D11_BLEND_COUNT
337 || from
.SrcBlendAlpha
>= D3D11_BLEND_COUNT
338 || from
.DestBlend
>= D3D11_BLEND_COUNT
339 || from
.DestBlendAlpha
>= D3D11_BLEND_COUNT
341 || from
.BlendOpAlpha
>= 6
343 || !from
.BlendOpAlpha
347 to
.blend_enable
= BlendEnable
;
349 to
.rgb_func
= from
.BlendOp
- 1;
350 to
.alpha_func
= from
.BlendOpAlpha
- 1;
352 to
.rgb_src_factor
= d3d11_to_pipe_blend
[from
.SrcBlend
];
353 to
.alpha_src_factor
= d3d11_to_pipe_blend
[from
.SrcBlendAlpha
];
354 to
.rgb_dst_factor
= d3d11_to_pipe_blend
[from
.DestBlend
];
355 to
.alpha_dst_factor
= d3d11_to_pipe_blend
[from
.DestBlendAlpha
];
357 to
.colormask
= RenderTargetWriteMask
& 0xf;
362 virtual HRESULT STDMETHODCALLTYPE
CreateBlendState(
363 const D3D11_BLEND_DESC
*pBlendStateDesc
,
364 ID3D11BlendState
**ppBlendState
367 virtual HRESULT STDMETHODCALLTYPE
CreateBlendState1(
368 const D3D10_BLEND_DESC1
*pBlendStateDesc
,
369 ID3D10BlendState1
**ppBlendState
375 pipe_blend_state state
;
376 memset(&state
, 0, sizeof(state
));
377 state
.alpha_to_coverage
= !!pBlendStateDesc
->AlphaToCoverageEnable
;
378 state
.independent_blend_enable
= !!pBlendStateDesc
->IndependentBlendEnable
;
379 assert(PIPE_MAX_COLOR_BUFS
>= 8);
380 for(unsigned i
= 0; i
< 8; ++i
)
382 if(!convert_blend_state(
384 pBlendStateDesc
->RenderTarget
[i
],
385 pBlendStateDesc
->RenderTarget
[i
].BlendEnable
,
386 pBlendStateDesc
->RenderTarget
[i
].RenderTargetWriteMask
))
393 void* object
= immediate_pipe
->create_blend_state(immediate_pipe
, &state
);
397 *ppBlendState
= new GalliumD3D11BlendState(this, object
, *pBlendStateDesc
);
402 virtual HRESULT STDMETHODCALLTYPE
CreateBlendState(
403 const D3D10_BLEND_DESC
*pBlendStateDesc
,
404 ID3D10BlendState
**ppBlendState
409 pipe_blend_state state
;
410 memset(&state
, 0, sizeof(state
));
411 state
.alpha_to_coverage
= !!pBlendStateDesc
->AlphaToCoverageEnable
;
412 assert(PIPE_MAX_COLOR_BUFS
>= 8);
413 for(unsigned i
= 0; i
< 8; ++i
)
415 if(!convert_blend_state(
418 pBlendStateDesc
->BlendEnable
[i
],
419 pBlendStateDesc
->RenderTargetWriteMask
[i
]))
423 for(unsigned i
= 1; i
< 8; ++i
)
425 if(memcmp(&state
.rt
[0], &state
.rt
[i
], sizeof(state
.rt
[0])))
427 state
.independent_blend_enable
= TRUE
;
432 void* object
= immediate_pipe
->create_blend_state(immediate_pipe
, &state
);
436 *ppBlendState
= new GalliumD3D11BlendState(this, object
, *pBlendStateDesc
);
441 virtual HRESULT STDMETHODCALLTYPE
CreateDepthStencilState(
442 const D3D11_DEPTH_STENCIL_DESC
*pDepthStencilStateDesc
,
443 ID3D11DepthStencilState
**ppDepthStencilState
448 pipe_depth_stencil_alpha_state state
;
449 memset(&state
, 0, sizeof(state
));
450 state
.depth
.enabled
= !!pDepthStencilStateDesc
->DepthEnable
;
451 state
.depth
.writemask
= pDepthStencilStateDesc
->DepthWriteMask
;
452 state
.depth
.func
= pDepthStencilStateDesc
->DepthFunc
- 1;
453 state
.stencil
[0].enabled
= !!pDepthStencilStateDesc
->StencilEnable
;
454 state
.stencil
[0].writemask
= pDepthStencilStateDesc
->StencilWriteMask
;
455 state
.stencil
[0].valuemask
= pDepthStencilStateDesc
->StencilReadMask
;
456 state
.stencil
[0].zpass_op
= d3d11_to_pipe_stencil_op
[pDepthStencilStateDesc
->FrontFace
.StencilPassOp
];
457 state
.stencil
[0].fail_op
= d3d11_to_pipe_stencil_op
[pDepthStencilStateDesc
->FrontFace
.StencilFailOp
];
458 state
.stencil
[0].zfail_op
= d3d11_to_pipe_stencil_op
[pDepthStencilStateDesc
->FrontFace
.StencilDepthFailOp
];
459 state
.stencil
[0].func
= pDepthStencilStateDesc
->FrontFace
.StencilFunc
- 1;
460 state
.stencil
[1].enabled
= !!pDepthStencilStateDesc
->StencilEnable
;
461 state
.stencil
[1].writemask
= pDepthStencilStateDesc
->StencilWriteMask
;
462 state
.stencil
[1].valuemask
= pDepthStencilStateDesc
->StencilReadMask
;
463 state
.stencil
[1].zpass_op
= d3d11_to_pipe_stencil_op
[pDepthStencilStateDesc
->BackFace
.StencilPassOp
];
464 state
.stencil
[1].fail_op
= d3d11_to_pipe_stencil_op
[pDepthStencilStateDesc
->BackFace
.StencilFailOp
];
465 state
.stencil
[1].zfail_op
= d3d11_to_pipe_stencil_op
[pDepthStencilStateDesc
->BackFace
.StencilDepthFailOp
];
466 state
.stencil
[1].func
= pDepthStencilStateDesc
->BackFace
.StencilFunc
- 1;
468 if(!ppDepthStencilState
)
471 void* object
= immediate_pipe
->create_depth_stencil_alpha_state(immediate_pipe
, &state
);
475 *ppDepthStencilState
= new GalliumD3D11DepthStencilState(this, object
, *pDepthStencilStateDesc
);
479 virtual HRESULT STDMETHODCALLTYPE
CreateRasterizerState(
480 const D3D11_RASTERIZER_DESC
*pRasterizerDesc
,
481 ID3D11RasterizerState
**ppRasterizerState
)
485 pipe_rasterizer_state state
;
486 memset(&state
, 0, sizeof(state
));
487 state
.gl_rasterization_rules
= 1; /* D3D10/11 use GL rules */
488 state
.fill_front
= state
.fill_back
= (pRasterizerDesc
->FillMode
== D3D11_FILL_WIREFRAME
) ? PIPE_POLYGON_MODE_LINE
: PIPE_POLYGON_MODE_FILL
;
489 if(pRasterizerDesc
->CullMode
== D3D11_CULL_FRONT
)
490 state
.cull_face
= PIPE_FACE_FRONT
;
491 else if(pRasterizerDesc
->CullMode
== D3D11_CULL_BACK
)
492 state
.cull_face
= PIPE_FACE_BACK
;
494 state
.cull_face
= PIPE_FACE_NONE
;
495 state
.front_ccw
= !!pRasterizerDesc
->FrontCounterClockwise
;
496 /* TODO: is this correct? */
497 /* TODO: we are ignoring DepthBiasClamp! */
498 state
.offset_tri
= state
.offset_line
= state
.offset_point
= pRasterizerDesc
->SlopeScaledDepthBias
|| pRasterizerDesc
->DepthBias
;
499 state
.offset_scale
= pRasterizerDesc
->SlopeScaledDepthBias
;
500 state
.offset_units
= pRasterizerDesc
->DepthBias
;
501 state
.scissor
= !!pRasterizerDesc
->ScissorEnable
;
502 state
.multisample
= !!pRasterizerDesc
->MultisampleEnable
;
503 state
.line_smooth
= !!pRasterizerDesc
->AntialiasedLineEnable
;
505 /* TODO: is this correct? */
506 state
.point_quad_rasterization
= 1;
508 if(!ppRasterizerState
)
511 void* object
= immediate_pipe
->create_rasterizer_state(immediate_pipe
, &state
);
515 *ppRasterizerState
= new GalliumD3D11RasterizerState(this, object
, *pRasterizerDesc
, !pRasterizerDesc
->DepthClipEnable
);
519 virtual HRESULT STDMETHODCALLTYPE
CreateSamplerState(
520 const D3D11_SAMPLER_DESC
*pSamplerDesc
,
521 ID3D11SamplerState
**ppSamplerState
)
525 pipe_sampler_state state
;
526 memset(&state
, 0, sizeof(state
));
527 state
.normalized_coords
= 1;
528 state
.min_mip_filter
= (pSamplerDesc
->Filter
& 1);
529 state
.mag_img_filter
= ((pSamplerDesc
->Filter
>> 2) & 1);
530 state
.min_img_filter
= ((pSamplerDesc
->Filter
>> 4) & 1);
531 if(pSamplerDesc
->Filter
& 0x40)
532 state
.max_anisotropy
= pSamplerDesc
->MaxAnisotropy
;
533 if(pSamplerDesc
->Filter
& 0x80)
535 state
.compare_mode
= PIPE_TEX_COMPARE_R_TO_TEXTURE
;
536 state
.compare_func
= pSamplerDesc
->ComparisonFunc
;
538 state
.wrap_s
= d3d11_to_pipe_wrap
[pSamplerDesc
->AddressU
];
539 state
.wrap_t
= d3d11_to_pipe_wrap
[pSamplerDesc
->AddressV
];
540 state
.wrap_r
= d3d11_to_pipe_wrap
[pSamplerDesc
->AddressW
];
541 state
.lod_bias
= pSamplerDesc
->MipLODBias
;
542 memcpy(state
.border_color
, pSamplerDesc
->BorderColor
, sizeof(state
.border_color
));
543 state
.min_lod
= pSamplerDesc
->MinLOD
;
544 state
.max_lod
= pSamplerDesc
->MaxLOD
;
549 void* object
= immediate_pipe
->create_sampler_state(immediate_pipe
, &state
);
553 *ppSamplerState
= new GalliumD3D11SamplerState(this, object
, *pSamplerDesc
);
557 virtual HRESULT STDMETHODCALLTYPE
CreateInputLayout(
558 const D3D11_INPUT_ELEMENT_DESC
*pInputElementDescs
,
559 unsigned NumElements
,
560 const void *pShaderBytecodeWithInputSignature
,
561 SIZE_T BytecodeLength
,
562 ID3D11InputLayout
**ppInputLayout
)
566 if(NumElements
> D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT
)
568 assert(D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT
<= PIPE_MAX_ATTRIBS
);
570 // putting semantics matching in the core API seems to be a (minor) design mistake
572 struct dxbc_chunk_signature
* sig
= dxbc_find_signature(pShaderBytecodeWithInputSignature
, BytecodeLength
, false);
573 D3D11_SIGNATURE_PARAMETER_DESC
* params
;
574 unsigned num_params
= dxbc_parse_signature(sig
, ¶ms
);
576 typedef std::unordered_map
<std::pair
<c_string
, unsigned>, unsigned> semantic_to_idx_map_t
;
577 semantic_to_idx_map_t semantic_to_idx_map
;
578 for(unsigned i
= 0; i
< NumElements
; ++i
)
579 semantic_to_idx_map
[std::make_pair(c_string(pInputElementDescs
[i
].SemanticName
), pInputElementDescs
[i
].SemanticIndex
)] = i
;
581 struct pipe_vertex_element elements
[D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT
];
583 unsigned num_params_to_use
= std::min(num_params
, (unsigned)D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT
);
584 for(unsigned i
= 0; i
< num_params_to_use
; ++i
)
587 semantic_to_idx_map_t::iterator iter
= semantic_to_idx_map
.find(std::make_pair(c_string(params
[i
].SemanticName
), params
[i
].SemanticIndex
));
588 if(iter
!= semantic_to_idx_map
.end())
591 // TODO: I kind of doubt Gallium drivers will like null elements; should we do something about it, either here, in the interface, or in the drivers?
592 // TODO: also, in which cases should we return errors? (i.e. duplicate semantics in vs, duplicate semantics in layout, unmatched semantic in vs, unmatched semantic in layout)
593 memset(&elements
[i
], 0, sizeof(elements
[i
]));
596 elements
[i
].src_format
= dxgi_to_pipe_format
[pInputElementDescs
[idx
].Format
];
597 elements
[i
].src_offset
= pInputElementDescs
[idx
].AlignedByteOffset
;
598 elements
[i
].vertex_buffer_index
= pInputElementDescs
[idx
].InputSlot
;
599 elements
[i
].instance_divisor
= pInputElementDescs
[idx
].InstanceDataStepRate
;
608 void* object
= immediate_pipe
->create_vertex_elements_state(immediate_pipe
, num_params_to_use
, elements
);
612 *ppInputLayout
= new GalliumD3D11InputLayout(this, object
);
616 static unsigned d3d11_to_pipe_bind_flags(unsigned BindFlags
)
619 if(BindFlags
& D3D11_BIND_VERTEX_BUFFER
)
620 bind
|= PIPE_BIND_VERTEX_BUFFER
;
621 if(BindFlags
& D3D11_BIND_INDEX_BUFFER
)
622 bind
|= PIPE_BIND_INDEX_BUFFER
;
623 if(BindFlags
& D3D11_BIND_CONSTANT_BUFFER
)
624 bind
|= PIPE_BIND_CONSTANT_BUFFER
;
625 if(BindFlags
& D3D11_BIND_SHADER_RESOURCE
)
626 bind
|= PIPE_BIND_SAMPLER_VIEW
;
627 if(BindFlags
& D3D11_BIND_STREAM_OUTPUT
)
628 bind
|= PIPE_BIND_STREAM_OUTPUT
;
629 if(BindFlags
& D3D11_BIND_RENDER_TARGET
)
630 bind
|= PIPE_BIND_RENDER_TARGET
;
631 if(BindFlags
& D3D11_BIND_DEPTH_STENCIL
)
632 bind
|= PIPE_BIND_DEPTH_STENCIL
;
636 inline HRESULT
create_resource(
637 pipe_texture_target target
,
644 const DXGI_SAMPLE_DESC
* SampleDesc
,
647 unsigned CPUAccessFlags
,
649 const D3D11_SUBRESOURCE_DATA
*pInitialData
,
650 DXGI_USAGE dxgi_usage
,
651 struct pipe_resource
** ppresource
654 if(invalid(Format
>= DXGI_FORMAT_COUNT
))
656 if(MiscFlags
& D3D11_RESOURCE_MISC_TEXTURECUBE
)
658 if(target
!= PIPE_TEXTURE_2D
)
660 target
= PIPE_TEXTURE_CUBE
;
672 struct pipe_resource templat
;
673 memset(&templat
, 0, sizeof(templat
));
674 templat
.target
= target
;
675 templat
.width0
= Width
;
676 templat
.height0
= Height
;
677 templat
.depth0
= Depth
;
678 templat
.last_level
= MipLevels
? (MipLevels
- 1) : 0;
679 templat
.format
= dxgi_to_pipe_format
[Format
];
680 templat
.bind
= d3d11_to_pipe_bind_flags(BindFlags
);
681 if(CPUAccessFlags
& D3D11_CPU_ACCESS_READ
)
682 templat
.bind
|= PIPE_BIND_TRANSFER_READ
;
683 if(CPUAccessFlags
& D3D11_CPU_ACCESS_WRITE
)
684 templat
.bind
|= PIPE_BIND_TRANSFER_WRITE
;
685 if(MiscFlags
& D3D11_RESOURCE_MISC_SHARED
)
686 templat
.bind
|= PIPE_BIND_SHARED
;
687 if(MiscFlags
& D3D11_RESOURCE_MISC_GDI_COMPATIBLE
)
688 templat
.bind
|= PIPE_BIND_TRANSFER_READ
| PIPE_BIND_TRANSFER_WRITE
;
689 if(dxgi_usage
& DXGI_USAGE_BACK_BUFFER
)
690 templat
.bind
|= PIPE_BIND_DISPLAY_TARGET
;
691 templat
.usage
= d3d11_to_pipe_usage
[Usage
];
692 if(invalid(!templat
.format
))
698 struct pipe_resource
* resource
= screen
->resource_create(screen
, &templat
);
703 for(unsigned slice
= 0; slice
< ArraySize
; ++slice
)
705 for(unsigned level
= 0; level
<= templat
.last_level
; ++level
)
707 struct pipe_subresource sr
;
711 box
.x
= box
.y
= box
.z
= 0;
712 box
.width
= u_minify(Width
, level
);
713 box
.height
= u_minify(Height
, level
);
714 box
.depth
= u_minify(Depth
, level
);
715 immediate_pipe
->transfer_inline_write(immediate_pipe
, resource
, sr
, PIPE_TRANSFER_WRITE
| PIPE_TRANSFER_DISCARD
| PIPE_TRANSFER_UNSYNCHRONIZED
, &box
, pInitialData
->pSysMem
, pInitialData
->SysMemPitch
, pInitialData
->SysMemSlicePitch
);
720 *ppresource
= resource
;
724 static unsigned d3d_to_dxgi_usage(unsigned bind
, unsigned misc
)
726 unsigned dxgi_usage
= 0;
727 if(bind
|= D3D11_BIND_RENDER_TARGET
)
728 dxgi_usage
|= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
729 if(bind
& D3D11_BIND_SHADER_RESOURCE
)
730 dxgi_usage
|= DXGI_USAGE_SHADER_INPUT
;
732 if(bind
& D3D11_BIND_UNORDERED_ACCESS
)
733 dxgi_usage
|= DXGI_USAGE_UNORDERED_ACCESS
;
735 if(misc
& D3D11_RESOURCE_MISC_SHARED
)
736 dxgi_usage
|= DXGI_USAGE_SHARED
;
740 virtual HRESULT STDMETHODCALLTYPE
CreateTexture1D(
741 const D3D11_TEXTURE1D_DESC
*pDesc
,
742 const D3D11_SUBRESOURCE_DATA
*pInitialData
,
743 ID3D11Texture1D
**ppTexture1D
)
747 struct pipe_resource
* resource
;
748 DXGI_USAGE dxgi_usage
= d3d_to_dxgi_usage(pDesc
->BindFlags
, pDesc
->MiscFlags
);
749 HRESULT hr
= create_resource(PIPE_TEXTURE_1D
, pDesc
->Width
, 1, 1, pDesc
->MipLevels
, pDesc
->ArraySize
, pDesc
->Format
, 0, pDesc
->Usage
, pDesc
->BindFlags
, pDesc
->CPUAccessFlags
, pDesc
->MiscFlags
, pInitialData
, dxgi_usage
, ppTexture1D
? &resource
: 0);
752 *ppTexture1D
= new GalliumD3D11Texture1D(this, resource
, *pDesc
, dxgi_usage
);
756 virtual HRESULT STDMETHODCALLTYPE
CreateTexture2D(
757 const D3D11_TEXTURE2D_DESC
*pDesc
,
758 const D3D11_SUBRESOURCE_DATA
*pInitialData
,
759 ID3D11Texture2D
**ppTexture2D
)
763 struct pipe_resource
* resource
;
764 DXGI_USAGE dxgi_usage
= d3d_to_dxgi_usage(pDesc
->BindFlags
, pDesc
->MiscFlags
);
765 HRESULT hr
= create_resource(PIPE_TEXTURE_2D
, pDesc
->Width
, pDesc
->Height
, 1, pDesc
->MipLevels
, pDesc
->ArraySize
, pDesc
->Format
, &pDesc
->SampleDesc
, pDesc
->Usage
, pDesc
->BindFlags
, pDesc
->CPUAccessFlags
, pDesc
->MiscFlags
, pInitialData
, dxgi_usage
, ppTexture2D
? &resource
: 0);
768 if(pDesc
->MipLevels
== 1 && pDesc
->ArraySize
== 1)
769 *ppTexture2D
= new GalliumD3D11Surface(this, resource
, *pDesc
, dxgi_usage
);
771 *ppTexture2D
= new GalliumD3D11Texture2D(this, resource
, *pDesc
, dxgi_usage
);
775 virtual HRESULT STDMETHODCALLTYPE
CreateTexture3D(
776 const D3D11_TEXTURE3D_DESC
*pDesc
,
777 const D3D11_SUBRESOURCE_DATA
*pInitialData
,
778 ID3D11Texture3D
**ppTexture3D
)
782 struct pipe_resource
* resource
;
783 DXGI_USAGE dxgi_usage
= d3d_to_dxgi_usage(pDesc
->BindFlags
, pDesc
->MiscFlags
);
784 HRESULT hr
= create_resource(PIPE_TEXTURE_3D
, pDesc
->Width
, pDesc
->Height
, pDesc
->Depth
, pDesc
->MipLevels
, 1, pDesc
->Format
, 0, pDesc
->Usage
, pDesc
->BindFlags
, pDesc
->CPUAccessFlags
, pDesc
->MiscFlags
, pInitialData
, dxgi_usage
, ppTexture3D
? &resource
: 0);
787 *ppTexture3D
= new GalliumD3D11Texture3D(this, resource
, *pDesc
, dxgi_usage
);
791 virtual HRESULT STDMETHODCALLTYPE
CreateBuffer(
792 const D3D11_BUFFER_DESC
*pDesc
,
793 const D3D11_SUBRESOURCE_DATA
*pInitialData
,
794 ID3D11Buffer
**ppBuffer
)
799 if(pDesc
->StructureByteStride
> 1)
802 struct pipe_resource
* resource
;
803 DXGI_USAGE dxgi_usage
= d3d_to_dxgi_usage(pDesc
->BindFlags
, pDesc
->MiscFlags
);
804 HRESULT hr
= create_resource(PIPE_BUFFER
, pDesc
->ByteWidth
, 1, 1, 1, 1, DXGI_FORMAT_R8_UNORM
, 0, pDesc
->Usage
, pDesc
->BindFlags
, pDesc
->CPUAccessFlags
, pDesc
->MiscFlags
, pInitialData
, dxgi_usage
, ppBuffer
? &resource
: 0);
807 *ppBuffer
= new GalliumD3D11Buffer(this, resource
, *pDesc
, dxgi_usage
);
811 virtual HRESULT STDMETHODCALLTYPE
OpenGalliumResource(
812 struct pipe_resource
* resource
,
813 IUnknown
** dxgi_resource
)
817 /* TODO: maybe support others */
818 assert(resource
->target
== PIPE_TEXTURE_2D
);
820 D3D11_TEXTURE2D_DESC desc
;
821 memset(&desc
, 0, sizeof(desc
));
822 desc
.Width
= resource
->width0
;
823 desc
.Height
= resource
->height0
;
824 init_pipe_to_dxgi_format();
825 desc
.Format
= pipe_to_dxgi_format
[resource
->format
];
826 desc
.SampleDesc
.Count
= resource
->nr_samples
;
827 desc
.SampleDesc
.Quality
= 0;
829 desc
.MipLevels
= resource
->last_level
+ 1;
830 desc
.CPUAccessFlags
= D3D11_CPU_ACCESS_READ
| D3D11_CPU_ACCESS_WRITE
;
831 if(resource
->bind
& PIPE_BIND_RENDER_TARGET
)
832 desc
.BindFlags
|= D3D11_BIND_RENDER_TARGET
;
833 if(resource
->bind
& PIPE_BIND_DEPTH_STENCIL
)
834 desc
.BindFlags
|= D3D11_BIND_DEPTH_STENCIL
;
835 if(resource
->bind
& PIPE_BIND_SAMPLER_VIEW
)
836 desc
.BindFlags
|= D3D11_BIND_SHADER_RESOURCE
;
837 if(resource
->bind
& PIPE_BIND_SHARED
)
838 desc
.MiscFlags
|= D3D11_RESOURCE_MISC_SHARED
;
839 DXGI_USAGE dxgi_usage
= d3d_to_dxgi_usage(desc
.BindFlags
, desc
.MiscFlags
);
840 if(desc
.MipLevels
== 1 && desc
.ArraySize
== 1)
841 *dxgi_resource
= (ID3D11Texture2D
*)new GalliumD3D11Surface(this, resource
, desc
, dxgi_usage
);
843 *dxgi_resource
= (ID3D11Texture2D
*)new GalliumD3D11Texture2D(this, resource
, desc
, dxgi_usage
);
847 virtual HRESULT STDMETHODCALLTYPE
CreateSurface(
848 const DXGI_SURFACE_DESC
*pDesc
,
849 unsigned NumSurfaces
,
851 const DXGI_SHARED_RESOURCE
*pSharedResource
,
852 IDXGISurface
**ppSurface
)
856 D3D11_TEXTURE2D_DESC desc
;
857 memset(&desc
, 0, sizeof(desc
));
859 struct pipe_resource
* resource
;
860 desc
.Width
= pDesc
->Width
;
861 desc
.Height
= pDesc
->Height
;
862 desc
.Format
= pDesc
->Format
;
863 desc
.SampleDesc
= pDesc
->SampleDesc
;
864 desc
.ArraySize
= NumSurfaces
;
866 desc
.CPUAccessFlags
= D3D11_CPU_ACCESS_READ
| D3D11_CPU_ACCESS_WRITE
;
867 if(Usage
& DXGI_USAGE_RENDER_TARGET_OUTPUT
)
868 desc
.BindFlags
|= D3D11_BIND_RENDER_TARGET
;
869 if(Usage
& DXGI_USAGE_SHADER_INPUT
)
870 desc
.BindFlags
|= D3D11_BIND_SHADER_RESOURCE
;
872 if(Usage
& DXGI_USAGE_UNORDERED_ACCESS
)
873 desc
.BindFlags
|= D3D11_BIND_UNORDERED_ACCESS
;
875 if(Usage
& DXGI_USAGE_SHARED
)
876 desc
.MiscFlags
|= D3D11_RESOURCE_MISC_SHARED
;
877 HRESULT hr
= create_resource(PIPE_TEXTURE_2D
, pDesc
->Width
, pDesc
->Height
, 1, 1, NumSurfaces
, pDesc
->Format
, &pDesc
->SampleDesc
, D3D11_USAGE_DEFAULT
, desc
.BindFlags
, D3D11_CPU_ACCESS_READ
| D3D11_CPU_ACCESS_WRITE
, desc
.MiscFlags
, 0, Usage
, &resource
);
880 *ppSurface
= new GalliumD3D11Surface(this, resource
, desc
, Usage
);
884 virtual HRESULT STDMETHODCALLTYPE
CreateShaderResourceView(
885 ID3D11Resource
*pResource
,
886 const D3D11_SHADER_RESOURCE_VIEW_DESC
*pDesc
,
887 ID3D11ShaderResourceView
**ppSRView
)
890 D3D11_SHADER_RESOURCE_VIEW_DESC def_desc
;
892 if(pDesc
->ViewDimension
== D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY
)
894 D3D10_SHADER_RESOURCE_VIEW_DESC1 desc1
;
895 memset(&desc1
, 0, sizeof(desc1
));
896 memcpy(&desc1
, pDesc
, sizeof(*pDesc
));
897 return CreateShaderResourceView1(pResource
, &desc1
, (ID3D10ShaderResourceView1
**)ppSRView
);
900 virtual HRESULT STDMETHODCALLTYPE
CreateShaderResourceView1(
901 ID3D11Resource
*pResource
,
902 const D3D10_SHADER_RESOURCE_VIEW_DESC1
*pDesc
,
903 ID3D10ShaderResourceView1
**ppSRView
)
905 D3D10_SHADER_RESOURCE_VIEW_DESC1 def_desc
;
911 struct pipe_resource
* resource
= ((GalliumD3D11Resource
<>*)pResource
)->resource
;
912 init_pipe_to_dxgi_format();
913 memset(&def_desc
, 0, sizeof(def_desc
));
914 def_desc
.Format
= pipe_to_dxgi_format
[resource
->format
];
915 switch(resource
->target
)
918 def_desc
.ViewDimension
= D3D11_SRV_DIMENSION_BUFFER
;
919 def_desc
.Buffer
.ElementWidth
= 1;
921 def_desc
.Buffer
.NumElements
= resource
->width0
;
924 case PIPE_TEXTURE_1D
:
925 def_desc
.ViewDimension
= D3D11_SRV_DIMENSION_TEXTURE1D
;
926 def_desc
.Texture1D
.MipLevels
= resource
->last_level
+ 1;
928 case PIPE_TEXTURE_2D
:
929 case PIPE_TEXTURE_RECT
:
930 def_desc
.ViewDimension
= D3D11_SRV_DIMENSION_TEXTURE2D
;
931 def_desc
.Texture2D
.MipLevels
= resource
->last_level
+ 1;
933 case PIPE_TEXTURE_3D
:
934 def_desc
.ViewDimension
= D3D11_SRV_DIMENSION_TEXTURE3D
;
935 def_desc
.Texture3D
.MipLevels
= resource
->last_level
+ 1;
937 case PIPE_TEXTURE_CUBE
:
938 def_desc
.ViewDimension
= D3D11_SRV_DIMENSION_TEXTURECUBE
;
939 def_desc
.TextureCube
.MipLevels
= resource
->last_level
+ 1;
947 struct pipe_sampler_view templat
;
948 memset(&templat
, 0, sizeof(templat
));
949 if(invalid(Format
>= DXGI_FORMAT_COUNT
))
951 templat
.format
= dxgi_to_pipe_format
[pDesc
->Format
];
954 templat
.swizzle_r
= PIPE_SWIZZLE_RED
;
955 templat
.swizzle_g
= PIPE_SWIZZLE_GREEN
;
956 templat
.swizzle_b
= PIPE_SWIZZLE_BLUE
;
957 templat
.swizzle_a
= PIPE_SWIZZLE_ALPHA
;
959 templat
.texture
= ((GalliumD3D11Resource
<>*)pResource
)->resource
;
960 switch(pDesc
->ViewDimension
)
962 case D3D11_SRV_DIMENSION_TEXTURE1D
:
963 case D3D11_SRV_DIMENSION_TEXTURE2D
:
964 case D3D11_SRV_DIMENSION_TEXTURE3D
:
965 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY
:
966 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY
:
967 /* yes, this works for all of these types (but TODO: texture arrays) */
968 templat
.first_level
= pDesc
->Texture1D
.MostDetailedMip
;
969 templat
.last_level
= templat
.first_level
+ pDesc
->Texture1D
.MipLevels
- 1;
971 case D3D11_SRV_DIMENSION_BUFFER
:
972 case D3D11_SRV_DIMENSION_TEXTURE2DMS
:
973 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY
:
982 struct pipe_sampler_view
* view
= immediate_pipe
->create_sampler_view(immediate_pipe
, templat
.texture
, &templat
);
985 *ppSRView
= new GalliumD3D11ShaderResourceView(this, (GalliumD3D11Resource
<>*)pResource
, view
, *pDesc
);
990 virtual HRESULT STDMETHODCALLTYPE
CreateUnorderedAccessView(
991 ID3D11Resource
*pResource
,
992 const D3D11_UNORDERED_ACCESS_VIEW_DESC
*pDesc
,
993 ID3D11UnorderedAccessView
**ppUAView
)
999 // remember to return S_FALSE and not crash if ppUAView == 0 and parameters are valid
1003 virtual HRESULT STDMETHODCALLTYPE
CreateRenderTargetView(
1004 ID3D11Resource
*pResource
,
1005 const D3D11_RENDER_TARGET_VIEW_DESC
*pDesc
,
1006 ID3D11RenderTargetView
**ppRTView
)
1010 D3D11_RENDER_TARGET_VIEW_DESC def_desc
;
1013 struct pipe_resource
* resource
= ((GalliumD3D11Resource
<>*)pResource
)->resource
;
1014 init_pipe_to_dxgi_format();
1015 memset(&def_desc
, 0, sizeof(def_desc
));
1016 def_desc
.Format
= pipe_to_dxgi_format
[resource
->format
];
1017 switch(resource
->target
)
1020 def_desc
.ViewDimension
= D3D11_RTV_DIMENSION_BUFFER
;
1021 def_desc
.Buffer
.ElementWidth
= 1;
1023 def_desc
.Buffer
.NumElements
= resource
->width0
;
1026 case PIPE_TEXTURE_1D
:
1027 def_desc
.ViewDimension
= D3D11_RTV_DIMENSION_TEXTURE1D
;
1029 case PIPE_TEXTURE_2D
:
1030 case PIPE_TEXTURE_RECT
:
1031 def_desc
.ViewDimension
= D3D11_RTV_DIMENSION_TEXTURE2D
;
1033 case PIPE_TEXTURE_3D
:
1034 def_desc
.ViewDimension
= D3D11_RTV_DIMENSION_TEXTURE3D
;
1035 def_desc
.Texture3D
.WSize
= resource
->depth0
;
1037 case PIPE_TEXTURE_CUBE
:
1038 def_desc
.ViewDimension
= D3D11_RTV_DIMENSION_TEXTURE2DARRAY
;
1039 def_desc
.Texture2DArray
.ArraySize
= 6;
1042 return E_INVALIDARG
;
1047 unsigned zslice
= 0;
1050 enum pipe_format format
;
1051 if(invalid(pDesc
->Format
>= DXGI_FORMAT_COUNT
))
1052 return E_INVALIDARG
;
1053 format
= dxgi_to_pipe_format
[pDesc
->Format
];
1057 switch(pDesc
->ViewDimension
)
1059 case D3D11_RTV_DIMENSION_TEXTURE1D
:
1060 case D3D11_RTV_DIMENSION_TEXTURE2D
:
1061 level
= pDesc
->Texture1D
.MipSlice
;
1063 case D3D11_RTV_DIMENSION_TEXTURE3D
:
1064 level
= pDesc
->Texture3D
.MipSlice
;
1065 zslice
= pDesc
->Texture3D
.FirstWSlice
;
1067 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY
:
1068 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY
:
1069 level
= pDesc
->Texture1DArray
.MipSlice
;
1070 face
= pDesc
->Texture1DArray
.FirstArraySlice
;
1072 case D3D11_RTV_DIMENSION_BUFFER
:
1073 case D3D11_RTV_DIMENSION_TEXTURE2DMS
:
1074 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY
:
1077 return E_INVALIDARG
;
1083 struct pipe_surface
* surface
= screen
->get_tex_surface(screen
,
1084 ((GalliumD3D11Resource
<>*)pResource
)->resource
,
1085 face
, level
, zslice
, PIPE_BIND_RENDER_TARGET
);
1088 /* muhahahahaha, let's hope this actually works */
1089 surface
->format
= format
;
1090 *ppRTView
= new GalliumD3D11RenderTargetView(this, (GalliumD3D11Resource
<>*)pResource
, surface
, *pDesc
);
1094 virtual HRESULT STDMETHODCALLTYPE
CreateDepthStencilView(
1095 ID3D11Resource
*pResource
,
1096 const D3D11_DEPTH_STENCIL_VIEW_DESC
*pDesc
,
1097 ID3D11DepthStencilView
**ppDepthStencilView
)
1101 D3D11_DEPTH_STENCIL_VIEW_DESC def_desc
;
1104 struct pipe_resource
* resource
= ((GalliumD3D11Resource
<>*)pResource
)->resource
;
1105 init_pipe_to_dxgi_format();
1106 memset(&def_desc
, 0, sizeof(def_desc
));
1107 def_desc
.Format
= pipe_to_dxgi_format
[resource
->format
];
1108 switch(resource
->target
)
1110 case PIPE_TEXTURE_1D
:
1111 def_desc
.ViewDimension
= D3D11_DSV_DIMENSION_TEXTURE1D
;
1113 case PIPE_TEXTURE_2D
:
1114 case PIPE_TEXTURE_RECT
:
1115 def_desc
.ViewDimension
= D3D11_DSV_DIMENSION_TEXTURE2D
;
1117 case PIPE_TEXTURE_CUBE
:
1118 def_desc
.ViewDimension
= D3D11_DSV_DIMENSION_TEXTURE2DARRAY
;
1119 def_desc
.Texture2DArray
.ArraySize
= 6;
1122 return E_INVALIDARG
;
1127 unsigned zslice
= 0;
1130 enum pipe_format format
;
1131 if(invalid(pDesc
->Format
>= DXGI_FORMAT_COUNT
))
1132 return E_INVALIDARG
;
1133 format
= dxgi_to_pipe_format
[pDesc
->Format
];
1137 switch(pDesc
->ViewDimension
)
1139 case D3D11_DSV_DIMENSION_TEXTURE1D
:
1140 case D3D11_DSV_DIMENSION_TEXTURE2D
:
1141 level
= pDesc
->Texture1D
.MipSlice
;
1143 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY
:
1144 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY
:
1145 level
= pDesc
->Texture1DArray
.MipSlice
;
1146 face
= pDesc
->Texture1DArray
.FirstArraySlice
;
1148 case D3D11_DSV_DIMENSION_TEXTURE2DMS
:
1149 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY
:
1152 return E_INVALIDARG
;
1155 if(!ppDepthStencilView
)
1158 struct pipe_surface
* surface
= screen
->get_tex_surface(screen
,
1159 ((GalliumD3D11Resource
<>*)pResource
)->resource
,
1160 face
, level
, zslice
, PIPE_BIND_DEPTH_STENCIL
);
1163 /* muhahahahaha, let's hope this actually works */
1164 surface
->format
= format
;
1165 *ppDepthStencilView
= new GalliumD3D11DepthStencilView(this, (GalliumD3D11Resource
<>*)pResource
, surface
, *pDesc
);
1169 GalliumD3D11Shader
<>* create_stage_shader(unsigned type
, const void *pShaderBytecode
, SIZE_T BytecodeLength
1171 , ID3D11ClassLinkage
*pClassLinkage
1175 dxbc_chunk_header
* sm4_chunk
= dxbc_find_shader_bytecode(pShaderBytecode
, BytecodeLength
);
1179 std::auto_ptr
<sm4_program
> sm4(sm4_parse(sm4_chunk
+ 1, bswap_le32(sm4_chunk
->size
)));
1183 struct pipe_shader_state tgsi_shader
;
1184 memset(&tgsi_shader
, 0, sizeof(tgsi_shader
));
1185 tgsi_shader
.tokens
= (const tgsi_token
*)sm4_to_tgsi(*sm4
);
1186 if(!tgsi_shader
.tokens
)
1190 GalliumD3D11Shader
<>* shader
;
1194 case PIPE_SHADER_VERTEX
:
1195 shader_cso
= immediate_pipe
->create_vs_state(immediate_pipe
, &tgsi_shader
);
1196 shader
= (GalliumD3D11Shader
<>*)new GalliumD3D11VertexShader(this, shader_cso
);
1198 case PIPE_SHADER_FRAGMENT
:
1199 shader_cso
= immediate_pipe
->create_fs_state(immediate_pipe
, &tgsi_shader
);
1200 shader
= (GalliumD3D11Shader
<>*)new GalliumD3D11PixelShader(this, shader_cso
);
1202 case PIPE_SHADER_GEOMETRY
:
1203 shader_cso
= immediate_pipe
->create_gs_state(immediate_pipe
, &tgsi_shader
);
1204 shader
= (GalliumD3D11Shader
<>*)new GalliumD3D11GeometryShader(this, shader_cso
);
1214 shader
->slot_to_resource
= sm4
->slot_to_resource
;
1215 shader
->slot_to_sampler
= sm4
->slot_to_sampler
;
1218 free((void*)tgsi_shader
.tokens
);
1223 #define CREATE_SHADER_ARGS \
1224 const void *pShaderBytecode, \
1225 SIZE_T BytecodeLength, \
1226 ID3D11ClassLinkage *pClassLinkage
1227 #define PASS_SHADER_ARGS pShaderBytecode, BytecodeLength, pClassLinkage
1229 #define CREATE_SHADER_ARGS \
1230 const void *pShaderBytecode, \
1231 SIZE_T BytecodeLength
1232 #define PASS_SHADER_ARGS pShaderBytecode, BytecodeLength
1235 #define IMPLEMENT_CREATE_SHADER(Stage, GALLIUM) \
1236 virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \
1237 CREATE_SHADER_ARGS, \
1238 ID3D11##Stage##Shader **pp##Stage##Shader) \
1241 GalliumD3D11##Stage##Shader* shader = (GalliumD3D11##Stage##Shader*)create_stage_shader(PIPE_SHADER_##GALLIUM, PASS_SHADER_ARGS); \
1244 if(pp##Stage##Shader) \
1246 *pp##Stage##Shader = shader; \
1251 shader->Release(); \
1256 #define IMPLEMENT_NOTIMPL_CREATE_SHADER(Stage) \
1257 virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \
1258 CREATE_SHADER_ARGS, \
1259 ID3D11##Stage##Shader **pp##Stage##Shader) \
1264 IMPLEMENT_CREATE_SHADER(Vertex
, VERTEX
)
1265 IMPLEMENT_CREATE_SHADER(Pixel
, FRAGMENT
)
1266 IMPLEMENT_CREATE_SHADER(Geometry
, GEOMETRY
)
1268 IMPLEMENT_NOTIMPL_CREATE_SHADER(Hull
)
1269 IMPLEMENT_NOTIMPL_CREATE_SHADER(Domain
)
1270 IMPLEMENT_NOTIMPL_CREATE_SHADER(Compute
)
1273 virtual HRESULT STDMETHODCALLTYPE
CreateGeometryShaderWithStreamOutput(
1274 const void *pShaderBytecode
,
1275 SIZE_T BytecodeLength
,
1276 const D3D11_SO_DECLARATION_ENTRY
*pSODeclaration
,
1277 unsigned NumEntries
,
1279 const unsigned *pBufferStrides
,
1280 unsigned NumStrides
,
1281 unsigned RasterizedStream
,
1282 ID3D11ClassLinkage
*pClassLinkage
,
1284 UINT OutputStreamStride
,
1286 ID3D11GeometryShader
**ppGeometryShader
)
1290 if(!ppGeometryShader
)
1295 // remember to return S_FALSE if ppGeometyShader == NULL and the shader is OK
1299 virtual HRESULT STDMETHODCALLTYPE
CreateClassLinkage(
1300 ID3D11ClassLinkage
**ppLinkage
)
1311 virtual HRESULT STDMETHODCALLTYPE
CreateQuery(
1312 const D3D11_QUERY_DESC
*pQueryDesc
,
1313 ID3D11Query
**ppQuery
)
1317 if(invalid(pQueryDesc
->Query
>= D3D11_QUERY_COUNT
))
1318 return E_INVALIDARG
;
1319 unsigned query_type
= d3d11_to_pipe_query
[pQueryDesc
->Query
];
1326 struct pipe_query
* query
= immediate_pipe
->create_query(immediate_pipe
, query_type
);
1330 *ppQuery
= new GalliumD3D11Query(this, query
, d3d11_query_size
[pQueryDesc
->Query
], *pQueryDesc
);
1334 virtual HRESULT STDMETHODCALLTYPE
CreatePredicate(
1335 const D3D11_QUERY_DESC
*pPredicateDesc
,
1336 ID3D11Predicate
**ppPredicate
)
1340 unsigned query_type
;
1341 switch(pPredicateDesc
->Query
)
1343 case D3D11_QUERY_SO_OVERFLOW_PREDICATE
:
1345 case D3D11_QUERY_OCCLUSION_PREDICATE
:
1346 query_type
= PIPE_QUERY_OCCLUSION_COUNTER
;
1349 return E_INVALIDARG
;
1355 struct pipe_query
* query
= immediate_pipe
->create_query(immediate_pipe
, query_type
);
1359 *ppPredicate
= new GalliumD3D11Predicate(this, query
, sizeof(BOOL
), *pPredicateDesc
);
1364 virtual HRESULT STDMETHODCALLTYPE
CreateCounter(
1365 const D3D11_COUNTER_DESC
*pCounterDesc
,
1366 ID3D11Counter
**ppCounter
)
1372 // remember to return S_FALSE if ppCounter == NULL and everything is OK
1376 virtual HRESULT STDMETHODCALLTYPE
CreateDeferredContext(
1377 unsigned ContextFlags
,
1378 ID3D11DeviceContext
**ppDeferredContext
)
1382 // TODO: this will have to be implemented using a new Gallium util module
1385 // remember to return S_FALSE if ppCounter == NULL and everything is OK
1389 virtual HRESULT STDMETHODCALLTYPE
OpenSharedResource(
1391 REFIID ReturnedInterface
,
1396 // TODO: the problem here is that we need to communicate dimensions somehow
1399 // remember to return S_FALSE if ppCounter == NULL and everything is OK
1401 struct pipe_resou rce templat
;
1402 struct winsys_handle handle
;
1404 handle
.handle
= hResource
;
1405 handle
.type
= DRM_API_HANDLE_TYPE_SHARED
;
1406 screen
->resource_from_handle(screen
, &templat
, &handle
);
1411 /* these are documented as "Not implemented".
1412 * According to the UMDDI documentation, they apparently turn on a
1413 * (Width + 1) x (Height + 1) convolution filter for 1-bit textures.
1414 * Probably nothing uses these, assuming it has ever been implemented anywhere.
1416 void STDMETHODCALLTYPE
SetTextFilterSize(
1422 virtual void STDMETHODCALLTYPE
GetTextFilterSize(
1430 virtual void STDMETHODCALLTYPE
RestoreGalliumState()
1432 GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(immediate_context
);
1435 virtual void STDMETHODCALLTYPE
RestoreGalliumStateBlitOnly()
1437 GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(immediate_context
);
1441 virtual struct pipe_context
* STDMETHODCALLTYPE
GetGalliumContext(void)
1443 return immediate_pipe
;