d3d11_screen.h revision d2cc8aedb5d544608842b58b6ae4754313ded939
168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer/************************************************************************** 268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * 368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * Copyright 2010 Luca Barbieri 468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * 568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * Permission is hereby granted, free of charge, to any person obtaining 668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * a copy of this software and associated documentation files (the 768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * "Software"), to deal in the Software without restriction, including 868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * without limitation the rights to use, copy, modify, merge, publish, 968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * distribute, sublicense, and/or sell copies of the Software, and to 1068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * permit persons to whom the Software is furnished to do so, subject to 1168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * the following conditions: 1268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * 1368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * The above copyright notice and this permission notice (including the 1468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * next paragraph) shall be included in all copies or substantial 1568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * portions of the Software. 1668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * 17001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1888af6b9217f9ff8b4592f38ac5175de697275f49Michael J. Spencer * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 191f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 2025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 227acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * 2568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer **************************************************************************/ 2668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 2768b3f0c40e29e461dbbc85370078692df4336b42Michael J. SpencerDEBUG_GET_ONCE_BOOL_OPTION(dump_shaders, "D3D1X_DUMP_SHADERS", FALSE); 287acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer 297acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer/* These cap sets are much more correct than the ones in u_caps.c */ 307acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer/* TODO: it seems cube levels should be the same as 2D levels */ 317acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer 327acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer/* DX 9_1 */ 3325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerstatic unsigned caps_dx_9_1[] = { 347acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), 357acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ 367acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 8), /* 256 */ 377acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ 387acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer UTIL_CHECK_TERMINATE 397acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer}; 407acdb4d237181976b04e72f6a6c329c3b2604440Michael J. Spencer 4168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer/* DX 9_2 */ 4225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerstatic unsigned caps_dx_9_2[] = { 4325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(OCCLUSION_QUERY), 4425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(TWO_SIDED_STENCIL), 4525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(TEXTURE_MIRROR_CLAMP), 4625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), 47dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), 48dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ 49dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ 50dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ 5125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_TERMINATE 5225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer}; 5325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 5425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer/* DX 9_3 */ 5525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencerstatic unsigned caps_dx_9_3[] = { 5625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(OCCLUSION_QUERY), 5725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(TWO_SIDED_STENCIL), 5868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(TEXTURE_MIRROR_CLAMP), 5968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), 6068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(SM3), 6107ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer UTIL_CHECK_CAP(VERTEX_ELEMENT_INSTANCE_DIVISOR), 6268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(OCCLUSION_QUERY), 6368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_INT(MAX_RENDER_TARGETS, 4), 6468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), /* 4096 */ 6568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ 66dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ 67dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer UTIL_CHECK_TERMINATE 68dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer}; 69dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer 7068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencerstatic unsigned caps_dx_10_0[] = { 7168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(INDEP_BLEND_ENABLE), 7268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(ANISOTROPIC_FILTER), 7368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(MIXED_COLORBUFFER_FORMATS), 7425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(FRAGMENT_COLOR_CLAMP_CONTROL), 7568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_CAP(STREAM_OUTPUT), 7625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(CONDITIONAL_RENDER), 7725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(PRIMITIVE_RESTART), 7825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_CAP(TGSI_INSTANCEID), 7968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), 8068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), 8168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_INT(MAX_TEXTURE_ARRAY_LAYERS, 512), 8225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16), 8368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_SHADER(GEOMETRY, MAX_CONST_BUFFERS, 14), 8468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_SHADER(GEOMETRY, MAX_TEXTURE_SAMPLERS, 16), 8568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_SHADER(GEOMETRY, SUBROUTINES, 1), 8625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer UTIL_CHECK_SHADER(FRAGMENT, INTEGERS, 1), 8768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer UTIL_CHECK_TERMINATE 8868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer}; 8968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 9068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 9168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer// this is called "screen" because in the D3D10 case it's only part of the device 9207ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramertemplate<bool threadsafe> 9368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencerstruct GalliumD3D11ScreenImpl : public GalliumD3D11Screen 9468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer{ 9568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer D3D_FEATURE_LEVEL feature_level; 9668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer int format_support[PIPE_FORMAT_COUNT]; 97dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer unsigned creation_flags; 98dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer unsigned exception_mode; 99dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer maybe_mutex_t<threadsafe> mutex; 100dedd6ee135f886e219035b2cf5957ce492f90ed1Michael J. Spencer 10168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer/* TODO: Direct3D 11 specifies that fine-grained locking should be used if the driver supports it. 10268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer * Right now, I don't trust Gallium drivers to get this right. 10368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer */ 10468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#define SYNCHRONIZED lock_t<maybe_mutex_t<threadsafe> > lock_(mutex) 10525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 10668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer GalliumD3D11ScreenImpl(struct pipe_screen* screen, struct pipe_context* immediate_pipe, BOOL owns_immediate_pipe,unsigned creation_flags, IDXGIAdapter* adapter) 10725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer : GalliumD3D11Screen(screen, immediate_pipe, adapter), creation_flags(creation_flags) 10825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer { 10925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer memset(&screen_caps, 0, sizeof(screen_caps)); 11025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer screen_caps.gs = screen->get_shader_param(screen, PIPE_SHADER_GEOMETRY, PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 11168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer screen_caps.so = !!screen->get_param(screen, PIPE_CAP_STREAM_OUTPUT); 11268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer screen_caps.queries = screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY); 11325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer screen_caps.render_condition = screen->get_param(screen, PIPE_CAP_CONDITIONAL_RENDER); 11407ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer for(unsigned i = 0; i < PIPE_SHADER_TYPES; ++i) 11507ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer screen_caps.constant_buffers[i] = screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_CONST_BUFFERS); 11668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer screen_caps.stages = 0; 11768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer for(unsigned i = 0; i < PIPE_SHADER_TYPES; ++i) 11868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 11968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer if(!screen->get_shader_param(screen, i, PIPE_SHADER_CAP_MAX_INSTRUCTIONS)) 12068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer break; 12168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer screen_caps.stages = i + 1; 12268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 123001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer 12468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer screen_caps.stages_with_sampling = (1 << screen_caps.stages) - 1; 12568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer if(!screen->get_shader_param(screen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS)) 12668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer screen_caps.stages_with_sampling &=~ (1 << PIPE_SHADER_VERTEX); 12768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 12868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer memset(format_support, 0xff, sizeof(format_support)); 129001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer 13068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer float default_level = 9.1f; 131001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer if(!util_check_caps(screen, caps_dx_9_1)) 132001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer _debug_printf("Warning: driver does not even meet D3D_FEATURE_LEVEL_9_1 features, advertising it anyway!\n"); 133001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer else if(!util_check_caps(screen, caps_dx_9_2)) 13468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer default_level = 9.1f; 13568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer else if(!util_check_caps(screen, caps_dx_9_3)) 13668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer default_level = 9.2f; 13768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer else if(!util_check_caps(screen, caps_dx_10_0)) 13868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer default_level = 9.3f; 13968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer else 14025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer default_level = 10.0f; 14125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 14225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer char default_level_name[64]; 14368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer sprintf(default_level_name, "%.1f", default_level); 14425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer float feature_level_number = atof(debug_get_option("D3D11_FEATURE_LEVEL", default_level_name)); 14525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if(!feature_level_number) 14625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer feature_level_number = default_level; 14725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 14825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer#if API >= 11 14925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if(feature_level_number >= 11.0f) 15068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer feature_level = D3D_FEATURE_LEVEL_11_0; 15168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer else 15268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#endif 15325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if(feature_level_number >= 10.1f) 15425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer feature_level = D3D_FEATURE_LEVEL_10_1; 15525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if(feature_level_number >= 10.0f) 15625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer feature_level = D3D_FEATURE_LEVEL_10_0; 15725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer else if(feature_level_number >= 9.3f) 15825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer feature_level = D3D_FEATURE_LEVEL_9_3; 15907ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer else if(feature_level_number >= 9.2f) 16007ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer feature_level = D3D_FEATURE_LEVEL_9_2; 16168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer else 16268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer feature_level = D3D_FEATURE_LEVEL_9_1; 16368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 16468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#if API >= 11 16568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer immediate_context = GalliumD3D11ImmediateDeviceContext_Create(this, immediate_pipe, owns_immediate_pipe); 16668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer // release to the reference to ourselves that the immediate context took, to avoid a garbage cycle 16768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer immediate_context->Release(); 16868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#endif 16968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 17068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 17168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer ~GalliumD3D11ScreenImpl() 17268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 17368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#if API >= 11 17468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer GalliumD3D11ImmediateDeviceContext_Destroy(immediate_context); 17568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#endif 17668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 17768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 17868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE GetFeatureLevel(void) 17968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 18068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return feature_level; 18168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 18268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 18325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer virtual unsigned STDMETHODCALLTYPE GetCreationFlags(void) 18425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer { 18525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return creation_flags; 18625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 18725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 18825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason(void) 18968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 19068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return S_OK; 19168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 19268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 19368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#if API >= 11 19468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer virtual void STDMETHODCALLTYPE GetImmediateContext( 19568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer ID3D11DeviceContext **out_immediate_context) 19668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 19768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer immediate_context->AddRef(); 19868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer *out_immediate_context = immediate_context; 19968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 20068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#endif 20168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 20268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer virtual HRESULT STDMETHODCALLTYPE SetExceptionMode(unsigned RaiseFlags) 20368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 20468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer exception_mode = RaiseFlags; 20568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return S_OK; 20668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 20788af6b9217f9ff8b4592f38ac5175de697275f49Michael J. Spencer 20868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer virtual unsigned STDMETHODCALLTYPE GetExceptionMode(void) 20968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 21068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return exception_mode; 21168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 21268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 21388af6b9217f9ff8b4592f38ac5175de697275f49Michael J. Spencer virtual HRESULT STDMETHODCALLTYPE CheckCounter( 21468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer const D3D11_COUNTER_DESC *desc, 21568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer D3D11_COUNTER_TYPE *type, 216001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer unsigned *active_counters, 217001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer LPSTR sz_name, 218001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer unsigned *name_length, 219001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer LPSTR sz_units, 220001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer unsigned *units_length, 221001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer LPSTR sz_description, 222001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer unsigned *description_length) 22368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 22468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return E_NOTIMPL; 22568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 22668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 22768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer virtual void STDMETHODCALLTYPE CheckCounterInfo( 22868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer D3D11_COUNTER_INFO *counter_info) 22968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 23068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer /* none supported at the moment */ 23168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer counter_info->LastDeviceDependentCounter = (D3D11_COUNTER)0; 23268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer counter_info->NumDetectableParallelUnits = 1; 23368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer counter_info->NumSimultaneousCounters = 0; 23468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 23568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 23668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer#if API >= 11 23725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport( 23825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer D3D11_FEATURE feature, 23968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer void *out_feature_support_data, 24068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer unsigned feature_support_data_size) 24125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer { 24225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer SYNCHRONIZED; 24368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 24468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer switch(feature) 24525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer { 24625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer case D3D11_FEATURE_THREADING: 24768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 24868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer D3D11_FEATURE_DATA_THREADING* data = (D3D11_FEATURE_DATA_THREADING*)out_feature_support_data; 24925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if(feature_support_data_size != sizeof(*data)) 25025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return E_INVALIDARG; 25168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 25268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer data->DriverCommandLists = FALSE; 25325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer data->DriverConcurrentCreates = FALSE; 25425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return S_OK; 25568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 25668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer case D3D11_FEATURE_DOUBLES: 25725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer { 25825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer D3D11_FEATURE_DATA_DOUBLES* data = (D3D11_FEATURE_DATA_DOUBLES*)out_feature_support_data; 25968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer if(feature_support_data_size != sizeof(*data)) 26068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return E_INVALIDARG; 26168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 26268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer data->DoublePrecisionFloatShaderOps = FALSE; 26368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return S_OK; 26468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 26568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer case D3D11_FEATURE_FORMAT_SUPPORT: 26668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 26768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer D3D11_FEATURE_DATA_FORMAT_SUPPORT* data = (D3D11_FEATURE_DATA_FORMAT_SUPPORT*)out_feature_support_data; 26868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer if(feature_support_data_size != sizeof(*data)) 26968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return E_INVALIDARG; 27068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 27168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return this->CheckFormatSupport(data->InFormat, &data->OutFormatSupport); 27225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 27325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer case D3D11_FEATURE_FORMAT_SUPPORT2: 27468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 27568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer D3D11_FEATURE_DATA_FORMAT_SUPPORT* data = (D3D11_FEATURE_DATA_FORMAT_SUPPORT*)out_feature_support_data; 27625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if(feature_support_data_size != sizeof(*data)) 27725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return E_INVALIDARG; 27868b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 27968b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer data->OutFormatSupport = 0; 28025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer /* TODO: should this be S_OK? */ 28125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return E_INVALIDARG; 28268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 28368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS: 28425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer { 28525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS* data = (D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS*)out_feature_support_data; 28668b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer if(feature_support_data_size != sizeof(*data)) 28768b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return E_INVALIDARG; 28825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 28925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer data->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = FALSE; 29068b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer return S_OK; 29168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 29225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer default: 29325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return E_INVALIDARG; 29468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 29568b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer } 29607ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer#endif 29707ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer 29807ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer virtual HRESULT STDMETHODCALLTYPE CheckFormatSupport( 29907ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer DXGI_FORMAT dxgi_format, 30007ea23aa2d17f701fa125442c20c1eba75b55fdbBenjamin Kramer unsigned *out_format_support 30168b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer ) 30268b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer { 30368b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer SYNCHRONIZED; 30468b3f0c40e29e461dbbc85370078692df4336b42Michael J. Spencer 305 /* TODO: MSAA, advanced features */ 306 pipe_format format = dxgi_to_pipe_format[dxgi_format]; 307 if(!format) 308 return E_INVALIDARG; 309 310 int support = format_support[format]; 311 if(support < 0) 312 { 313 support = 0; 314 unsigned buffer = D3D11_FORMAT_SUPPORT_BUFFER | D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER | D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER; 315 unsigned sampler_view = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; 316 if(util_format_is_depth_or_stencil(format)) 317 sampler_view |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON; 318 319 /* TODO: do this properly when Gallium drivers actually support index/vertex format queries */ 320 if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_VERTEX_BUFFER) 321 || (screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_INDEX_BUFFER) 322 || format == PIPE_FORMAT_R8_UNORM)) 323 support |= buffer; 324 if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_STREAM_OUTPUT)) 325 support |= buffer | D3D11_FORMAT_SUPPORT_SO_BUFFER; 326 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_1D, 0, PIPE_BIND_SAMPLER_VIEW)) 327 support |= D3D11_FORMAT_SUPPORT_TEXTURE1D | sampler_view; 328 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW)) 329 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view; 330 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW)) 331 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view; 332 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW)) 333 support |= D3D11_FORMAT_SUPPORT_TEXTURE3D | sampler_view; 334 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) 335 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE; 336 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) 337 support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL; 338 if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET)) 339 support |= D3D11_FORMAT_SUPPORT_DISPLAY; 340 format_support[format] = support; 341 } 342 *out_format_support = support; 343 return S_OK; 344 } 345 346 virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels( 347 DXGI_FORMAT format, 348 unsigned sample_count, 349 unsigned *pcount 350 ) 351 { 352 SYNCHRONIZED; 353 354 if(sample_count == 1) 355 *pcount = 1; 356 else 357 *pcount = 0; 358 return S_OK; 359 } 360 361 template<typename T, typename U> 362 bool convert_blend_state(T& to, const U& from, unsigned BlendEnable, unsigned RenderTargetWriteMask) 363 { 364 if(invalid(0 365 || from.SrcBlend >= D3D11_BLEND_COUNT 366 || from.SrcBlendAlpha >= D3D11_BLEND_COUNT 367 || from.DestBlend >= D3D11_BLEND_COUNT 368 || from.DestBlendAlpha >= D3D11_BLEND_COUNT 369 || from.BlendOp >= 6 370 || from.BlendOpAlpha >= 6 371 || !from.BlendOp 372 || !from.BlendOpAlpha 373 )) 374 return false; 375 376 to.blend_enable = BlendEnable; 377 378 to.rgb_func = from.BlendOp - 1; 379 to.alpha_func = from.BlendOpAlpha - 1; 380 381 to.rgb_src_factor = d3d11_to_pipe_blend[from.SrcBlend]; 382 to.alpha_src_factor = d3d11_to_pipe_blend[from.SrcBlendAlpha]; 383 to.rgb_dst_factor = d3d11_to_pipe_blend[from.DestBlend]; 384 to.alpha_dst_factor = d3d11_to_pipe_blend[from.DestBlendAlpha]; 385 386 to.colormask = RenderTargetWriteMask & 0xf; 387 return true; 388 } 389 390#if API >= 11 391 virtual HRESULT STDMETHODCALLTYPE CreateBlendState( 392 const D3D11_BLEND_DESC *blend_state_desc, 393 ID3D11BlendState **out_blend_state 394 ) 395#else 396 virtual HRESULT STDMETHODCALLTYPE CreateBlendState1( 397 const D3D10_BLEND_DESC1 *blend_state_desc, 398 ID3D10BlendState1 **out_blend_state 399 ) 400#endif 401 { 402 SYNCHRONIZED; 403 404 pipe_blend_state state; 405 memset(&state, 0, sizeof(state)); 406 state.alpha_to_coverage = !!blend_state_desc->AlphaToCoverageEnable; 407 state.independent_blend_enable = !!blend_state_desc->IndependentBlendEnable; 408 assert(PIPE_MAX_COLOR_BUFS >= 8); 409 for(unsigned i = 0; i < 8; ++i) 410 { 411 if(!convert_blend_state( 412 state.rt[i], 413 blend_state_desc->RenderTarget[i], 414 blend_state_desc->RenderTarget[i].BlendEnable, 415 blend_state_desc->RenderTarget[i].RenderTargetWriteMask)) 416 return E_INVALIDARG; 417 } 418 419 if(!out_blend_state) 420 return S_FALSE; 421 422 void* object = immediate_pipe->create_blend_state(immediate_pipe, &state); 423 if(!object) 424 return E_FAIL; 425 426 *out_blend_state = new GalliumD3D11BlendState(this, object, *blend_state_desc); 427 return S_OK; 428 } 429 430#if API < 11 431 virtual HRESULT STDMETHODCALLTYPE CreateBlendState( 432 const D3D10_BLEND_DESC *blend_state_desc, 433 ID3D10BlendState **out_blend_state 434 ) 435 { 436 SYNCHRONIZED; 437 438 pipe_blend_state state; 439 memset(&state, 0, sizeof(state)); 440 state.alpha_to_coverage = !!blend_state_desc->AlphaToCoverageEnable; 441 assert(PIPE_MAX_COLOR_BUFS >= 8); 442 for(unsigned i = 0; i < 8; ++i) 443 { 444 if(!convert_blend_state( 445 state.rt[i], 446 *blend_state_desc, 447 blend_state_desc->BlendEnable[i], 448 blend_state_desc->RenderTargetWriteMask[i])) 449 return E_INVALIDARG; 450 } 451 452 for(unsigned i = 1; i < 8; ++i) 453 { 454 if(memcmp(&state.rt[0], &state.rt[i], sizeof(state.rt[0]))) 455 { 456 state.independent_blend_enable = TRUE; 457 break; 458 } 459 } 460 461 void* object = immediate_pipe->create_blend_state(immediate_pipe, &state); 462 if(!object) 463 return E_FAIL; 464 465 *out_blend_state = new GalliumD3D11BlendState(this, object, *blend_state_desc); 466 return S_OK; 467 } 468#endif 469 470 virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilState( 471 const D3D11_DEPTH_STENCIL_DESC *depth_stencil_state_desc, 472 ID3D11DepthStencilState **depth_stencil_state 473 ) 474 { 475 SYNCHRONIZED; 476 477 pipe_depth_stencil_alpha_state state; 478 memset(&state, 0, sizeof(state)); 479 state.depth.enabled = !!depth_stencil_state_desc->DepthEnable; 480 state.depth.writemask = depth_stencil_state_desc->DepthWriteMask; 481 state.depth.func = depth_stencil_state_desc->DepthFunc - 1; 482 state.stencil[0].enabled = !!depth_stencil_state_desc->StencilEnable; 483 state.stencil[0].writemask = depth_stencil_state_desc->StencilWriteMask; 484 state.stencil[0].valuemask = depth_stencil_state_desc->StencilReadMask; 485 state.stencil[0].zpass_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilPassOp]; 486 state.stencil[0].fail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilFailOp]; 487 state.stencil[0].zfail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->FrontFace.StencilDepthFailOp]; 488 state.stencil[0].func = depth_stencil_state_desc->FrontFace.StencilFunc - 1; 489 state.stencil[1].enabled = !!depth_stencil_state_desc->StencilEnable; 490 state.stencil[1].writemask = depth_stencil_state_desc->StencilWriteMask; 491 state.stencil[1].valuemask = depth_stencil_state_desc->StencilReadMask; 492 state.stencil[1].zpass_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilPassOp]; 493 state.stencil[1].fail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilFailOp]; 494 state.stencil[1].zfail_op = d3d11_to_pipe_stencil_op[depth_stencil_state_desc->BackFace.StencilDepthFailOp]; 495 state.stencil[1].func = depth_stencil_state_desc->BackFace.StencilFunc - 1; 496 497 if(!depth_stencil_state) 498 return S_FALSE; 499 500 void* object = immediate_pipe->create_depth_stencil_alpha_state(immediate_pipe, &state); 501 if(!object) 502 return E_FAIL; 503 504 *depth_stencil_state = new GalliumD3D11DepthStencilState(this, object, *depth_stencil_state_desc); 505 return S_OK; 506 } 507 508 virtual HRESULT STDMETHODCALLTYPE CreateRasterizerState( 509 const D3D11_RASTERIZER_DESC *rasterizer_desc, 510 ID3D11RasterizerState **out_rasterizer_state) 511 { 512 SYNCHRONIZED; 513 514 pipe_rasterizer_state state; 515 memset(&state, 0, sizeof(state)); 516 state.gl_rasterization_rules = 1; /* D3D10/11 use GL rules */ 517 state.fill_front = state.fill_back = (rasterizer_desc->FillMode == D3D11_FILL_WIREFRAME) ? PIPE_POLYGON_MODE_LINE : PIPE_POLYGON_MODE_FILL; 518 if(rasterizer_desc->CullMode == D3D11_CULL_FRONT) 519 state.cull_face = PIPE_FACE_FRONT; 520 else if(rasterizer_desc->CullMode == D3D11_CULL_BACK) 521 state.cull_face = PIPE_FACE_BACK; 522 else 523 state.cull_face = PIPE_FACE_NONE; 524 state.front_ccw = !!rasterizer_desc->FrontCounterClockwise; 525 state.offset_tri = state.offset_line = state.offset_point = rasterizer_desc->SlopeScaledDepthBias || rasterizer_desc->DepthBias; 526 state.offset_scale = rasterizer_desc->SlopeScaledDepthBias; 527 state.offset_units = rasterizer_desc->DepthBias; 528 state.offset_clamp = rasterizer_desc->DepthBiasClamp; 529 state.scissor = !!rasterizer_desc->ScissorEnable; 530 state.multisample = !!rasterizer_desc->MultisampleEnable; 531 state.line_smooth = !!rasterizer_desc->AntialiasedLineEnable; 532 state.flatshade_first = 1; 533 state.line_width = 1.0f; 534 state.point_size = 1.0f; 535 536 /* TODO: is this correct? */ 537 state.point_quad_rasterization = 1; 538 539 if(!out_rasterizer_state) 540 return S_FALSE; 541 542 void* object = immediate_pipe->create_rasterizer_state(immediate_pipe, &state); 543 if(!object) 544 return E_FAIL; 545 546 *out_rasterizer_state = new GalliumD3D11RasterizerState(this, object, *rasterizer_desc, !rasterizer_desc->DepthClipEnable); 547 return S_OK; 548 } 549 550 virtual HRESULT STDMETHODCALLTYPE CreateSamplerState( 551 const D3D11_SAMPLER_DESC *sampler_desc, 552 ID3D11SamplerState **out_sampler_state) 553 { 554 SYNCHRONIZED; 555 556 pipe_sampler_state state; 557 memset(&state, 0, sizeof(state)); 558 state.normalized_coords = 1; 559 state.min_mip_filter = (sampler_desc->Filter & 1); 560 state.mag_img_filter = ((sampler_desc->Filter >> 2) & 1); 561 state.min_img_filter = ((sampler_desc->Filter >> 4) & 1); 562 if(sampler_desc->Filter & 0x40) 563 state.max_anisotropy = sampler_desc->MaxAnisotropy; 564 if(sampler_desc->Filter & 0x80) 565 { 566 state.compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE; 567 state.compare_func = sampler_desc->ComparisonFunc; 568 } 569 state.wrap_s = d3d11_to_pipe_wrap[sampler_desc->AddressU]; 570 state.wrap_t = d3d11_to_pipe_wrap[sampler_desc->AddressV]; 571 state.wrap_r = d3d11_to_pipe_wrap[sampler_desc->AddressW]; 572 state.lod_bias = sampler_desc->MipLODBias; 573 memcpy(state.border_color.f, sampler_desc->BorderColor, sizeof(state.border_color)); 574 state.min_lod = sampler_desc->MinLOD; 575 state.max_lod = sampler_desc->MaxLOD; 576 577 if(!out_sampler_state) 578 return S_FALSE; 579 580 void* object = immediate_pipe->create_sampler_state(immediate_pipe, &state); 581 if(!object) 582 return E_FAIL; 583 584 *out_sampler_state = new GalliumD3D11SamplerState(this, object, *sampler_desc); 585 return S_OK; 586 } 587 588 virtual HRESULT STDMETHODCALLTYPE CreateInputLayout( 589 const D3D11_INPUT_ELEMENT_DESC *input_element_descs, 590 unsigned count, 591 const void *shader_bytecode_with_input_signature, 592 SIZE_T bytecode_length, 593 ID3D11InputLayout **out_input_layout) 594 { 595 SYNCHRONIZED; 596 597 if(count > D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT) 598 return E_INVALIDARG; 599 assert(D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT <= PIPE_MAX_ATTRIBS); 600 601 // putting semantics matching in the core API seems to be a (minor) design mistake 602 603 struct dxbc_chunk_signature* sig = dxbc_find_signature(shader_bytecode_with_input_signature, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); 604 D3D11_SIGNATURE_PARAMETER_DESC* params; 605 unsigned num_params = dxbc_parse_signature(sig, ¶ms); 606 607 typedef std::unordered_map<std::pair<c_string, unsigned>, unsigned> semantic_to_idx_map_t; 608 semantic_to_idx_map_t semantic_to_idx_map; 609 for(unsigned i = 0; i < count; ++i) 610 semantic_to_idx_map[std::make_pair(c_string(input_element_descs[i].SemanticName), input_element_descs[i].SemanticIndex)] = i; 611 612 struct pipe_vertex_element elements[D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT]; 613 614 unsigned num_params_to_use = std::min(num_params, (unsigned)D3D11_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT); 615 for(unsigned i = 0; i < num_params_to_use; ++i) 616 { 617 int idx = -1; 618 semantic_to_idx_map_t::iterator iter = semantic_to_idx_map.find(std::make_pair(c_string(params[i].SemanticName), params[i].SemanticIndex)); 619 if(iter != semantic_to_idx_map.end()) 620 idx = iter->second; 621 622 // 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? 623 // 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) 624 memset(&elements[i], 0, sizeof(elements[i])); 625 if(idx >= 0) 626 { 627 elements[i].src_format = dxgi_to_pipe_format[input_element_descs[idx].Format]; 628 elements[i].src_offset = input_element_descs[idx].AlignedByteOffset; 629 elements[i].vertex_buffer_index = input_element_descs[idx].InputSlot; 630 elements[i].instance_divisor = input_element_descs[idx].InstanceDataStepRate; 631 } 632 } 633 634 free(params); 635 636 if(!out_input_layout) 637 return S_FALSE; 638 639 void* object = immediate_pipe->create_vertex_elements_state(immediate_pipe, num_params_to_use, elements); 640 if(!object) 641 return E_FAIL; 642 643 *out_input_layout = new GalliumD3D11InputLayout(this, object); 644 return S_OK; 645 } 646 647 static unsigned d3d11_to_pipe_bind_flags(unsigned bind_flags) 648 { 649 unsigned bind = 0; 650 if(bind_flags & D3D11_BIND_VERTEX_BUFFER) 651 bind |= PIPE_BIND_VERTEX_BUFFER; 652 if(bind_flags & D3D11_BIND_INDEX_BUFFER) 653 bind |= PIPE_BIND_INDEX_BUFFER; 654 if(bind_flags & D3D11_BIND_CONSTANT_BUFFER) 655 bind |= PIPE_BIND_CONSTANT_BUFFER; 656 if(bind_flags & D3D11_BIND_SHADER_RESOURCE) 657 bind |= PIPE_BIND_SAMPLER_VIEW; 658 if(bind_flags & D3D11_BIND_STREAM_OUTPUT) 659 bind |= PIPE_BIND_STREAM_OUTPUT; 660 if(bind_flags & D3D11_BIND_RENDER_TARGET) 661 bind |= PIPE_BIND_RENDER_TARGET; 662 if(bind_flags & D3D11_BIND_DEPTH_STENCIL) 663 bind |= PIPE_BIND_DEPTH_STENCIL; 664 return bind; 665 } 666 667 inline HRESULT create_resource( 668 pipe_texture_target target, 669 unsigned width, 670 unsigned height, 671 unsigned depth, 672 unsigned mip_levels, 673 unsigned array_size, 674 DXGI_FORMAT format, 675 const DXGI_SAMPLE_DESC* SampleDesc, 676 D3D11_USAGE usage, 677 unsigned bind_flags, 678 unsigned c_p_u_access_flags, 679 unsigned misc_flags, 680 const D3D11_SUBRESOURCE_DATA *initial_data, 681 DXGI_USAGE dxgi_usage, 682 struct pipe_resource** ppresource 683 ) 684 { 685 if(invalid(format >= DXGI_FORMAT_COUNT)) 686 return E_INVALIDARG; 687 if(misc_flags & D3D11_RESOURCE_MISC_TEXTURECUBE) 688 { 689 if(target != PIPE_TEXTURE_2D) 690 return E_INVALIDARG; 691 target = PIPE_TEXTURE_CUBE; 692 693 if(array_size != 6) 694 return E_NOTIMPL; 695 } 696 else 697 { 698 if(array_size > 1) 699 return E_NOTIMPL; 700 array_size = 1; 701 } 702 /* TODO: msaa */ 703 struct pipe_resource templat; 704 memset(&templat, 0, sizeof(templat)); 705 templat.target = target; 706 templat.width0 = width; 707 templat.height0 = height; 708 templat.depth0 = depth; 709 if(mip_levels) 710 templat.last_level = mip_levels - 1; 711 else 712 templat.last_level = MAX2(MAX2(util_logbase2(templat.width0), util_logbase2(templat.height0)), util_logbase2(templat.depth0)); 713 templat.format = dxgi_to_pipe_format[format]; 714 templat.bind = d3d11_to_pipe_bind_flags(bind_flags); 715 if(c_p_u_access_flags & D3D11_CPU_ACCESS_READ) 716 templat.bind |= PIPE_BIND_TRANSFER_READ; 717 if(c_p_u_access_flags & D3D11_CPU_ACCESS_WRITE) 718 templat.bind |= PIPE_BIND_TRANSFER_WRITE; 719 if(misc_flags & D3D11_RESOURCE_MISC_SHARED) 720 templat.bind |= PIPE_BIND_SHARED; 721 if(misc_flags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) 722 templat.bind |= PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE; 723 if(dxgi_usage & DXGI_USAGE_BACK_BUFFER) 724 templat.bind |= PIPE_BIND_DISPLAY_TARGET; 725 templat.usage = d3d11_to_pipe_usage[usage]; 726 if(invalid(!templat.format)) 727 return E_NOTIMPL; 728 729 if(!ppresource) 730 return S_FALSE; 731 732 struct pipe_resource* resource = screen->resource_create(screen, &templat); 733 if(!resource) 734 return E_FAIL; 735 if(initial_data) 736 { 737 for(unsigned slice = 0; slice < array_size; ++slice) 738 { 739 for(unsigned level = 0; level <= templat.last_level; ++level) 740 { 741 struct pipe_box box; 742 box.x = box.y = 0; 743 box.z = slice; 744 box.width = u_minify(width, level); 745 box.height = u_minify(height, level); 746 box.depth = 1; 747 immediate_pipe->transfer_inline_write(immediate_pipe, resource, level, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_UNSYNCHRONIZED, &box, initial_data->pSysMem, initial_data->SysMemPitch, initial_data->SysMemSlicePitch); 748 ++initial_data; 749 } 750 } 751 } 752 *ppresource = resource; 753 return S_OK; 754 } 755 756 static unsigned d3d_to_dxgi_usage(unsigned bind, unsigned misc) 757 { 758 unsigned dxgi_usage = 0; 759 if(bind |= D3D11_BIND_RENDER_TARGET) 760 dxgi_usage |= DXGI_USAGE_RENDER_TARGET_OUTPUT; 761 if(bind & D3D11_BIND_SHADER_RESOURCE) 762 dxgi_usage |= DXGI_USAGE_SHADER_INPUT; 763#if API >= 11 764 if(bind & D3D11_BIND_UNORDERED_ACCESS) 765 dxgi_usage |= DXGI_USAGE_UNORDERED_ACCESS; 766#endif 767 if(misc & D3D11_RESOURCE_MISC_SHARED) 768 dxgi_usage |= DXGI_USAGE_SHARED; 769 return dxgi_usage; 770 } 771 772 virtual HRESULT STDMETHODCALLTYPE CreateTexture1D( 773 const D3D11_TEXTURE1D_DESC *desc, 774 const D3D11_SUBRESOURCE_DATA *initial_data, 775 ID3D11Texture1D **out_texture1d) 776 { 777 SYNCHRONIZED; 778 779 struct pipe_resource* resource; 780 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 781 HRESULT hr = create_resource(PIPE_TEXTURE_1D, desc->Width, 1, 1, desc->MipLevels, desc->ArraySize, desc->Format, 0, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_texture1d ? &resource : 0); 782 if(hr != S_OK) 783 return hr; 784 D3D11_TEXTURE1D_DESC cdesc = *desc; 785 cdesc.MipLevels = resource->last_level + 1; 786 *out_texture1d = new GalliumD3D11Texture1D(this, resource, cdesc, dxgi_usage); 787 return S_OK; 788 } 789 790 virtual HRESULT STDMETHODCALLTYPE CreateTexture2D( 791 const D3D11_TEXTURE2D_DESC *desc, 792 const D3D11_SUBRESOURCE_DATA *initial_data, 793 ID3D11Texture2D **out_texture2d) 794 { 795 SYNCHRONIZED; 796 797 struct pipe_resource* resource; 798 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 799 HRESULT hr = create_resource(PIPE_TEXTURE_2D, desc->Width, desc->Height, 1, desc->MipLevels, desc->ArraySize, desc->Format, &desc->SampleDesc, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_texture2d ? &resource : 0); 800 if(hr != S_OK) 801 return hr; 802 D3D11_TEXTURE2D_DESC cdesc = *desc; 803 cdesc.MipLevels = resource->last_level + 1; 804 if(cdesc.MipLevels == 1 && cdesc.ArraySize == 1) 805 *out_texture2d = new GalliumD3D11Surface(this, resource, cdesc, dxgi_usage); 806 else 807 *out_texture2d = new GalliumD3D11Texture2D(this, resource, cdesc, dxgi_usage); 808 return S_OK; 809 } 810 811 virtual HRESULT STDMETHODCALLTYPE CreateTexture3D( 812 const D3D11_TEXTURE3D_DESC *desc, 813 const D3D11_SUBRESOURCE_DATA *initial_data, 814 ID3D11Texture3D **out_texture3d) 815 { 816 SYNCHRONIZED; 817 818 struct pipe_resource* resource; 819 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 820 HRESULT hr = create_resource(PIPE_TEXTURE_3D, desc->Width, desc->Height, desc->Depth, desc->MipLevels, 1, desc->Format, 0, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_texture3d ? &resource : 0); 821 if(hr != S_OK) 822 return hr; 823 D3D11_TEXTURE3D_DESC cdesc = *desc; 824 cdesc.MipLevels = resource->last_level + 1; 825 *out_texture3d = new GalliumD3D11Texture3D(this, resource, cdesc, dxgi_usage); 826 return S_OK; 827 } 828 829 virtual HRESULT STDMETHODCALLTYPE CreateBuffer( 830 const D3D11_BUFFER_DESC *desc, 831 const D3D11_SUBRESOURCE_DATA *initial_data, 832 ID3D11Buffer **out_buffer) 833 { 834 SYNCHRONIZED; 835 836 struct pipe_resource* resource; 837 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc->BindFlags, desc->MiscFlags); 838 HRESULT hr = create_resource(PIPE_BUFFER, desc->ByteWidth, 1, 1, 1, 1, DXGI_FORMAT_R8_UNORM, 0, desc->Usage, desc->BindFlags, desc->CPUAccessFlags, desc->MiscFlags, initial_data, dxgi_usage, out_buffer ? &resource : 0); 839 if(hr != S_OK) 840 return hr; 841 *out_buffer = new GalliumD3D11Buffer(this, resource, *desc, dxgi_usage); 842 return S_OK; 843 } 844 845 virtual HRESULT STDMETHODCALLTYPE OpenGalliumResource( 846 struct pipe_resource* resource, 847 IUnknown** dxgi_resource) 848 { 849 SYNCHRONIZED; 850 851 /* TODO: maybe support others */ 852 assert(resource->target == PIPE_TEXTURE_2D); 853 *dxgi_resource = 0; 854 D3D11_TEXTURE2D_DESC desc; 855 memset(&desc, 0, sizeof(desc)); 856 desc.Width = resource->width0; 857 desc.Height = resource->height0; 858 init_pipe_to_dxgi_format(); 859 desc.Format = pipe_to_dxgi_format[resource->format]; 860 desc.SampleDesc.Count = resource->nr_samples; 861 desc.SampleDesc.Quality = 0; 862 desc.ArraySize = 1; 863 desc.MipLevels = resource->last_level + 1; 864 desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; 865 if(resource->bind & PIPE_BIND_RENDER_TARGET) 866 desc.BindFlags |= D3D11_BIND_RENDER_TARGET; 867 if(resource->bind & PIPE_BIND_DEPTH_STENCIL) 868 desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; 869 if(resource->bind & PIPE_BIND_SAMPLER_VIEW) 870 desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; 871 if(resource->bind & PIPE_BIND_SHARED) 872 desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; 873 DXGI_USAGE dxgi_usage = d3d_to_dxgi_usage(desc.BindFlags, desc.MiscFlags); 874 if(desc.MipLevels == 1 && desc.ArraySize == 1) 875 *dxgi_resource = (ID3D11Texture2D*)new GalliumD3D11Surface(this, resource, desc, dxgi_usage); 876 else 877 *dxgi_resource = (ID3D11Texture2D*)new GalliumD3D11Texture2D(this, resource, desc, dxgi_usage); 878 return S_OK; 879 } 880 881 virtual HRESULT STDMETHODCALLTYPE CreateSurface( 882 const DXGI_SURFACE_DESC *dxgi_desc, 883 unsigned count, 884 DXGI_USAGE usage, 885 const DXGI_SHARED_RESOURCE *shared_resource, 886 IDXGISurface **out_surface) 887 { 888 SYNCHRONIZED; 889 890 D3D11_TEXTURE2D_DESC desc; 891 memset(&desc, 0, sizeof(desc)); 892 893 struct pipe_resource* resource; 894 desc.Width = dxgi_desc->Width; 895 desc.Height = dxgi_desc->Height; 896 desc.Format = dxgi_desc->Format; 897 desc.SampleDesc = dxgi_desc->SampleDesc; 898 desc.ArraySize = count; 899 desc.MipLevels = 1; 900 desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; 901 if(usage & DXGI_USAGE_RENDER_TARGET_OUTPUT) 902 desc.BindFlags |= D3D11_BIND_RENDER_TARGET; 903 if(usage & DXGI_USAGE_SHADER_INPUT) 904 desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; 905#if API >= 11 906 if(usage & DXGI_USAGE_UNORDERED_ACCESS) 907 desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; 908#endif 909 if(usage & DXGI_USAGE_SHARED) 910 desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; 911 HRESULT hr = create_resource(PIPE_TEXTURE_2D, dxgi_desc->Width, dxgi_desc->Height, 1, 1, count, dxgi_desc->Format, &dxgi_desc->SampleDesc, D3D11_USAGE_DEFAULT, desc.BindFlags, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, desc.MiscFlags, 0, usage, &resource); 912 if(hr != S_OK) 913 return hr; 914 *out_surface = new GalliumD3D11Surface(this, resource, desc, usage); 915 return S_OK; 916 } 917 918 virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView( 919 ID3D11Resource *iresource, 920 const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, 921 ID3D11ShaderResourceView **out_srv) 922 { 923#if API >= 11 924 D3D11_SHADER_RESOURCE_VIEW_DESC def_desc; 925#else 926 if(desc->ViewDimension == D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY) 927 return E_INVALIDARG; 928 D3D10_SHADER_RESOURCE_VIEW_DESC1 desc1; 929 memset(&desc1, 0, sizeof(desc1)); 930 memcpy(&desc1, desc, sizeof(*desc)); 931 return CreateShaderResourceView1(iresource, &desc1, (ID3D10ShaderResourceView1**)out_srv); 932 } 933 934 virtual HRESULT STDMETHODCALLTYPE CreateShaderResourceView1( 935 ID3D11Resource *iresource, 936 const D3D10_SHADER_RESOURCE_VIEW_DESC1 *desc, 937 ID3D10ShaderResourceView1 **out_srv) 938 { 939 D3D10_SHADER_RESOURCE_VIEW_DESC1 def_desc; 940#endif 941 SYNCHRONIZED; 942 943 if(!desc) 944 { 945 struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource; 946 init_pipe_to_dxgi_format(); 947 memset(&def_desc, 0, sizeof(def_desc)); 948 def_desc.Format = pipe_to_dxgi_format[resource->format]; 949 switch(resource->target) 950 { 951 case PIPE_BUFFER: 952 def_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; 953 def_desc.Buffer.ElementWidth = resource->width0; 954 break; 955 case PIPE_TEXTURE_1D: 956 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; 957 def_desc.Texture1D.MipLevels = resource->last_level + 1; 958 break; 959 case PIPE_TEXTURE_2D: 960 case PIPE_TEXTURE_RECT: 961 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 962 def_desc.Texture2D.MipLevels = resource->last_level + 1; 963 break; 964 case PIPE_TEXTURE_3D: 965 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; 966 def_desc.Texture3D.MipLevels = resource->last_level + 1; 967 break; 968 case PIPE_TEXTURE_CUBE: 969 def_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; 970 def_desc.TextureCube.MipLevels = resource->last_level + 1; 971 break; 972 default: 973 return E_INVALIDARG; 974 } 975 desc = &def_desc; 976 } 977 978 struct pipe_sampler_view templat; 979 memset(&templat, 0, sizeof(templat)); 980 if(invalid(format >= DXGI_FORMAT_COUNT)) 981 return E_INVALIDARG; 982 templat.format = dxgi_to_pipe_format[desc->Format]; 983 if(!templat.format) 984 return E_NOTIMPL; 985 templat.swizzle_r = PIPE_SWIZZLE_RED; 986 templat.swizzle_g = PIPE_SWIZZLE_GREEN; 987 templat.swizzle_b = PIPE_SWIZZLE_BLUE; 988 templat.swizzle_a = PIPE_SWIZZLE_ALPHA; 989 990 templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource; 991 switch(desc->ViewDimension) 992 { 993 case D3D11_SRV_DIMENSION_TEXTURE1D: 994 case D3D11_SRV_DIMENSION_TEXTURE2D: 995 case D3D11_SRV_DIMENSION_TEXTURE3D: 996 case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: 997 case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: 998 /* yes, this works for all of these types (but TODO: texture arrays) */ 999 templat.u.tex.first_level = desc->Texture1D.MostDetailedMip; 1000 templat.u.tex.last_level = templat.u.tex.first_level + desc->Texture1D.MipLevels - 1; 1001 break; 1002 case D3D11_SRV_DIMENSION_BUFFER: 1003 case D3D11_SRV_DIMENSION_TEXTURE2DMS: 1004 case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: 1005 return E_NOTIMPL; 1006 default: 1007 return E_INVALIDARG; 1008 } 1009 1010 if(!out_srv) 1011 return S_FALSE; 1012 1013 struct pipe_sampler_view* view = immediate_pipe->create_sampler_view(immediate_pipe, templat.texture, &templat); 1014 if(!view) 1015 return E_FAIL; 1016 *out_srv = new GalliumD3D11ShaderResourceView(this, (GalliumD3D11Resource<>*)iresource, view, *desc); 1017 return S_OK; 1018 } 1019 1020#if API >= 11 1021 virtual HRESULT STDMETHODCALLTYPE CreateUnorderedAccessView( 1022 ID3D11Resource *resource, 1023 const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc, 1024 ID3D11UnorderedAccessView **out_uav) 1025 { 1026 SYNCHRONIZED; 1027 1028 return E_NOTIMPL; 1029 1030 // remember to return S_FALSE and not crash if out_u_a_view == 0 and parameters are valid 1031 } 1032#endif 1033 1034 virtual HRESULT STDMETHODCALLTYPE CreateRenderTargetView( 1035 ID3D11Resource *iresource, 1036 const D3D11_RENDER_TARGET_VIEW_DESC *desc, 1037 ID3D11RenderTargetView **out_rtv) 1038 { 1039 SYNCHRONIZED; 1040 1041 D3D11_RENDER_TARGET_VIEW_DESC def_desc; 1042 if(!desc) 1043 { 1044 struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource; 1045 init_pipe_to_dxgi_format(); 1046 memset(&def_desc, 0, sizeof(def_desc)); 1047 def_desc.Format = pipe_to_dxgi_format[resource->format]; 1048 switch(resource->target) 1049 { 1050 case PIPE_BUFFER: 1051 def_desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER; 1052 def_desc.Buffer.ElementWidth = resource->width0; 1053 break; 1054 case PIPE_TEXTURE_1D: 1055 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; 1056 break; 1057 case PIPE_TEXTURE_2D: 1058 case PIPE_TEXTURE_RECT: 1059 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 1060 break; 1061 case PIPE_TEXTURE_3D: 1062 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; 1063 def_desc.Texture3D.WSize = resource->depth0; 1064 break; 1065 case PIPE_TEXTURE_CUBE: 1066 def_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 1067 def_desc.Texture2DArray.ArraySize = 6; 1068 break; 1069 default: 1070 return E_INVALIDARG; 1071 } 1072 desc = &def_desc; 1073 } 1074 1075 struct pipe_surface templat; 1076 memset(&templat, 0, sizeof(templat)); 1077 if(invalid(desc->format >= DXGI_FORMAT_COUNT)) 1078 return E_INVALIDARG; 1079 templat.format = dxgi_to_pipe_format[desc->Format]; 1080 if(!templat.format) 1081 return E_NOTIMPL; 1082 templat.usage = PIPE_BIND_RENDER_TARGET; 1083 templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource; 1084 1085 switch(desc->ViewDimension) 1086 { 1087 case D3D11_RTV_DIMENSION_TEXTURE1D: 1088 case D3D11_RTV_DIMENSION_TEXTURE2D: 1089 templat.u.tex.level = desc->Texture1D.MipSlice; 1090 break; 1091 case D3D11_RTV_DIMENSION_TEXTURE3D: 1092 templat.u.tex.level = desc->Texture3D.MipSlice; 1093 templat.u.tex.first_layer = desc->Texture3D.FirstWSlice; 1094 /* XXX FIXME */ 1095 templat.u.tex.last_layer = desc->Texture3D.FirstWSlice; 1096 break; 1097 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: 1098 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: 1099 templat.u.tex.level = desc->Texture1DArray.MipSlice; 1100 templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice; 1101 /* XXX FIXME */ 1102 templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice; 1103 break; 1104 case D3D11_RTV_DIMENSION_BUFFER: 1105 case D3D11_RTV_DIMENSION_TEXTURE2DMS: 1106 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: 1107 return E_NOTIMPL; 1108 default: 1109 return E_INVALIDARG; 1110 } 1111 1112 if(!out_rtv) 1113 return S_FALSE; 1114 1115 struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat); 1116 if(!surface) 1117 return E_FAIL; 1118 *out_rtv = new GalliumD3D11RenderTargetView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc); 1119 return S_OK; 1120 } 1121 1122 virtual HRESULT STDMETHODCALLTYPE CreateDepthStencilView( 1123 ID3D11Resource *iresource, 1124 const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, 1125 ID3D11DepthStencilView **out_depth_stencil_view) 1126 { 1127 SYNCHRONIZED; 1128 1129 D3D11_DEPTH_STENCIL_VIEW_DESC def_desc; 1130 if(!desc) 1131 { 1132 struct pipe_resource* resource = ((GalliumD3D11Resource<>*)iresource)->resource; 1133 init_pipe_to_dxgi_format(); 1134 memset(&def_desc, 0, sizeof(def_desc)); 1135 def_desc.Format = pipe_to_dxgi_format[resource->format]; 1136 switch(resource->target) 1137 { 1138 case PIPE_TEXTURE_1D: 1139 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; 1140 break; 1141 case PIPE_TEXTURE_2D: 1142 case PIPE_TEXTURE_RECT: 1143 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 1144 break; 1145 case PIPE_TEXTURE_CUBE: 1146 def_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; 1147 def_desc.Texture2DArray.ArraySize = 6; 1148 break; 1149 default: 1150 return E_INVALIDARG; 1151 } 1152 desc = &def_desc; 1153 } 1154 1155 struct pipe_surface templat; 1156 memset(&templat, 0, sizeof(templat)); 1157 if(invalid(desc->format >= DXGI_FORMAT_COUNT)) 1158 return E_INVALIDARG; 1159 templat.format = dxgi_to_pipe_format[desc->Format]; 1160 if(!templat.format) 1161 return E_NOTIMPL; 1162 templat.usage = PIPE_BIND_DEPTH_STENCIL; 1163 templat.texture = ((GalliumD3D11Resource<>*)iresource)->resource; 1164 1165 switch(desc->ViewDimension) 1166 { 1167 case D3D11_DSV_DIMENSION_TEXTURE1D: 1168 case D3D11_DSV_DIMENSION_TEXTURE2D: 1169 templat.u.tex.level = desc->Texture1D.MipSlice; 1170 break; 1171 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: 1172 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: 1173 templat.u.tex.level = desc->Texture1DArray.MipSlice; 1174 templat.u.tex.first_layer = desc->Texture1DArray.FirstArraySlice; 1175 /* XXX FIXME */ 1176 templat.u.tex.last_layer = desc->Texture1DArray.FirstArraySlice; 1177 break; 1178 case D3D11_DSV_DIMENSION_TEXTURE2DMS: 1179 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: 1180 return E_NOTIMPL; 1181 default: 1182 return E_INVALIDARG; 1183 } 1184 1185 if(!out_depth_stencil_view) 1186 return S_FALSE; 1187 1188 struct pipe_surface* surface = immediate_pipe->create_surface(immediate_pipe, templat.texture, &templat); 1189 if(!surface) 1190 return E_FAIL; 1191 *out_depth_stencil_view = new GalliumD3D11DepthStencilView(this, (GalliumD3D11Resource<>*)iresource, surface, *desc); 1192 return S_OK; 1193 } 1194 1195 GalliumD3D11Shader<>* create_stage_shader(unsigned type, const void* shader_bytecode, SIZE_T bytecode_length 1196#if API >= 11 1197 , ID3D11ClassLinkage *class_linkage 1198#endif 1199 ) 1200 { 1201 bool dump = debug_get_option_dump_shaders(); 1202 1203 dxbc_chunk_header* sm4_chunk = dxbc_find_shader_bytecode(shader_bytecode, bytecode_length); 1204 if(!sm4_chunk) 1205 return 0; 1206 1207 std::auto_ptr<sm4_program> sm4(sm4_parse(sm4_chunk + 1, bswap_le32(sm4_chunk->size))); 1208 if(!sm4.get()) 1209 return 0; 1210 1211 if(dump) 1212 sm4->dump(); 1213 1214 struct dxbc_chunk_signature* sig; 1215 1216 sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_INPUT_SIGNATURE); 1217 if(sig) 1218 sm4->num_params_in = dxbc_parse_signature(sig, &sm4->params_in); 1219 1220 sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_OUTPUT_SIGNATURE); 1221 if(sig) 1222 sm4->num_params_out = dxbc_parse_signature(sig, &sm4->params_out); 1223 1224 sig = dxbc_find_signature(shader_bytecode, bytecode_length, DXBC_FIND_PATCH_SIGNATURE); 1225 if(sig) 1226 sm4->num_params_patch = dxbc_parse_signature(sig, &sm4->params_patch); 1227 1228 struct pipe_shader_state tgsi_shader; 1229 memset(&tgsi_shader, 0, sizeof(tgsi_shader)); 1230 tgsi_shader.tokens = (const tgsi_token*)sm4_to_tgsi(*sm4); 1231 if(!tgsi_shader.tokens) 1232 return 0; 1233 1234 if(dump) 1235 tgsi_dump(tgsi_shader.tokens, 0); 1236 1237 void* shader_cso; 1238 GalliumD3D11Shader<>* shader; 1239 1240 switch(type) 1241 { 1242 case PIPE_SHADER_VERTEX: 1243 shader_cso = immediate_pipe->create_vs_state(immediate_pipe, &tgsi_shader); 1244 shader = (GalliumD3D11Shader<>*)new GalliumD3D11VertexShader(this, shader_cso); 1245 break; 1246 case PIPE_SHADER_FRAGMENT: 1247 shader_cso = immediate_pipe->create_fs_state(immediate_pipe, &tgsi_shader); 1248 shader = (GalliumD3D11Shader<>*)new GalliumD3D11PixelShader(this, shader_cso); 1249 break; 1250 case PIPE_SHADER_GEOMETRY: 1251 shader_cso = immediate_pipe->create_gs_state(immediate_pipe, &tgsi_shader); 1252 shader = (GalliumD3D11Shader<>*)new GalliumD3D11GeometryShader(this, shader_cso); 1253 break; 1254 default: 1255 shader_cso = 0; 1256 shader = 0; 1257 break; 1258 } 1259 1260 free((void*)tgsi_shader.tokens); 1261 return shader; 1262 } 1263 1264#if API >= 11 1265#define CREATE_SHADER_ARGS \ 1266 const void *shader_bytecode, \ 1267 SIZE_T bytecode_length, \ 1268 ID3D11ClassLinkage *class_linkage 1269#define PASS_SHADER_ARGS shader_bytecode, bytecode_length, class_linkage 1270#else 1271#define CREATE_SHADER_ARGS \ 1272 const void *shader_bytecode, \ 1273 SIZE_T bytecode_length 1274#define PASS_SHADER_ARGS shader_bytecode, bytecode_length 1275#endif 1276 1277#define IMPLEMENT_CREATE_SHADER(Stage, GALLIUM) \ 1278 virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \ 1279 CREATE_SHADER_ARGS, \ 1280 ID3D11##Stage##Shader **out_shader) \ 1281 { \ 1282 SYNCHRONIZED; \ 1283 GalliumD3D11##Stage##Shader* shader = (GalliumD3D11##Stage##Shader*)create_stage_shader(PIPE_SHADER_##GALLIUM, PASS_SHADER_ARGS); \ 1284 if(!shader) \ 1285 return E_FAIL; \ 1286 if(out_shader) \ 1287 { \ 1288 *out_shader = shader; \ 1289 return S_OK; \ 1290 } \ 1291 else \ 1292 { \ 1293 shader->Release(); \ 1294 return S_FALSE; \ 1295 } \ 1296 } 1297 1298#define IMPLEMENT_NOTIMPL_CREATE_SHADER(Stage) \ 1299 virtual HRESULT STDMETHODCALLTYPE Create##Stage##Shader( \ 1300 CREATE_SHADER_ARGS, \ 1301 ID3D11##Stage##Shader **out_shader) \ 1302 { \ 1303 return E_NOTIMPL; \ 1304 } 1305 1306 IMPLEMENT_CREATE_SHADER(Vertex, VERTEX) 1307 IMPLEMENT_CREATE_SHADER(Pixel, FRAGMENT) 1308 IMPLEMENT_CREATE_SHADER(Geometry, GEOMETRY) 1309#if API >= 11 1310 IMPLEMENT_NOTIMPL_CREATE_SHADER(Hull) 1311 IMPLEMENT_NOTIMPL_CREATE_SHADER(Domain) 1312 IMPLEMENT_NOTIMPL_CREATE_SHADER(Compute) 1313#endif 1314 1315 virtual HRESULT STDMETHODCALLTYPE CreateGeometryShaderWithStreamOutput( 1316 const void *shader_bytecode, 1317 SIZE_T bytecode_length, 1318 const D3D11_SO_DECLARATION_ENTRY *so_declaration, 1319 unsigned num_entries, 1320#if API >= 11 1321 const unsigned *buffer_strides, 1322 unsigned num_strides, 1323 unsigned rasterized_stream, 1324 ID3D11ClassLinkage *class_linkage, 1325#else 1326 UINT output_stream_stride, 1327#endif 1328 ID3D11GeometryShader **out_geometry_shader) 1329 { 1330 SYNCHRONIZED; 1331 1332 return E_NOTIMPL; 1333 1334 // remember to return S_FALSE if ppGeometyShader == NULL and the shader is OK 1335 } 1336 1337#if API >= 11 1338 virtual HRESULT STDMETHODCALLTYPE CreateClassLinkage( 1339 ID3D11ClassLinkage **out_linkage) 1340 { 1341 SYNCHRONIZED; 1342 1343 return E_NOTIMPL; 1344 } 1345#endif 1346 1347 virtual HRESULT STDMETHODCALLTYPE CreateQuery( 1348 const D3D11_QUERY_DESC *query_desc, 1349 ID3D11Query **out_query) 1350 { 1351 SYNCHRONIZED; 1352 1353 if(invalid(query_desc->Query >= D3D11_QUERY_COUNT)) 1354 return E_INVALIDARG; 1355 unsigned query_type = d3d11_to_pipe_query[query_desc->Query]; 1356 if(query_type >= PIPE_QUERY_TYPES) 1357 return E_NOTIMPL; 1358 1359 if(!out_query) 1360 return S_FALSE; 1361 1362 struct pipe_query* query = immediate_pipe->create_query(immediate_pipe, query_type); 1363 if(!query) 1364 return E_FAIL; 1365 1366 *out_query = new GalliumD3D11Query(this, query, d3d11_query_size[query_desc->Query], *query_desc); 1367 return S_OK; 1368 } 1369 1370 virtual HRESULT STDMETHODCALLTYPE CreatePredicate( 1371 const D3D11_QUERY_DESC *predicate_desc, 1372 ID3D11Predicate **out_predicate) 1373 { 1374 SYNCHRONIZED; 1375 1376 unsigned query_type; 1377 switch(predicate_desc->Query) 1378 { 1379 case D3D11_QUERY_SO_OVERFLOW_PREDICATE: 1380 query_type = PIPE_QUERY_SO_OVERFLOW_PREDICATE; 1381 break; 1382 case D3D11_QUERY_OCCLUSION_PREDICATE: 1383 query_type = PIPE_QUERY_OCCLUSION_PREDICATE; 1384 break; 1385 default: 1386 return E_INVALIDARG; 1387 } 1388 1389 if(out_predicate) 1390 return S_FALSE; 1391 1392 struct pipe_query* query = immediate_pipe->create_query(immediate_pipe, query_type); 1393 if(!query) 1394 return E_FAIL; 1395 1396 *out_predicate = new GalliumD3D11Predicate(this, query, sizeof(BOOL), *predicate_desc); 1397 return S_OK; 1398 } 1399 1400 1401 virtual HRESULT STDMETHODCALLTYPE CreateCounter( 1402 const D3D11_COUNTER_DESC *counter_desc, 1403 ID3D11Counter **out_counter) 1404 { 1405 SYNCHRONIZED; 1406 1407 return E_NOTIMPL; 1408 1409 // remember to return S_FALSE if out_counter == NULL and everything is OK 1410 } 1411 1412#if API >= 11 1413 virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext( 1414 unsigned context_flags, 1415 ID3D11DeviceContext **out_deferred_context) 1416 { 1417 SYNCHRONIZED; 1418 1419 // TODO: this will have to be implemented using a new Gallium util module 1420 return E_NOTIMPL; 1421 1422 // remember to return S_FALSE if out_counter == NULL and everything is OK 1423 } 1424#endif 1425 1426 virtual HRESULT STDMETHODCALLTYPE OpenSharedResource( 1427 HANDLE resource, 1428 REFIID iid, 1429 void **out_resource) 1430 { 1431 SYNCHRONIZED; 1432 1433 // TODO: the problem here is that we need to communicate dimensions somehow 1434 return E_NOTIMPL; 1435 1436 // remember to return S_FALSE if out_counter == NULL and everything is OK 1437#if 0 1438 struct pipe_resou rce templat; 1439 struct winsys_handle handle; 1440 handle.stride = 0; 1441 handle.handle = resource; 1442 handle.type = DRM_API_HANDLE_TYPE_SHARED; 1443 screen->resource_from_handle(screen, &templat, &handle); 1444#endif 1445 } 1446 1447#if API < 11 1448 /* these are documented as "Not implemented". 1449 * According to the UMDDI documentation, they apparently turn on a 1450 * (width + 1) x (height + 1) convolution filter for 1-bit textures. 1451 * Probably nothing uses these, assuming it has ever been implemented anywhere. 1452 */ 1453 void STDMETHODCALLTYPE SetTextFilterSize( 1454 UINT width, 1455 UINT height 1456 ) 1457 {} 1458 1459 virtual void STDMETHODCALLTYPE GetTextFilterSize( 1460 UINT *width, 1461 UINT *height 1462 ) 1463 {} 1464#endif 1465 1466#if API >= 11 1467 virtual void STDMETHODCALLTYPE RestoreGalliumState() 1468 { 1469 GalliumD3D11ImmediateDeviceContext_RestoreGalliumState(immediate_context); 1470 } 1471 1472 virtual void STDMETHODCALLTYPE RestoreGalliumStateBlitOnly() 1473 { 1474 GalliumD3D11ImmediateDeviceContext_RestoreGalliumStateBlitOnly(immediate_context); 1475 } 1476#endif 1477 1478 virtual struct pipe_context* STDMETHODCALLTYPE GetGalliumContext(void) 1479 { 1480 return immediate_pipe; 1481 } 1482 1483#undef SYNCHRONIZED 1484}; 1485